Previous Up Next

Chapter 5  Basic CFITSIO Interface Routines

This chapter describes the basic routines in the CFITSIO user interface that provide all the functions normally needed to read and write most FITS files. It is recommended that these routines be used for most applications and that the more advanced routines described in the next chapter only be used in special circumstances when necessary.

The following conventions are used in this chapter in the description of each function:

1. Most functions have 2 names: a long descriptive name and a short concise name. Both names are listed on the first line of the following descriptions, separated by a slash (/) character. Programmers may use either name in their programs but the long names are recommended to help document the code and make it easier to read.

2. A right arrow symbol (>) is used in the function descriptions to separate the input parameters from the output parameters in the definition of each routine. This symbol is not actually part of the C calling sequence.

3. The function parameters are defined in more detail in the alphabetical listing in Appendix B.

4. The first argument in almost all the functions is a pointer to a structure of type `fitsfile'. Memory for this structure is allocated by CFITSIO when the FITS file is first opened or created and is freed when the FITS file is closed.

5. The last argument in almost all the functions is the error status parameter. It must be equal to 0 on input, otherwise the function will immediately exit without doing anything. A non-zero output value indicates that an error occurred in the function. In most cases the status value is also returned as the value of the function itself.

5.1  CFITSIO Error Status Routines

1
Return a descriptive text string (30 char max.) corresponding to a CFITSIO error status code.
  void fits_get_errstatus / ffgerr (int status, > char *err_text)
2
Return the top (oldest) 80-character error message from the internal CFITSIO stack of error messages and shift any remaining messages on the stack up one level. Call this routine repeatedly to get each message in sequence. The function returns a value = 0 and a null error message when the error stack is empty.
  int fits_read_errmsg / ffgmsg (char *err_msg)
3
Print out the error message corresponding to the input status value and all the error messages on the CFITSIO stack to the specified file stream (normally to stdout or stderr). If the input status value = 0 then this routine does nothing.
  void fits_report_error / ffrprt (FILE *stream, > status)
4
The fits_write_errmark routine puts an invisible marker on the CFITSIO error stack. The fits_clear_errmark routine can then be used to delete any more recent error messages on the stack, back to the position of the marker. This preserves any older error messages on the stack. The fits_clear_errmsg routine simply clears all the messages (and marks) from the stack. These routines are called without any arguments.
  void fits_write_errmark / ffpmrk (void)
  void fits_clear_errmark / ffcmrk (void)
  void fits_clear_errmsg / ffcmsg (void)

5.2  FITS File Access Routines

1
Open an existing data file.
int fits_open_file / ffopen
    (fitsfile **fptr, char *filename, int iomode, > int *status)

int fits_open_diskfile / ffdkopen
    (fitsfile **fptr, char *filename, int iomode, > int *status)

int fits_open_data / ffdopn
    (fitsfile **fptr, char *filename, int iomode, > int *status)

int fits_open_table / fftopn
    (fitsfile **fptr, char *filename, int iomode, > int *status)

int fits_open_image / ffiopn
    (fitsfile **fptr, char *filename, int iomode, > int *status)

The iomode parameter determines the read/write access allowed in the file and can have values of READONLY (0) or READWRITE (1). The filename parameter gives the name of the file to be opened, followed by an optional argument giving the name or index number of the extension within the FITS file that should be moved to and opened (e.g., myfile.fits+3 or myfile.fits[3] moves to the 3rd extension within the file, and myfile.fits[events] moves to the extension with the keyword EXTNAME = 'EVENTS').

The fits_open_diskfile routine is similar to the fits_open_file routine except that it does not support the extended filename syntax in the input file name. This routine simply tries to open the specified input file on magnetic disk. This routine is mainly for use in cases where the filename (or directory path) contains square or curly bracket characters that would confuse the extended filename parser.

The fits_open_data routine is similar to the fits_open_file routine except that it will move to the first HDU containing significant data, if a HDU name or number to open was not explicitly specified as part of the filename. In this case, it will look for the first IMAGE HDU with NAXIS > 0, or the first table that does not contain the strings `GTI' (Good Time Interval extension) or `OBSTABLE' in the EXTNAME keyword value.

The fits_open_table and fits_open_image routines are similar to fits_open_data except they will move to the first significant table HDU or image HDU in the file, respectively, if a HDU name or number is not specified as part of the filename.

IRAF images (.imh format files) and raw binary data arrays may also be opened with READONLY access. CFITSIO will automatically test if the input file is an IRAF image, and if, so will convert it on the fly into a virtual FITS image before it is opened by the application program. If the input file is a raw binary data array of numbers, then the data type and dimensions of the array must be specified in square brackets following the name of the file (e.g. 'rawfile.dat[i512,512]' opens a 512 x 512 short integer image). See the `Extended File Name Syntax' chapter for more details on how to specify the raw file name. The raw file is converted on the fly into a virtual FITS image in memory that is then opened by the application program with READONLY access.

Programs can read the input file from the 'stdin' file stream if a dash character ('-') is given as the filename. Files can also be opened over the network using FTP or HTTP protocols by supplying the appropriate URL as the filename.

The input file can be modified in various ways to create a virtual file (usually stored in memory) that is then opened by the application program by supplying a filtering or binning specifier in square brackets following the filename. Some of the more common filtering methods are illustrated in the following paragraphs, but users should refer to the 'Extended File Name Syntax' chapter for a complete description of the full file filtering syntax.

When opening an image, a rectangular subset of the physical image may be opened by listing the first and last pixel in each dimension (and optional pixel skipping factor):

myimage.fits[101:200,301:400]

will create and open a 100x100 pixel virtual image of that section of the physical image, and myimage.fits[*,-*] opens a virtual image that is the same size as the physical image but has been flipped in the vertical direction.

When opening a table, the filtering syntax can be used to add or delete columns or keywords in the virtual table: myfile.fits[events][col !time; PI = PHA*1.2] opens a virtual table in which the TIME column has been deleted and a new PI column has been added with a value 1.2 times that of the PHA column. Similarly, one can filter a table to keep only those rows that satisfy a selection criterion: myfile.fits[events][pha > 50] creates and opens a virtual table containing only those rows with a PHA value greater than 50. A large number of boolean and mathematical operators can be used in the selection expression. One can also filter table rows using 'Good Time Interval' extensions, and spatial region filters as in myfile.fits[events][gtifilter()] and myfile.fits[events][regfilter( "stars.rng")].

Finally, table columns may be binned or histogrammed to generate a virtual image. For example, myfile.fits[events][bin (X,Y)=4] will result in a 2-dimensional image calculated by binning the X and Y columns in the event table with a bin size of 4 in each dimension. The TLMINn and TLMAXn keywords will be used by default to determine the range of the image.

A single program can open the same FITS file more than once and then treat the resulting fitsfile pointers as though they were completely independent FITS files. Using this facility, a program can open a FITS file twice, move to 2 different extensions within the file, and then read and write data in those extensions in any order.

2
Create and open a new empty output FITS file.
int fits_create_file / ffinit
    (fitsfile **fptr, char *filename, > int *status)

int fits_create_diskfile / ffdkinit
    (fitsfile **fptr, char *filename, > int *status)

An error will be returned if the specified file already exists, unless the filename is prefixed with an exclamation point (!). In that case CFITSIO will overwrite (delete) any existing file with the same name. Note that the exclamation point is a special UNIX character so if it is used on the command line it must be preceded by a backslash to force the UNIX shell to accept the character as part of the filename.

The output file will be written to the 'stdout' file stream if a dash character ('-') or the string 'stdout' is given as the filename. Similarly, '-.gz' or 'stdout.gz' will cause the file to be gzip compressed before it is written out to the stdout stream.

Optionally, the name of a template file that is used to define the structure of the new file may be specified in parentheses following the output file name. The template file may be another FITS file, in which case the new file, at the time it is opened, will be an exact copy of the template file except that the data structures (images and tables) will be filled with zeros. Alternatively, the template file may be an ASCII format text file containing directives that define the keywords to be created in each HDU of the file. See the 'Extended File Name Syntax' section for a complete description of the template file syntax.

The fits_create_diskfile routine is similar to the fits_create_file routine except that it does not support the extended filename syntax in the input file name. This routine simply tries to create the specified file on magnetic disk. This routine is mainly for use in cases where the filename (or directory path) contains square or curly bracket characters that would confuse the extended filename parser.

3
Close a previously opened FITS file. The first routine simply closes the file, whereas the second one also DELETES THE FILE, which can be useful in cases where a FITS file has been partially created, but then an error occurs which prevents it from being completed.
  int fits_close_file / ffclos (fitsfile *fptr, > int *status)

  int fits_delete_file / ffdelt (fitsfile *fptr, > int *status)
4
Return the name, I/O mode (READONLY or READWRITE), and/or the file type (e.g. 'file://', 'ftp://') of the opened FITS file.
  int fits_file_name / ffflnm (fitsfile *fptr, > char *filename, int *status)

  int fits_file_mode / ffflmd (fitsfile *fptr, > int *iomode, int *status)

  int fits_url_type / ffurlt (fitsfile *fptr, > char *urltype, int *status)

5.3  HDU Access Routines

The following functions perform operations on Header-Data Units (HDUs) as a whole.

1
Move to a different HDU in the file. The first routine moves to a specified absolute HDU number (starting with 1 for the primary array) in the FITS file, and the second routine moves a relative number HDUs forward or backward from the current HDU. A null pointer may be given for the hdutype parameter if it's value is not needed. The third routine moves to the (first) HDU which has the specified extension type and EXTNAME and EXTVER keyword values (or HDUNAME and HDUVER keywords). The hdutype parameter may have a value of IMAGE_HDU, ASCII_TBL, BINARY_TBL, or ANY_HDU where ANY_HDU means that only the extname and extver values will be used to locate the correct extension. If the input value of extver is 0 then the EXTVER keyword is ignored and the first HDU with a matching EXTNAME (or HDUNAME) keyword will be found. If no matching HDU is found in the file then the current HDU will remain unchanged and a status = BAD_HDU_NUM will be returned.
  int fits_movabs_hdu / ffmahd
      (fitsfile *fptr, int hdunum, > int *hdutype, int *status)

  int fits_movrel_hdu / ffmrhd
      (fitsfile *fptr, int nmove, > int *hdutype, int *status)

  int fits_movnam_hdu / ffmnhd
      (fitsfile *fptr, int hdutype, char *extname, int extver, > int *status)
2
Return the total number of HDUs in the FITS file. The current HDU remains unchanged.
  int fits_get_num_hdus / ffthdu
      (fitsfile *fptr, > int *hdunum, int *status)
3
Return the number of the current HDU (CHDU) in the FITS file (where the primary array = 1). This function returns the HDU number rather than a status value.
  int fits_get_hdu_num / ffghdn
      (fitsfile *fptr, > int *hdunum)
4
Return the type of the current HDU in the FITS file. The possible values for hdutype are: IMAGE_HDU, ASCII_TBL, or BINARY_TBL.
  int fits_get_hdu_type / ffghdt
      (fitsfile *fptr, > int *hdutype, int *status)
5
Copy all or part of the HDUs in the FITS file associated with infptr and append them to the end of the FITS file associated with outfptr. If 'previous' is true (not 0), then any HDUs preceding the current HDU in the input file will be copied to the output file. Similarly, 'current' and 'following' determine whether the current HDU, and/or any following HDUs in the input file will be copied to the output file. Thus, if all 3 parameters are true, then the entire input file will be copied. On exit, the current HDU in the input file will be unchanged, and the last HDU in the output file will be the current HDU.
  int fits_copy_file / ffcpfl
      (fitsfile *infptr, fitsfile *outfptr, int previous, int current,
          int following, > int *status)
6
Copy the current HDU from the FITS file associated with infptr and append it to the end of the FITS file associated with outfptr. Space may be reserved for MOREKEYS additional keywords in the output header.
  int fits_copy_hdu / ffcopy
      (fitsfile *infptr, fitsfile *outfptr, int morekeys, > int *status)
7
Copy the header (and not the data) from the CHDU associated with infptr to the CHDU associated with outfptr. If the current output HDU is not completely empty, then the CHDU will be closed and a new HDU will be appended to the output file. An empty output data unit will be created with all values initially = 0).
  int fits_copy_header / ffcphd
      (fitsfile *infptr, fitsfile *outfptr, > int *status)
8
Delete the CHDU in the FITS file. Any following HDUs will be shifted forward in the file, to fill in the gap created by the deleted HDU. In the case of deleting the primary array (the first HDU in the file) then the current primary array will be replace by a null primary array containing the minimum set of required keywords and no data. If there are more extensions in the file following the one that is deleted, then the the CHDU will be redefined to point to the following extension. If there are no following extensions then the CHDU will be redefined to point to the previous HDU. The output hdutype parameter returns the type of the new CHDU. A null pointer may be given for hdutype if the returned value is not needed.
  int fits_delete_hdu / ffdhdu
      (fitsfile *fptr, > int *hdutype, int *status)

5.4  Header Keyword Read/Write Routines

These routines read or write keywords in the Current Header Unit (CHU). Wild card characters (*, ?, or #) may be used when specifying the name of the keyword to be read: a '?' will match any single character at that position in the keyword name and a '*' will match any length (including zero) string of characters. The '#' character will match any consecutive string of decimal digits (0 - 9). When a wild card is used the routine will only search for a match from the current header position to the end of the header and will not resume the search from the top of the header back to the original header position as is done when no wildcards are included in the keyword name. The fits_read_record routine may be used to set the starting position when doing wild card searchs. A status value of KEY_NO_EXIST is returned if the specified keyword to be read is not found in the header.

5.4.1  Keyword Reading Routines

1
Return the number of existing keywords (not counting the END keyword) and the amount of space currently available for more keywords. It returns morekeys = -1 if the header has not yet been closed. Note that CFITSIO will dynamically add space if required when writing new keywords to a header so in practice there is no limit to the number of keywords that can be added to a header. A null pointer may be entered for the morekeys parameter if it's value is not needed.
  int fits_get_hdrspace / ffghsp
      (fitsfile *fptr, > int *keysexist, int *morekeys, int *status)
2
Return the specified keyword. In the first routine, the datatype parameter specifies the desired returned data type of the 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. Within the context of this routine, TSTRING corresponds to a 'char*' data type, i.e., a pointer to a character array. Data type conversion will be performed for numeric values if the keyword value does not have the same data type. If the value of the keyword is undefined (i.e., the value field is blank) then an error status = VALUE_UNDEFINED will be returned.

The second routine returns the keyword value as a character string (a literal copy of what is in the value field) regardless of the intrinsic data type of the keyword. The third routine returns the entire 80-character header record of the keyword.

If a NULL comment pointer is supplied then the comment string will not be returned.

  int fits_read_key / ffgky
      (fitsfile *fptr, int datatype, char *keyname, > DTYPE *value,
       char *comment, int *status)

  int fits_read_keyword / ffgkey
      (fitsfile *fptr, char *keyname, > char *value, char *comment,
       int *status)

  int fits_read_card / ffgcrd
      (fitsfile *fptr, char *keyname, > char *card, int *status)
3
Return the nth header record in the CHU. The first keyword in the header is at keynum = 1; if keynum = 0 then these routines simply reset the internal CFITSIO pointer to the beginning of the header so that subsequent keyword operations will start at the top of the header (e.g., prior to searching for keywords using wild cards in the keyword name). The first routine returns the entire 80-character header record, while the second routine parses the record and returns the name, value, and comment fields as separate character strings. If a NULL comment pointer is given on input, then the comment string will not be returned.
  int fits_read_record / ffgrec
      (fitsfile *fptr, int keynum, > char *card, int *status)

  int fits_read_keyn / ffgkyn
      (fitsfile *fptr, int keynum, > char *keyname, char *value,
       char *comment, int *status)
4
Return the next keyword whose name matches one of the strings in 'inclist' but does not match any of the strings in 'exclist'. The strings in inclist and exclist may contain wild card characters (*, ?, and #) as described at the beginning of this section. This routine searches from the current header position to the end of the header, only, and does not continue the search from the top of the header back to the original position. The current header position may be reset with the ffgrec routine. Note that nexc may be set = 0 if there are no keywords to be excluded. This routine returns status = KEY_NO_EXIST if a matching keyword is not found.
  int fits_find_nextkey / ffgnxk
      (fitsfile *fptr, char **inclist, int ninc, char **exclist,
       int nexc, > char *card, int  *status)
5
Return the physical units string from an existing keyword. This routine uses a local convention, shown in the following example, in which the keyword units are enclosed in square brackets in the beginning of the keyword comment field. A null string is returned if no units are defined for the keyword.
     VELOCITY=                 12.3 / [km/s] orbital speed

  int fits_read_key_unit / ffgunt
      (fitsfile *fptr, char *keyname, > char *unit, int *status)
6
Concatenate the header keywords in the CHDU into a single long string of characters. This provides a convenient way of passing all or part of the header information in a FITS HDU to other subroutines. Each 80-character fixed-length keyword record is appended to the output character string, in order, with no intervening separator or terminating characters. The last header record is terminated with a NULL character. This routine allocates memory for the returned character array, so the calling program must free the memory when finished.

Selected keywords may be excluded from the returned character string. If the second parameter (nocomments) is TRUE (nonzero) then any COMMENT, HISTORY, or blank keywords in the header will not be copied to the output string.

The 'exclist' parameter may be used to supply a list of keywords that are to be excluded from the output character string. Wild card characters (*, ?, and #) may be used in the excluded keyword names. If no additional keywords are to be excluded, then set nexc = 0 and specify NULL for the the **header parameter.

  int fits_hdr2str
      (fitsfile *fptr, int nocomments, char **exclist, int nexc,
      > char **header, int *nkeys, int *status)

5.4.2  Keyword Writing Routines

1
Write a keyword of the appropriate data type into the CHU. The first routine simply appends a new keyword whereas the second routine will update the value and comment fields of the keyword if it already exists, otherwise it appends a new keyword. Note that the address to the value, and not the value itself, must be entered. The datatype parameter specifies the data type of the keyword value with one of the following values: TSTRING, TLOGICAL (== int), TBYTE, TSHORT, TUSHORT, TINT, TUINT, TLONG, TULONG, TFLOAT, TDOUBLE. Within the context of this routine, TSTRING corresponds to a 'char*' data type, i.e., a pointer to a character array. A null pointer may be entered for the comment parameter in which case the keyword comment field will be unmodified or left blank.
  int fits_write_key / ffpky
      (fitsfile *fptr, int datatype, char *keyname, DTYPE *value,
          char *comment, > int *status)

  int fits_update_key / ffuky
      (fitsfile *fptr, int datatype, char *keyname, DTYPE *value,
          char *comment, > int *status)
2
Write a keyword with a null or undefined value (i.e., the value field in the keyword is left blank). The first routine simply appends a new keyword whereas the second routine will update the value and comment fields of the keyword if it already exists, otherwise it appends a new keyword. A null pointer may be entered for the comment parameter in which case the keyword comment field will be unmodified or left blank.
  int fits_write_key_null / ffpkyu
      (fitsfile *fptr, char *keyname, char *comment, > int *status)

  int fits_update_key_null / ffukyu
      (fitsfile *fptr, char *keyname, char *comment, > int *status)
3
Write (append) a COMMENT or HISTORY keyword to the CHU. The comment or history string will be continued over multiple keywords if it is longer than 70 characters.
  int fits_write_comment / ffpcom
      (fitsfile *fptr, char *comment, > int *status)

  int fits_write_history / ffphis
      (fitsfile *fptr, char *history, > int *status)
4
Write the DATE keyword to the CHU. The keyword value will contain the current system date as a character string in 'yyyy-mm-ddThh:mm:ss' format. If a DATE keyword already exists in the header, then this routine will simply update the keyword value with the current date.
  int fits_write_date / ffpdat
      (fitsfile *fptr, > int *status)
5
Write a user specified keyword record into the CHU. This is a low–level routine which can be used to write any arbitrary record into the header. The record must conform to the all the FITS format requirements.
  int fits_write_record / ffprec
      (fitsfile *fptr, char *card, > int *status)
6
Update an 80-character record in the CHU. If a keyword with the input name already exists, then it is overwritten by the value of card. This could modify the keyword name as well as the value and comment fields. If the keyword doesn't already exist then a new keyword card is appended to the header.
  int fits_update_card / ffucrd
      (fitsfile *fptr, char *keyname, char *card, > int *status)
7
Modify (overwrite) the comment field of an existing keyword.
  int fits_modify_comment / ffmcom
      (fitsfile *fptr, char *keyname, char *comment, > int *status)
8
Write the physical units string into an existing keyword. This routine uses a local convention, shown in the following example, in which the keyword units are enclosed in square brackets in the beginning of the keyword comment field.
     VELOCITY=                 12.3 / [km/s] orbital speed

  int fits_write_key_unit / ffpunt
      (fitsfile *fptr, char *keyname, char *unit, > int *status)
9
Rename an existing keyword, preserving the current value and comment fields.
  int fits_modify_name / ffmnam
      (fitsfile *fptr, char *oldname, char *newname, > int *status)
10
Delete a keyword record. The space occupied by the keyword is reclaimed by moving all the following header records up one row in the header. The first routine deletes a keyword at a specified position in the header (the first keyword is at position 1), whereas the second routine deletes a specifically named keyword. Wild card characters may be used when specifying the name of the keyword to be deleted.
  int fits_delete_record / ffdrec
      (fitsfile *fptr, int   keynum,  > int *status)

  int fits_delete_key / ffdkey
      (fitsfile *fptr, char *keyname, > int *status)

5.5  Primary Array or IMAGE Extension I/O Routines

These routines read or write data values in the primary data array (i.e., the first HDU in a FITS file) or an IMAGE extension. There are also routines to get information about the data type and size of the image. Users should also read the following chapter on the CFITSIO iterator function which provides a more `object oriented' method of reading and writing images. The iterator function is a little more complicated to use, but the advantages are that it usually takes less code to perform the same operation, and the resulting program oftens runs faster because the FITS files are read and written using the most efficient block size.

C programmers should note that the ordering of arrays in FITS files, and hence in all the CFITSIO calls, is more similar to the dimensionality of arrays in Fortran rather than C. For instance if a FITS image has NAXIS1 = 100 and NAXIS2 = 50, then a 2-D array just large enough to hold the image should be declared as array[50][100] and not as array[100][50].

The `datatype' parameter specifies the data type of the `nulval' and `array' pointers and can have one of the following values: TBYTE, TSBYTE, TSHORT, TUSHORT, TINT, TUINT, TLONG, TLONGLONG, TULONG, TFLOAT, TDOUBLE. Automatic data type conversion is performed if the data type of the FITS array (as defined by the BITPIX keyword) differs from that specified by 'datatype'. The data values are also automatically scaled by the BSCALE and BZERO keyword values as they are being read or written in the FITS array.

1
Get the data type or equivalent data type of the image. The first routine returns the physical data type of the FITS image, as given by the BITPIX keyword, with allowed values of BYTE_IMG (8), SHORT_IMG (16), LONG_IMG (32), FLOAT_IMG (-32), and DOUBLE_IMG (-64). The second routine is similar, except that if the image pixel values are scaled, with non-default values for the BZERO and BSCALE keywords, then the routine will return the 'equivalent' data type that is needed to store the scaled values. For example, if BITPIX = 16 and BSCALE = 0.1 then the equivalent data type is FLOAT_IMG. Similarly if BITPIX = 16, BSCALE = 1, and BZERO = 32768, then the the pixel values span the range of an unsigned short integer and the returned data type will be USHORT_IMG.
  int fits_get_img_type / ffgidt
      (fitsfile *fptr, > int *bitpix, int *status)

  int fits_get_img_equivtype / ffgiet
      (fitsfile *fptr, > int *bitpix, int *status)
2
Get the number of dimensions, and/or the size of each dimension in the image . The number of axes in the image is given by naxis, and the size of each dimension is given by the naxes array (a maximum of maxdim dimensions will be returned).
  int fits_get_img_dim / ffgidm
      (fitsfile *fptr, > int *naxis, int *status)

  int fits_get_img_size / ffgisz
      (fitsfile *fptr, int maxdim, > long *naxes, int *status)

  int fits_get_img_param / ffgipr
      (fitsfile *fptr, int maxdim, > int *bitpix, int *naxis, long *naxes,
       int *status)
3
Create a new primary array or IMAGE extension with a specified data type and size. If the FITS file is currently empty then a primary array is created, otherwise a new IMAGE extension is appended to the file.
  int fits_create_img / ffcrim
      ( fitsfile *fptr, int bitpix, int naxis, long *naxes, > int *status)
4
Write a rectangular subimage (or the whole image) to the FITS data array. The fpixel and lpixel arrays give the coordinates of the first (lower left corner) and last (upper right corner) pixels in FITS image to be written to.
  int fits_write_subset / ffpss
      (fitsfile *fptr, int datatype, long *fpixel, long *lpixel,
       DTYPE *array, > int *status)
5
Write pixels into the FITS data array. 'fpixel' is an array of length NAXIS which gives the coordinate of the starting pixel to be written to, such that fpixel[0] is in the range 1 to NAXIS1, fpixel[1] is in the range 1 to NAXIS2, etc. The first routine simply writes the array of pixels to the FITS file (doing data type conversion if necessary) whereas the second routine will substitute the appropriate FITS null value for any elements which are equal to the input value of nulval (note that this parameter gives the address of the null value, not the null value itself). For integer FITS arrays, the FITS null value is defined by the BLANK keyword (an error is returned if the BLANK keyword doesn't exist). For floating point FITS arrays the special IEEE NaN (Not-a-Number) value will be written into the FITS file. If a null pointer is entered for nulval, then the null value is ignored and this routine behaves the same as fits_write_pix.
  int fits_write_pix / ffppx
      (fitsfile *fptr, int datatype, long *fpixel, long nelements,
       DTYPE *array, int *status);

  int fits_write_pixnull / ffppxn
      (fitsfile *fptr, int datatype, long *fpixel, long nelements,
       DTYPE *array, DTYPE *nulval, > int *status);
6
Set FITS data array elements equal to the appropriate null pixel value. For integer FITS arrays, the FITS null value is defined by the BLANK keyword (an error is returned if the BLANK keyword doesn't exist). For floating point FITS arrays the special IEEE NaN (Not-a-Number) value will be written into the FITS file. Note that 'firstelem' is a scalar giving the offset to the first pixel to be written in the equivalent 1-dimensional array of image pixels.
  int fits_write_null_img / ffpprn
      (fitsfile *fptr, long firstelem, long nelements, > int *status)
7
Read a rectangular subimage (or the whole image) from the FITS data array. The fpixel and lpixel arrays give the coordinates of the first (lower left corner) and last (upper right corner) pixels to be read from the FITS image. Undefined FITS array elements will be returned with a value = *nullval, (note that this parameter gives the address of the null value, not the null value itself) unless nulval = 0 or *nulval = 0, in which case no checks for undefined pixels will be performed.
  int fits_read_subset / ffgsv
      (fitsfile *fptr, int  datatype, long *fpixel, long *lpixel, long *inc,
       DTYPE *nulval, > DTYPE *array, int *anynul, int *status)
8
Read pixels from the FITS data array. 'fpixel' is the starting pixel location and is an array of length NAXIS such that fpixel[0] is in the range 1 to NAXIS1, fpixel[1] is in the range 1 to NAXIS2, etc. The nelements parameter specifies the number of pixels to read. If fpixel is set to the first pixel, and nelements is set equal to the NAXIS1 value, then this routine would read the first row of the image. Alternatively, if nelements is set equal to NAXIS1 * NAXIS2 then it would read an entire 2D image, or the first plane of a 3-D datacube.

The first routine will return any undefined pixels in the FITS array equal to the value of *nullval (note that this parameter gives the address of the null value, not the null value itself) unless nulval = 0 or *nulval = 0, in which case no checks for undefined pixels will be performed. The second routine is similar except that any undefined pixels will have the corresponding nullarray element set equal to TRUE (= 1).

  int fits_read_pix / ffgpxv
      (fitsfile *fptr, int  datatype, long *fpixel, long nelements,
       DTYPE *nulval, > DTYPE *array, int *anynul, int *status)

  int fits_read_pixnull / ffgpxf
      (fitsfile *fptr, int  datatype, long *fpixel, long nelements,
       > DTYPE *array, char *nullarray, int *anynul, int *status)

5.6  Image Compression

CFITSIO now transparently supports 2 types of image compression:

1) The entire FITS file may be externally compressed with the gzip or Unix compress algorithm, producing a *.gz or *.Z file, respectively. When reading compressed files of this type, CFITSIO first uncompresses the entire file into memory before performing the requested read operations. Output files can be directly written in the gzip compressed format if the user-specified filename ends with `.gz'. In this case, CFITSIO initially writes the uncompressed file in memory and then compresses it and writes it to disk when the FITS file is closed, thus saving user disk space. Read and write access to these compressed FITS files is generally quite fast; the main limitation is that there must be enough available memory (or swap space) to hold the entire uncompressed FITS file.

2) CFITSIO also supports a newer image compression format in which the image is divided into a grid of rectangular tiles, and each tile of pixels is individually compressed. The compressed tiles are stored in rows of a variable length array column in a FITS binary table, but CFITSIO recognizes that the binary table extension contains an image and treats it as if it were an IMAGE extension. This tile-compressed format is especially well suited for compressing very large images because a) the FITS header keywords remain uncompressed for rapid read access, and because b) it is possible to extract and uncompress sections of the image without having to uncompress the entire image. This format is also much more effective in compressing floating point images (using a lossy compression algorithm) than simply compressing the image using gzip or compress.

A detailed description of this format is available at:

http://heasarc.gsfc.nasa.gov/docs/software/fitsio/
       compression/compress_image.html

The N-dimensional FITS image can be divided into any desired rectangular grid of compression tiles. By default the tiles are chosen to correspond to the rows of the image, each containing NAXIS1 pixels. For example, a 800 x 800 x 4 pixel data cube would be divided in to 3200 tiles containing 800 pixels each by default. Alternatively, this data cube could be divided into 256 tiles that are each 100 X 100 X 1 pixels in size, or 4 tiles containing 800 x 800 X 1 pixels, or a single tile containing the entire data cube. Note that the image dimensions are not required to be an integer multiple of the tile dimensions, so, for example, this data cube could also be divided into 250 X 200 pixel tiles, in which case the last tile in each row would only contain 50 X 200 pixels.

Currently, 3 image compression algorithms are supported: Rice, GZIP, and PLIO. Rice and GZIP are general purpose algorithms that can be used to compress almost any image. The PLIO algorithm, on the other hand, is more specialized and was developed for use in IRAF to store pixel data quality masks. It is designed to only work on images containing positive integers with values up to about 2**24. Other image compression algorithms may be supported in the future.

The 3 supported image compression algorithms are all 'loss-less' when applied to integer FITS images; the pixel values are preserved exactly with no loss of information during the compression and uncompression process. Floating point FITS images (which have BITPIX = -32 or -64) are first quantized into scaled integer pixel values before being compressed. This technique produces much higher compression factors than simply using GZIP to compress the image, but it also means that the original floating value pixel values may not be precisely returned when the image is uncompressed. When done properly, this only discards the 'noise' from the floating point values without losing any significant information. The amount of noise that is discarded can be controlled by the 'noise_bits' compression parameter.

No special action is required to read tile-compressed images because all the CFITSIO routines that read normal uncompressed FITS images can also read images in the tile-compressed format; CFITSIO essentially treats the binary table that contains the compressed tiles as if it were an IMAGE extension.

When creating (writing) a new image with CFITSIO, a normal uncompressed FITS primary array or IMAGE extension will be written unless the tile-compressed format has been specified in 1 of 2 possible ways:

1) At run time, when specifying the name of the output FITS file to be created at run time, the user can indicate that images should be written in tile-compressed format by enclosing the compression parameters in square brackets following the root disk file name. The `imcopy' example program that included with the CFITSIO distribution can be used for this purpose to compress or uncompress images. Here are some examples of the extended file name syntax for specifying tile-compressed output images:

    myfile.fit[compress]    - use the default compression algorithm (Rice)
                              and the default tile size (row by row)

    myfile.fit[compress GZIP] - use the specified compression algorithm;
    myfile.fit[compress Rice]     only the first letter of the algorithm
    myfile.fit[compress PLIO]     name is required.

    myfile.fit[compress R 100,100]   - use Rice compression and
                                       100 x 100 pixel tile size

    myfile.fit[compress R 100,100;2] - as above, and also use noisebits = 2

2) Before calling the CFITSIO routine to write the image header keywords (e.g., fits_create_image) the programmer can call the routines described below to specify the compression algorithm and the tiling pattern that is to be used. There are 3 routines for specifying the various compression parameters and 3 corresponding routines to return the current values of the parameters:

  int fits_set_compression_type(fitsfile *fptr, int comptype, int *status)
  int fits_set_tile_dim(fitsfile *fptr, int ndim, long *tilesize, int *status)
  int fits_set_noise_bits(fitsfile *fptr, int noisebits, int *status)

  int fits_get_compression_type(fitsfile *fptr, int *comptype, int *status)
  int fits_get_tile_dim(fitsfile *fptr, int ndim, long *tilesize, int *status)
  int fits_get_noise_bits(fitsfile *fptr, int *noisebits, int *status)

3 symbolic constants are defined for use as the value of the `comptype' parameter: GZIP_1, RICE_1, or PLIO_1. Entering NULL for comptype will turn off the tile-compression and cause normal FITS images to be written.

The 'noisebits' parameter is only used when compressing floating point images. The default value is 4. Decreasing the value of noisebits will improve the overall compression efficiency at the expense of losing more information.

A small example program called 'imcopy' is included with CFITSIO that can be used to compress (or uncompress) any FITS image. This program can be used to experiment with the various compression options on existing FITS images as shown in these examples:

1)  imcopy infile.fit 'outfile.fit[compress]'

       This will use the default compression algorithm (Rice) and the
       default tile size (row by row)

2)  imcopy infile.fit 'outfile.fit[compress GZIP]'

       This will use the GZIP compression algorithm and the default
       tile size (row by row).  The allowed compression algorithms are
       Rice, GZIP, and PLIO.  Only the first letter of the algorithm
       name needs to be specified.

3)  imcopy infile.fit 'outfile.fit[compress G 100,100]'

       This will use the GZIP compression algorithm and 100 X 100 pixel
       tiles.

4)  imcopy infile.fit 'outfile.fit[compress R 100,100; 4]'

       This will use the Rice compression algorithm, 100 X 100 pixel
       tiles, and noise_bits = 4 (assuming the input image has a
       floating point data type).  Decreasing the value of noisebits
       will improve the overall compression efficiency at the expense
       of losing more information.

5)  imcopy infile.fit outfile.fit

       If the input file is in tile-compressed format, then it will be
       uncompressed to the output file.  Otherwise, it simply copies
       the input image to the output image.

6)  imcopy 'infile.fit[1001:1500,2001:2500]'  outfile.fit

       This extracts a 500 X 500 pixel section of the much larger
       input image (which may be in tile-compressed format).  The
       output is a normal uncompressed FITS image.

7)  imcopy 'infile.fit[1001:1500,2001:2500]'  outfile.fit.gz

       Same as above, except the output file is externally compressed
       using the gzip algorithm.

5.7  ASCII and Binary Table Routines

These routines perform read and write operations on columns of data in FITS ASCII or Binary tables. Note that in the following discussions, the first row and column in a table is at position 1 not 0.

Users should also read the following chapter on the CFITSIO iterator function which provides a more `object oriented' method of reading and writing table columns. The iterator function is a little more complicated to use, but the advantages are that it usually takes less code to perform the same operation, and the resulting program oftens runs faster because the FITS files are read and written using the most efficient block size.

5.7.1  Create New Table

1
Create a new ASCII or bintable table extension. If the FITS file is currently empty then a dummy primary array will be created before appending the table extension to it. The tbltype parameter defines the type of table and can have values of ASCII_TBL or BINARY_TBL. The naxis2 parameter gives the initial number of rows to be created in the table, and should normally be set = 0. CFITSIO will automatically increase the size of the table as additional rows are written. A non-zero number of rows may be specified to reserve space for that many rows, even if a fewer number of rows will be written. The tunit and extname parameters are optional and a null pointer may be given if they are not defined. The FITS Standard recommends that only letters, digits, and the underscore character be used in column names (the ttype parameter) with no embedded spaces. Trailing blank characters are not significant. It is recommended that all the column names in a given table be unique within the first 8 characters, and strongly recommended that the names be unique within the first 16 characters.
  int fits_create_tbl / ffcrtb
      (fitsfile *fptr, int tbltype, long naxis2, int tfields, char *ttype[],
       char *tform[], char *tunit[], char *extname, int *status)

5.7.2  Column Information Routines

1
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_num_rows / ffgnrw
      (fitsfile *fptr, > long *nrows, int *status);

  int fits_get_num_cols / ffgncl
      (fitsfile *fptr, > int *ncols, int *status);
2
Get the table column number (and name) of the column whose name matches an input template name. If casesen = CASESEN then the column name match will be case-sensitive, whereas if casesen = CASEINSEN then the case will be ignored. As a general rule, the column names should be treated as case INsensitive.

The input column name template may be either the exact name of the column to be searched for, or it may contain wild card characters (*, ?, or #), or it may contain the integer number of the desired column (with the first column = 1). The `*' wild card character matches any sequence of characters (including zero characters) and the `?' character matches any single character. The # wildcard will match 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 other cases that match the template, call the routine again leaving the input status value equal to COL_NOT_UNIQUE and the next matching name will then be returned. Repeat this process until a status = COL_NOT_FOUND is returned.

The FITS Standard recommends that only letters, digits, and the underscore character be used in column names (with no embedded spaces). Trailing blank characters are not significant. It is recommended that all the column names in a given table be unique within the first 8 characters, and strongly recommended that the names be unique within the first 16 characters.

  int fits_get_colnum / ffgcno
      (fitsfile *fptr, int casesen, char *templt, > int *colnum,
       int *status)

  int fits_get_colname / ffgcnn
      (fitsfile *fptr, int casesen, char *templt, > char *colname,
       int *colnum, int *status)
3
Return the data type, vector repeat value, and the width in bytes of a column in an ASCII or binary table. Allowed values for the data type in ASCII tables are: TSTRING, TSHORT, TLONG, TFLOAT, and TDOUBLE. Binary tables also support these types: TLOGICAL, TBIT, TBYTE, TCOMPLEX and TDBLCOMPLEX. The negative of the data type code value is returned if it is a variable length array column. Note that in the case of a 'J' 32-bit integer binary table column, this routine will return data type = TINT32BIT (which in fact is equivalent to TLONG). With most current C compilers, a value in a 'J' column has the same size as an 'int' variable, and may not be equivalent to a 'long' variable, which is 64-bits long on an increasing number of compilers.

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.

The second routine, fit_get_eqcoltype is similar except that in the case of scaled integer columns it returns the 'equivalent' data type that is needed to store the scaled values, and not necessarily the physical data type 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. Similarly, if a column has TTYPEn = '1I' and TSCALn = 0.12, then the returned typecode will be TFLOAT.

  int fits_get_coltype / ffgtcl
      (fitsfile *fptr, int colnum, > int *typecode, long *repeat,
       long *width, int *status)

  int fits_get_eqcoltype / ffeqty
      (fitsfile *fptr, int colnum, > int *typecode, long *repeat,
       long *width, int *status)
4
Return the display width of a column. This is the length of the string that will be returned by the fits_read_col routine when reading the column as a formatted string. The display width is determined by the TDISPn keyword, if present, otherwise by the data type of the column.
  int fits_get_col_display_width / ffgcdw
      (fitsfile *fptr, int colnum, > int *dispwidth, int *status)
5
Return the number of and size of the dimensions of a table column in a binary table. Normally this information is given by the TDIMn keyword, but if this keyword is not present then this routine returns naxis = 1 and naxes[0] equal to the repeat count in the TFORM keyword.
  int fits_read_tdim / ffgtdm
      (fitsfile *fptr, int colnum, int maxdim, > int *naxis,
       long *naxes, int *status)
6
Decode the input TDIMn keyword string (e.g. '(100,200)') and return the number of and size of the dimensions of a binary table column. If the input tdimstr character string is null, then this routine returns naxis = 1 and naxes[0] equal to the repeat count in the TFORM keyword. This routine is called by fits_read_tdim.
  int fits_decode_tdim / ffdtdm
      (fitsfile *fptr, char *tdimstr, int colnum, int maxdim, > int *naxis,
       long *naxes, int *status)
7
Write a TDIMn keyword whose value has the form '(l,m,n...)' where l, m, n... are the dimensions of a multidimension array column in a binary table.
  int fits_write_tdim / ffptdm
      (fitsfile *fptr, int colnum, int naxis, long *naxes, > int *status)

5.7.3  Routines to Edit Rows or Columns

1
Insert or delete rows in an ASCII or binary table. When inserting rows all the rows following row FROW are shifted down by NROWS rows; if FROW = 0 then the blank rows are inserted at the beginning of the table. The first delete routine deletes NROWS consecutive rows starting with row FIRSTROW. The second delete routine takes an input string that lists the rows or row ranges (e.g., '5-10,12,20-30'), whereas the third delete routine takes an input integer array that specifies each individual row to be deleted. In both latter cases, the input list of rows to delete must be sorted in ascending order. These routines update the NAXIS2 keyword to reflect the new number of rows in the table.
  int fits_insert_rows / ffirow
      (fitsfile *fptr, long firstrow, long nrows, > int *status)

  int fits_delete_rows / ffdrow
      (fitsfile *fptr, long firstrow, long nrows, > int *status)

  int fits_delete_rowrange / ffdrrg
      (fitsfile *fptr, char *rangelist, > int *status)

  int fits_delete_rowlist / ffdrws
      (fitsfile *fptr, long *rowlist, long nrows, > int *status)
2
Insert or delete column(s) in an ASCII or binary table. When inserting, COLNUM specifies the column number that the (first) new column should occupy in the table. NCOLS specifies how many columns are to be inserted. Any existing columns from this position and higher are shifted over to allow room for the new column(s). The index number on all the following keywords will be incremented or decremented if necessary to reflect the new position of the column(s) in the table: TBCOLn, TFORMn, TTYPEn, TUNITn, TNULLn, TSCALn, TZEROn, TDISPn, TDIMn, TLMINn, TLMAXn, TDMINn, TDMAXn, TCTYPn, TCRPXn, TCRVLn, TCDLTn, TCROTn, and TCUNIn.
  int fits_insert_col / fficol
      (fitsfile *fptr, int colnum, char *ttype, char *tform,
       > int *status)

  int fits_insert_cols / fficls
      (fitsfile *fptr, int colnum, int ncols, char **ttype,
       char **tform, > int *status)

  int fits_delete_col / ffdcol(fitsfile *fptr, int colnum, > int *status)
3
Copy a column from one HDU to another (or to the same HDU). If create_col = TRUE, then a new column will be inserted in the output table, at position `outcolumn', otherwise the existing output column will be overwritten (in which case it must have a compatible data type). If outcolnum is greater than the number of column in the table, then the new column will be appended to the end of the table. Note that the first column in a table is at colnum = 1. The standard indexed keywords that related to the column (e.g., TDISPn, TUNITn, TCRPXn, TCDLTn, etc.) will also be copied.
  int fits_copy_col / ffcpcl
      (fitsfile *infptr, fitsfile *outfptr, int incolnum, int outcolnum,
       int create_col, > int *status);
4
Modify the vector length of a binary table column (e.g., change a column from TFORMn = '1E' to '20E'). The vector length may be increased or decreased from the current value.
  int fits_modify_vector_len / ffmvec
      (fitsfile *fptr, int colnum, long newveclen, > int *status)

5.7.4  Read and Write Column Data Routines

The following routines write or read data values in the current ASCII or binary table extension. If a write operation extends beyond the current size of the table, then the number of rows in the table will automatically be increased and the NAXIS2 keyword value will be updated. Attempts to read beyond the end of the table will result in an error.

Automatic data type conversion is performed for numerical data types (only) if the data type of the column (defined by the TFORMn keyword) differs from the data type of the calling routine. ASCII and binary tables support the following data type values: TSTRING, TBYTE, TSBYTE, TSHORT, TUSHORT, TINT, TUINT, TLONG, TLONGLONG, TULONG, TFLOAT, or TDOUBLE. Binary tables also support TLOGICAL (internally mapped to the `char' data type), TCOMPLEX, and TDBLCOMPLEX.

Note that within the context of these routines, the TSTRING data type corresponds to a C 'char**' data type, i.e., a pointer to an array of pointers to an array of characters. This is different from the keyword reading and writing routines where TSTRING corresponds to a C 'char*' data type, i.e., a single pointer to an array of characters. When reading strings from a table, the char arrays obviously must have been allocated long enough to hold the whole FITS table string.

Numerical data values are automatically scaled by the TSCALn and TZEROn keyword values (if they exist).

In the case of binary tables with vector elements, the 'felem' parameter defines the starting element (beginning with 1, not 0) within the cell (a cell is defined as the intersection of a row and a column and may contain a single value or a vector of values). The felem parameter is ignored when dealing with ASCII tables. Similarly, in the case of binary tables the 'nelements' parameter specifies the total number of vector values to be read or written (continuing on subsequent rows if required) and not the number of table cells.

1
Write elements into an ASCII or binary table column.

The first routine simply writes the array of values to the FITS file (doing data type conversion if necessary) whereas the second routine will substitute the appropriate FITS null value for all elements which are equal to the input value of nulval (note that this parameter gives the address of nulval, not the null value itself). For integer columns the FITS null value is defined by the TNULLn keyword (an error is returned if the keyword doesn't exist). For floating point columns the special IEEE NaN (Not-a-Number) value will be written into the FITS file. If a null pointer is entered for nulval, then the null value is ignored and this routine behaves the same as the first routine. The second routine must not be used to write to variable length array columns. The third routine simply writes undefined pixel values to the column.

  int fits_write_col / ffpcl
      (fitsfile *fptr, int datatype, int colnum, long firstrow,
       long firstelem, long nelements, DTYPE *array, > int *status)

  int fits_write_colnull / ffpcn
      (fitsfile *fptr, int datatype, int colnum, long firstrow,
      long firstelem, long nelements, DTYPE *array, DTYPE *nulval,
      > int *status)

   int fits_write_col_null / ffpclu
       (fitsfile *fptr, int colnum, long firstrow, long firstelem,
        long nelements, > int *status)
2
Read elements from an ASCII or binary table column. The data type parameter specifies the data type of the `nulval' and `array' pointers; Undefined array elements will be returned with a value = *nullval, (note that this parameter gives the address of the null value, not the null value itself) unless nulval = 0 or *nulval = 0, in which case no checking for undefined pixels will be performed. The second routine is similar except that any undefined pixels will have the corresponding nullarray element set equal to TRUE (= 1).

Any column, regardless of it's intrinsic data type, may be read as a string. It should be noted however that reading a numeric column as a string is 10 - 100 times slower than reading the same column as a number due to the large overhead in constructing the formatted strings. The display format of the returned strings will be determined by the TDISPn keyword, if it exists, otherwise by the data type of the column. The length of the returned strings (not including the null terminating character) can be determined with the fits_get_col_display_width routine. The following TDISPn display formats are currently supported:

    Iw.m   Integer
    Ow.m   Octal integer
    Zw.m   Hexadecimal integer
    Fw.d   Fixed floating point
    Ew.d   Exponential floating point
    Dw.d   Exponential floating point
    Gw.d   General; uses Fw.d if significance not lost, else Ew.d

where w is the width in characters of the displayed values, m is the minimum number of digits displayed, and d is the number of digits to the right of the decimal. The .m field is optional.

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

  int fits_read_colnull / ffgcf
      (fitsfile *fptr, int datatype, int colnum, long firstrow, long firstelem,
      long nelements, DTYPE *array, char *nullarray, int *anynul, int *status)

5.7.5  Row Selection and Calculator Routines

These routines all parse and evaluate an input string containing a user defined arithmetic expression. The first 3 routines select rows in a FITS table, based on whether the expression evaluates to true (not equal to zero) or false (zero). The other routines evaluate the expression and calculate a value for each row of the table. The allowed expression syntax is described in the row filter section in the `Extended File Name Syntax' chapter of this document. The expression may also be written to a text file, and the name of the file, prepended with a '@' character may be supplied for the 'expr' parameter (e.g. '@filename.txt'). The expression in the file can be arbitrarily complex and extend over multiple lines of the file. Lines that begin with 2 slash characters ('//') will be ignored and may be used to add comments to the file.

1
Evaluate a boolean expression over the indicated rows, returning an array of flags indicating which rows evaluated to TRUE/FALSE
  int fits_find_rows / fffrow
      (fitsfile *fptr,  char *expr, long firstrow, long nrows,
      > long *n_good_rows, char *row_status,  int *status)
2
Find the first row which satisfies the input boolean expression
  int fits_find_first_row / ffffrw
      (fitsfile *fptr,  char *expr, > long *rownum, int *status)
3
Evaluate an expression on all rows of a table. If the input and output files are not the same, copy the TRUE rows to the output file. If the files are the same, delete the FALSE rows (preserve the TRUE rows).
  int fits_select_rows / ffsrow
      (fitsfile *infptr, fitsfile *outfptr,  char *expr,  > int *status )
4
Calculate an expression for the indicated rows of a table, returning the results, cast as datatype (TSHORT, TDOUBLE, etc), in array. If nulval==NULL, UNDEFs will be zeroed out. For vector results, the number of elements returned may be less than nelements if nelements is not an even multiple of the result dimension. Call fits_test_expr to obtain the dimensions of the results.
  int fits_calc_rows / ffcrow
      (fitsfile *fptr,  int datatype, char *expr, long firstrow,
       long nelements, void *nulval, > void *array,  int *anynul, int *status)
5
Evaluate an expression and write the result either to a column (if the expression is a function of other columns in the table) or to a keyword (if the expression evaluates to a constant and is not a function of other columns in the table). In the former case, the parName parameter is the name of the column (which may or may not already exist) into which to write the results, and parInfo contains an optional TFORM keyword value if a new column is being created. If a TFORM value is not specified then a default format will be used, depending on the expression. If the expression evaluates to a constant, then the result will be written to the keyword name given by the parName parameter, and the parInfo parameter may be used to supply an optional comment for the keyword. If the keyword does not already exist, then the name of the keyword must be preceded with a '#' character, otherwise the result will be written to a column with that name.
  int fits_calculator / ffcalc
      (fitsfile *infptr, char *expr, fitsfile *outfptr, char *parName,
       char *parInfo, >  int *status)
6
This calculator routine is similar to the previous routine, except that the expression is only evaluated over the specified row ranges. nranges specifies the number of row ranges, and firstrow and lastrow give the starting and ending row number of each range.
  int fits_calculator_rng / ffcalc_rng
      (fitsfile *infptr, char *expr, fitsfile *outfptr, char *parName,
       char *parInfo, int nranges, long *firstrow, long *lastrow
       >  int *status)
7
Evaluate the given expression and return information on the result.
  int fits_test_expr / fftexp
      (fitsfile *fptr, char *expr, > int *datatype, long *nelem, int *naxis,
       long *naxes, int *status)

5.8  Utility Routines

5.8.1  File Checksum Routines

The following routines either compute or validate the checksums for the CHDU. The DATASUM keyword is used to store the numerical value of the 32-bit, 1's complement checksum for the data unit alone. If there is no data unit then the value is set to zero. The numerical value is stored as an ASCII string of digits, enclosed in quotes, because the value may be too large to represent as a 32-bit signed integer. 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. These checksum keyword conventions are based on a paper by Rob Seaman published in the proceedings of the ADASS IV conference in Baltimore in November 1994 and a later revision in June 1995. See Appendix B for the definition of the parameters used in these routines.

1
Compute and write the DATASUM and CHECKSUM keyword values for the CHDU into the current header. If the keywords already exist, their values will be updated only if necessary (i.e., if the file has been modified since the original keyword values were computed).
  int fits_write_chksum / ffpcks
      (fitsfile *fptr, > int *status)
2
Update the CHECKSUM keyword value in the CHDU, assuming that the DATASUM keyword exists and already has the correct value. This routine calculates the new checksum for the current header unit, adds it to the data unit checksum, encodes the value into an ASCII string, and writes the string to the CHECKSUM keyword.
  int fits_update_chksum / ffupck
      (fitsfile *fptr, > int *status)
3
Verify the CHDU by computing the checksums and comparing them with the keywords. The data unit is verified correctly if the computed checksum equals the value of the DATASUM keyword. The checksum for the entire HDU (header plus data unit) is correct if it equals zero. The output DATAOK and HDUOK parameters in this routine are integers which 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_verify_chksum / ffvcks
      (fitsfile *fptr, > int *dataok, int *hduok, int *status)
4
Compute and return the checksum values for the CHDU without creating or modifying the CHECKSUM and DATASUM keywords. This routine is used internally by ffvcks, but may be useful in other situations as well.
  int fits_get_chksum/ /ffgcks
      (fitsfile *fptr, > unsigned long *datasum, unsigned long *hdusum,
       int *status)
5
Encode a checksum value into a 16-character string. If complm is non-zero (true) then the 32-bit sum value will be complemented before encoding.
  int fits_encode_chksum / ffesum
      (unsigned long sum, int complm, > char *ascii);
6
Decode a 16-character checksum string into a unsigned long value. If is non-zero (true). then the 32-bit sum value will be complemented after decoding. The checksum value is also returned as the value of the function.
  unsigned long fits_decode_chksum / ffdsum
           (char *ascii, int complm, > unsigned long *sum);

5.8.2  Date and Time Utility Routines

The following routines help to construct or parse the FITS date/time strings. Starting in the year 2000, the FITS DATE keyword values (and the values of other `DATE-' keywords) must have the form 'YYYY-MM-DD' (date only) or 'YYYY-MM-DDThh:mm:ss.ddd...' (date and time) where the number of decimal places in the seconds value is optional. These times are in UTC. The older 'dd/mm/yy' date format may not be used for dates after 01 January 2000. See Appendix B for the definition of the parameters used in these routines.

1
Get the current system date. C already provides standard library routines for getting the current date and time, but this routine is provided for compatibility with the Fortran FITSIO library. The returned year has 4 digits (1999, 2000, etc.)
  int fits_get_system_date/ffgsdt
      ( > int *day, int *month, int *year, int *status )
2
Get the current system date and time string ('YYYY-MM-DDThh:mm:ss'). The time will be in UTC/GMT if available, as indicated by a returned timeref value = 0. If the returned value of timeref = 1 then this indicates that it was not possible to convert the local time to UTC, and thus the local time was returned.
  int fits_get_system_time/ffgstm
      (> char *datestr, int  *timeref, int *status)
3
Construct a date string from the input date values. If the year is between 1900 and 1998, inclusive, then the returned date string will have the old FITS format ('dd/mm/yy'), otherwise the date string will have the new FITS format ('YYYY-MM-DD'). Use fits_time2str instead to always return a date string using the new FITS format.
  int fits_date2str/ffdt2s
      (int year, int month, int day, > char *datestr, int *status)
4
Construct a new-format date + time string ('YYYY-MM-DDThh:mm:ss.ddd...'). If the year, month, and day values all = 0 then only the time is encoded with format 'hh:mm:ss.ddd...'. The decimals parameter specifies how many decimal places of fractional seconds to include in the string. If `decimals' is negative, then only the date will be return ('YYYY-MM-DD').
  int fits_time2str/fftm2s
      (int year, int month, int day, int hour, int minute, double second,
      int decimals, > char *datestr, int *status)
5
Return the date as read from the input string, where the string may be in either the old ('dd/mm/yy') or new ('YYYY-MM-DDThh:mm:ss' or 'YYYY-MM-DD') FITS format. Null pointers may be supplied for any unwanted output date parameters.
  int fits_str2date/ffs2dt
      (char *datestr, > int *year, int *month, int *day, int *status)
6
Return the date and time as read from the input string, where the string may be in either the old or new FITS format. The returned hours, minutes, and seconds values will be set to zero if the input string does not include the time ('dd/mm/yy' or 'YYYY-MM-DD') . Similarly, the returned year, month, and date values will be set to zero if the date is not included in the input string ('hh:mm:ss.ddd...'). Null pointers may be supplied for any unwanted output date and time parameters.
  int fits_str2time/ffs2tm
      (char *datestr, > int *year, int *month, int *day, int *hour,
      int *minute, double *second, int *status)

5.8.3  General Utility Routines

The following utility routines may be useful for certain applications.

1
Return the revision number of the CFITSIO library. The revision number will be incremented with each new release of CFITSIO.
  float fits_get_version / ffvers ( > float *version)
2
Write an 80-character message to the CFITSIO error stack. Application programs should not normally write to the stack, but there may be some situations where this is desirable.
  void fits_write_errmsg / ffpmsg (char *err_msg)
3
Convert a character string to uppercase (operates in place).
  void fits_uppercase / ffupch (char *string)
4
Compare the input template string against the reference string to see if they match. The template string may contain wildcard characters: '*' will match any sequence of characters (including zero characters) and '%' will match any single character in the reference string. If casesen = CASESEN = TRUE then the match will be case sensitive, otherwise the case of the letters will be ignored if casesen = CASEINSEN = FALSE. The returned MATCH parameter will be TRUE if the 2 strings match, and EXACT will be TRUE if the match is exact (i.e., if no wildcard characters were used in the match). Both strings must be 68 characters or less in length.
  void fits_compare_str / ffcmps
       (char *templt, char *string, int casesen, > int *match, int *exact)
5
Split a string containing a list of names (typically file names or column names) into individual name tokens by a sequence of calls to fits_split_names. The names in the list must be delimited by a comma and/or spaces. This routine ignores spaces and commas that occur within parentheses, brackets, or curly brackets. It also strips any leading and trailing blanks from the returned name.

This routine is similar to the ANSI C 'strtok' function:

The first call to fits_split_names has a non-null input string. It finds the first name in the string and terminates it by overwriting the next character of the string with a null terminator and returns a pointer to the name. Each subsequent call, indicated by a NULL value of the input string, returns the next name, searching from just past the end of the previous name. It returns NULL when no further names are found.

   char *fits_split_names(char *namelist)

The following example shows how a string would be split into 3 names:

    myfile[1][bin (x,y)=4], file2.fits  file3.fits
    ^^^^^^^^^^^^^^^^^^^^^^  ^^^^^^^^^^  ^^^^^^^^^^
        1st name             2nd name    3rd name
6
Test that the keyword name contains only legal characters (A-Z,0-9, hyphen, and underscore) or that the keyword record contains only legal printable ASCII characters
  int fits_test_keyword / fftkey (char *keyname, > int *status)

  int fits_test_record / fftrec (char *card, > int *status)
7
Test whether the current header contains any NULL (ASCII 0) characters. These characters are illegal in the header, but they will go undetected by most of the CFITSIO keyword header routines, because the null is interpreted as the normal end-of-string terminator. This routine returns the position of the first null character in the header, or zero if there are no nulls. For example a returned value of 110 would indicate that the first NULL is located in the 30th character of the second keyword in the header (recall that each header record is 80 characters long). Note that this is one of the few CFITSIO routines in which the returned value is not necessarily equal to the status value).
  int fits_null_check / ffnchk (char *card, > int *status)
8
Parse a header keyword record and return the name of the keyword, and the length of the name. The keyword name normally occupies the first 8 characters of the record, except under the HIERARCH convention where the name can be up to 70 characters in length.
  int fits_get_keyname / ffgknm
      (char *card, > char *keyname, int *keylength, int *status)
9
Parse a 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.
  int fits_parse_value / ffpsvc
      (char *card, > char *value, char *comment, int *status)
10
Construct an array indexed keyword name (ROOT + nnn). This routine appends the sequence number to the root string to create a keyword name (e.g., 'NAXIS' + 2 = 'NAXIS2')
  int fits_make_keyn / ffkeyn
      (char *keyroot, int value, > char *keyname, int *status)
11
Construct a sequence keyword name (n + ROOT). This routine concatenates the sequence number to the front of the root string to create a keyword name (e.g., 1 + 'CTYP' = '1CTYP')
  int fits_make_nkey / ffnkey
      (int value, char *keyroot, > char *keyname, int *status)
12
Determine the data type of a keyword value string. This routine parses the keyword value string to determine its data type. Returns 'C', 'L', 'I', 'F' or 'X', for character string, logical, integer, floating point, or complex, respectively.
  int fits_get_keytype / ffdtyp
      (char *value, > char *dtype, int *status)
13
Return the class of an input header record. The record is classified into one of the following categories (the class values are defined in fitsio.h). Note that this is one of the few CFITSIO routines that does not return a status value.
       Class  Value             Keywords
  TYP_STRUC_KEY  10  SIMPLE, BITPIX, NAXIS, NAXISn, EXTEND, BLOCKED,
                     GROUPS, PCOUNT, GCOUNT, END
                     XTENSION, TFIELDS, TTYPEn, TBCOLn, TFORMn, THEAP,
                     and the first 4 COMMENT keywords in the primary array
                     that define the FITS format.
  TYP_CMPRS_KEY  20  The experimental keywords used in the compressed
                     image format ZIMAGE, ZCMPTYPE, ZNAMEn, ZVALn,
                     ZTILEn, ZBITPIX, ZNAXISn, ZSCALE, ZZERO, ZBLANK
  TYP_SCAL_KEY   30  BSCALE, BZERO, TSCALn, TZEROn
  TYP_NULL_KEY   40  BLANK, TNULLn
  TYP_DIM_KEY    50  TDIMn
  TYP_RANG_KEY   60  TLMINn, TLMAXn, TDMINn, TDMAXn, DATAMIN, DATAMAX
  TYP_UNIT_KEY   70  BUNIT, TUNITn
  TYP_DISP_KEY   80  TDISPn
  TYP_HDUID_KEY  90  EXTNAME, EXTVER, EXTLEVEL, HDUNAME, HDUVER, HDULEVEL
  TYP_CKSUM_KEY 100  CHECKSUM, DATASUM
  TYP_WCS_KEY   110  CTYPEn, CUNITn, CRVALn, CRPIXn, CROTAn, CDELTn
                     CDj_is, PVj_ms, LONPOLEs, LATPOLEs
                     TCTYPn, TCTYns, TCUNIn, TCUNns, TCRVLn, TCRVns, TCRPXn,
                     TCRPks, TCDn_k, TCn_ks, TPVn_m, TPn_ms, TCDLTn, TCROTn
                     jCTYPn, jCTYns, jCUNIn, jCUNns, jCRVLn, jCRVns, iCRPXn,
                     iCRPns, jiCDn,  jiCDns, jPVn_m, jPn_ms, jCDLTn, jCROTn
                     (i,j,m,n are integers, s is any letter)
  TYP_REFSYS_KEY 120 EQUINOXs, EPOCH, MJD-OBSs, RADECSYS, RADESYSs
  TYP_COMM_KEY   130 COMMENT, HISTORY, (blank keyword)
  TYP_CONT_KEY   140 CONTINUE
  TYP_USER_KEY   150 all other keywords

  int fits_get_keyclass / ffgkcl (char *card)
14
Parse the 'TFORM' binary table column format string. This routine parses the input TFORM character string and returns the integer data type code, the repeat count of the field, and, in the case of character string fields, the length of the unit string. See Appendix B for the allowed values for the returned typecode parameter. A null pointer may be given for any output parameters that are not needed.
   int fits_binary_tform / ffbnfm
       (char *tform, > int *typecode, long *repeat, long *width,
        int *status)
15
Parse the 'TFORM' keyword value that defines the column format in an ASCII table. This routine parses the input TFORM character string and returns the data type code, the width of the column, and (if it is a floating point column) the number of decimal places to the right of the decimal point. The returned data type codes are the same as for the binary table, with the following additional rules: integer columns that are between 1 and 4 characters wide are defined to be short integers (code = TSHORT). Wider integer columns are defined to be regular integers (code = TLONG). Similarly, Fixed decimal point columns (with TFORM = 'Fw.d') are defined to be single precision reals (code = TFLOAT) if w is between 1 and 7 characters wide, inclusive. Wider 'F' columns will return a double precision data code (= TDOUBLE). 'Ew.d' format columns will have datacode = TFLOAT, and 'Dw.d' format columns will have datacode = TDOUBLE. A null pointer may be given for any output parameters that are not needed.
  int fits_ascii_tform / ffasfm
      (char *tform, > int *typecode, long *width, int *decimals,
       int *status)
16
Calculate the starting column positions and total ASCII table width based on the input array of ASCII table TFORM values. The SPACE input parameter defines how many blank spaces to leave between each column (it is recommended to have one space between columns for better human readability).
  int fits_get_tbcol / ffgabc
      (int tfields, char **tform, int space, > long *rowlen,
       long *tbcol, int *status)
17
Parse a template header record and return a formatted 80-character string suitable for appending to (or deleting from) a FITS header file. This routine is useful for parsing lines from an ASCII template file and reformatting them into legal FITS header records. The formatted string may then be passed to the fits_write_record, ffmcrd, or fits_delete_key routines to append or modify a FITS header record.
  int fits_parse_template / ffgthd
      (char *templt, > char *card, int *keytype, int *status)

The input templt character string generally should contain 3 tokens: (1) the KEYNAME, (2) the VALUE, and (3) the COMMENT string. The TEMPLATE string must adhere to the following format:

-
The KEYNAME token must begin in columns 1-8 and be a maximum of 8 characters long. A legal FITS keyword name may only contain the characters A-Z, 0-9, and '-' (minus sign) and underscore. This routine will automatically convert any lowercase characters to uppercase in the output string. If the first 8 characters of the template line are blank then the remainder of the line is considered to be a FITS comment (with a blank keyword name).
-
The VALUE token must be separated from the KEYNAME token by one or more spaces and/or an '=' character. The data type of the VALUE token (numeric, logical, or character string) is automatically determined and the output CARD string is formatted accordingly. The value token may be forced to be interpreted as a string (e.g. if it is a string of numeric digits) by enclosing it in single quotes.
-
The COMMENT token is optional, but if present must be separated from the VALUE token by at least one blank space and a '/' character.
-
One exception to the above rules is that if the first non-blank character in the first 8 characters of the template string is a minus sign ('-') followed by a single token, or a single token followed by an equal sign, then it is interpreted as the name of a keyword which is to be deleted from the FITS header.
-
The second exception is that if the template string starts with a minus sign and is followed by 2 tokens (without an equals sign between them) then the second token is interpreted as the new name for the keyword specified by first token. In this case the old keyword name (first token) is returned in characters 1-8 of the returned CARD string, and the new keyword name (the second token) is returned in characters 41-48 of the returned CARD string. These old and new names may then be passed to the ffmnam routine which will change the keyword name.

The keytype output parameter indicates how the returned CARD string should be interpreted:

        keytype                  interpretation
        -------          -------------------------------------------------
           -2            Rename the keyword with name = the first 8 characters of CARD
                         to the new name given in characters 41 - 48 of CARD.

           -1            delete the keyword with this name from the FITS header.

            0            append the CARD string to the FITS header if the
                         keyword does not already exist, otherwise update
                         the keyword value and/or comment field if is already exists.

            1            This is a HISTORY or COMMENT keyword; append it to the header

            2            END record; do not explicitly write it to the FITS file.

EXAMPLES: The following lines illustrate valid input template strings:

      INTVAL 7 / This is an integer keyword
      RVAL           34.6   /     This is a floating point keyword
      EVAL=-12.45E-03  / This is a floating point keyword in exponential notation
      lval F / This is a boolean keyword
                  This is a comment keyword with a blank keyword name
      SVAL1 = 'Hello world'   /  this is a string keyword
      SVAL2  '123.5'  this is also a string keyword
      sval3  123+  /  this is also a string keyword with the value '123+    '
      # the following template line deletes the DATE keyword
      - DATE
      # the following template line modifies the NAME keyword to OBJECT
      - NAME OBJECT
18
Parse the input string containing a list of rows or row ranges, and return integer arrays containing the first and last row in each range. For example, if rowlist = "3-5, 6, 8-9" then it will return numranges = 3, rangemin = 3, 6, 8 and rangemax = 5, 6, 9. At most, 'maxranges' number of ranges will be returned. 'maxrows' is the maximum number of rows in the table; any rows or ranges larger than this will be ignored. The rows must be specified in increasing order, and the ranges must not overlap. A minus sign may be use to specify all the rows to the upper or lower bound, so "50-" means all the rows from 50 to the end of the table, and "-" means all the rows in the table, from 1 - maxrows.
    int fits_parse_range / ffrwrg(char *rowlist, long maxrows, int maxranges, >
       int *numranges, long *rangemin, long *rangemax, int *status)
19
Check that the Header fill bytes (if any) are all blank. These are the bytes that may follow END keyword and before the beginning of data unit, or the end of the HDU if there is no data unit.
    int ffchfl(fitsfile *fptr, > int *status)
20
Check that the Data fill bytes (if any) are all zero (for IMAGE or BINARY Table HDU) or all blanks (for ASCII table HDU). These file bytes may be located after the last valid data byte in the HDU and before the physical end of the HDU.
    int ffcdfl(fitsfile *fptr, > int *status)

Previous Up Next