As described in Section 2, extensions can be used to store non-standard items in an NDF. A typical use of an extension would be to store information associated with a particular instrument; this information would be processed by the data-reduction package specific to that instrument. Programmers who design extensions should register the extension names with Starlink to avoid duplication. Obvious generic names such as ‘ASTROMETRY’ should be avoided as these are likely to be defined by Starlink in the future.
It is, of course, possible to perform all access to HDS structures using HDS routines (see SUN/92). The NDF routines simply provide a convenient method of accessing standard items in NDFs, but the programmer must resort to HDS routines to deal with items in extensions. However, the NDF routines do include facilities for propagating extensions, checking for the presence of extensions, creating and deleting extensions and finding HDS locators to specific extensions.
This last statement requires some explanation. HDS refers to items in a structure via locators; each
locator is a CHARACTER*15
variable which points to a HDS object. Strictly, a locator is a string of length
DAT__SZLOC
– this latter item being a symbolic constant which is defined in the SAE_PAR
include file.
Locators must be declared as CHARACTER*(DAT__SZLOC)
as there is no guarantee that the length of 15
will be used for future HDS implementations on machines other than VAXs. The use of locators is
illustrated in the example which follows.
Recalling the program ADAM_EXAMPLES:ADD7.FOR discussed in Section 6, a constant value was
added to each element in an NDF main data array. NDF_ASSOC was used to associate the input file
with an NDF identifier and NDF_MAP was used to map the main data array. The program below
performs a similar task, but uses HDS DAT_
routines.
Two locators ILOC and DLOC are used in this program; ILOC is associated with the top-level of
the input NDF, i.e. with INPUT
, and DLOC with INPUT.DATA_ARRAY
. Both are declared as
CHARACTER*DAT__SZLOC
and both are annulled with a call to DAT_ANNUL
at the end of the program.
Annulling a locator cancels the association between the locator and the object and unmaps any arrays
mapped via the locator. The first call to DAT_ASSOC associates a locator ILOC with the input file.
This locator effectively points to the top-level of the file. To find a locator to a first-level
object, DAT_FIND is used. For example, the call above finds a locator to INPUT.DATA_ARRAY.
DAT_MAPV maps the object INPUT.DATA_ARRAY
as a vectorised array, just as NDF_MAP did in
ADD7.
However, this program will only work if the main data array is to be found in INPUT.DATA_ARRAY
– i.e.
the NDF is primitive. If INPUT.DATA_ARRAY
is a structure with the actual data array contained in
INPUT.DATA_ARRAY.DATA
as is also consistent with the NDF definition, then ADD8 will crash. The
program could perform checks to discern the format for itself, but it is obviously easier to use the NDF
routines to access standard objects.
However this option is not available when wishing to process information in extensions. The next
example considered here uses information from the FIGARO extension. This extension may contain
the exposure time for an observation. If this exists it will be held in .OBS.TIME in the FIGARO
extension. This extract from a TRACE on ADAM_EXAMPLES:FIGDATA.SDF shows the actual
location is FIGDATA.MORE.FIGARO.OBS.TIME.
The example program ADAM_EXAMPLES:DIVTIM.FOR reads the value of the exposure time and divides the main data array by this value. The steps involved in accessing the exposure time value are described below.
The input file is associated with an NDF identifier in the usual way. The program checks for the existence of a FIGARO extension and if such an extension does exist, a locator to it is found.
It is now necessary to use HDS routines. The program checks to see if there is an .OBS structure in the FIGARO extension; if there is, a locator to it is found.
Now the program checks for the existence of a .TIME object in the FIGARO .OBS structure. If this exists, a locator to it is found.
The value of the .OBS.TIME
object is now retrieved. The locator to it can be annulled.