When a new FITS file is created with a call to fits_create_file, the name of a template file may be supplied in parentheses immediately following the name of the new file to be created. This template is used to define the structure of one or more HDUs in the new file. The template file may be another FITS file, in which case the newly created file will have exactly the same keywords in each HDU as in the template FITS file, but all the data units will be filled with zeros. The template file may also be an ASCII text file, where each line (in general) describes one FITS keyword record. The format of the ASCII template file is described in the following sections.
The format of each ASCII template line closely follows the format of a FITS keyword record:
KEYWORD = KEYVALUE / COMMENT
except that free format may be used (e.g., the equals sign may appear at any position in the line) and TAB characters are allowed and are treated the same as space characters. The KEYVALUE and COMMENT fields are optional. The equals sign character is also optional, but it is recommended that it be included for clarity. Any template line that begins with the pound ’#’ character is ignored by the template parser and may be use to insert comments into the template file itself.
The KEYWORD name field is limited to 8 characters in length and only the letters A-Z, digits 0-9, and the hyphen and underscore characters may be used, without any embedded spaces. Lowercase letters in the template keyword name will be converted to uppercase. Leading spaces in the template line preceding the keyword name are generally ignored, except if the first 8 characters of a template line are all blank, then the entire line is treated as a FITS comment keyword (with a blank keyword name) and is copied verbatim into the FITS header.
The KEYVALUE field may have any allowed FITS data type: character string, logical, integer, real, complex integer, or complex real. Integer values must be within the allowed range of a ’signed long’ variable; some C compilers only suppport 4-byte long integers with a range from -2147483648 to +2147483647, whereas other C compilers support 8-byte integers with a range of plus or minus 2**63.
The character string values need not be enclosed in single quote characters unless they are necessary to distinguish the string from a different data type (e.g. 2.0 is a real but ’2.0’ is a string). The keyword has an undefined (null) value if the template record only contains blanks following the "=" or between the "=" and the "/" comment field delimiter.
String keyword values longer than 68 characters (the maximum length that will fit in a single FITS keyword record) are permitted using the CFITSIO long string convention. They can either be specified as a single long line in the template, or by using multiple lines where the continuing lines contain the ’CONTINUE’ keyword, as in this example:
LONGKEY = 'This is a long string value that is contin&' CONTINUE 'ued over 2 records' / comment field goes here
The format of template lines with CONTINUE keyword is very strict: 3 spaces must follow CONTINUE and the rest of the line is copied verbatim to the FITS file.
The start of the optional COMMENT field must be preceded by "/", which is used to separate it from the keyword value field. Exceptions are if the KEYWORD name field contains COMMENT, HISTORY, CONTINUE, or if the first 8 characters of the template line are blanks.
More than one Header-Data Unit (HDU) may be defined in the template file. The start of an HDU definition is denoted with a SIMPLE or XTENSION template line:
1) SIMPLE begins a Primary HDU definition. SIMPLE may only appear as the first keyword in the template file. If the template file begins with XTENSION instead of SIMPLE, then a default empty Primary HDU is created, and the template is then assumed to define the keywords starting with the first extension following the Primary HDU.
2) XTENSION marks the beginning of a new extension HDU definition. The previous HDU will be closed at this point and processing of the next extension begins.
If a template keyword name ends with a "#" character, it is said to be ’auto-indexed’. Each "#" character will be replaced by the current integer index value, which gets reset = 1 at the start of each new HDU in the file (or 7 in the special case of a GROUP definition). The FIRST indexed keyword in each template HDU definition is used as the ’incrementor’; each subsequent occurrence of this SAME keyword will cause the index value to be incremented. This behavior can be rather subtle, as illustrated in the following examples in which the TTYPE keyword is the incrementor in both cases:
TTYPE# = TIME TFORM# = 1D TTYPE# = RATE TFORM# = 1E
will create TTYPE1, TFORM1, TTYPE2, and TFORM2 keywords. But if the template looks like,
TTYPE# = TIME TTYPE# = RATE TFORM# = 1D TFORM# = 1E
this results in a FITS files with TTYPE1, TTYPE2, TFORM2, and TFORM2, which is probably not what was intended!
In addition to the template lines which define individual keywords, the
template parser recognizes 3 special directives which are each preceded
by the backslash character: \include, \group
, and \end
.
The ’include’ directive must be followed by a filename. It forces the parser to temporarily stop reading the current template file and begin reading the include file. Once the parser reaches the end of the include file it continues parsing the current template file. Include files can be nested, and HDU definitions can span multiple template files.
The start of a GROUP definition is denoted with the ’group’ directive, and the end of a GROUP definition is denoted with the ’end’ directive. Each GROUP contains 0 or more member blocks (HDUs or GROUPs). Member blocks of type GROUP can contain their own member blocks. The GROUP definition itself occupies one FITS file HDU of special type (GROUP HDU), so if a template specifies 1 group with 1 member HDU like:
\group grpdescr = 'demo' xtension bintable # this bintable has 0 cols, 0 rows \end
then the parser creates a FITS file with 3 HDUs :
1) dummy PHDU 2) GROUP HDU (has 1 member, which is bintable in HDU number 3) 3) bintable (member of GROUP in HDU number 2)
Technically speaking, the GROUP HDU is a BINTABLE with 6 columns. Applications can define additional columns in a GROUP HDU using TFORMn and TTYPEn (where n is 7, 8, ....) keywords or their auto-indexing equivalents.
For a more complicated example of a template file using the group directives, look at the sample.tpl file that is included in the CFITSIO distribution.
The template syntax can formally be defined as follows:
TEMPLATE = BLOCK [ BLOCK ... ] BLOCK = { HDU | GROUP } GROUP = \GROUP [ BLOCK ... ] \END HDU = XTENSION [ LINE ... ] { XTENSION | \GROUP | \END | EOF } LINE = [ KEYWORD [ = ] ] [ VALUE ] [ / COMMENT ] X ... - X can be present 1 or more times { X | Y } - X or Y [ X ] - X is optional
At the topmost level, the template defines 1 or more template blocks. Blocks can be either HDU (Header Data Unit) or a GROUP. For each block the parser creates 1 (or more for GROUPs) FITS file HDUs.
In general the fits_execute_template() function tries to be as atomic as possible, so either everything is done or nothing is done. If an error occurs during parsing of the template, fits_execute_template() will (try to) delete the top level BLOCK (with all its children if any) in which the error occurred, then it will stop reading the template file and it will return with an error.
1. This template file will create a 200 x 300 pixel image, with 4-byte integer pixel values, in the primary HDU:
SIMPLE = T BITPIX = 32 NAXIS = 2 / number of dimensions NAXIS1 = 100 / length of first axis NAXIS2 = 200 / length of second axis OBJECT = NGC 253 / name of observed object
The allowed values of BITPIX are 8, 16, 32, -32, or -64, representing, respectively, 8-bit integer, 16-bit integer, 32-bit integer, 32-bit floating point, or 64 bit floating point pixels.
2. To create a FITS table, the template first needs to include XTENSION = TABLE or BINTABLE to define whether it is an ASCII or binary table, and NAXIS2 to define the number of rows in the table. Two template lines are then needed to define the name (TTYPEn) and FITS data format (TFORMn) of the columns, as in this example:
xtension = bintable naxis2 = 40 ttype# = Name tform# = 10a ttype# = Npoints tform# = j ttype# = Rate tunit# = counts/s tform# = e
The above example defines a null primary array followed by a 40-row binary table extension with 3 columns called ’Name’, ’Npoints’, and ’Rate’, with data formats of ’10A’ (ASCII character string), ’1J’ (integer) and ’1E’ (floating point), respectively. Note that the other required FITS keywords (BITPIX, NAXIS, NAXIS1, PCOUNT, GCOUNT, TFIELDS, and END) do not need to be explicitly defined in the template because their values can be inferred from the other keywords in the template. This example also illustrates that the templates are generally case-insensitive (the keyword names and TFORMn values are converted to upper-case in the FITS file) and that string keyword values generally do not need to be enclosed in quotes.