This chapter describes the basic routines in the CFITSIO user interface that provide all the functions normally needed to read and write most FITS files. It is recommended that these routines be used for most applications and that the more advanced routines described in the next chapter only be used in special circumstances when necessary.
The following conventions are used in this chapter in the description of each function:
1. Most functions have 2 names: a long descriptive name and a short concise name. Both names are listed on the first line of the following descriptions, separated by a slash (/) character. Programmers may use either name in their programs but the long names are recommended to help document the code and make it easier to read.
2. A right arrow symbol (>) is used in the function descriptions to separate the input parameters from the output parameters in the definition of each routine. This symbol is not actually part of the C calling sequence.
3. The function parameters are defined in more detail in the alphabetical listing in Appendix B.
4. The first argument in almost all the functions is a pointer to a structure of type ‘fitsfile’. Memory for this structure is allocated by CFITSIO when the FITS file is first opened or created and is freed when the FITS file is closed.
5. The last argument in almost all the functions is the error status parameter. It must be equal to 0 on input, otherwise the function will immediately exit without doing anything. A non-zero output value indicates that an error occurred in the function. In most cases the status value is also returned as the value of the function itself.
void fits_get_errstatus / ffgerr (int status, > char *err_text)
int fits_read_errmsg / ffgmsg (char *err_msg)
void fits_report_error / ffrprt (FILE *stream, status)
void fits_write_errmark / ffpmrk (void) void fits_clear_errmark / ffcmrk (void) void fits_clear_errmsg / ffcmsg (void)
int fits_open_file / ffopen (fitsfile **fptr, char *filename, int iomode, > int *status) int fits_open_diskfile / ffdkopn (fitsfile **fptr, char *filename, int iomode, > int *status) int fits_open_data / ffdopn (fitsfile **fptr, char *filename, int iomode, > int *status) int fits_open_table / fftopn (fitsfile **fptr, char *filename, int iomode, > int *status) int fits_open_image / ffiopn (fitsfile **fptr, char *filename, int iomode, > int *status) int fits_open_extlist / ffeopn (fitsfile **fptr, char *filename, int iomode, char *extlist, > int *hdutype, int *status)
The iomode parameter determines the read/write access allowed in the
file and can have values of READONLY (0) or READWRITE (1). The filename
parameter gives the name of the file to be opened, followed by an
optional argument giving the name or index number of the extension
within the FITS file that should be moved to and opened (e.g.,
myfile.fits+3
or myfile.fits[3]
moves to the 3rd extension within
the file, and myfile.fits[events]
moves to the extension with the
keyword EXTNAME = ’EVENTS’).
The fits_open_diskfile routine is similar to the fits_open_file routine except that it does not support the extended filename syntax in the input file name. This routine simply tries to open the specified input file on magnetic disk. This routine is mainly for use in cases where the filename (or directory path) contains square or curly bracket characters that would confuse the extended filename parser.
The fits_open_data routine is similar to the fits_open_file routine except that it will move to the first HDU containing significant data, if a HDU name or number to open was not explicitly specified as part of the filename. In this case, it will look for the first IMAGE HDU with NAXIS greater than 0, or the first table that does not contain the strings ‘GTI’ (Good Time Interval extension) or ‘OBSTABLE’ in the EXTNAME keyword value.
The fits_open_table and fits_open_image routines are similar to fits_open_data except they will move to the first significant table HDU or image HDU in the file, respectively, if a HDU name or number is not specified as part of the filename.
The fits_open_extlist routine opens the file and attempts to move to a ’useful’ HDU. If after opening the file CFITSIO is pointing to null primary array, then CFITSIO will attempt to move to the first extension that has an EXTNAME or HDUNAME keyword value that matches one of the names in the input extlist space-delimited list of names (wildcards are permitted). If that fails, then CFITSIO simply moves to the 2nd HDU in the file. Upon return, the type of the HDU is returned in *hdutype, as described in 5.3 HDU Access Routines.
IRAF images (.imh format files) and raw binary data arrays may also be opened with READONLY access. CFITSIO will automatically test if the input file is an IRAF image, and if, so will convert it on the fly into a virtual FITS image before it is opened by the application program. If the input file is a raw binary data array of numbers, then the data type and dimensions of the array must be specified in square brackets following the name of the file (e.g. ’rawfile.dat[i512,512]’ opens a 512 x 512 short integer image). See the ‘Extended File Name Syntax’ chapter for more details on how to specify the raw file name. The raw file is converted on the fly into a virtual FITS image in memory that is then opened by the application program with READONLY access.
Programs can read the input file from the ’stdin’ file stream if a dash character (’-’) is given as the filename. Files can also be opened over the network using FTP or HTTP protocols by supplying the appropriate URL as the filename. The HTTPS and FTPS protocols are also supported if the CFITSIO build includes the libcurl library. (If the CFITSIO ’configure’ script finds a usable libcurl library on your system, it will automatically be included in the build.)
The input file can be modified in various ways to create a virtual file (usually stored in memory) that is then opened by the application program by supplying a filtering or binning specifier in square brackets following the filename. Some of the more common filtering methods are illustrated in the following paragraphs, but users should refer to the ’Extended File Name Syntax’ chapter for a complete description of the full file filtering syntax.
When opening an image, a rectangular subset of the physical image may be opened by listing the first and last pixel in each dimension (and optional pixel skipping factor):
myimage.fits[101:200,301:400]
will create and open a 100x100 pixel virtual image of that section of
the physical image, and myimage.fits[*,-*]
opens a virtual image
that is the same size as the physical image but has been flipped in
the vertical direction.
When opening a table, the filtering syntax can be used to add or delete
columns or keywords in the virtual table:
myfile.fits[events][col !time; PI = PHA*1.2]
opens a virtual table in which the TIME column
has been deleted and a new PI column has been added with a value 1.2
times that of the PHA column. Similarly, one can filter a table to keep
only those rows that satisfy a selection criterion:
myfile.fits[events][pha > 50]
creates and opens a virtual table
containing only those rows with a PHA value greater than 50. A large
number of boolean and mathematical operators can be used in the
selection expression. One can also filter table rows using ’Good Time
Interval’ extensions, and spatial region filters as in
myfile.fits[events][gtifilter()]
and
myfile.fits[events][regfilter( "stars.rng")]
.
Finally, table columns may be binned or histogrammed to generate a
virtual image. For example, myfile.fits[events][bin (X,Y)=4]
will
result in a 2-dimensional image calculated by binning the X and Y
columns in the event table with a bin size of 4 in each dimension. The
TLMINn and TLMAXn keywords will be used by default to determine the
range of the image.
A single program can open the same FITS file more than once and then treat the resulting fitsfile pointers as though they were completely independent FITS files. Using this facility, a program can open a FITS file twice, move to 2 different extensions within the file, and then read and write data in those extensions in any order.
int fits_create_file / ffinit (fitsfile **fptr, char *filename, > int *status) int fits_create_diskfile / ffdkinit (fitsfile **fptr, char *filename, > int *status)
An error will be returned if the specified file already exists, unless the filename is prefixed with an exclamation point (!). In that case CFITSIO will overwrite (delete) any existing file with the same name. Note that the exclamation point is a special UNIX character so if it is used on the command line it must be preceded by a backslash to force the UNIX shell to accept the character as part of the filename.
The output file will be written to the ’stdout’ file stream if a dash character (’-’) or the string ’stdout’ is given as the filename. Similarly, ’-.gz’ or ’stdout.gz’ will cause the file to be gzip compressed before it is written out to the stdout stream.
Optionally, the name of a template file that is used to define the structure of the new file may be specified in parentheses following the output file name. The template file may be another FITS file, in which case the new file, at the time it is opened, will be an exact copy of the template file except that the data structures (images and tables) will be filled with zeros. Alternatively, the template file may be an ASCII format text file containing directives that define the keywords to be created in each HDU of the file. See the ’Extended File Name Syntax’ section for a complete description of the template file syntax.
The fits_create_diskfile routine is similar to the fits_create_file routine except that it does not support the extended filename syntax in the input file name. This routine simply tries to create the specified file on magnetic disk. This routine is mainly for use in cases where the filename (or directory path) contains square or curly bracket characters that would confuse the extended filename parser.
int fits_close_file / ffclos (fitsfile *fptr, > int *status) int fits_delete_file / ffdelt (fitsfile *fptr, > int *status)
int fits_file_name / ffflnm (fitsfile *fptr, > char *filename, int *status) int fits_file_mode / ffflmd (fitsfile *fptr, > int *iomode, int *status) int fits_url_type / ffurlt (fitsfile *fptr, > char *urltype, int *status)
The following functions perform operations on Header-Data Units (HDUs) as a whole.
int fits_movabs_hdu / ffmahd (fitsfile *fptr, int hdunum, > int *hdutype, int *status) int fits_movrel_hdu / ffmrhd (fitsfile *fptr, int nmove, > int *hdutype, int *status) int fits_movnam_hdu / ffmnhd (fitsfile *fptr, int hdutype, char *extname, int extver, > int *status)
int fits_get_num_hdus / ffthdu (fitsfile *fptr, > int *hdunum, int *status)
int fits_get_hdu_num / ffghdn (fitsfile *fptr, > int *hdunum)
int fits_get_hdu_type / ffghdt (fitsfile *fptr, > int *hdutype, int *status)
int fits_copy_file / ffcpfl (fitsfile *infptr, fitsfile *outfptr, int previous, int current, int following, > int *status)
int fits_copy_hdu / ffcopy (fitsfile *infptr, fitsfile *outfptr, int morekeys, > int *status)
int fits_write_hdu / ffwrhdu (fitsfile *infptr, FILE *stream, > int *status)
int fits_copy_header / ffcphd (fitsfile *infptr, fitsfile *outfptr, > int *status)
int fits_delete_hdu / ffdhdu (fitsfile *fptr, > int *hdutype, int *status)
These routines read or write keywords in the Current Header Unit (CHU). Wild card characters (*, ?, or #) may be used when specifying the name of the keyword to be read: a ’?’ will match any single character at that position in the keyword name and a ’*’ will match any length (including zero) string of characters. The ’#’ character will match any consecutive string of decimal digits (0 - 9). When a wild card is used the routine will only search for a match from the current header position to the end of the header and will not resume the search from the top of the header back to the original header position as is done when no wildcards are included in the keyword name. The fits_read_record routine may be used to set the starting position when doing wild card searches. A status value of KEY_NO_EXIST is returned if the specified keyword to be read is not found in the header.
int fits_get_hdrspace / ffghsp (fitsfile *fptr, > int *keysexist, int *morekeys, int *status)
The second routine returns the keyword value as a character string (a literal copy of what is in the value field) regardless of the intrinsic data type of the keyword. The third routine returns the entire 80-character header record of the keyword, with any trailing blank characters stripped off. The fourth routine returns the (next) header record that contains the literal string of characters specified by the ’string’ argument.
If a NULL comment pointer is supplied then the comment string will not be returned.
int fits_read_key / ffgky (fitsfile *fptr, int datatype, char *keyname, > DTYPE *value, char *comment, int *status) int fits_read_keyword / ffgkey (fitsfile *fptr, char *keyname, > char *value, char *comment, int *status) int fits_read_card / ffgcrd (fitsfile *fptr, char *keyname, > char *card, int *status) int fits_read_str / ffgstr (fitsfile *fptr, char *string, > char *card, int *status)
int fits_get_key_strlen / ffgksl (fitsfile *fptr, const char *keyname, int *length, int *status); int fits_read_string_key / ffgsky (fitsfile *fptr, const char *keyname, int firstchar, int maxchar, char *value, int *valuelen, char *comm, int *status);
int fits_read_record / ffgrec (fitsfile *fptr, int keynum, > char *card, int *status) int fits_read_keyn / ffgkyn (fitsfile *fptr, int keynum, > char *keyname, char *value, char *comment, int *status)
int fits_find_nextkey / ffgnxk (fitsfile *fptr, char **inclist, int ninc, char **exclist, int nexc, > char *card, int *status)
VELOCITY= 12.3 / [km/s] orbital speed int fits_read_key_unit / ffgunt (fitsfile *fptr, char *keyname, > char *unit, int *status)
There are 2 related routines: fits_hdr2str simply concatenates all the existing keywords in the header; fits_convert_hdr2str is similar, except that if the CHDU is a tile compressed image (stored in a binary table) then it will first convert that header back to that of the corresponding normal FITS image before concatenating the keywords.
Selected keywords may be excluded from the returned character string. If the second parameter (nocomments) is TRUE (nonzero) then any COMMENT, HISTORY, or blank keywords in the header will not be copied to the output string.
The ’exclist’ parameter may be used to supply a list of keywords that are to be excluded from the output character string. Wild card characters (*, ?, and #) may be used in the excluded keyword names. If no additional keywords are to be excluded, then set nexc = 0 and specify NULL for the the **exclist parameter.
int fits_hdr2str / ffhdr2str (fitsfile *fptr, int nocomments, char **exclist, int nexc, > char **header, int *nkeys, int *status) int fits_convert_hdr2str / ffcnvthdr2str (fitsfile *fptr, int nocomments, char **exclist, int nexc, > char **header, int *nkeys, int *status) int fits_free_memory / fffree (char *header, > int *status);
int fits_write_key / ffpky (fitsfile *fptr, int datatype, char *keyname, DTYPE *value, char *comment, > int *status) int fits_update_key / ffuky (fitsfile *fptr, int datatype, char *keyname, DTYPE *value, char *comment, > int *status)
int fits_write_key_null / ffpkyu (fitsfile *fptr, char *keyname, char *comment, > int *status) int fits_update_key_null / ffukyu (fitsfile *fptr, char *keyname, char *comment, > int *status)
int fits_write_comment / ffpcom (fitsfile *fptr, char *comment, > int *status) int fits_write_history / ffphis (fitsfile *fptr, char *history, > int *status)
int fits_write_date / ffpdat (fitsfile *fptr, > int *status)
int fits_write_record / ffprec (fitsfile *fptr, char *card, > int *status)
int fits_update_card / ffucrd (fitsfile *fptr, char *keyname, char *card, > int *status)
int fits_modify_comment / ffmcom (fitsfile *fptr, char *keyname, char *comment, > int *status)
VELOCITY= 12.3 / [km/s] orbital speed int fits_write_key_unit / ffpunt (fitsfile *fptr, char *keyname, char *unit, > int *status)
int fits_modify_name / ffmnam (fitsfile *fptr, char *oldname, char *newname, > int *status)
int fits_delete_record / ffdrec (fitsfile *fptr, int keynum, > int *status) int fits_delete_key / ffdkey (fitsfile *fptr, char *keyname, > int *status) int fits_delete_str / ffdstr (fitsfile *fptr, char *string, > int *status)
These routines read or write data values in the primary data array (i.e., the first HDU in a FITS file) or an IMAGE extension. There are also routines to get information about the data type and size of the image. Users should also read the following chapter on the CFITSIO iterator function which provides a more ‘object oriented’ method of reading and writing images. The iterator function is a little more complicated to use, but the advantages are that it usually takes less code to perform the same operation, and the resulting program often runs faster because the FITS files are read and written using the most efficient block size.
C programmers should note that the ordering of arrays in FITS files, and hence in all the CFITSIO calls, is more similar to the dimensionality of arrays in Fortran rather than C. For instance if a FITS image has NAXIS1 = 100 and NAXIS2 = 50, then a 2-D array just large enough to hold the image should be declared as array[50][100] and not as array[100][50].
The ‘datatype’ parameter specifies the data type of the ‘nulval’ and ‘array’ pointers and can have one of the following values: TBYTE, TSBYTE, TSHORT, TUSHORT, TINT, TUINT, TLONG, TLONGLONG, TULONG, TULONGLONG, TFLOAT, TDOUBLE. Automatic data type conversion is performed if the data type of the FITS array (as defined by the BITPIX keyword) differs from that specified by ’datatype’. The data values are also automatically scaled by the BSCALE and BZERO keyword values as they are being read or written in the FITS array.
int fits_get_img_type / ffgidt (fitsfile *fptr, > int *bitpix, int *status) int fits_get_img_equivtype / ffgiet (fitsfile *fptr, > int *bitpix, int *status)
int fits_get_img_dim / ffgidm (fitsfile *fptr, > int *naxis, int *status) int fits_get_img_size / ffgisz (fitsfile *fptr, int maxdim, > long *naxes, int *status) int fits_get_img_sizell / ffgiszll (fitsfile *fptr, int maxdim, > LONGLONG *naxes, int *status) int fits_get_img_param / ffgipr (fitsfile *fptr, int maxdim, > int *bitpix, int *naxis, long *naxes, int *status) int fits_get_img_paramll / ffgiprll (fitsfile *fptr, int maxdim, > int *bitpix, int *naxis, LONGLONG *naxes, int *status)
int fits_create_img / ffcrim ( fitsfile *fptr, int bitpix, int naxis, long *naxes, > int *status) int fits_create_imgll / ffcrimll ( fitsfile *fptr, int bitpix, int naxis, LONGLONG *naxes, > int *status)
The ’cell2image’ routine will append a new image extension (or primary array) to the output file. Any WCS keywords associated with the input column image will be translated into the appropriate form for an image extension. Any other keywords in the table header that are not specifically related to defining the binary table structure or to other columns in the table will also be copied to the header of the output image.
The ’image2cell’ routine will copy the input image into the specified row and column of the current binary table in the output file. The binary table HDU must exist before calling this routine, but it may be empty, with no rows or columns of data. The specified column (and row) will be created if it does not already exist. The ’copykeyflag’ parameter controls which keywords are copied from the input image to the header of the output table: 0 = no keywords will be copied, 1 = all keywords will be copied (except those keywords that would be invalid in the table header), and 2 = copy only the WCS keywords.
int fits_copy_cell2image (fitsfile *infptr, fitsfile *outfptr, char *colname, long rownum, > int *status) int fits_copy_image2cell (fitsfile *infptr, fitsfile *outfptr, char *colname, long rownum, int copykeyflag > int *status)
int fits_write_subset / ffpss (fitsfile *fptr, int datatype, long *fpixel, long *lpixel, DTYPE *array, > int *status)
int fits_write_pix / ffppx (fitsfile *fptr, int datatype, long *fpixel, LONGLONG nelements, DTYPE *array, int *status); int fits_write_pixll / ffppxll (fitsfile *fptr, int datatype, LONGLONG *fpixel, LONGLONG nelements, DTYPE *array, int *status); int fits_write_pixnull / ffppxn (fitsfile *fptr, int datatype, long *fpixel, LONGLONG nelements, DTYPE *array, DTYPE *nulval, > int *status); int fits_write_pixnullll / ffppxnll (fitsfile *fptr, int datatype, LONGLONG *fpixel, LONGLONG nelements, DTYPE *array, DTYPE *nulval, > int *status);
int fits_write_null_img / ffpprn (fitsfile *fptr, LONGLONG firstelem, LONGLONG nelements, > int *status)
int fits_read_subset / ffgsv (fitsfile *fptr, int datatype, long *fpixel, long *lpixel, long *inc, DTYPE *nulval, > DTYPE *array, int *anynul, int *status)
The first 2 routines will return any undefined pixels in the FITS array equal to the value of *nullval (note that this parameter gives the address of the null value, not the null value itself) unless nulval = 0 or *nulval = 0, in which case no checks for undefined pixels will be performed. The second 2 routines are similar except that any undefined pixels will have the corresponding nullarray element set equal to TRUE (= 1).
int fits_read_pix / ffgpxv (fitsfile *fptr, int datatype, long *fpixel, LONGLONG nelements, DTYPE *nulval, > DTYPE *array, int *anynul, int *status) int fits_read_pixll / ffgpxvll (fitsfile *fptr, int datatype, LONGLONG *fpixel, LONGLONG nelements, DTYPE *nulval, > DTYPE *array, int *anynul, int *status) int fits_read_pixnull / ffgpxf (fitsfile *fptr, int datatype, long *fpixel, LONGLONG nelements, > DTYPE *array, char *nullarray, int *anynul, int *status) int fits_read_pixnullll / ffgpxfll (fitsfile *fptr, int datatype, LONGLONG *fpixel, LONGLONG nelements, > DTYPE *array, char *nullarray, int *anynul, int *status)
int fits_copy_image_section / ffcpimg (fitsfile *infptr, fitsfile *outfptr, char *section, int *status)
CFITSIO transparently supports the 2 methods of image compression described below.
1) The entire FITS file may be externally compressed with the gzip or Unix compress utility programs, producing a *.gz or *.Z file, respectively. When reading compressed files of this type, CFITSIO first uncompresses the entire file into memory before performing the requested read operations. Output files can be directly written in the gzip compressed format if the user-specified filename ends with ‘.gz’. In this case, CFITSIO initially writes the uncompressed file in memory and then compresses it and writes it to disk when the FITS file is closed, thus saving user disk space. Read and write access to these compressed FITS files is generally quite fast since all the I/O is performed in memory; the main limitation with this technique is that there must be enough available memory (or swap space) to hold the entire uncompressed FITS file.
2) CFITSIO also supports the FITS tiled image compression convention in which the image is subdivided into a grid of rectangular tiles, and each tile of pixels is individually compressed. The details of this FITS compression convention are described at the FITS Support Office web site at http://fits.gsfc.nasa.gov/fits_registry.html, and in the fpackguide pdf file that is included with the CFITSIO source file distributions Basically, the compressed image tiles are stored in rows of a variable length array column in a FITS binary table, however CFITSIO recognizes that this binary table extension contains an image and treats it as if it were an IMAGE extension. This tile-compressed format is especially well suited for compressing very large images because a) the FITS header keywords remain uncompressed for rapid read access, and because b) it is possible to extract and uncompress sections of the image without having to uncompress the entire image. This format is also much more effective in compressing floating point images than simply compressing the image using gzip or compress because it approximates the floating point values with scaled integers which can then be compressed more efficiently.
Currently CFITSIO supports 3 general purpose compression algorithms plus one other special-purpose compression technique that is designed for data masks with positive integer pixel values. The 3 general purpose algorithms are GZIP, Rice, and HCOMPRESS, and the special purpose algorithm is the IRAF pixel list compression technique (PLIO). There are 2 variants of the GZIP algorithm: GZIP_1 compresses the array of image pixel value normally with the GZIP algorithm, while GZIP_2 first shuffles the bytes in all the pixel values so that the most-significant byte of every pixel appears first, followed by the less significant bytes in sequence. GZIP_2 may be more effective in cases where the most significant byte in most of the image pixel values contains the same bit pattern. In principle, any number of other compression algorithms could also be supported by the FITS tiled image compression convention.
The FITS image can be subdivided into any desired rectangular grid of compression tiles. With the GZIP, Rice, and PLIO algorithms, the default is to take each row of the image as a tile. The HCOMPRESS algorithm is inherently 2-dimensional in nature, so the default in this case is to take 16 rows of the image per tile. In most cases it makes little difference what tiling pattern is used, so the default tiles are usually adequate. In the case of very small images, it could be more efficient to compress the whole image as a single tile. Note that the image dimensions are not required to be an integer multiple of the tile dimensions; if not, then the tiles at the edges of the image will be smaller than the other tiles.
The 4 supported image compression algorithms are all ’loss-less’ when applied to integer FITS images; the pixel values are preserved exactly with no loss of information during the compression and uncompression process. In addition, the HCOMPRESS algorithm supports a ’lossy’ compression mode that will produce larger amount of image compression. This is achieved by specifying a non-zero value for the HCOMPRESS “scale” parameter. Since the amount of compression that is achieved depends directly on the RMS noise in the image, it is usually more convention to specify the HCOMPRESS scale factor relative to the RMS noise. Setting s = 2.5 means use a scale factor that is 2.5 times the calculated RMS noise in the image tile. In some cases it may be desirable to specify the exact scaling to be used, instead of specifying it relative to the calculated noise value. This may be done by specifying the negative of desired scale value (typically in the range -2 to -100).
Very high compression factors (of 100 or more) can be achieved by using large HCOMPRESS scale values, however, this can produce undesirable “blocky” artifacts in the compressed image. A variation of the HCOMPRESS algorithm (called HSCOMPRESS) can be used in this case to apply a small amount of smoothing of the image when it is uncompressed to help cover up these artifacts. This smoothing is purely cosmetic and does not cause any significant change to the image pixel values.
Floating point FITS images (which have BITPIX = -32 or -64) usually contain too much “noise” in the least significant bits of the mantissa of the pixel values to be effectively compressed with any lossless algorithm. Consequently, floating point images are first quantized into scaled integer pixel values (and thus throwing away much of the noise) before being compressed with the specified algorithm (either GZIP, Rice, or HCOMPRESS). This technique produces much higher compression factors than simply using the GZIP utility to externally compress the whole FITS file, but it also means that the original floating value pixel values are not exactly preserved. When done properly, this integer scaling technique will only discard the insignificant noise while still preserving all the real information in the image. The amount of precision that is retained in the pixel values is controlled by the "quantization level" parameter, q. Larger values of q will result in compressed images whose pixels more closely match the floating point pixel values, but at the same time the amount of compression that is achieved will be reduced. Users should experiment with different values for this parameter to determine the optimal value that preserves all the useful information in the image, without needlessly preserving all the “noise” which will hurt the compression efficiency.
The default value for the quantization scale factor is 4.0, which means that scaled integer pixel values will be quantized such that the difference between adjacent integer values will be 1/4th of the noise level in the image background. CFITSIO uses an optimized algorithm to accurately estimate the noise in the image. As an example, if the RMS noise in the background pixels of an image = 32.0, then the spacing between adjacent scaled integer pixel values will equal 8.0 by default. Note that the RMS noise is independently calculated for each tile of the image, so the resulting integer scaling factor may fluctuate slightly for each tile. In some cases it may be desirable to specify the exact quantization level to be used, instead of specifying it relative to the calculated noise value. This may be done by specifying the negative of desired quantization level for the value of q. In the previous example, one could specify q = -8.0 so that the quantized integer levels differ by exactly 8.0. Larger negative values for q means that the levels are more coarsely spaced, and will produce higher compression factors.
When floating point images are being quantized, one must also specify what quantization method is to be used. The default algorithm is called “SUBTRACTIVE_DITHER_1”. A second variation called “SUBTRACTIVE_DITHER_2” is also available, which does the same thing except that any pixels with a value of 0.0 are not dithered and instead the zero values are exactly preserved in the compressed image. This is intended for the special case where “bad pixels” in the image have been artifically set to zero to indicate that they have no valid value. It is not currently supported with HCOMPRESS, and if requested while using HCOMPRESS, it will be replaced with “SUBTRACTIVE_DITHER_1”. One may also turn off dithering completely with the “NO_DITHER” option, but this is not recommended because it can cause larger systematic errors in measurements of the position or brightness of objects in the compressed image.
There are 3 methods for specifying all the parameters needed to write a FITS image in the tile compressed format. The parameters may either be specified at run time as part of the file name of the output compressed FITS file, or the writing program may call a set of helper CFITSIO subroutines that are provided for specifying the parameter values, or “compression directive” keywords may be added to the header of each image HDU to specify the compression parameters. These 3 methods are described below.
1) At run time, when specifying the name of the output FITS file to be created, the user can indicate that images should be written in tile-compressed format by enclosing the compression parameters in square brackets following the root disk file name in the following format:
[compress NAME T1,T2; q[z] QLEVEL, s HSCALE]
where
NAME = algorithm name: GZIP, Rice, HCOMPRESS, HSCOMPRSS or PLIO may be abbreviated to the first letter (or HS for HSCOMPRESS) T1,T2 = tile dimension (e.g. 100,100 for square tiles 100 pixels wide) QLEVEL = quantization level for floating point FITS images HSCALE = HCOMPRESS scale factor; default = 0 which is lossless.
Here are a few examples of this extended syntax:
myfile.fit[compress] - use the default compression algorithm (Rice) and the default tile size (row by row) myfile.fit[compress G] - use the specified compression algorithm; myfile.fit[compress R] only the first letter of the algorithm myfile.fit[compress P] should be given. myfile.fit[compress H] myfile.fit[compress R 100,100] - use Rice and 100 x 100 pixel tiles myfile.fit[compress R; q 10.0] - quantization level = (RMS-noise) / 10. myfile.fit[compress R; qz 10.0] - quantization level = (RMS-noise) / 10. also use the SUBTRACTIVE_DITHER_2 quantization method myfile.fit[compress HS; s 2.0] - HSCOMPRESS (with smoothing) and scale = 2.0 * RMS-noise
2) Before calling the CFITSIO routine to write the image header keywords (e.g., fits_create_image) the programmer can call the routines described below to specify the compression algorithm and the tiling pattern that is to be used. There are routines for specifying the various compression parameters and similar routines to return the current values of the parameters:
int fits_set_compression_type(fitsfile *fptr, int comptype, int *status) int fits_set_tile_dim(fitsfile *fptr, int ndim, long *tilesize, int *status) int fits_set_quantize_level(fitsfile *fptr, float qlevel, int *status) int fits_set_quantize_method(fitsfile *fptr, int method, int *status) int fits_set_quantize_dither(fitsfile *fptr, int dither, int *status) int fits_set_dither_seed(fitsfile *fptr, int seed, int *status) int fits_set_dither_offset(fitsfile *fptr, int offset, int *status) int fits_set_lossy_int(fitsfile *fptr, int lossy_int, int *status) this forces integer image to be converted to floats, then quantized int fits_set_huge_hdu(fitsfile *fptr, int huge, int *status); this should be called when the compressed image size is more than 4 GB. int fits_set_hcomp_scale(fitsfile *fptr, float scale, int *status) int fits_set_hcomp_smooth(fitsfile *fptr, int smooth, int *status) Set smooth = 1 to apply smoothing when uncompressing the image int fits_get_compression_type(fitsfile *fptr, int *comptype, int *status) int fits_get_tile_dim(fitsfile *fptr, int ndim, long *tilesize, int *status) int fits_get_quantize_level(fitsfile *fptr, float *level, int *status) int fits_get_hcomp_scale(fitsfile *fptr, float *scale, int *status)
Several symbolic constants are defined for use as the value of the ‘comptype’ parameter: GZIP_1, GZIP_2, RICE_1, HCOMPRESS_1 or PLIO_1. Entering NULL for comptype will turn off the tile-compression and cause normal FITS images to be written.
There are also defined symbolic constants for the quantization method: “SUBTRACTIVE_DITHER_1”, “SUBTRACTIVE_DITHER_2”, and “NO_DITHER”.
3) CFITSIO will uses the values of the following keywords, if they are present in the header of the image HDU, to determine how to compress that HDU. These keywords override any compression parameters that were specified with the previous 2 methods.
FZALGOR - 'RICE_1' , 'GZIP_1', 'GZIP_2', 'HCOMPRESS_1', 'PLIO_1', 'NONE' FZTILE - 'ROW', 'WHOLE', or '(n,m)' FZQVALUE - float value (default = 4.0) FZQMETHD - 'SUBTRACTIVE_DITHER_1', 'SUBTRACTIVE_DITHER_2', 'NO_DITHER' FZDTHRSD - 'CLOCK', 'CHECKSUM', 1 - 10000 FZINT2F - T, or F: Convert integers to floats, then quantize? FZHSCALE - float value (default = 0). Hcompress scale value.
No special action is required by software when read tile-compressed images because all the CFITSIO routines that read normal uncompressed FITS images also transparently read images in the tile-compressed format; CFITSIO essentially treats the binary table that contains the compressed tiles as if it were an IMAGE extension.
The following 2 routines are available for compressing or or decompressing an image:
int fits_img_compress(fitsfile *infptr, fitsfile *outfptr, int *status); int fits_img_decompress (fitsfile *infptr, fitsfile *outfptr, int *status);
Before calling the compression routine, the compression parameters must first be defined in one of the 3 way described in the previous paragraphs. There is also a routine to determine if the current HDU contains a tile compressed image (it returns 1 or 0):
int fits_is_compressed_image(fitsfile *fptr, int *status);
A small example program called ’imcopy’ is included with CFITSIO that can be used to compress (or uncompress) any FITS image. This program can be used to experiment with the various compression options on existing FITS images as shown in these examples:
1) imcopy infile.fit 'outfile.fit[compress]' This will use the default compression algorithm (Rice) and the default tile size (row by row) 2) imcopy infile.fit 'outfile.fit[compress GZIP]' This will use the GZIP compression algorithm and the default tile size (row by row). The allowed compression algorithms are Rice, GZIP, and PLIO. Only the first letter of the algorithm name needs to be specified. 3) imcopy infile.fit 'outfile.fit[compress G 100,100]' This will use the GZIP compression algorithm and 100 X 100 pixel tiles. 4) imcopy infile.fit 'outfile.fit[compress R 100,100; qz 10.0]' This will use the Rice compression algorithm, 100 X 100 pixel tiles, and quantization level = RMSnoise / 10.0 (assuming the input image has a floating point data type). By specifying qz instead of q, this means use the subtractive dither2 quantization method. 5) imcopy infile.fit outfile.fit If the input file is in tile-compressed format, then it will be uncompressed to the output file. Otherwise, it simply copies the input image to the output image. 6) imcopy 'infile.fit[1001:1500,2001:2500]' outfile.fit This extracts a 500 X 500 pixel section of the much larger input image (which may be in tile-compressed format). The output is a normal uncompressed FITS image. 7) imcopy 'infile.fit[1001:1500,2001:2500]' outfile.fit.gz Same as above, except the output file is externally compressed using the gzip algorithm.
These routines perform read and write operations on columns of data in FITS ASCII or Binary tables. Note that in the following discussions, the first row and column in a table is at position 1 not 0.
Users should also read the following chapter on the CFITSIO iterator function which provides a more ‘object oriented’ method of reading and writing table columns. The iterator function is a little more complicated to use, but the advantages are that it usually takes less code to perform the same operation, and the resulting program often runs faster because the FITS files are read and written using the most efficient block size.
int fits_create_tbl / ffcrtb (fitsfile *fptr, int tbltype, LONGLONG naxis2, int tfields, char *ttype[], char *tform[], char *tunit[], char *extname, int *status)
int fits_copy_hdutab / ffcpht (fitsfile *infptr, fitsfile *outfptr, LONGLONG firstrow, LONGLONG nrows, > int *status)
int fits_get_num_rows / ffgnrw (fitsfile *fptr, > long *nrows, int *status); int fits_get_num_rowsll / ffgnrwll (fitsfile *fptr, > LONGLONG *nrows, int *status); int fits_get_num_cols / ffgncl (fitsfile *fptr, > int *ncols, int *status);
The input column name template may be either the exact name of the column to be searched for, or it may contain wild card characters (*, ?, or #), or it may contain the integer number of the desired column (with the first column = 1). The ‘*’ wild card character matches any sequence of characters (including zero characters) and the ‘?’ character matches any single character. The # wildcard will match any consecutive string of decimal digits (0-9). If more than one column name in the table matches the template string, then the first match is returned and the status value will be set to COL_NOT_UNIQUE as a warning that a unique match was not found. To find the other cases that match the template, call the routine again leaving the input status value equal to COL_NOT_UNIQUE and the next matching name will then be returned. Repeat this process until a status = COL_NOT_FOUND is returned.
The FITS Standard recommends that only letters, digits, and the underscore character be used in column names (with no embedded spaces). Trailing blank characters are not significant.
int fits_get_colnum / ffgcno (fitsfile *fptr, int casesen, char *templt, > int *colnum, int *status) int fits_get_colname / ffgcnn (fitsfile *fptr, int casesen, char *templt, > char *colname, int *colnum, int *status)
The ’repeat’ parameter returns the vector repeat count on the binary table TFORMn keyword value. (ASCII table columns always have repeat = 1). The ’width’ parameter returns the width in bytes of a single column element (e.g., a ’10D’ binary table column will have width = 8, an ASCII table ’F12.2’ column will have width = 12, and a binary table’60A’ character string column will have width = 60); Note that CFITSIO supports the local convention for specifying arrays of fixed length strings within a binary table character column using the syntax TFORM = ’rAw’ where ’r’ is the total number of characters (= the width of the column) and ’w’ is the width of a unit string within the column. Thus if the column has TFORM = ’60A12’ then this means that each row of the table contains 5 12-character substrings within the 60-character field, and thus in this case this routine will return typecode = TSTRING, repeat = 60, and width = 12. (The 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 number of substrings in any binary table character string field can be calculated by (repeat/width). A null pointer may be given for any of the output parameters that are not needed.
The second routine, fit_get_eqcoltype is similar except that in the case of scaled integer columns it returns the ’equivalent’ data type that is needed to store the scaled values, and not necessarily the physical data type of the unscaled values as stored in the FITS table. For example if a ’1I’ column in a binary table has TSCALn = 1 and TZEROn = 32768, then this column effectively contains unsigned short integer values, and thus the returned value of typecode will be TUSHORT, not TSHORT. Similarly, if a column has TTYPEn = ’1I’ and TSCALn = 0.12, then the returned typecode will be TFLOAT.
int fits_get_coltype / ffgtcl (fitsfile *fptr, int colnum, > int *typecode, long *repeat, long *width, int *status) int fits_get_coltypell / ffgtclll (fitsfile *fptr, int colnum, > int *typecode, LONGLONG *repeat, LONGLONG *width, int *status) int fits_get_eqcoltype / ffeqty (fitsfile *fptr, int colnum, > int *typecode, long *repeat, long *width, int *status) int fits_get_eqcoltypell / ffeqtyll (fitsfile *fptr, int colnum, > int *typecode, LONGLONG *repeat, LONGLONG *width, int *status)
int fits_get_col_display_width / ffgcdw (fitsfile *fptr, int colnum, > int *dispwidth, int *status)
int fits_read_tdim / ffgtdm (fitsfile *fptr, int colnum, int maxdim, > int *naxis, long *naxes, int *status) int fits_read_tdimll / ffgtdmll (fitsfile *fptr, int colnum, int maxdim, > int *naxis, LONGLONG *naxes, int *status)
int fits_decode_tdim / ffdtdm (fitsfile *fptr, char *tdimstr, int colnum, int maxdim, > int *naxis, long *naxes, int *status) int fits_decode_tdimll / ffdtdmll (fitsfile *fptr, char *tdimstr, int colnum, int maxdim, > int *naxis, LONGLONG *naxes, int *status)
int fits_write_tdim / ffptdm (fitsfile *fptr, int colnum, int naxis, long *naxes, > int *status) int fits_write_tdimll / ffptdmll (fitsfile *fptr, int colnum, int naxis, LONGLONG *naxes, > int *status)
The first delete routine deletes NROWS consecutive rows starting with row FIRSTROW. The second delete routine takes an input string that lists the rows or row ranges (e.g., ’5-10,12,20-30’), whereas the third delete routine takes an input integer array that specifies each individual row to be deleted. In both latter cases, the input list of rows to delete must be sorted in ascending order. These routines update the NAXIS2 keyword to reflect the new number of rows in the table.
int fits_insert_rows / ffirow (fitsfile *fptr, LONGLONG firstrow, LONGLONG nrows, > int *status) int fits_delete_rows / ffdrow (fitsfile *fptr, LONGLONG firstrow, LONGLONG nrows, > int *status) int fits_delete_rowrange / ffdrrg (fitsfile *fptr, char *rangelist, > int *status) int fits_delete_rowlist / ffdrws (fitsfile *fptr, long *rowlist, long nrows, > int *status) int fits_delete_rowlistll / ffdrwsll (fitsfile *fptr, LONGLONG *rowlist, LONGLONG nrows, > int *status)
int fits_insert_col / fficol (fitsfile *fptr, int colnum, char *ttype, char *tform, > int *status) int fits_insert_cols / fficls (fitsfile *fptr, int colnum, int ncols, char **ttype, char **tform, > int *status) int fits_delete_col / ffdcol(fitsfile *fptr, int colnum, > int *status)
The first form copies a single column incolnum to outcolnum. Copying within the same HDU is permitted. The second form copies ncols columns from the input, starting at column incolnum to the output, starting at outcolnum. For the second form, the input and output must be different HDUs.
If outcolnum is greater than the number of column in the output table, then the new column(s) will be appended to the end of the table. Note that the first column in a table is at colnum = 1. The standard indexed keywords that related to the columns (e.g., TDISPn, TUNITn, TCRPXn, TCDLTn, etc.) will also be copied.
int fits_copy_col / ffcpcl (fitsfile *infptr, fitsfile *outfptr, int incolnum, int outcolnum, int create_col, > int *status); int fits_copy_cols / ffccls (fitsfile *infptr, fitsfile *outfptr, int incolnum, int outcolnum, int ncols, int create_col, > int *status);
The fits_copy_selrows
form copies only selected rows to the output.
Which rows are transferred is determined by an array of flags, row_status[]
,
which could be returned by fits_find_rows()
or constructed by the user.
FITS row N is copied if row_status[N-first_row]
is non-zero.
int fits_copy_rows / ffcprw (fitsfile *infptr, fitsfile *outfptr, LONGLONG firstrow, LONGLONG nrows, > int *status); int fits_copy_selrows / ffcpsr (fitsfile *infptr, fitsfile *outfptr, LONGLONG firstrow, LONGLONG nrows, char *row_status, > int *status);
int fits_modify_vector_len / ffmvec (fitsfile *fptr, int colnum, LONGLONG newveclen, > int *status)
The following routines write or read data values in the current ASCII or binary table extension. If a write operation extends beyond the current size of the table, then the number of rows in the table will automatically be increased and the NAXIS2 keyword value will be updated. Attempts to read beyond the end of the table will result in an error.
Automatic data type conversion is performed for numerical data types (only) if the data type of the column (defined by the TFORMn keyword) differs from the data type of the array in the calling routine. ASCII and binary tables support the following data type values: TSTRING, TBYTE, TSBYTE, TSHORT, TUSHORT, TINT, TUINT, TLONG, TLONGLONG, TULONG, TULONGLONG, TFLOAT, or TDOUBLE. Binary tables also support TLOGICAL (internally mapped to the ‘char’ data type), TCOMPLEX, and TDBLCOMPLEX.
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.
Individual bits in a binary table ’X’ or ’B’ column may be read/written to/from a *char array by specifying the TBIT datatype. The *char array will be interpreted as an array of logical TRUE (1) or FALSE (0) values that correspond to the value of each bit in the FITS ’X’ or ’B’ column. Alternatively, the values in a binary table ’X’ column may be read/written 8 bits at a time to/from an array of 8-bit integers by specifying the TBYTE datatype.
Note that within the context of these routines, the TSTRING data type corresponds to a C ’char**’ data type, i.e., a pointer to an array of pointers to an array of characters. This is different from the keyword reading and writing routines where TSTRING corresponds to a C ’char*’ data type, i.e., a single pointer to an array of characters. When reading strings from a table, the char arrays obviously must have been allocated long enough to hold the whole FITS table string. See section 4.5 (“Dealing with Character Strings”) for more information.
For complex and double complex data types, nelements
is the number
of numerical pairs; the number of floats or doubles stored by
array
must be 2*nelements
.
For the logical data (TLOGICAL), the C storage type is a char
single-byte character. A FITS value of ‘T
’rue reads as 1 and
‘F
’ reads as 0; other non-FITS characters are preserved untranslated.
Numerical data values are automatically scaled by the TSCALn and TZEROn keyword values (if they exist).
In the case of binary tables with vector elements, the firstelem
parameter defines the starting element (beginning with 1, not 0) within
the cell (a cell is defined as the intersection of a row and a column
and may contain a single value or a vector of values). The firstelem
parameter is ignored when dealing with ASCII tables. Similarly, in the
case of binary tables the ’nelements’ parameter specifies the total
number of vector values to be read or written (continuing on subsequent
rows if required) and not the number of table cells.
The first routine simply writes the array of values to the FITS file (doing data type conversion if necessary) whereas the second routine will substitute the appropriate FITS null value for all elements which are equal to the input value of nulval (note that this parameter gives the address of nulval, not the null value itself). For integer columns the FITS null value is defined by the TNULLn keyword (an error is returned if the keyword doesn’t exist). For floating point columns the special IEEE NaN (Not-a-Number) value will be written into the FITS file. If a null pointer is entered for nulval, then the null value is ignored and this routine behaves the same as the first routine. The third routine simply writes undefined pixel values to the column. The fourth routine fills every column in the table with null values, in the specified rows (ignoring any columns that do not have a defined null value).
The fits_write_cols()
variant writes multiple columns in a
single pass, which may be significantly faster for large data
files. The “chunk” size is determined automatically based upon
CFITSIO’s buffer sizes. Only whole rows can be written, of any
type except TBIT or TSTRING. For this variant, datatype, colnum,
array and nulval are arrays of the equivalent single-column
parameter (i.e. datatype[i]
is the data type of column
i
).
int fits_write_col / ffpcl (fitsfile *fptr, int datatype, int colnum, LONGLONG firstrow, LONGLONG firstelem, LONGLONG nelements, DTYPE *array, > int *status) int fits_write_colnull / ffpcn (fitsfile *fptr, int datatype, int colnum, LONGLONG firstrow, LONGLONG firstelem, LONGLONG nelements, DTYPE *array, DTYPE *nulval, > int *status) int fits_write_col_null / ffpclu (fitsfile *fptr, int colnum, LONGLONG firstrow, LONGLONG firstelem, LONGLONG nelements, > int *status) int fits_write_nullrows / ffprwu (fitsfile *fptr, LONGLONG firstrow, LONGLONG nelements, > int *status) int fits_write_cols / ffpcln (fitsfile *fptr, int ncols, int *datatype, int *colnum, LONGLONG firstrow, LONGLONG nrows, DTYPE **array, DTYPE **nulval, int *status)
array
before calling.
Undefined array elements will be returned with a value = *nullval,
(note that this parameter gives the address of the null value, not the
null value itself) unless nulval = 0 or *nulval = 0, in which case
no checking for undefined pixels will be performed. The second
routine is similar except that any undefined pixels will have the
corresponding nullarray element set equal to TRUE (= 1).Reading data as TSTRING values is different than for other data types as described above.
Any column, regardless of it’s intrinsic data type, may be read as a string. It should be noted however that reading a numeric column as a string is 10 - 100 times slower than reading the same column as a number due to the large overhead in constructing the formatted strings. The display format of the returned strings will be determined by the TDISPn keyword, if it exists, otherwise by the data type of the column. The length of the returned strings (not including the null terminating character) can be determined with the fits_get_col_display_width routine. The following TDISPn display formats are currently supported:
Iw.m Integer Ow.m Octal integer Zw.m Hexadecimal integer Fw.d Fixed floating point Ew.d Exponential floating point Dw.d Exponential floating point Gw.d General; uses Fw.d if significance not lost, else Ew.d
where w is the width in characters of the displayed values, m is the minimum number of digits displayed, and d is the number of digits to the right of the decimal. The .m field is optional.
The fits_read_cols()
variant read multiple columns in a
single pass, which may be significantly faster for large data
files. The “chunk” size is determined automatically based upon
CFITSIO’s buffer sizes. Only whole rows can be read, of any type
except TBIT or TSTRING. For this variant, datatype, colnum, array
and nulval are arrays of the equivalent single-column parameter
(i.e. datatype[i]
is the data type of column i
).
int fits_read_col / ffgcv (fitsfile *fptr, int datatype, int colnum, LONGLONG firstrow, LONGLONG firstelem, LONGLONG nelements, DTYPE *nulval, DTYPE *array, int *anynul, int *status) int fits_read_colnull / ffgcf (fitsfile *fptr, int datatype, int colnum, LONGLONG firstrow, LONGLONG firstelem, LONGLONG nelements, DTYPE *array, char *nullarray, int *anynul, int *status) int fits_read_cols / ffgcvn (fitsfile *fptr, int ncols, int *datatype, int *colnum, LONGLONG firstrow, LONGLONG nrows, DTYPE **nulval, DTYPE **array, int **anynul, int *status)
These routines all parse and evaluate an input string containing a user defined arithmetic expression. The first 3 routines select rows in a FITS table, based on whether the expression evaluates to true (not equal to zero) or false (zero). The other routines evaluate the expression and calculate a value for each row of the table. The allowed expression syntax is described in the row filter section in the ‘Extended File Name Syntax’ chapter of this document. The expression may also be written to a text file, and the name of the file, prepended with a ’@’ character may be supplied for the ’expr’ parameter (e.g. ’@filename.txt’). The expression in the file can be arbitrarily complex and extend over multiple lines of the file. Lines that begin with 2 slash characters (’//’) will be ignored and may be used to add comments to the file.
int fits_find_rows / fffrow (fitsfile *fptr, char *expr, long firstrow, long nrows, > long *n_good_rows, char *row_status, int *status)
int fits_find_first_row / ffffrw (fitsfile *fptr, char *expr, > long *rownum, int *status)
int fits_select_rows / ffsrow (fitsfile *infptr, fitsfile *outfptr, char *expr, > int *status )
int fits_calc_rows / ffcrow (fitsfile *fptr, int datatype, char *expr, long firstrow, long nelements, void *nulval, > void *array, int *anynul, int *status)
int fits_calculator / ffcalc (fitsfile *infptr, char *expr, fitsfile *outfptr, char *parName, char *parInfo, > int *status)
int fits_calculator_rng / ffcalc_rng (fitsfile *infptr, char *expr, fitsfile *outfptr, char *parName, char *parInfo, int nranges, long *firstrow, long *lastrow > int *status)
int fits_test_expr / fftexp (fitsfile *fptr, char *expr, int maxdim > int *datatype, long *nelem, int *naxis, long *naxes, int *status)
The following routines may be useful when performing histogramming operations on column(s) of a table to generate an image in a primary array or image extension.
MININ and MAXIN are input arrays that give the minimum and maximum value for the histogram, along each axis. Alternatively, the name of keywords that give the min, max, and binsize may be give with the MINNAME, MAXNAME, and BINNAME array parameters. If the value = DOUBLENULLVALUE and no keyword names are given, then the routine will use the TLMINn and TLMAXn keywords, if present, or the actual min and/or max values in the column.
The “d” version has double precision floating point outputs as noted in the calling signature. The version without “d” has single precision floating point outputs.
BINSIZEIN is an array giving the binsize along each axis. If the value = DOUBLENULLVALUE, and a keyword name is not specified with BINNAME, then this routine will first look for the TDBINn keyword, or else will use a binsize = 1, or a binsize that produces 10 histogram bins, which ever is smaller.
int fits_calc_binning[d] Input parameters: (fitsfile *fptr, /* IO - pointer to table to be binned */ int naxis, /* I - number of axes/columns in the binned image */ char colname[4][FLEN_VALUE], /* I - optional column names */ double *minin, /* I - optional lower bound value for each axis */ double *maxin, /* I - optional upper bound value, for each axis */ double *binsizein, /* I - optional bin size along each axis */ char minname[4][FLEN_VALUE], /* I - optional keywords for min */ char maxname[4][FLEN_VALUE], /* I - optional keywords for max */ char binname[4][FLEN_VALUE], /* I - optional keywords for binsize */ Output parameters: int *colnum, /* O - column numbers, to be binned */ long *naxes, /* O - number of bins in each histogram axis */ float[double] *amin, /* O - lower bound of the histogram axes */ float[double] *amax, /* O - upper bound of the histogram axes */ float[double] *binsize, /* O - width of histogram bins/pixels on each axis */ int *status)
int fits_copy_pixlist2image (fitsfile *infptr, /* I - pointer to input HDU */ fitsfile *outfptr, /* I - pointer to output HDU */ int firstkey, /* I - first HDU keyword to start with */ int naxis, /* I - number of axes in the image */ int *colnum, /* I - numbers of the columns to be binned */ int *status) /* IO - error status */
int fits_write_keys_histo (fitsfile *fptr, /* I - pointer to table to be binned */ fitsfile *histptr, /* I - pointer to output histogram image HDU */ int naxis, /* I - number of axes in the histogram image */ int *colnum, /* I - column numbers of the binned columns */ int *status)
The “d” version has double precision floating point inputs as noted in the calling signature. The version without “d” has single precision floating point inputs.
int fits_rebin_wcs[d] (fitsfile *fptr, /* I - pointer to table to be binned */ int naxis, /* I - number of axes in the histogram image */ float[double] *amin, /* I - first pixel include in each axis */ float[double] *binsize, /* I - binning factor for each axis */ int *status)
The “d” version has double precision floating point inputs as noted in the calling signature. The version without “d” has single precision floating point inputs.
int fits_make_hist[d] (fitsfile *fptr, /* I - pointer to table with X and Y cols; */ fitsfile *histptr, /* I - pointer to output FITS image */ int bitpix, /* I - datatype for image: 16, 32, -32, etc */ int naxis, /* I - number of axes in the histogram image */ long *naxes, /* I - size of axes in the histogram image */ int *colnum, /* I - column numbers (array length = naxis) */ float[double] *amin, /* I - minimum histogram value, for each axis */ float[double] *amax, /* I - maximum histogram value, for each axis */ float[double] *binsize, /* I - bin size along each axis */ float[double] weight, /* I - binning weighting factor (FLOATNULLVALUE */ /* for no weighting) */ int wtcolnum, /* I - keyword or col for weight (or NULL) */ int recip, /* I - use reciprocal of the weight? 0 or 1 */ char *selectrow, /* I - optional array (length = no. of */ /* rows in the table). If the element is true */ /* then the corresponding row of the table will */ /* be included in the histogram, otherwise the */ /* row will be skipped. Ingnored if *selectrow */ /* is equal to NULL. */ int *status)
The following routines either compute or validate the checksums for the CHDU. The DATASUM keyword is used to store the numerical value of the 32-bit, 1’s complement checksum for the data unit alone. If there is no data unit then the value is set to zero. The numerical value is stored as an ASCII string of digits, enclosed in quotes, because the value may be too large to represent as a 32-bit signed integer. The CHECKSUM keyword is used to store the ASCII encoded COMPLEMENT of the checksum for the entire HDU. Storing the complement, rather than the actual checksum, forces the checksum for the whole HDU to equal zero. If the file has been modified since the checksums were computed, then the HDU checksum will usually not equal zero. These checksum keyword conventions are based on a paper by Rob Seaman published in the proceedings of the ADASS IV conference in Baltimore in November 1994 and a later revision in June 1995. See Appendix B for the definition of the parameters used in these routines.
int fits_write_chksum / ffpcks (fitsfile *fptr, > int *status)
int fits_update_chksum / ffupck (fitsfile *fptr, > int *status)
int fits_verify_chksum / ffvcks (fitsfile *fptr, > int *dataok, int *hduok, int *status)
int fits_get_chksum/ /ffgcks (fitsfile *fptr, > unsigned long *datasum, unsigned long *hdusum, int *status)
int fits_encode_chksum / ffesum (unsigned long sum, int complm, > char *ascii);
unsigned long fits_decode_chksum / ffdsum (char *ascii, int complm, > unsigned long *sum);
The following routines help to construct or parse the FITS date/time strings. Starting in the year 2000, the FITS DATE keyword values (and the values of other ‘DATE-’ keywords) must have the form ’YYYY-MM-DD’ (date only) or ’YYYY-MM-DDThh:mm:ss.ddd...’ (date and time) where the number of decimal places in the seconds value is optional. These times are in UTC. The older ’dd/mm/yy’ date format may not be used for dates after 01 January 2000. See Appendix B for the definition of the parameters used in these routines.
int fits_get_system_date/ffgsdt ( > int *day, int *month, int *year, int *status )
int fits_get_system_time/ffgstm (> char *datestr, int *timeref, int *status)
int fits_date2str/ffdt2s (int year, int month, int day, > char *datestr, int *status)
int fits_time2str/fftm2s (int year, int month, int day, int hour, int minute, double second, int decimals, > char *datestr, int *status)
int fits_str2date/ffs2dt (char *datestr, > int *year, int *month, int *day, int *status)
int fits_str2time/ffs2tm (char *datestr, > int *year, int *month, int *day, int *hour, int *minute, double *second, int *status)
The following utility routines may be useful for certain applications.
float fits_get_version / ffvers ( > float *version)
void fits_write_errmsg / ffpmsg (char *err_msg)
void fits_uppercase / ffupch (char *string)
void fits_compare_str / ffcmps (char *templt, char *string, int casesen, > int *match, int *exact)
This routine is similar to the ANSI C ’strtok’ function:
The first call to fits_split_names has a non-null input string. It finds the first name in the string and terminates it by overwriting the next character of the string with a null terminator and returns a pointer to the name. Each subsequent call, indicated by a NULL value of the input string, returns the next name, searching from just past the end of the previous name. It returns NULL when no further names are found.
char *fits_split_names(char *namelist)
The following example shows how a string would be split into 3 names:
myfile[1][bin (x,y)=4], file2.fits file3.fits ^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^ ^^^^^^^^^^ 1st name 2nd name 3rd name
int fits_test_keyword / fftkey (char *keyname, > int *status) int fits_test_record / fftrec (char *card, > int *status)
int fits_null_check / ffnchk (char *card, > int *status)
int fits_get_keyname / ffgknm (char *card, > char *keyname, int *keylength, int *status)
int fits_parse_value / ffpsvc (char *card, > char *value, char *comment, int *status)
int fits_make_key / ffmkky (const char *keyname, const char *value, const char *comment, > char *card, int *status)
int fits_make_keyn / ffkeyn (char *keyroot, int value, > char *keyname, int *status)
int fits_make_nkey / ffnkey (int value, char *keyroot, > char *keyname, int *status)
int fits_get_keytype / ffdtyp (char *value, > char *dtype, int *status)
Data Type Range TSBYTE: -128 to 127 TBYTE: 128 to 255 TSHORT: -32768 to 32767 TUSHORT: 32768 to 65535 TINT -2147483648 to 2147483647 TUINT 2147483648 to 4294967295 TLONGLONG -9223372036854775808 to 9223372036854775807
int fits_get_inttype / ffinttyp (char *value, > int *datatype, int *neg, int *status)
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 WCS keywords defined in the the WCS papers, including: 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, DATE-OBS TYP_COMM_KEY 130 COMMENT, HISTORY, (blank keyword) TYP_CONT_KEY 140 CONTINUE TYP_USER_KEY 150 all other keywords int fits_get_keyclass / ffgkcl (char *card)
int fits_binary_tform / ffbnfm (char *tform, > int *typecode, long *repeat, long *width, int *status) int fits_binary_tformll / ffbnfmll (char *tform, > int *typecode, LONGLONG *repeat, long *width, int *status)
int fits_ascii_tform / ffasfm (char *tform, > int *typecode, long *width, int *decimals, int *status)
int fits_get_tbcol / ffgabc (int tfields, char **tform, int space, > long *rowlen, long *tbcol, int *status)
int fits_parse_template / ffgthd (char *templt, > char *card, int *keytype, int *status)
The input templt character string generally should contain 3 tokens: (1) the KEYNAME, (2) the VALUE, and (3) the COMMENT string. The TEMPLATE string must adhere to the following format:
The keytype output parameter indicates how the returned CARD string should be interpreted:
keytype interpretation ------- ------------------------------------------------- -2 Rename the keyword with name = the first 8 characters of CARD to the new name given in characters 41 - 48 of CARD. -1 delete the keyword with this name from the FITS header. 0 append the CARD string to the FITS header if the keyword does not already exist, otherwise update the keyword value and/or comment field if is already exists. 1 This is a HISTORY or COMMENT keyword; append it to the header 2 END record; do not explicitly write it to the FITS file.
EXAMPLES: The following lines illustrate valid input template strings:
INTVAL 7 / This is an integer keyword RVAL 34.6 / This is a floating point keyword EVAL=-12.45E-03 / This is a floating point keyword in exponential notation lval F / This is a boolean keyword This is a comment keyword with a blank keyword name SVAL1 = 'Hello world' / this is a string keyword SVAL2 '123.5' this is also a string keyword sval3 123+ / this is also a string keyword with the value '123+ ' # the following template line deletes the DATE keyword - DATE # the following template line modifies the NAME keyword to OBJECT - NAME OBJECT
The user passes an array of patterns to be matched. Input pattern number i is pattern[i][0], and output pattern number i is pattern[i][1]. Keywords are matched against the input patterns. If a match is found then the keyword is re-written according to the output pattern.
Order is important. The first match is accepted. The fastest match will be made when templates with the same first character are grouped together.
Several characters have special meanings:
i,j - single digits, preserved in output template n - column number of one or more digits, preserved in output template m - generic number of one or more digits, preserved in output template a - coordinate designator, preserved in output template # - number of one or more digits ? - any character * - only allowed in first character position, to match all keywords; only useful as last pattern in the list
i, j, n, and m are returned by the routine.
For example, the input pattern "iCTYPn" will match "1CTYP5" (if n_value is 5); the output pattern "CTYPEi" will be re-written as "CTYPE1". Notice that "i" is preserved.
The following output patterns are special:
"-" - do not copy a keyword that matches the corresponding input pattern
"–" - if match occurs, outrec will have "-KEYNAME"
"+" - copy the input unchanged
The inrec string could be just the 8-char keyword name, or the entire 80-char header record. Characters 9 - 80 in the input string simply get appended to the translated keyword name.
Upon return, outrec will have the converted string, starting from the pattern[i][1] pattern and applying the numerical substitutions as described above. If the output pattern is "–" then the resulting outrec will be "-KEYNAME", which may indicate to the calling routine that KEYNAME is to be deleted.
If n_range = 0, then only keywords with ’n’ equal to n_value will be considered as a pattern match. If n_range = +1, then all values of ’n’ greater than or equal to n_value will be a match, and if -1, then values of ’n’ less than or equal to n_value will match.
int fits_translate_keyword( char *inrec, /* I - input string */ char *outrec, /* O - output converted string, or */ /* a null string if input does not */ /* match any of the patterns */ char *patterns[][2],/* I - pointer to input / output string */ /* templates */ int npat, /* I - number of templates passed */ int n_value, /* I - base 'n' template value of interest */ int n_offset, /* I - offset to be applied to the 'n' */ /* value in the output string */ int n_range, /* I - controls range of 'n' template */ /* values of interest (-1,0, or +1) */ int *pat_num, /* O - matched pattern number (0 based) or -1 */ int *i, /* O - value of i, if any, else 0 */ int *j, /* O - value of j, if any, else 0 */ int *m, /* O - value of m, if any, else 0 */ int *n, /* O - value of n, if any, else 0 */ int *status) /* IO - error status */
char *patterns[][2] = {{"TSCALn", "BSCALE" }, /* Standard FITS keywords */ {"TZEROn", "BZERO" }, {"TUNITn", "BUNIT" }, {"TNULLn", "BLANK" }, {"TDMINn", "DATAMIN" }, {"TDMAXn", "DATAMAX" }, {"iCTYPn", "CTYPEi" }, /* Coordinate labels */ {"iCTYna", "CTYPEia" }, {"iCUNIn", "CUNITi" }, /* Coordinate units */ {"iCUNna", "CUNITia" }, {"iCRVLn", "CRVALi" }, /* WCS keywords */ {"iCRVna", "CRVALia" }, {"iCDLTn", "CDELTi" }, {"iCDEna", "CDELTia" }, {"iCRPXn", "CRPIXi" }, {"iCRPna", "CRPIXia" }, {"ijPCna", "PCi_ja" }, {"ijCDna", "CDi_ja" }, {"iVn_ma", "PVi_ma" }, {"iSn_ma", "PSi_ma" }, {"iCRDna", "CRDERia" }, {"iCSYna", "CSYERia" }, {"iCROTn", "CROTAi" }, {"WCAXna", "WCSAXESa"}, {"WCSNna", "WCSNAMEa"}};
It is allowed for infptr and outfptr to point to the same HDU.
If any output matched patterns are of the form "-KEYNAME" then this routine will attempt to delete the keyword KEYNAME. It is not an error if KEYNAME is not present in the output HDU.
int fits_translate_keywords( fitsfile *infptr, /* I - pointer to input HDU */ fitsfile *outfptr, /* I - pointer to output HDU */ int firstkey, /* I - first HDU record number to start with */ char *patterns[][2],/* I - pointer to input / output keyword templates */ int npat, /* I - number of templates passed */ int n_value, /* I - base 'n' template value of interest */ int n_offset, /* I - offset to be applied to the 'n' */ /* value in the output string */ int n_range, /* I - controls range of 'n' template */ /* values of interest (-1,0, or +1) */ int *status) /* IO - error status */
int fits_parse_range / ffrwrg(char *rowlist, LONGLONG maxrows, int maxranges, > int *numranges, long *rangemin, long *rangemax, int *status) int fits_parse_rangell / ffrwrgll(char *rowlist, LONGLONG maxrows, int maxranges, > int *numranges, LONGLONG *rangemin, LONGLONG *rangemax, int *status)
int ffchfl(fitsfile *fptr, > int *status)
int ffcdfl(fitsfile *fptr, > int *status)
int fits_rms_float (float fdata[], int npix, float in_null_value, > double *rms, int *status) int fits_rms_short (short fdata[], int npix, short in_null_value, > double *rms, int *status)
int fits_is_reentrant(void)