FITSIO provides easy-to-use support for reading and writing data in variable length fields of a binary table. The variable length columns have TFORMn keyword values of the form `1Pt(len)' where `t' is the datatype code (e.g., I, J, E, D, etc.) and `len' is an integer specifying the maximum length of the vector in the table. If the value of `len' is not specified when the table is created (e.g., if the TFORM keyword value is simply specified as '1PE' instead of '1PE(400) ), then FITSIO will automatically scan the table when it is closed to determine the maximum length of the vector and will append this value to the TFORMn value.
The same routines which read and write data in an ordinary fixed length binary table extension are also used for variable length fields, however, the subroutine parameters take on a slightly different interpretation as described below.
All the data in a variable length field is written into an area called the `heap' which follows the main fixed-length FITS binary table. The size of the heap, in bytes, is specified with the PCOUNT keyword in the FITS header. When creating a new binary table, the initial value of PCOUNT should usually be set to zero. FITSIO will recompute the size of the heap as the data is written and will automatically update the PCOUNT keyword value when the table is closed. Thus, application programs usually do not need to worry about the heap size except when inserting a new binary table HDU in front of other existing HDUs in the FITS file (with ftibin). In this specific case the correct final value of PCOUNT (or a larger value) must be specified when the HDU is initially created so that the correct amount of space will be inserted into the FITS file.
By default the heap data area starts immediately after the last row of the fixed-length table. (This default starting location may be overridden by the THEAP keyword, but this is not recommended). Thus when writing variable length arrays the number of rows in the table should be correctly specified (with the NAXIS2 keyword) at the time the table is first created. This differs from the simpler case of tables that only contain fixed-length columns where the number of rows in the table does not have to be explicitly defined until just before the table is closed. It is still possible to insert additional rows into a binary table containing variable-length columns (with the FTIROW routine), however, the performance may be rather slow due to all the internal shuffling of the data that must be performed.
When writing to a variable length field, the entire array of values for a given row of the table must be written with a single call to FTPCLx. The total length of the array is calculated from (NELEM+FELEM-1). One cannot append more elements to an existing field at a later time; any attempt to do so will simply overwrite all the data which was previously written. Note also that the new data will be written to a new area of the heap and the heap space used by the previous write cannot be reclaimed. For this reason it is advised that each row of a variable length field only be written once. An exception to this general rule occurs when setting elements of an array as undefined. One must first write a dummy value into the array with FTPCLx, and then call FTPCLU to flag the desired elements as undefined. (Do not use the FTPCNx family of routines with variable length fields). Note that the rows of a table may be written in any order.
When reading or writing to a variable length ASCII character field (e.g., TFORM = '1PA') only a single character string is read or written. FTPCLS writes the whole length of the input string (minus any trailing blank characters), thus the NELEM and FELEM parameters are ignored. If the input string is completely blank then FITSIO will write one blank character to the FITS file. Similarly, FTGCVS and FTGCFS read the entire string (truncated to the width of the character string argument in the subroutine call) and also ignore the NELEM and FELEM parameters.
The FTPDES subroutine is useful in situations where multiple rows of a variable length column have the identical array of values. One can simply write the array once for the first row, and then use FTPDES to write the same descriptor values into the other rows (use the FTGDES routine to read the first descriptor value); all the rows will then point to the same storage location thus saving disk space.
When reading from a variable length array field one can only read as many elements as exist in that row of the table; reading does not automatically continue with the next row of the table as occurs when reading an ordinary fixed length table field. Attempts to read more than this will return an error. One can determine the length of each row of the field with the FTGDES subroutine.