This section will walk you through the Fortran source code for a simple application which uses the CAT library to write a small catalogue. First, however, a few preliminaries.
CAT_PAR
and CAT_ERR
. These INCLUDE files define
symbolic constants which application programs may use. Section 3.2 explains how to
access these files. It is worth your while printing out and examining copies of both
files. The comments included in the files should be sufficient to explain the purpose of
each constant. CAT_PAR
contains general constants pertaining to the CAT library. CAT_ERR
contains constants corresponding to the various error codes which can be set by the CAT
library. If your application needs to access one of these values you should always use
the appropriate symbolic constant; never hard-code the actual value into your code. The
values may (and probably will) change in subsequent releases of the CAT library.
.TRUE.
.FALSE.
This scheme is adopted in both the routines to get a value from a catalogue and those to put a value to a field in a catalogue. It is adopted to avoid any possible ambiguity in interpreting null values.
When a null value is obtained from a catalogue the actual datum returned will be the ADAM ‘bad’ value for the appropriate data type (where one is available). This procedure facilitates passing values obtained from CAT into other ADAM subroutines. It means, however, that the null value returned through the CAT interface is not necessarily the same as the representation of the null stored in the catalogue. Existing catalogues, for example FITS tables from external sources, can come with a variety of values used to represent null values. The necessary checks and substitutions are performed automatically and invisibly within the catalogue-format specific parts of the CAT library. Your application will simply see the appropriate ADAM ‘bad’ value.
Not all catalogues support null values in all their columns. If a column does not support null
values then the null value flag will always be returned set to .FALSE.
The treatment of null values is described in greater detail in Section 8.2. In particular, Section 8.2.5 prescribes how applications should handle null values.
We are now ready to examine a simple application which uses the CAT library. We will use one of the
example applications released with the library, EXAMPLE_WRITE
. This example creates and
writes values to a small catalogue. I strongly recommend that you print out a copy of the
source code and refer to it as you work through the example. The source code is available in
file:
/star/share/cat/example_write.f
This example program is simpler than a real application. Starting at the beginning, the first thing to notice about the application is that, because it is an ADAM A-task, at its top level it is a subroutine, not a main program:
The status argument is used to keep track of the success of the application as it proceeds with its task.
After the ADAM prologue comments the CAT symbolic constants are INCLUDEd. Some of the constants defined in this file will be used by the application.
The various variables used in the application are defined next.
The first executable statement is the usual check that the status is ok. This check is mandatory in ADAM applications.
Once it is out of the way the application proper can start. It starts with a call to CAT_CREAT
:
This subroutine will create a new catalogue, whose name it obtains from
the ADAM parameter system (in practice the user will be prompted for
it)3.
The first argument of CAT_CREAT
is the name of the ADAM parameter which will supply the catalogue
name. The remaining two arguments are returned by CAT_CREAT
; CI
is the identifier for the catalogue.
We will use this variable to refer to the catalogue throughout the application. STATUS
is the running
status argument which is usual in ADAM libraries. If the routine has succeeded its value is
SAI__OK
.
After CAT_CREAT
has executed successfully a new catalogue has been created, but no columns or
parameters have been defined for it, and it contains no data. The next step is to define some columns.
The first column defined is an INTEGER column called COLI
. Subroutine CAT_PNEW0
is used for this
task:
The first argument, CI
, identifies the catalogue to which the new column belongs. The second
argument tells CAT_PNEW0
that it has to create a new column; this argument should always be
CAT__FITYP
when a column is to be created. The third argument is the name of the column, COLI
in the
present case, and the fourth argument defines its data type. There are symbolic constants defined
in CAT_PAR
for each of the data types supported by CAT. COLI
is an INTEGER column,
so the code for an INTEGER is used. The codes for the different data types are listed in
Table 4.
The fifth argument, FII
, is returned rather than given and is an identifier for the column; subsequent
references to the column will be via this identifier. The final argument is the usual ADAM running
status.
The mandatory information which you must supply to define a column is: the catalogue to which it
belongs, its name and its data type. All these values are specified using routine CAT_PNEW0
. However,
as explained in Section 2, a column is defined by a set of attributes, of which the name and data type
are but two, albeit mandatory ones. Section 6.7 lists all the attributes for a column. If you do not
specify the remaining attributes default values are adopted for them. You can, however,
supply your own values to over-ride the defaults. The next line is an example of doing
so.
This routine is one of a family of similar routines, one for each data type (CAT_TATTC
for attributes of
data type CHARACTER, CAT_TATTI
attributes of type INTEGER etc). Here it is used to set the
comment attribute, COMM of column FII
to the value ‘Integer column’. Other attributes of column
COLI
could have been set in the same way, but in this example they are not, and the defaults are
adopted4.
Two additional columns are created in the same way; the REAL column COLR
and the CHARACTER
column COLC
. Note that in the case of COLC
the CHARACTER size attribute CSIZE is set using routine
CAT_TATTI
.
An important restriction to remember is that columns must be created, and their attributes set, before any rows of data are written to the catalogue. Once a table of values have been written to a catalogue the details of its existing columns are frozen and no new columns can be created for it.
After creating the columns, some parameters are created. The first of these is the INTEGER
parameter PARI
. It is created with the same routine that was used to create the columns,
CAT_PNEW0
:
Again the first argument is the catalogue identifier. The second argument indicates that a parameter is
to be created; this argument should always be set to CAT__QITYP
when a parameter is to be created.
The remaining arguments are exactly the same as they were for creating a column: PARI
is the
parameter name, CAT__TYPEI
the data type and QII
and STATUS
are the identifier for the parameter
and the running status, respectively.
As for columns, only the minimum, mandatory attributes for the parameter are set with CAT_PNEW0
,
and default values are adopted for the remaining attributes. Section 6.9 lists the attributes
of a parameter. Also just like columns, the attributes of parameters can be set using the
CAT_TATTt
family of routines (where t = C
for CHARACTER attributes, I
for INTEGER etc). In
the example CAT_TATTC
is used to set the comments attribute, COMM of parameter
PARI
and CAT_TATTI
is used to set the value attribute VALUE. The latter point is worth
remembering; having created a parameter with CAT_PNEW0
it is necessary to use one of the
CAT_TATTt
routines to set its value, and the routine chosen should correspond to the data type of the
parameter5.
Two additional parameters are created; the REAL parameter PARR
and the CHARACTER parameter
PARC
. Note that, as was the case for columns, for the CHARACTER parameter PARC
the CHARACTER
size attribute ‘CSIZE’ must be set using CAT_TATTI
.
Note that, unlike columns, parameters can be created at any stage while writing a catalogue. They do not have to be created prior to writing the table of values for the catalogue.
Once the parameters have been created the example starts a loop which will write the table of values.
In the CAT interface the basic method of writing (and reading) a catalogue is one row at a time. Each increment of the loop will correspond to a separate row of the catalogue, and thus in total twenty-five rows will be written, numbered from one to twenty-five.
The first few lines of code inside the loop are concerned with inventing values to write to the catalogue. The next few lines set the null value flags (all the rows contain non-null values, except row ten, where the flags are set to null). In a real application, of course, these values would not be invented, but would either be the results of a calculation or read from an external file.
The line:
writes a single value to column COLI
. FII
is the column identifier, VALI
and NULI
the value and null
value flag respectively. STATUS
is, of course, the running status. CAT_PUT0I
is one of the family of
CAT_PUT0t
routines, with one routine per data type. (I
for INTEGER, C
for CHARACTER etc). Thus
there are corresponding calls to write the REAL and CHARACTER columns COLR
and
COLC
:
CAT has the concept of the ‘current row buffer’, which is an internal
copy of the row of the catalogue which it is working on currently. The
CAT_PUT0t
routines put fields to the current row buffer (and the corresponding
CAT_GET0t
routines read values from it).
Writes out the current row buffer for catalogue CI
to the actual catalogue file, appending it to the end
of the catalogue. The internal current row buffer is initialized ready to receive new values, and the
internal count of the actual catalogue row number to which the current row buffer corresponds is
incremented by one. That is, CAT_RAPND
takes care of writing the current row buffer to the catalogue
and readies CAT to receive values for a new current row buffer. When a catalogue is created the
current row buffer is initialized automatically and the row number to which it corresponds is set to
one.
Thus a loop with one increment corresponding to one row in the catalogue and containing calls to
CAT_PUT0t
routines to put values to the current row buffer and a call to CAT_RAPND
to append the
current row buffer to the catalogue is all that is necessary to write a table of values to a
catalogue. The current row has been written, so the loop generating each row can now
terminate:
There is one final call to a CAT routine:
This call ‘releases’ catalogue identifier CI
and closes the corresponding catalogue. Identifiers to items
within the catalogue, such as the various columns and parameters, are also released. Any remaining
values are written to disk, the files are closed etc. The creation of the catalogue is complete. Finally, if
all has succeeded, the application reports a message and then terminates.
Having worked through this example application you might like to try it out. Type:
You will be prompted for the catalogue name. Reply, for example:
After a couple of moments the message ‘Catalogue created successfully.
’ should appear and a
binary FITS table called test.fit
should have been created in your current directory. You can
examine its contents using the xcatview
catalogue browser in CURSA (see SUN/190[3]) or the
listout
utility in CAT-EXAMPLES. For the latter simply type:
and answer the prompts (see Section 3.4 for details).
Another example program is available which reads back the catalogue created by EXAMPLE_WRITE
. It is
called EXAMPLE_READ
and the source code is available in file:
You might like to print out a copy and try to understand it. If you have followed the discussion for
EXAMPLE_WRITE
you should be able to do so without any difficulty.
3It is possible to create or open a CAT catalogue without going through the ADAM parameter system by calling routine
CAT_TOPEN
rather than CAT_CREAT
. This routine is not used in the present example, but is described in Section 7.5,
below.
4For convenience two additional routines, which are not used in the present example, are provided for
creating columns. CAT_CNEWS
creates a column and simultaneously sets some of the more commonly
used attributes; CAT_CNEWA
creates a column and simultaneously sets all of its attributes. These
routines may be more convenient to use than a call to CAT_PNEW0
followed by multiple calls to
CAT_TATTt
.
They are described in Section 7.8.3, below.
5For convenience two additional routines, which are not used in the present example, are provided for creating parameters.
CAT_PPTSt
creates a parameter and simultaneously sets some of the more commonly used attributes;
CAT_PPTAt
creates a parameter and simultaneously sets all of its attributes. These routines may
be more convenient to use than a call to CAT_PNEW0
followed by multiple calls to
CAT_TATTt
.
They are described in Section 7.8.4, below.