Open GENIE Data Access Interface (new get)

This document describes a set of routines designed to create, populate, read and modify ISIS format and NeXus format data files. The aim of these routines is to provide one simple way to read and write all styles of data files. The routines are based on the routines used in Open GENIE and will therefore cope with automatic detection of file input types for all Open GENIE supported file formats.

Basic Principles

Any data interface design is a compromise between flexibility and complexity. The interface below is intended to be simple to use from C, C++ or FORTRAN programs but does make use of some of the most advanced parts of the Open GENIE data access subsystem to do this. As a result, it is worth being aware of how data is actually read or written by the interface.

File conversions

When reading a file on different machine types, there are inherently several different conversion problems which may arise. Some are due to differences in the structure of the data files, others may be due to differences in numerical precision or binary format. As a result, the access routines work in two stages.

For reading:

  1. Access and convert the desired data block from the file.
  2. Select the data from the block to read into the program.

For writing:

  1. Construct a data block to be written to the file.
  2. Write and convert the data to the file.

In both cases, this is a very simple operation if the structure of the data file is simple. On the other hand, if the structure of the data file is complex, the data access routines provide a unique and powerful data structure parsing mechanism which allows complex structures to be easily snipped up into manageable (if not byte sized!) pieces.

Handles

A "Handle" is the name given to the data block which has been converted from the file but has not yet been loaded into your program. It is simply a user chosen name to identify the block of data in transition between stages (1) and (2) above, effectively the data enters a holding area where you can then make detailed requests of it. For example, if we read one experimental parameter from an ISIS raw file, "NSP1", the fragment of the program using handles would look something like the one below.

        ...
* Access the data item by name and put in the transfer area
    CALL GX_get('MY_HANDLE', 'NSP1', 0)

* Read the value into the INTEGER variable "my_nsp"
    CALL GX_transfer('MY_HANDLE', '-->', 'INTEGER', my_nsp, 0, 0)
        ...

The handle name links the request to get the data with the subsequent request to load the data into a program variable.

A handle can be re-used as often as required or several different handles may be used to allow to store data blocks before reading them out into the code. A handle expression can also be used to select a small amount of data to read into the program from a larger data block.

Let's assume now that we want to read the first "MAXLEN" elements of the detector to spectrum mapping table and write it out to a new file. We know the name of the data item in the ISIS raw file and can access it as below.

* Somewhere to put the data we are about to read
    INTEGER*4 my_tab(42)
        ...
* Get the whole data block to the handle.
    CALL GX_get('MY_HANDLE', 'SPEC', 0)

* Select part of the data to read out from the handle.
    CALL GX_transfer('MY_HANDLE[1:42]', '-->', 'INTEGER', my_tab, 42, 1)
        ...

This way we can slice the first 42 elements out of the array (assuming it has at least 42 elements). This example could have just specified a single array element if only one value was required. In some file formats, the block may contain named fields or attributes. These can be accessed using the syntax for accessing workspaces, for example "My_Handle.Two_Theta".

Data access routines descriptions

Before reading or writing data, a session must be initialised using GX_activate_session(), at the end of data access GX_deactivate_session() session should also be called. These routines control the allocation and deallocation of memory as well as setting the default output file format.

The interface makes the general assumption that a user may well want to have one file open for writing at the same time as having a different file open for reading. This is achieved by having both GX_select_source() and GX_select_destination routines(), either or both of these calls may be used in a data access session. The GX_directory() function allows the calling program to find out what data items are available for a program to read in the specified file.

The following is a generic description of the Application Programming Interface (API) and is divided into sections grouping similar functions. Language specific routine calls are given in the reference documentation for each rouitine.

Session Control

Function Return value Description
GX_activate_session(in default_format) status code Initialises the interface selecting a default data format for output.
GX_deactivate_session() status code Deactivates the interface, frees storage

File operations

Function Return value Description
GX_select_source(in filename) status code Selects a data source for subsequent operations
GX_select_destination(in filename, in file_format) status code Selects a data destination for subsequent operations
GX_directory(in filename, [out dir_listing]) status code Returns a directory of available fields in any data file.

Data reading/writing

Function Return value Description
GX_get(in handle, in tag, in object-id) status code Associates a handle with the referenced data file object.
GX_put(in handle, in tag, in object-id, in flag) status code Writes data associated with a handle into a data file.

Handle manipulation

Function Return value Description
GX_assign_handle(in handle_lval, in handle_rval) status code Assign one handle to the whole or part of another handle.
GX_release_handle(in handle) status code Deactivate the handle and release and storage.
GX_transfer(in handle, in direction, in type, inout data, in length, in dims) status code Transfer data to or from variables in the program.

 

NOTES:

  1. References to an object in the data file can be made either by a string tag or an object-id (number) for the data file. For a GX_get, if both are specified, the tag must correspond to the tag on the object selected by the object-id. Objects may also be accessed by block number if the object-id is negative (e.g. -1 for block 1).
  2. For a GX_put, the object at the object-id specified may be overwritten with the new tag and associated handle value. If the "flag" parameter to GX_put is set to "OVERWRITE", when the object-id corresponds with that already in an output file, the object and tag will be overwritten.
  3. Handles are always strings and are marked as "in" parameters. It is worth pointing out that although the handle is effectively a constant reference, what it points to acts like a variable.