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.
9.1 Detailed Template Line Format
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. 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.
9.2 Auto-indexing of Keywords
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!
9.3 Template Parser Directives
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.
9.4 Formal Template Syntax
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.
9.5 Errors
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.
9.6 Examples
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.