# Chapter 6  Advanced Interface Subroutines

This chapter defines all the available subroutines in the FITSIO user interface. For completeness, the basic subroutines described in the previous chapter are also repeated here. A right arrow symbol is used here to separate the input parameters from the output parameters in the definition of each subroutine. This symbol is not actually part of the calling sequence. An alphabetical list and definition of all the parameters is given at the end of this section.

## 6.1 FITS File Open and Close Subroutines:

1
  Open an existing FITS file with readonly or readwrite access. The FTDKOPN routine simply opens the specified file without trying to interpret the filename using the extended filename syntax. FTDOPN opens the file and also moves to the first HDU containing significant data, if no specific HDU is specified as part of the filename. FTTOPN and FTIOPN are similar except that they will move to the first table HDU or image HDU, respectively, if a HDU name or number is not specified as part of the filename.

            FTOPEN(unit,filename,rwmode, > blocksize,status)
            FTDKOPN(unit,filename,rwmode, > blocksize,status)

            FTDOPN(unit,filename,rwmode, > status)
            FTTOPN(unit,filename,rwmode, > status)
            FTIOPN(unit,filename,rwmode, > status)

2
  Open an existing FITS file with readonly or readwrite access and move to a following extension, if one was specified as part of the filename. (e.g., ’filename.fits+2’ or ’filename.fits[2]’ will move to the 3rd HDU in the file). Note that this routine differs from FTOPEN in that it does not have the redundant blocksize argument.

            FTNOPN(unit,filename,rwmode, > status)

3
  Reopen a FITS file that was previously opened with FTOPEN, FTNOPN, or FTINIT. The newunit number may then be treated as a separate file, and one may simultaneously read or write to 2 (or more) different extensions in the same file. The FTOPEN and FTNOPN routines (above) automatically detects cases where a previously opened file is being opened again, and then internally call FTREOPEN, so programs should rarely need to explicitly call this routine.

           FTREOPEN(unit, > newunit, status)

4
  Open and initialize a new empty FITS file. The FTDKINIT routine simply creates the specified file without trying to interpret the filename using the extended filename syntax.

           FTINIT(unit,filename,blocksize, > status)
           FTDKINIT(unit,filename,blocksize, > status)

5
  Create a new FITS file, using a template file to define its initial size and structure. The template may be another FITS HDU or an ASCII template file. If the input template file name is blank, then this routine behaves the same as FTINIT. The currently supported format of the ASCII template file is described under the fits_parse_template routine (in the general Utilities section), but this may change slightly later releases of CFITSIO.

           FTTPLT(unit, filename, tplfilename, > status)

6
  Flush internal buffers of data to the output FITS file previously opened with ftopen or ftinit. The routine usually never needs to be called, but doing so will ensure that if the program subsequently aborts, then the FITS file will have at least been closed properly.

            FTFLUS(unit, > status)

7
  Close a FITS file previously opened with ftopen or ftinit

            FTCLOS(unit, > status)

8
  Close and DELETE a FITS file previously opened with ftopen or ftinit. This routine may be useful in cases where a FITS file is created, but an error occurs which prevents the complete file from being written.

            FTDELT(unit, > status)

9
  Get the value of an unused I/O unit number which may then be used as input to FTOPEN or FTINIT. This routine searches for the first unused unit number in the range from with 99 down to 50. This routine just keeps an internal list of the allocated unit numbers and does not physically check that the Fortran unit is available (to be compatible with the SPP version of FITSIO). Thus users must not independently allocate any unit numbers in the range 50 - 99 if this routine is also to be used in the same program. This routine is provided for convenience only, and it is not required that the unit numbers used by FITSIO be allocated by this routine.

            FTGIOU( > iounit, status)

10
  Free (deallocate) an I/O unit number which was previously allocated with FTGIOU. All previously allocated unit numbers may be deallocated at once by calling FTFIOU with iounit = -1.

            FTFIOU(iounit, > status)

11
  Return the Fortran unit number that corresponds to the C fitsfile pointer value, or vice versa. These 2 C routines may be useful in mixed language programs where both C and Fortran subroutines need to access the same file. For example, if a FITS file is opened with unit 12 by a Fortran subroutine, then a C routine within the same program could get the fitfile pointer value to access the same file by calling ’fptr = CUnit2FITS(12)’. These routines return a value of zero if an error occurs.

          int       CFITS2Unit(fitsfile *ptr);
          fitsfile* CUnit2FITS(int unit);

11
  Parse the input filename and return the HDU number that would be moved to if the file were opened with FTNOPN. The returned HDU number begins with 1 for the primary array, so for example, if the input filename = ‘myfile.fits[2]’ then hdunum = 3 will be returned. FITSIO does not open the file to check if the extension actually exists if an extension number is specified. If an extension *name* is included in the file name specification (e.g. ‘myfile.fits[EVENTS]’ then this routine will have to open the FITS file and look for the position of the named extension, then close file again. This is not possible if the file is being read from the stdin stream, and an error will be returned in this case. If the filename does not specify an explicit extension (e.g. ’myfile.fits’) then hdunum = -99 will be returned, which is functionally equivalent to hdunum = 1. This routine is mainly used for backward compatibility in the ftools software package and is not recommended for general use. It is generally better and more efficient to first open the FITS file with FTNOPN, then use FTGHDN to determine which HDU in the file has been opened, rather than calling FTEXTN followed by a call to FTNOPN.

            FTEXTN(filename, > nhdu, status)

12
  Return the name of the opened FITS file.

            FTFLNM(unit, > filename, status)

13
  Return the I/O mode of the open FITS file (READONLY = 0, READWRITE = 1).

            FTFLMD(unit, > iomode, status)

14
  Return the file type of the opened FITS file (e.g. ’file://’, ’ftp://’, etc.).

            FTURLT(unit, > urltype, status)

15
  Parse the input filename or URL into its component parts: the file type (file://, ftp://, http://, etc), the base input file name, the name of the output file that the input file is to be copied to prior to opening, the HDU or extension specification, the filtering specifier, the binning specifier, and the column specifier. Blank strings will be returned for any components that are not present in the input file name.

           FTIURL(filename, > filetype, infile, outfile, extspec, filter,
                   binspec, colspec, status)

16
  Parse the input file name and return the root file name. The root name includes the file type if specified, (e.g. ’ftp://’ or ’http://’) and the full path name, to the extent that it is specified in the input filename. It does not include the HDU name or number, or any filtering specifications.

           FTRTNM(filename, > rootname, status)

16
  Test if the input file or a compressed version of the file (with a .gz, .Z, .z, or .zip extension) exists on disk. The returned value of the ’exists’ parameter will have 1 of the 4 following values:

         2:  the file does not exist, but a compressed version does exist
         1:  the disk file does exist
         0:  neither the file nor a compressed version of the file exist
        -1:  the input file name is not a disk file (could be a ftp, http,
             smem, or mem file, or a file piped in on the STDIN stream)

          FTEXIST(filename, > exists, status);

## 6.2 HDU-Level Operations

When a FITS file is first opened or created, the internal buffers in FITSIO automatically point to the first HDU in the file. The following routines may be used to move to another HDU in the file. Note that the HDU numbering convention used in FITSIO denotes the primary array as the first HDU, the first extension in a FITS file is the second HDU, and so on.

1
  Move to a specified (absolute) HDU in the FITS file (nhdu = 1 for the FITS primary array)

            FTMAHD(unit,nhdu, > hdutype,status)

2
  Move to a new (existing) HDU forward or backwards relative to the CHDU

            FTMRHD(unit,nmove, > hdutype,status)

3
  Move to the (first) HDU which has the specified extension type and EXTNAME (or HDUNAME) and EXTVER keyword values. The hdutype parameter may have a value of IMAGE_HDU (0), ASCII_TBL (1), BINARY_TBL (2), or ANY_HDU (-1) 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 (301) will be returned.

            FTMNHD(unit, hdutype, extname, extver, > status)

4
  Get the number of the current HDU in the FITS file (primary array = 1)

            FTGHDN(unit, > nhdu)

5
  Return the type of the current HDU in the FITS file. The possible values for hdutype are IMAGE_HDU (0), ASCII_TBL (1), or BINARY_TBL (2).

            FTGHDT(unit, > hdutype, status)

6
  Return the total number of HDUs in the FITS file. The CHDU remains unchanged.

            FTTHDU(unit, > hdunum, status)

7
  Create (append) a new empty HDU at the end of the FITS file. This new HDU becomes the Current HDU, but it is completely empty and contains no header keywords or data. It is recommended that FTIIMG, FTITAB or FTIBIN be used instead of this routine.

            FTCRHD(unit, > status)

8
  Create a primary array (if none already exists), or insert a new IMAGE extension immediately following the CHDU, or insert a new Primary Array at the beginning of the file. Any following extensions in the file will be shifted down to make room for the new extension. If the CHDU is the last HDU in the file then the new image extension will simply be appended to the end of the file. One can force a new primary array to be inserted at the beginning of the FITS file by setting status = -9 prior to calling the routine. In this case the existing primary array will be converted to an IMAGE extension. The new extension (or primary array) will become the CHDU. The FTIIMGLL routine is identical to the FTIIMG routine except that the 4th parameter (the length of each axis) is an array of 64-bit integers rather than an array of 32-bit integers.

            FTIIMG(unit,bitpix,naxis,naxes, > status)
            FTIIMGLL(unit,bitpix,naxis,naxesll, > status)

9
  Insert a new ASCII TABLE extension immediately following the CHDU. Any following extensions will be shifted down to make room for the new extension. If there are no other following extensions then the new table extension will simply be appended to the end of the file. The new extension will become the CHDU. The FTITABLL routine is identical to the FTITAB routine except that the 2nd and 3rd parameters (that give the size of the table) are 64-bit integers rather than 32-bit integers.

            FTITAB(unit,rowlen,nrows,tfields,ttype,tbcol,tform,tunit,extname, >
                   status)
            FTITABLL(unit,rowlenll,nrowsll,tfields,ttype,tbcol,tform,tunit,extname, >
                   status)

10
  Insert a new binary table extension immediately following the CHDU. Any following extensions will be shifted down to make room for the new extension. If there are no other following extensions then the new bintable extension will simply be appended to the end of the file. The new extension will become the CHDU. The FTIBINLL routine is identical to the FTIBIN routine except that the 2nd parameter (that gives the length of the table) is a 64-bit integer rather than a 32-bit integer.

            FTIBIN(unit,nrows,tfields,ttype,tform,tunit,extname,varidat > status)
            FTIBINLL(unit,nrowsll,tfields,ttype,tform,tunit,extname,varidat > status)

11
  Resize an image by modifing the size, dimensions, and/or datatype of the current primary array or image extension. If the new image, as specified by the input arguments, is larger than the current existing image in the FITS file then zero fill data will be inserted at the end of the current image and any following extensions will be moved further back in the file. Similarly, if the new image is smaller than the current image then any following extensions will be shifted up towards the beginning of the FITS file and the image data will be truncated to the new size. This routine rewrites the BITPIX, NAXIS, and NAXISn keywords with the appropriate values for new image. The FTRSIMLL routine is identical to the FTRSIM routine except that the 4th parameter (the length of each axis) is an array of 64-bit integers rather than an array of 32-bit integers.

            FTRSIM(unit,bitpix,naxis,naxes,status)
            FTRSIMLL(unit,bitpix,naxis,naxesll,status)

12
  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 indicates the type of the new CHDU after the previous CHDU has been deleted.

            FTDHDU(unit, > hdutype,status)

13
  Copy all or part of the input FITS file and append it to the end of the output FITS file. If ’previous’ (an integer parameter) is not equal to 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. If all 3 parameters are not equal to zero, then the entire input file will be copied. On return, the current HDU in the input file will be unchanged, and the last copied HDU will be the current HDU in the output file.

            FTCPFL(iunit, ounit, previous, current, following, > status)

14
  Copy the entire CHDU from the FITS file associated with IUNIT to the CHDU of the FITS file associated with OUNIT. The output HDU must be empty and not already contain any keywords. Space will be reserved for MOREKEYS additional keywords in the output header if there is not already enough space.

            FTCOPY(iunit,ounit,morekeys, > status)

15
  Copy the header (and not the data) from the CHDU associated with inunit to the CHDU associated with outunit. 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. This routine will automatically transform the necessary keywords when copying a primary array to and image extension, or an image extension to a primary array. An empty output data unit will be created (all values = 0).

            FTCPHD(inunit, outunit, > status)

16
  Copy just the data from the CHDU associated with IUNIT to the CHDU associated with OUNIT. This will overwrite any data previously in the OUNIT CHDU. This low level routine is used by FTCOPY, but it may also be useful in certain application programs which want to copy the data from one FITS file to another but also want to modify the header keywords in the process. all the required header keywords must be written to the OUNIT CHDU before calling this routine

            FTCPDT(iunit,ounit, > status)

## 6.3 Define or Redefine the structure of the CHDU

It should rarely be necessary to call the subroutines in this section. FITSIO internally calls these routines whenever necessary, so any calls to these routines by application programs will likely be redundant.

1
  This routine forces FITSIO to scan the current header keywords that define the structure of the HDU (such as the NAXISn, PCOUNT and GCOUNT keywords) so that it can initialize the internal buffers that describe the HDU structure. This routine may be used instead of the more complicated calls to ftpdef, ftadef or ftbdef. This routine is also very useful for reinitializing the structure of an HDU, if the number of rows in a table, as specified by the NAXIS2 keyword, has been modified from its initial value.

            FTRDEF(unit, > status)   (DEPRECATED)

2
  Define the structure of the primary array or IMAGE extension. When writing GROUPed FITS files that by convention set the NAXIS1 keyword equal to 0, ftpdef must be called with naxes(1) = 1, NOT 0, otherwise FITSIO will report an error status=308 when trying to write data to a group. Note: it is usually simpler to call FTRDEF rather than this routine.

            FTPDEF(unit,bitpix,naxis,naxes,pcount,gcount, > status)  (DEPRECATED)

3
  Define the structure of an ASCII table (TABLE) extension. Note: it is usually simpler to call FTRDEF rather than this routine.

            FTADEF(unit,rowlen,tfields,tbcol,tform,nrows > status) (DEPRECATED)

4
  Define the structure of a binary table (BINTABLE) extension. Note: it is usually simpler to call FTRDEF rather than this routine.

            FTBDEF(unit,tfields,tform,varidat,nrows > status) (DEPRECATED)

5
  Define the size of the Current Data Unit, overriding the length of the data unit as previously defined by ftpdef, ftadef, or ftbdef. This is useful if one does not know the total size of the data unit until after the data have been written. The size (in bytes) of an ASCII or Binary table is given by NAXIS1 * NAXIS2. (Note that to determine the value of NAXIS1 it is often more convenient to read the value of the NAXIS1 keyword from the output file, rather than computing the row length directly from all the TFORM keyword values). Note: it is usually simpler to call FTRDEF rather than this routine.

            FTDDEF(unit,bytlen, > status) (DEPRECATED)

6
  Define the zero indexed byte offset of the ’heap’ measured from the start of the binary table data. By default the heap is assumed to start immediately following the regular table data, i.e., at location NAXIS1 x NAXIS2. This routine is only relevant for binary tables which contain variable length array columns (with TFORMn = ’Pt’). This subroutine also automatically writes the value of theap to a keyword in the extension header. This subroutine must be called after the required keywords have been written (with ftphbn) and after the table structure has been defined (with ftbdef) but before any data is written to the table.

            FTPTHP(unit,theap, > status)

## 6.4 FITS Header I/O Subroutines

### 6.4.1 Header Space and Position Routines

1
  Reserve space in the CHU for MOREKEYS more header keywords. This subroutine may be called to reserve space for keywords which are to be written at a later time, after the data unit or subsequent extensions have been written to the FITS file. If this subroutine is not explicitly called, then the initial size of the FITS header will be limited to the space available at the time that the first data is written to the associated data unit. FITSIO has the ability to dynamically add more space to the header if needed, however it is more efficient to preallocate the required space if the size is known in advance.

            FTHDEF(unit,morekeys, > status)

2
  Return the number of existing keywords in the CHU (NOT including the END keyword which is not considered a real keyword) and the remaining space available to write additional keywords in the CHU. (returns KEYSADD = -1 if the header has not yet been closed). Note that FITSIO will attempt to dynamically add space for more keywords if required when appending new keywords to a header.

            FTGHSP(iunit, > keysexist,keysadd,status)

3
  Return the number of keywords in the header and the current position in the header. This returns the number of the keyword record that will be read next (or one greater than the position of the last keyword that was read or written). A value of 1 is returned if the pointer is positioned at the beginning of the header.

            FTGHPS(iunit, > keysexist,key_no,status)

### 6.4.2 Read or Write Standard Header Routines

These subroutines provide a simple method of reading or writing most of the keyword values that are normally required in a FITS files. These subroutines are provided for convenience only and are not required to be used. If preferred, users may call the lower-level subroutines described in the previous section to individually read or write the required keywords. Note that in most cases, the required keywords such as NAXIS, TFIELD, TTYPEn, etc, which define the structure of the HDU must be written to the header before any data can be written to the image or table.

1
  Put the primary header or IMAGE extension keywords into the CHU. There are 2 available routines: The simpler FTPHPS routine is equivalent to calling ftphpr with the default values of SIMPLE = true, pcount = 0, gcount = 1, and EXTEND = true. PCOUNT, GCOUNT and EXTEND keywords are not required in the primary header and are only written if pcount is not equal to zero, gcount is not equal to zero or one, and if extend is TRUE, respectively. When writing to an IMAGE extension, the SIMPLE and EXTEND parameters are ignored.

            FTPHPS(unit,bitpix,naxis,naxes, > status)

            FTPHPR(unit,simple,bitpix,naxis,naxes,pcount,gcount,extend, > status)

2
  Get primary header or IMAGE extension keywords from the CHU. When reading from an IMAGE extension the SIMPLE and EXTEND parameters are ignored.

            FTGHPR(unit,maxdim, > simple,bitpix,naxis,naxes,pcount,gcount,extend,
                   status)

3
  Put the ASCII table header keywords into the CHU. The optional TUNITn and EXTNAME keywords are written only if the input string values are not blank.

            FTPHTB(unit,rowlen,nrows,tfields,ttype,tbcol,tform,tunit,extname, >
                   status)

4
  Get the ASCII table header keywords from the CHU

            FTGHTB(unit,maxdim, > rowlen,nrows,tfields,ttype,tbcol,tform,tunit,
                   extname,status)

5
  Put the binary table header keywords into the CHU. The optional TUNITn and EXTNAME keywords are written only if the input string values are not blank. The pcount parameter, which specifies the size of the variable length array heap, should initially = 0; FITSIO will automatically update the PCOUNT keyword value if any variable length array data is written to the heap. The TFORM keyword value for variable length vector columns should have the form ’Pt(len)’ or ’1Pt(len)’ where ‘t’ is the data type code letter (A,I,J,E,D, etc.) and ‘len’ is an integer specifying the maximum length of the vectors in that column (len must be greater than or equal to the longest vector in the column). If ‘len’ is not specified when the table is created (e.g., the input TFORMn value is just ’1Pt’) then FITSIO will scan the column when the table is first closed and will append the maximum length to the TFORM keyword value. Note that if the table is subsequently modified to increase the maximum length of the vectors then the modifying program is responsible for also updating the TFORM keyword value.

            FTPHBN(unit,nrows,tfields,ttype,tform,tunit,extname,varidat, > status)

6
  Get the binary table header keywords from the CHU

            FTGHBN(unit,maxdim, > nrows,tfields,ttype,tform,tunit,extname,varidat,
                   status)

### 6.4.3 Write Keyword Subroutines

1
  Put (append) an 80-character record into the CHU.

            FTPREC(unit,card, > status)

2
  Put (append) a COMMENT keyword into the CHU. Multiple COMMENT keywords will be written if the input comment string is longer than 72 characters.

            FTPCOM(unit,comment, > status)

3
  Put (append) a HISTORY keyword into the CHU. Multiple HISTORY keywords will be written if the input history string is longer than 72 characters.

            FTPHIS(unit,history, > status)

4
  Put (append) the DATE keyword into the CHU. The keyword value will contain the current system date as a character string in ’dd/mm/yy’ format. If a DATE keyword already exists in the header, then this subroutine will simply update the keyword value in-place with the current date.

            FTPDAT(unit, > status)

5
  Put (append) a new keyword of the appropriate datatype into the CHU. Note that FTPKYS will only write string values up to 68 characters in length; longer strings will be truncated. The FTPKLS routine can be used to write longer strings, using a non-standard FITS convention. The E and D versions of this routine have the added feature that if the ’decimals’ parameter is negative, then the ’G’ display format rather then the ’E’ format will be used when constructing the keyword value, taking the absolute value of ’decimals’ for the precision. This will suppress trailing zeros, and will use a fixed format rather than an exponential format, depending on the magnitude of the value.

            FTPKY[JKLS](unit,keyword,keyval,comment, > status)
            FTPKY[EDFG](unit,keyword,keyval,decimals,comment, > status)

6
  Put (append) a string valued keyword into the CHU which may be longer than 68 characters in length. This uses the Long String Keyword convention that is described in the "Usage Guidelines and Suggestions" section of this document. Since this uses a non-standard FITS convention to encode the long keyword string, programs which use this routine should also call the FTPLSW routine to add some COMMENT keywords to warn users of the FITS file that this convention is being used. FTPLSW also writes a keyword called LONGSTRN to record the version of the longstring convention that has been used, in case a new convention is adopted at some point in the future. If the LONGSTRN keyword is already present in the header, then FTPLSW will simply return and will not write duplicate keywords.

            FTPKLS(unit,keyword,keyval,comment, > status)
            FTPLSW(unit, > status)

7
  Put (append) a new keyword with an undefined, or null, value into the CHU. The value string of the keyword is left blank in this case.

            FTPKYU(unit,keyword,comment, > status)

8
  Put (append) a numbered sequence of keywords into the CHU. One may append the same comment to every keyword (and eliminate the need to have an array of identical comment strings, one for each keyword) by including the ampersand character as the last non-blank character in the (first) COMMENTS string parameter. This same string will then be used for the comment field in all the keywords. (Note that the SPP version of these routines only supports a single comment string).

            FTPKN[JKLS](unit,keyroot,startno,no_keys,keyvals,comments, > status)
            FTPKN[EDFG](unit,keyroot,startno,no_keys,keyvals,decimals,comments, >
                       status)

9
  Copy an indexed keyword from one HDU to another, modifying the index number of the keyword name in the process. For example, this routine could read the TLMIN3 keyword from the input HDU (by giving keyroot = "TLMIN" and innum = 3) and write it to the output HDU with the keyword name TLMIN4 (by setting outnum = 4). If the input keyword does not exist, then this routine simply returns without indicating an error.

            FTCPKY(inunit, outunit, innum, outnum, keyroot, > status)

10
  Put (append) a ’triple precision’ keyword into the CHU in F28.16 format. The floating point keyword value is constructed by concatenating the input integer value with the input double precision fraction value (which must have a value between 0.0 and 1.0). The FTGKYT routine should be used to read this keyword value, because the other keyword reading subroutines will not preserve the full precision of the value.

            FTPKYT(unit,keyword,intval,dblval,comment, > status)

11
  Write keywords to the CHDU that are defined in an ASCII template file. The format of the template file is described under the ftgthd routine below.

            FTPKTP(unit, filename, > status)

12
  Append the physical units string to 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

            FTPUNT(unit,keyword,units, > status)

### 6.4.4 Insert Keyword Subroutines

1
  Insert a new keyword record into the CHU at the specified position (i.e., immediately preceding the (keyno)th keyword in the header.) This ’insert record’ subroutine is somewhat less efficient then the ’append record’ subroutine (FTPREC) described above because the remaining keywords in the header have to be shifted down one slot.

            FTIREC(unit,key_no,card, > status)

2
  Insert a new keyword into the CHU. The new keyword is inserted immediately following the last keyword that has been read from the header. The FTIKLS subroutine works the same as the FTIKYS subroutine, except it also supports long string values greater than 68 characters in length. These ’insert keyword’ subroutines are somewhat less efficient then the ’append keyword’ subroutines described above because the remaining keywords in the header have to be shifted down one slot.

            FTIKEY(unit, card, > status)
            FTIKY[JKLS](unit,keyword,keyval,comment, > status)
            FTIKLS(unit,keyword,keyval,comment, > status)
            FTIKY[EDFG](unit,keyword,keyval,decimals,comment, > status)

3
  Insert a new keyword with an undefined, or null, value into the CHU. The value string of the keyword is left blank in this case.

            FTIKYU(unit,keyword,comment, > status)

### 6.4.5 Read Keyword Subroutines

These routines return the value of the specified keyword(s). 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). Note that when a wild card is used in the input keyword name, the routine will only search for a match from the current header position to the end of the header. It 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. If the desired keyword string is 8-characters long (the maximum length of a keyword name) then a ’*’ may be appended as the ninth character of the input name to force the keyword search to stop at the end of the header (e.g., ’COMMENT *’ will search for the next COMMENT keyword). The ffgrec routine may be used to set the starting position when doing wild card searches.

1
  Get the nth 80-character header record from the CHU. The first keyword in the header is at key_no = 1; if key_no = 0 then this subroutine simple moves the internal pointer to the beginning of the header so that subsequent keyword operations will start at the top of the header; it also returns a blank card value in this case.

            FTGREC(unit,key_no, > card,status)

2
  Get the name, value (as a string), and comment of the nth keyword in CHU. This routine also checks that the returned keyword name (KEYWORD) contains only legal ASCII characters. Call FTGREC and FTPSVC to bypass this error check.

            FTGKYN(unit,key_no, > keyword,value,comment,status)

3
  Get the 80-character header record for the named keyword

            FTGCRD(unit,keyword, > card,status)

4
  Get 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 ftgrec routine. Note that nexc may be set = 0 if there are no keywords to be excluded. This routine returns status = 202 if a matching keyword is not found.

            FTGNXK(unit,inclist,ninc,exclist,nexc, > card,status)

5
  Get the literal keyword value as a character string. Regardless of the datatype of the keyword, this routine simply returns the string of characters in the value field of the keyword along with the comment field.

            FTGKEY(unit,keyword, > value,comment,status)

6
  Get a keyword value (with the appropriate datatype) and comment from the CHU

            FTGKY[EDJKLS](unit,keyword, > keyval,comment,status)

7
  Read a string-valued keyword and return the string length, the value string, and/or the comment field. The first routine, FTGKSL, simply returns the length of the character string value of the specified keyword. The second routine, FTGSKY, also returns up to maxchar characters of the keyword value string, starting with the firstchar character, and the keyword comment string. The length argument returns the total length of the keyword value string regardless of how much of the string is actually returned (which depends on the value of the firstchar and maxchar arguments). These routines support string keywords that use the CONTINUE convention to continue long string values over multiple FITS header records. Normally, string-valued keywords have a maximum length of 68 characters, however, CONTINUE’d string keywords may be arbitrarily long.

           FTGKSL(unit,keyword, > length,status)
           FTGSKY(unit,keyword,firstchar,maxchar,> keyval,length,comment,status)

8
  Get a sequence of numbered keyword values. These routines do not support wild card characters in the root name.

            FTGKN[EDJKLS](unit,keyroot,startno,max_keys, > keyvals,nfound,status)

9
  Get the value of a floating point keyword, returning the integer and fractional parts of the value in separate subroutine arguments. This subroutine may be used to read any keyword but is especially useful for reading the ’triple precision’ keywords written by FTPKYT.

            FTGKYT(unit,keyword, > intval,dblval,comment,status)

10
  Get the physical units string in 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 blank string is returned if no units are defined for the keyword.

        VELOCITY=                 12.3 / [km/s] orbital speed

            FTGUNT(unit,keyword, > units,status)

### 6.4.6 Modify Keyword Subroutines

Wild card characters, as described in the Read Keyword section, above, may be used when specifying the name of the keyword to be modified.

1
  Modify (overwrite) the nth 80-character header record in the CHU

            FTMREC(unit,key_no,card, > status)

2
  Modify (overwrite) the 80-character header record for the named keyword in the CHU. This can be used to overwrite the name of the keyword as well as its value and comment fields.

            FTMCRD(unit,keyword,card, > status)

3
  Modify (overwrite) the name of an existing keyword in the CHU preserving the current value and comment fields.

            FTMNAM(unit,oldkey,keyword, > status)

4
  Modify (overwrite) the comment field of an existing keyword in the CHU

            FTMCOM(unit,keyword,comment, > status)

5
  Modify the value and comment fields of an existing keyword in the CHU. The FTMKLS subroutine works the same as the FTMKYS subroutine, except it also supports long string values greater than 68 characters in length. Optionally, one may modify only the value field and leave the comment field unchanged by setting the input COMMENT parameter equal to the ampersand character (&). The E and D versions of this routine have the added feature that if the ’decimals’ parameter is negative, then the ’G’ display format rather then the ’E’ format will be used when constructing the keyword value, taking the absolute value of ’decimals’ for the precision. This will suppress trailing zeros, and will use a fixed format rather than an exponential format, depending on the magnitude of the value.

            FTMKY[JKLS](unit,keyword,keyval,comment, > status)
            FTMKLS(unit,keyword,keyval,comment, > status)
            FTMKY[EDFG](unit,keyword,keyval,decimals,comment, > status)

6
  Modify the value of an existing keyword to be undefined, or null. The value string of the keyword is set to blank. Optionally, one may leave the comment field unchanged by setting the input COMMENT parameter equal to the ampersand character (&).

            FTMKYU(unit,keyword,comment, > status)

### 6.4.7 Update Keyword Subroutines

1
  Update an 80-character record in the CHU. If the specified keyword already exists then that header record will be replaced with the input CARD string. If it does not exist then the new record will be added to the header. The FTUKLS subroutine works the same as the FTUKYS subroutine, except it also supports long string values greater than 68 characters in length.

            FTUCRD(unit,keyword,card, > status)

2
  Update the value and comment fields of a keyword in the CHU. The specified keyword is modified if it already exists (by calling FTMKYx) otherwise a new keyword is created by calling FTPKYx. The E and D versions of this routine have the added feature that if the ’decimals’ parameter is negative, then the ’G’ display format rather then the ’E’ format will be used when constructing the keyword value, taking the absolute value of ’decimals’ for the precision. This will suppress trailing zeros, and will use a fixed format rather than an exponential format, depending on the magnitude of the value.

            FTUKY[JKLS](unit,keyword,keyval,comment, > status)
            FTUKLS(unit,keyword,keyval,comment, > status)
            FTUKY[EDFG](unit,keyword,keyval,decimals,comment, > status)

3
  Update the value of an existing keyword to be undefined, or null, or insert a new undefined-value keyword if it doesn’t already exist. The value string of the keyword is left blank in this case.

            FTUKYU(unit,keyword,comment, > status)

### 6.4.8 Delete Keyword Subroutines

1
  Delete an existing keyword record. The space previously 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, as described in the Read Keyword section, above, may be used when specifying the name of the keyword to be deleted (be careful!).

            FTDREC(unit,key_no, > status)
            FTDKEY(unit,keyword, > status)

## 6.5 Data Scaling and Undefined Pixel Parameters

These subroutines define or modify the internal parameters used by FITSIO to either scale the data or to represent undefined pixels. Generally FITSIO will scale the data according to the values of the BSCALE and BZERO (or TSCALn and TZEROn) keywords, however these subroutines may be used to override the keyword values. This may be useful when one wants to read or write the raw unscaled values in the FITS file. Similarly, FITSIO generally uses the value of the BLANK or TNULLn keyword to signify an undefined pixel, but these routines may be used to override this value. These subroutines do not create or modify the corresponding header keyword values.

1
  Reset the scaling factors in the primary array or image extension; does not change the BSCALE and BZERO keyword values and only affects the automatic scaling performed when the data elements are written/read to/from the FITS file. When reading from a FITS file the returned data value = (the value given in the FITS array) * BSCALE + BZERO. The inverse formula is used when writing data values to the FITS file. (NOTE: BSCALE and BZERO must be declared as Double Precision variables).

            FTPSCL(unit,bscale,bzero, > status)

2
  Reset the scaling parameters for a table column; does not change the TSCALn or TZEROn keyword values and only affects the automatic scaling performed when the data elements are written/read to/from the FITS file. When reading from a FITS file the returned data value = (the value given in the FITS array) * TSCAL + TZERO. The inverse formula is used when writing data values to the FITS file. (NOTE: TSCAL and TZERO must be declared as Double Precision variables).

            FTTSCL(unit,colnum,tscal,tzero, > status)

3
  Define the integer value to be used to signify undefined pixels in the primary array or image extension. This is only used if BITPIX = 8, 16, 32. or 64 This does not create or change the value of the BLANK keyword in the header. FTPNULLL is identical to FTPNUL except that the blank value is a 64-bit integer instead of a 32-bit integer.

            FTPNUL(unit,blank, > status)
            FTPNULLL(unit,blankll, > status)

4
  Define the string to be used to signify undefined pixels in a column in an ASCII table. This does not create or change the value of the TNULLn keyword.

            FTSNUL(unit,colnum,snull > status)

5
  Define the value to be used to signify undefined pixels in an integer column in a binary table (where TFORMn = ’B’, ’I’, ’J’, or ’K’). This does not create or change the value of the TNULLn keyword. FTTNULLL is identical to FTTNUL except that the tnull value is a 64-bit integer instead of a 32-bit integer.

            FTTNUL(unit,colnum,tnull > status)
            FTTNULLL(unit,colnum,tnullll > status)

## 6.6 FITS Primary Array or IMAGE Extension I/O Subroutines

These subroutines put or get data values in the primary data array (i.e., the first HDU in the FITS file) or an IMAGE extension. The data array is represented as a single one-dimensional array of pixels regardless of the actual dimensionality of the array, and the FPIXEL parameter gives the position within this 1-D array of the first pixel to read or write. Automatic data type conversion is performed for numeric data (except for complex data types) if the data type of the primary array (defined by the BITPIX keyword) differs from the data type of the array in the calling subroutine. The data values are also scaled by the BSCALE and BZERO header values as they are being written or read from the FITS array. The ftpscl subroutine MUST be called to define the scaling parameters when writing data to the FITS array or to override the default scaling value given in the header when reading the FITS array.

Two sets of subroutines are provided to read the data array which differ in the way undefined pixels are handled. The first set of routines (FTGPVx) simply return an array of data elements in which undefined pixels are set equal to a value specified by the user in the ’nullval’ parameter. An additional feature of these subroutines is that if the user sets nullval = 0, then no checks for undefined pixels will be performed, thus increasing the speed of the program. The second set of routines (FTGPFx) returns the data element array and, in addition, a logical array which defines whether the corresponding data pixel is undefined. The latter set of subroutines may be more convenient to use in some circumstances, however, it requires an additional array of logical values which can be unwieldy when working with large data arrays. Also for programmer convenience, sets of subroutines to directly read or write 2 and 3 dimensional arrays have been provided, as well as a set of subroutines to read or write any contiguous rectangular subset of pixels within the n-dimensional array.

1
  Get the data type of the image (= BITPIX value). Possible returned values are: 8, 16, 32, 64, -32, or -64 corresponding to unsigned byte, signed 2-byte integer, signed 4-byte integer, signed 8-byte integer, real, and double.

  The second subroutine is similar to FTGIDT, except that if the image pixel values are scaled, with non-default values for the BZERO and BSCALE keywords, then this 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 floating point, and -32 will be returned. There are 2 special cases: if the image contains unsigned 2-byte integer values, with BITPIX = 16, BSCALE = 1, and BZERO = 32768, then this routine will return a non-standard value of 20 for the bitpix value. Similarly if the image contains unsigned 4-byte integers, then bitpix will be returned with a value of 40.

            FTGIDT(unit, > bitpix,status)
            FTGIET(unit, > bitpix,status)

2
  Get the dimension (number of axes = NAXIS) of the image

            FTGIDM(unit, > naxis,status)

3
  Get the size of all the dimensions of the image. The FTGISZLL routine returns an array of 64-bit integers instead of 32-bit integers.

            FTGISZ(unit, maxdim, > naxes,status)
            FTGISZLL(unit, maxdim, > naxesll,status)

4
  Get the parameters that define the type and size of the image. This routine simply combines calls to the above 3 routines. The FTGIPRLL routine returns an array of 64-bit integers instead of 32-bit integers.

            FTGIPR(unit, maxdim, > bitpix, naxis, naxes, int *status)
            FTGIPRLL(unit, maxdim, > bitpix, naxis, naxesll, int *status)

5
  Put elements into the data array. The FTPPR[]LL routines accept 64-bit integers for fpixel and nelements.

            FTPPR[BIJKED](unit,group,fpixel,nelements,values, > status)
            FTPPR[BIJKED]LL(unit,group,fpixelll,nelementsll,values, > status)

6
  Put elements into the data array, substituting the appropriate FITS null value for all elements which are equal to the value of NULLVAL. For integer FITS arrays, the null value defined by the previous call to FTPNUL will be substituted; for floating point FITS arrays (BITPIX = -32 or -64) then the special IEEE NaN (Not-a-Number) value will be substituted. The FTPPN[]LL routines accept 64-bit integers for fpixel and nelements.

            FTPPN[BIJKED](unit,group,fpixel,nelements,values,nullval > status)
            FTPPN[BIJKED]LL(unit,group,fpixelll,nelementsll,values,nullval > status)

7
  Set data array elements as undefined. FTPPRULL accepts 64-bit integers for fpixel and nelements.

            FTPPRU(unit,group,fpixel,nelements, > status)
            FTPPRULL(unit,group,fpixelll,nelementsll, > status)

8
  Get elements from the data array. Undefined array elements will be returned with a value = nullval, unless nullval = 0 in which case no checks for undefined pixels will be performed. FTGPV[]LL accepts 64-bit integers for fpixel and nelements.

            FTGPV[BIJKED](unit,group,fpixel,nelements,nullval, > values,anyf,status)
            FTGPV[BIJKED]LL(unit,group,fpixelll,nelementsll,nullval, > values,anyf,status)

9
  Get elements and nullflags from data array. Any undefined array elements will have the corresponding flagvals element set equal to .TRUE.

            FTGPF[BIJKED](unit,group,fpixel,nelements, > values,flagvals,anyf,status)

10
  Put values into group parameters

            FTPGP[BIJKED](unit,group,fparm,nparm,values, > status)

11
  Get values from group parameters

            FTGGP[BIJKED](unit,group,fparm,nparm, > values,status)

The following 4 subroutines transfer FITS images with 2 or 3 dimensions to or from a data array which has been declared in the calling program. The dimensionality of the FITS image is passed by the naxis1, naxis2, and naxis3 parameters and the declared dimensions of the program array are passed in the dim1 and dim2 parameters. Note that the program array does not have to have the same dimensions as the FITS array, but must be at least as big. For example if a FITS image with NAXIS1 = NAXIS2 = 400 is read into a program array which is dimensioned as 512 x 512 pixels, then the image will just fill the lower left corner of the array with pixels in the range 1 - 400 in the X an Y directions. This has the effect of taking a contiguous set of pixel value in the FITS array and writing them to a non-contiguous array in program memory (i.e., there are now some blank pixels around the edge of the image in the program array).

11
  Put 2-D image into the data array

            FTP2D[BIJKED](unit,group,dim1,naxis1,naxis2,image, > status)

12
  Put 3-D cube into the data array

            FTP3D[BIJKED](unit,group,dim1,dim2,naxis1,naxis2,naxis3,cube, > status)

13
  Get 2-D image from the data array. Undefined pixels in the array will be set equal to the value of ’nullval’, unless nullval=0 in which case no testing for undefined pixels will be performed.

            FTG2D[BIJKED](unit,group,nullval,dim1,naxis1,naxis2, > image,anyf,status)

14
  Get 3-D cube from the data array. Undefined pixels in the array will be set equal to the value of ’nullval’, unless nullval=0 in which case no testing for undefined pixels will be performed.

            FTG3D[BIJKED](unit,group,nullval,dim1,dim2,naxis1,naxis2,naxis3, >
                         cube,anyf,status)

The following subroutines transfer a rectangular subset of the pixels in a FITS N-dimensional image to or from an array which has been declared in the calling program. The fpixels and lpixels parameters are integer arrays which specify the starting and ending pixels in each dimension of the FITS image that are to be read or written. (Note that these are the starting and ending pixels in the FITS image, not in the declared array). The array parameter is treated simply as a large one-dimensional array of the appropriate datatype containing the pixel values; The pixel values in the FITS array are read/written from/to this program array in strict sequence without any gaps; it is up to the calling routine to correctly interpret the dimensionality of this array. The two families of FITS reading routines (FTGSVx and FTGSFx subroutines) also have an ’incs’ parameter which defines the data sampling interval in each dimension of the FITS array. For example, if incs(1)=2 and incs(2)=3 when reading a 2-dimensional FITS image, then only every other pixel in the first dimension and every 3rd pixel in the second dimension will be returned in the ’array’ parameter. [Note: the FTGSSx family of routines which were present in previous versions of FITSIO have been superseded by the more general FTGSVx family of routines.]

15
  Put an arbitrary data subsection into the data array.

            FTPSS[BIJKED](unit,group,naxis,naxes,fpixels,lpixels,array, > status)

16
  Get an arbitrary data subsection from the data array. Undefined pixels in the array will be set equal to the value of ’nullval’, unless nullval=0 in which case no testing for undefined pixels will be performed.

            FTGSV[BIJKED](unit,group,naxis,naxes,fpixels,lpixels,incs,nullval, >
                         array,anyf,status)

17
  Get an arbitrary data subsection from the data array. Any Undefined pixels in the array will have the corresponding ’flagvals’ element set equal to .TRUE.

            FTGSF[BIJKED](unit,group,naxis,naxes,fpixels,lpixels,incs, >
                         array,flagvals,anyf,status)

## 6.7 FITS ASCII and Binary Table Data I/O Subroutines

### 6.7.1 Column Information Subroutines

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. The FTGNRWLL routine is identical to FTGNRW except that the number of rows is returned as a 64-bit integer rather than a 32-bit integer.

            FTGNRW(unit, > nrows, status)
            FTGNRWLL(unit, > nrowsll, status)
            FTGNCL(unit, > ncols, status)

2
  Get the table column number (and name) of the column whose name matches an input template name. The table column names are defined by the TTYPEn keywords in the FITS header. If a column does not have a TTYPEn keyword, then these routines assume that the name consists of all blank characters. These 2 subroutines perform the same function except that FTGCNO only returns the number of the matching column whereas FTGCNN also returns the name of the column. If CASESEN = .true. then the column name match will be case-sensitive.

  The input column name template (COLTEMPLATE) is (1) either the exact name of the column to be searched for, or (2) it may contain wild cards characters (*, ?, or #), or (3) it may contain the number of the desired column (where the number is expressed as ASCII digits). The first 2 wild cards behave similarly to UNIX filename matching: the ’*’ 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). As an example, the template strings ’AB?DE’, ’AB*E’, and ’AB*CDE’ will all match the string ’ABCDE’. 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 237 as a warning that a unique match was not found. To find the other cases that match the template, simply call the subroutine again leaving the input status value equal to 237 and the next matching name will then be returned. Repeat this process until a status = 219 (column name not found) is returned. If these subroutines fail to match the template to any of the columns in the table, they lastly check if the template can be interpreted as a simple positive integer (e.g., ’7’, or ’512’) and if so, they return that column number. If no matches are found then a status = 219 error is returned.

  Note that the FITS Standard recommends that only letters, digits, and the underscore character be used in column names (with no embedded spaces in the name). Trailing blank characters are not significant.

            FTGCNO(unit,casesen,coltemplate, > colnum,status)
            FTGCNN(unit,casesen,coltemplate, > colname,colnum,status)

3
  Get the datatype of a column in an ASCII or binary table. This routine returns an integer code value corresponding to the datatype of the column. (See the FTBNFM and FTASFM subroutines in the Utilities section of this document for a list of the code values). The vector repeat count (which is alway 1 for ASCII table columns) is also returned. If the specified column has an ASCII character datatype (code = 16) then the width of a unit string in the column is also returned. Note that this routine supports the local convention for specifying arrays of 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 routine will return datacode = 16, repeat = 60, and width = 12. (The TDIMn keyword may also be used to specify the unit string length; The pair of keywords TFORMn = ’60A’ and TDIMn = ’(12,5)’ would have the same effect as TFORMn = ’60A12’).

  The second routine, FTEQTY 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 the code for an unsigned short integer, not a signed short integer. Similarly, if a column has TTYPEn = ’1I’ and TSCALn = 0.12, then the returned typecode will be the code for a ’real’ column.

            FTGTCL(unit,colnum, > datacode,repeat,width,status)
            FTEQTY(unit,colnum, > datacode,repeat,width,status)

4
  Return the display width of a column. This is the length of the string that will be returned 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.

            FTGCDW(unit, colnum, > dispwidth, status)

5
  Get information about an existing ASCII table column. (NOTE: TSCAL and TZERO must be declared as Double Precision variables). All the returned parameters are scalar quantities.

            FTGACL(unit,colnum, >
                   ttype,tbcol,tunit,tform,tscal,tzero,snull,tdisp,status)

6
  Get information about an existing binary table column. (NOTE: TSCAL and TZERO must be declared as Double Precision variables). DATATYPE is a character string which returns the datatype of the column as defined by the TFORMn keyword (e.g., ’I’, ’J’,’E’, ’D’, etc.). In the case of an ASCII character column, DATATYPE will have a value of the form ’An’ where ’n’ is an integer expressing the width of the field in characters. For example, if TFORM = ’160A8’ then FTGBCL will return DATATYPE=’A8’ and REPEAT=20. All the returned parameters are scalar quantities.

            FTGBCL(unit,colnum, >
                   ttype,tunit,datatype,repeat,tscal,tzero,tnull,tdisp,status)

7
  Put (append) a TDIMn keyword whose value has the form ’(l,m,n...)’ where l, m, n... are the dimensions of a multidimensional array column in a binary table.

            FTPTDM(unit,colnum,naxis,naxes, > status)

8
  Return the number of and size of the dimensions of a table column. Normally this information is given by the TDIMn keyword, but if this keyword is not present then this routine returns NAXIS = 1 and NAXES(1) equal to the repeat count in the TFORM keyword.

            FTGTDM(unit,colnum,maxdim, > naxis,naxes,status)

9
  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 FTGTDM.

            FTDTDM(unit,tdimstr,colnum,maxdim, > naxis,naxes, status)

10
  Return the optimal number of rows to read or write at one time for maximum I/O efficiency. Refer to the “Optimizing Code” section in Chapter 5 for more discussion on how to use this routine.

            FTGRSZ(unit, > nrows,status)

### 6.7.2 Low-Level Table Access Subroutines

The following subroutines provide low-level access to the data in ASCII or binary tables and are mainly useful as an efficient way to copy all or part of a table from one location to another. These routines simply read or write the specified number of consecutive bytes in an ASCII or binary table, without regard for column boundaries or the row length in the table. The first two subroutines read or write consecutive bytes in a table to or from a character string variable, while the last two subroutines read or write consecutive bytes to or from a variable declared as a numeric data type (e.g., INTEGER, INTEGER*2, REAL, DOUBLE PRECISION). These routines do not perform any machine dependent data conversion or byte swapping, except that conversion to/from ASCII format is performed by the FTGTBS and FTPTBS routines on machines which do not use ASCII character codes in the internal data representations (e.g., on IBM mainframe computers).

1
  Read a consecutive string of characters from an ASCII table into a character variable (spanning columns and multiple rows if necessary) This routine should not be used with binary tables because of complications related to passing string variables between C and Fortran.

            FTGTBS(unit,frow,startchar,nchars, > string,status)

2
  Write a consecutive string of characters to an ASCII table from a character variable (spanning columns and multiple rows if necessary) This routine should not be used with binary tables because of complications related to passing string variables between C and Fortran.

            FTPTBS(unit,frow,startchar,nchars,string, > status)

3
  Read a consecutive array of bytes from an ASCII or binary table into a numeric variable (spanning columns and multiple rows if necessary). The array parameter may be declared as any numerical datatype as long as the array is at least ’nchars’ bytes long, e.g., if nchars = 17, then declare the array as INTEGER*4 ARRAY(5).

            FTGTBB(unit,frow,startchar,nchars, > array,status)

4
  Write a consecutive array of bytes to an ASCII or binary table from a numeric variable (spanning columns and multiple rows if necessary) The array parameter may be declared as any numerical datatype as long as the array is at least ’nchars’ bytes long, e.g., if nchars = 17, then declare the array as INTEGER*4 ARRAY(5).

            FTPTBB(unit,frow,startchar,nchars,array, > status)

### 6.7.3 Edit Rows or Columns

1
  Insert blank rows into an existing ASCII or binary table (in the CDU). All the rows FOLLOWING row FROW are shifted down by NROWS rows. If FROW or FROWLL equals 0 then the blank rows are inserted at the beginning of the table. These routines modify the NAXIS2 keyword to reflect the new number of rows in the table. Note that it is *not* necessary to insert rows in a table before writing data to those rows (indeed, it would be inefficient to do so). Instead, one may simply write data to any row of the table, whether that row of data already exists or not.

            FTIROW(unit,frow,nrows, > status)
            FTIROWLL(unit,frowll,nrowsll, > status)

2
  Delete rows from an existing ASCII or binary table (in the CDU). The NROWS (or NROWSLL) is the number of rows are deleted, starting with row FROW (or FROWLL), and any remaining rows in the table are shifted up to fill in the space. These routines modify the NAXIS2 keyword to reflect the new number of rows in the table.

            FTDROW(unit,frow,nrows, > status)
            FTDROWLL(unit,frowll,nrowsll, > status)

3
  Delete a list of rows from an ASCII or binary table (in the CDU). In the first routine, ’rowrange’ is a character string listing the rows or row ranges to delete (e.g., ’2-4, 5, 8-9’). In the second routine, ’rowlist’ is an integer array of row numbers to be deleted from the table. nrows is the number of row numbers in the list. The first row in the table is 1 not 0. The list of row numbers must be sorted in ascending order.

            FTDRRG(unit,rowrange, > status)
            FTDRWS(unit,rowlist,nrows, > status)

4
  Insert a blank column (or columns) into an existing ASCII or binary table (in the CDU). 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 moved over to allow room for the new column(s). The index number on all the following keywords will be incremented 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.

            FTICOL(unit,colnum,ttype,tform, > status)
            FTICLS(unit,colnum,ncols,ttype,tform, > status)

5
  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.

            FTMVEC(unit,colnum,newveclen, > status)

6
  Delete a column from an existing ASCII or binary table (in the CDU). The index number of all the keywords listed above (for FTICOL) will be decremented if necessary to reflect the new position of the column(s) in the table. Those index keywords that refer to the deleted column will also be deleted. Note that the physical size of the FITS file will not be reduced by this operation, and the empty FITS blocks if any at the end of the file will be padded with zeros.

            FTDCOL(unit,colnum, > status)

7
  Copy a column from one HDU to another (or to the same HDU). If createcol = 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 datatype). Note that the first column in a table is at colnum = 1.

            FTCPCL(inunit,outunit,incolnum,outcolnum,createcol, > status);

### 6.7.4 Read and Write Column Data Routines

These subroutines put or get data values in the current ASCII or Binary table extension. Automatic data type conversion is performed for numerical data types (B,I,J,E,D) if the data type of the column (defined by the TFORM keyword) differs from the data type of the calling subroutine. The data values are also scaled by the TSCALn and TZEROn header values as they are being written to or read from the FITS array. The fttscl subroutine MUST be used to define the scaling parameters when writing data to the table or to override the default scaling values given in the header when reading from the table. Note that it is *not* necessary to insert rows in a table before writing data to those rows (indeed, it would be inefficient to do so). Instead, one may simply write data to any row of the table, whether that row of data already exists or not.

In the case of binary tables with vector elements, the ’felem’ parameter defines the starting pixel within the element vector. This parameter is ignored with ASCII tables. Similarly, in the case of binary tables the ’nelements’ parameter specifies the total number of vector values read or written (continuing on subsequent rows if required) and not the number of table elements. Two sets of subroutines are provided to get the column data which differ in the way undefined pixels are handled. The first set of routines (FTGCV) simply return an array of data elements in which undefined pixels are set equal to a value specified by the user in the ’nullval’ parameter. An additional feature of these subroutines is that if the user sets nullval = 0, then no checks for undefined pixels will be performed, thus increasing the speed of the program. The second set of routines (FTGCF) returns the data element array and in addition a logical array of flags which defines whether the corresponding data pixel is undefined.

Any column, regardless of it’s intrinsic datatype, 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 datatype of the column. The length of the returned strings can be determined with the ftgcdw 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.

1
  Put elements into an ASCII or binary table column (in the CDU). (The SPP FSPCLS routine has an additional integer argument after the VALUES character string which specifies the size of the 1st dimension of this 2-D CHAR array).

  The alternate version of these routines, whose names end in ’LL’ after the datatype character, support large tables with more then 2*31 rows. When calling these routines, the frow and felem parameters *must* be 64-bit integer*8 variables, instead of normal 4-byte integers.

            FTPCL[SLBIJKEDCM](unit,colnum,frow,felem,nelements,values, > status)
            FTPCL[LBIJKEDCM]LL(unit,colnum,frow,felem,nelements,values, > status)

2
  Put elements into an ASCII or binary table column (in the CDU) substituting the appropriate FITS null value for any elements that are equal to NULLVAL. For ASCII TABLE extensions, the null value defined by the previous call to FTSNUL will be substituted; For integer FITS columns, in a binary table the null value defined by the previous call to FTTNUL will be substituted; For floating point FITS columns a special IEEE NaN (Not-a-Number) value will be substituted.

  The alternate version of these routines, whose names end in ’LL’ after the datatype character, support large tables with more then 2*31 rows. When calling these routines, the frow and felem parameters *must* be 64-bit integer*8 variables, instead of normal 4-byte integers.

            FTPCN[SBIJKED](unit,colnum,frow,felem,nelements,values,nullval > status)
            FTPCN[SBIJKED]LL(unit,colnum,(I*8) frow,(I*8) felem,nelements,values,
                     nullval > status)

3
  Put bit values into a binary byte (’B’) or bit (’X’) table column (in the CDU). LRAY is an array of logical values corresponding to the sequence of bits to be written. If LRAY is true then the corresponding bit is set to 1, otherwise the bit is set to 0. Note that in the case of ’X’ columns, FITSIO will write to all 8 bits of each byte whether they are formally valid or not. Thus if the column is defined as ’4X’, and one calls FTPCLX with fbit=1 and nbit=8, then all 8 bits will be written into the first byte (as opposed to writing the first 4 bits into the first row and then the next 4 bits into the next row), even though the last 4 bits of each byte are formally not defined.

            FTPCLX(unit,colnum,frow,fbit,nbit,lray, > status)

4
  Set table elements in a column as undefined

            FTPCLU(unit,colnum,frow,felem,nelements, > status)

5
  Get elements from an ASCII or binary table column (in the CDU). These routines return the values of the table column array elements. Undefined array elements will be returned with a value = nullval, unless nullval = 0 (or = ’ ’ for ftgcvs) in which case no checking for undefined values will be performed. The ANYF parameter is set to true if any of the returned elements are undefined. (Note: the ftgcl routine simple gets an array of logical data values without any checks for undefined values; use the ftgcfl routine to check for undefined logical elements). (The SPP FSGCVS routine has an additional integer argument after the VALUES character string which specifies the size of the 1st dimension of this 2-D CHAR array).

  The alternate version of these routines, whose names end in ’LL’ after the datatype character, support large tables with more then 2*31 rows. When calling these routines, the frow and felem parameters *must* be 64-bit integer*8 variables, instead of normal 4-byte integers.

            FTGCL(unit,colnum,frow,felem,nelements, > values,status)
            FTGCV[SBIJKEDCM](unit,colnum,frow,felem,nelements,nullval, >
                           values,anyf,status)
            FTGCV[BIJKEDCM]LL(unit,colnum,(I*8) frow, (I*8) felem, nelements,
                    nullval, > values,anyf,status)

6
  Get elements and null flags from an ASCII or binary table column (in the CHDU). These routines return the values of the table column array elements. Any undefined array elements will have the corresponding flagvals element set equal to .TRUE. The ANYF parameter is set to true if any of the returned elements are undefined. (The SPP FSGCFS routine has an additional integer argument after the VALUES character string which specifies the size of the 1st dimension of this 2-D CHAR array).

  The alternate version of these routines, whose names end in ’LL’ after the datatype character, support large tables with more then 2*31 rows. When calling these routines, the frow and felem parameters *must* be 64-bit integer*8 variables, instead of normal 4-byte integers.

            FTGCF[SLBIJKEDCM](unit,colnum,frow,felem,nelements, >
                             values,flagvals,anyf,status)
            FTGCF[BIJKED]LL(unit,colnum, (I*8) frow, (I*8) felem,nelements, >
                             values,flagvals,anyf,status)

7
  Get an arbitrary data subsection from an N-dimensional array in a binary table vector column. Undefined pixels in the array will be set equal to the value of ’nullval’, unless nullval=0 in which case no testing for undefined pixels will be performed. The first and last rows in the table to be read are specified by fpixels(naxis+1) and lpixels(naxis+1), and hence are treated as the next higher dimension of the FITS N-dimensional array. The INCS parameter specifies the sampling interval in each dimension between the data elements that will be returned.

            FTGSV[BIJKED](unit,colnum,naxis,naxes,fpixels,lpixels,incs,nullval, >
                         array,anyf,status)

8
  Get an arbitrary data subsection from an N-dimensional array in a binary table vector column. Any Undefined pixels in the array will have the corresponding ’flagvals’ element set equal to .TRUE. The first and last rows in the table to be read are specified by fpixels(naxis+1) and lpixels(naxis+1), and hence are treated as the next higher dimension of the FITS N-dimensional array. The INCS parameter specifies the sampling interval in each dimension between the data elements that will be returned.

            FTGSF[BIJKED](unit,colnum,naxis,naxes,fpixels,lpixels,incs, >
                         array,flagvals,anyf,status)

9
  Get bit values from a byte (’B’) or bit (‘X‘) table column (in the CDU). LRAY is an array of logical values corresponding to the sequence of bits to be read. If LRAY is true then the corresponding bit was set to 1, otherwise the bit was set to 0. Note that in the case of ’X’ columns, FITSIO will read all 8 bits of each byte whether they are formally valid or not. Thus if the column is defined as ’4X’, and one calls FTGCX with fbit=1 and nbit=8, then all 8 bits will be read from the first byte (as opposed to reading the first 4 bits from the first row and then the first 4 bits from the next row), even though the last 4 bits of each byte are formally not defined.

            FTGCX(unit,colnum,frow,fbit,nbit, > lray,status)

10
  Read any consecutive set of bits from an ’X’ or ’B’ column and interpret them as an unsigned n-bit integer. NBIT must be less than or equal to 16 when calling FTGCXI, and less than or equal to 32 when calling FTGCXJ; there is no limit on the value of NBIT for FTGCXD, but the returned double precision value only has 48 bits of precision on most 32-bit word machines. The NBITS bits are interpreted as an unsigned integer unless NBITS = 16 (in FTGCXI) or 32 (in FTGCXJ) in which case the string of bits are interpreted as 16-bit or 32-bit 2’s complement signed integers. If NROWS is greater than 1 then the same set of bits will be read from sequential rows in the table starting with row FROW. Note that the numbering convention used here for the FBIT parameter adopts 1 for the first element of the vector of bits; this is the Most Significant Bit of the integer value.

            FTGCX[IJD](unit,colnum,frow,nrows,fbit,nbit, > array,status)

11
  Get the descriptor for a variable length column in a binary table. The descriptor consists of 2 integer parameters: the number of elements in the array and the starting offset relative to the start of the heap. The first routine returns a single descriptor whereas the second routine returns the descriptors for a range of rows in the table.

            FTGDES(unit,colnum,rownum, > nelements,offset,status)
            FTGDESLL(unit,colnum,rownum, > nelementsll,offsetll,status)

            FTGDESS(unit,colnum,firstrow,nrows > nelements,offset, status)
            FTGDESSLL(unit,colnum,firstrow,nrows > nelementsll,offsetll, status)

12
  Write the descriptor for a variable length column in a binary table. These subroutines can be used in conjunction with FTGDES to enable 2 or more arrays to point to the same storage location to save storage space if the arrays are identical.

            FTPDES(unit,colnum,rownum,nelements,offset, > status)
            FTPDESLL(unit,colnum,rownum,nelementsll,offsetll, > status)

## 6.8 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 earlier ‘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

             FTFROW(unit,expr,firstrow, nrows, > n_good_rows, row_status, status)

2
  Find the first row which satisfies the input boolean expression

             FTFFRW(unit, expr, > rownum, 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 output table is not empty, then this routine will append the new selected rows after the existing rows. If the files are the same, delete the FALSE rows (preserve the TRUE rows).

             FTSROW(inunit, outunit, expr, > 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 FTTEXP to obtain the dimensions of the results.

             FTCROW(unit,datatype,expr,firstrow,nelements,nulval, >
                 array,anynul,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.

             FTCALC(inunit, expr, outunit, parName, parInfo, > 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.

             FTCALC_RNG(inunit, expr, outunit, parName, parInfo,
                nranges, firstrow, lastrow, > status)

7
  Evaluate the given expression and return dimension and type information on the result. The returned dimensions correspond to a single row entry of the requested expression, and are equivalent to the result of fits_read_tdim(). Note that strings are considered to be one element regardless of string length. If maxdim == 0, then naxes is optional.

             FTTEXP(unit, expr, maxdim > datatype, nelem, naxis, naxes, status)

## 6.9 Celestial Coordinate System Subroutines

The FITS community has adopted a set of keyword conventions that define the transformations needed to convert between pixel locations in an image and the corresponding celestial coordinates on the sky, or more generally, that define world coordinates that are to be associated with any pixel location in an n-dimensional FITS array. CFITSIO is distributed with a couple of self-contained World Coordinate System (WCS) routines, however, these routines DO NOT support all the latest WCS conventions, so it is STRONGLY RECOMMENDED that software developers use a more robust external WCS library. Several recommended libraries are:

      WCSLIB -  supported by Mark Calabretta
      WCSTools - supported by Doug Mink
      AST library - developed by the U.K. Starlink project

More information about the WCS keyword conventions and links to all of these WCS libraries can be found on the FITS Support Office web site at http://fits.gsfc.nasa.gov under the WCS link.

The functions provided in these external WCS libraries will need access to the WCS information contained in the FITS file headers. One convenient way to pass this information to the external library is to use FITSIO to copy the header keywords into one long character string, and then pass this string to an interface routine in the external library that will extract the necessary WCS information (e.g., see the astFitsChan and astPutCards routines in the Starlink AST library).

The following FITSIO routines DO NOT support the more recent WCS conventions that have been approved as part of the FITS standard. Consequently, the following routines ARE NOW DEPRECATED. It is STRONGLY RECOMMENDED that software developers not use these routines, and instead use an external WCS library, as described above.

These routines are included mainly for backward compatibility with existing software. They support the following standard map projections: -SIN, -TAN, -ARC, -NCP, -GLS, -MER, and -AIT (these are the legal values for the coordtype parameter). These routines are based on similar functions in Classic AIPS. All the angular quantities are given in units of degrees.

1
  Get the values of all the standard FITS celestial coordinate system keywords from the header of a FITS image (i.e., the primary array or an image extension). These values may then be passed to the subroutines that perform the coordinate transformations. If any or all of the WCS keywords are not present, then default values will be returned. If the first coordinate axis is the declination-like coordinate, then this routine will swap them so that the longitudinal-like coordinate is returned as the first axis.

  If the file uses the newer ’CDj_i’ WCS transformation matrix keywords instead of old style ’CDELTn’ and ’CROTA2’ keywords, then this routine will calculate and return the values of the equivalent old-style keywords. Note that the conversion from the new-style keywords to the old-style values is sometimes only an approximation, so if the approximation is larger than an internally defined threshold level, then CFITSIO will still return the approximate WCS keyword values, but will also return with status = 506, to warn the calling program that approximations have been made. It is then up to the calling program to decide whether the approximations are sufficiently accurate for the particular application, or whether more precise WCS transformations must be performed using new-style WCS keywords directly.

            FTGICS(unit, > xrval,yrval,xrpix,yrpix,xinc,yinc,rot,coordtype,status)

2
  Get the values of all the standard FITS celestial coordinate system keywords from the header of a FITS table where the X and Y (or RA and DEC coordinates are stored in 2 separate columns of the table. These values may then be passed to the subroutines that perform the coordinate transformations.

            FTGTCS(unit,xcol,ycol, >
                   xrval,yrval,xrpix,yrpix,xinc,yinc,rot,coordtype,status)

3
  Calculate the celestial coordinate corresponding to the input X and Y pixel location in the image.

            FTWLDP(xpix,ypix,xrval,yrval,xrpix,yrpix,xinc,yinc,rot,
                              coordtype, > xpos,ypos,status)

4
  Calculate the X and Y pixel location corresponding to the input celestial coordinate in the image.

            FTXYPX(xpos,ypos,xrval,yrval,xrpix,yrpix,xinc,yinc,rot,
                              coordtype, > xpix,ypix,status)

## 6.10 File Checksum Subroutines

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.

1
  Compute and write the DATASUM and CHECKSUM keyword values for the CHDU into the current header. The DATASUM value is the 32-bit checksum for the data unit, expressed as a decimal integer enclosed in single quotes. The CHECKSUM keyword value is a 16-character string which is the ASCII-encoded value for the complement of the checksum for the whole HDU. If these 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).

            FTPCKS(unit, > 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.

            FTUCKS(unit, > 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 subroutine 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.

            FTVCKS(unit, > dataok,hduok,status)

4
  Compute and return the checksum values for the CHDU (as double precision variables) without creating or modifying the CHECKSUM and DATASUM keywords. This routine is used internally by FTVCKS, but may be useful in other situations as well.

            FTGCKS(unit, > datasum,hdusum,status)

5
  Encode a checksum value (stored in a double precision variable) into a 16-character string. If COMPLEMENT = .true. then the 32-bit sum value will be complemented before encoding.

            FTESUM(sum,complement, > checksum)

6
  Decode a 16 character checksum string into a double precision value. If COMPLEMENT = .true. then the 32-bit sum value will be complemented after decoding.

            FTDSUM(checksum,complement, > sum)

## 6.11  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.

1
  Get the current system date. The returned year has 4 digits (1999, 2000, etc.)

            FTGSDT( > day, month, year, 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.

            FTGSTM(> datestr, timeref, 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 FTTM2S instead to always return a date string using the new FITS format.

            FTDT2S( year, month, day, > datestr, 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’).

            FTTM2S( year, month, day, hour, minute, second, decimals,
                    > datestr, 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.

            FTS2DT(datestr, > year, month, day, 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...’).

            FTS2TM(datestr, > year, month, day, hour, minute, second, status)

## 6.12 General Utility Subroutines

The following utility subroutines may be useful for certain applications:

1
  Return the starting byte address of the CHDU and the next HDU.

            FTGHAD(iunit, > curaddr, nextaddr)

2
  Convert a character string to uppercase (operates in place).

            FTUPCH(string)

3
  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. The ’#’ character will match any consecutive string of decimal digits (0 - 9). If CASESN = .true. then the match will be case sensitive. 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.

            FTCMPS(str_template, string, casesen, > match, exact)

4
  Test that the keyword name contains only legal characters: A-Z,0-9, hyphen, and underscore.

            FTTKEY(keyword, > status)

5
  Test that the keyword record contains only legal printable ASCII characters

            FTTREC(card, > status)

6
  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 FITSIO routines in which the returned value is not necessarily equal to the status value).

            FTNCHK(unit, > status)

7
  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.

            FTGKNM(card, > keyname, keylength, staThe '\#' character will match any consecutive string
        of decimal digits (0 - 9). tus)

8
  Parse a header keyword record. This subroutine parses the input header record to return the value (as a character string) and comment strings. If the keyword has no value (columns 9-10 not equal to ’= ’), then the value string is returned blank and the comment string is set equal to column 9 - 80 of the input string.

            FTPSVC(card, > value,comment,status)

9
  Construct a properly formated 80-character header keyword record from the input keyword name, keyword value, and keyword comment strings. Hierarchical keyword names (e.g., "ESO TELE CAM") are supported. The value string may contain an integer, floating point, logical, or quoted character string (e.g., "12", "15.7", "T", or "’NGC 1313’").

            FTMKKY(keyname, value, comment, > card, status)

10
  Construct a sequence keyword name (ROOT + nnn). This subroutine appends the sequence number to the root string to create a keyword name (e.g., ’NAXIS’ + 2 = ’NAXIS2’)

            FTKEYN(keyroot,seq_no, > keyword,status)

11
  Construct a sequence keyword name (n + ROOT). This subroutine concatenates the sequence number to the front of the root string to create a keyword name (e.g., 1 + ’CTYP’ = ’1CTYP’)

            FTNKEY(seq_no,keyroot, > keyword,status)

12
  Determine the datatype of a keyword value string. This subroutine parses the keyword value string (usually columns 11-30 of the header record) to determine its datatype.

            FTDTYP(value, > dtype,status)

13
  Return the class of 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 FITSIO 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 keywords used in the compressed image  or table
                         format, including 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

             class = FTGKCL (char *card)

14
  Parse the ’TFORM’ binary table column format string. This subroutine parses the input TFORM character string and returns the integer datatype code, the repeat count of the field, and, in the case of character string fields, the length of the unit string. The following datatype codes are returned (the negative of the value is returned if the column contains variable-length arrays):

                    Datatype                DATACODE value
                    bit, X                   1
                    byte, B                 11
                    logical, L              14
                    ASCII character, A      16
                    short integer, I        21
                    integer, J              41
                    real, E                 42
                    double precision, D     82
                    complex                 83
                    double complex          163

            FTBNFM(tform, > datacode,repeat,width,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 datatype 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 datatype codes are the same as for the binary table, listed above, with the following additional rules: integer columns that are between 1 and 4 characters wide are defined to be short integers (code = 21). Wider integer columns are defined to be regular integers (code = 41). Similarly, Fixed decimal point columns (with TFORM = ’Fw.d’) are defined to be single precision reals (code = 42) if w is between 1 and 7 characters wide, inclusive. Wider ’F’ columns will return a double precision data code (= 82). ’Ew.d’ format columns will have datacode = 42, and ’Dw.d’ format columns will have datacode = 82.

            FTASFM(tform, > datacode,width,decimals,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).

            FTGABC(tfields,tform,space, > rowlen,tbcol,status)

17
  Parse a template string and return a formatted 80-character string suitable for appending to (or deleting from) a FITS header file. This subroutine 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 FTPREC, FTMCRD, or FTDKEY subroutines to append or modify a FITS header record.

            FTGTHD(template, > card,hdtype,status)

The input TEMPLATE 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. 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). A legal FITS keyword name may only contain the characters A-Z, 0-9, and ’-’ (minus sign) and underscore. This subroutine will automatically convert any lowercase characters to uppercase in the output string. If KEYNAME = ’COMMENT’ or ’HISTORY’ then the remainder of the line is considered to be a FITS COMMENT or HISTORY record, respectively.

-
  The VALUE token must be separated from the KEYNAME token by one or more spaces and/or an ’=’ character. The datatype 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. If the value token is a character string that contains 1 or more embedded blank space characters or slash (’/’) characters then the entire character string must be enclosed in single quotes.

-
  The COMMENT token is optional, but if present must be separated from the VALUE token by a blank space or a ’/’ character.

-
  One exception to the above rules is that if the first non-blank character in 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 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 FTMNAM subroutine which will change the keyword name.

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

            hdtype                  interpretation
            ------           -------------------------------------------------
               -2            Modify the name of the keyword given in CARD(1:8)
                             to the new name given in CARD(41:48)

               -1            CARD(1:8) contains the name of a keyword to be deleted
                             from the FITS header.

                0            append the CARD string to the FITS header if the
                             keyword does not already exist, otherwise update
                             the value/comment if the keyword is already present
                             in the header.

                1            simply append this keyword to the FITS header (CARD
                             is either a HISTORY or COMMENT keyword).

                2            This is a FITS END record; it should not be written
                             to the FITS header because FITSIO automatically
                             appends the END record when the header is closed.

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.

        FTRWRG(rowlist, maxrows, maxranges, >
               numranges, rangemin, rangemax, status)