HDF comes with a library of access functions. On top of the HDF-library an application programmers interface (API) for NeXus was defined which hides many of the low level details and ideosyncracies of the HDF interface from the NeXus programmer. However, writing NeXus files stays hideous even with this interface due to the amount of repetitive code required to implement the NeXus structure. Now, repetitive tasks is one area a computer is good at. So, why not have the computer create the structure of the NeXus file? In order to do this the following components are needed:
A NXDDL dictionary is preferably initialized from a file. Such a NXDDL file has to follow these general structure guidelines:
The next thing to define is the content of the definition string. A
definition string will have the general form:
The path through the vGroup hierarchy to a data item will be described in a
manner analog to a Unix directory hierarchy. However, NeXus requires two
pieces of data in order to fully qualify a vGroup. This is it's name and
class. Consequently, both name and classname will be given for each vGroup,
separated by a komma. A valid path string then looks like:
/scan1,NXentry/DMC,NXinstrument/big_detector,NXdetector/TerminalSymbolThis translates into: TerminalSymbol in vGroup big_detector, class NXdetector, which resides in vGroup DMC of class NXinstrument, which in turn is situated in the vGroup scan1 of class NXentry.
The terminal symbol in a definition string is used to define the data item
at the end of the definition. NeXus currently supports only three types of
data items at the end of the chain: these are scientific data sets (SDS),
vGroups and links to other data items or vGroups. The terminal symbol for a link
is specified by the keyword NXLINK
followed
by a valid alias of another data item or vGroup. For example the terminal
symbol:
A vGroup would be denoted by the keyword VGROUP. By then, the vGroup has already been defined by the path string. This form of alias is only useful for the definition of links to vGroups.
A SDS is more involved. The definition of an SDS starts with the keyword SDS. This keyword must then be followed by the name of the SDS. Following the name there are option value pairs which define the details of the SDS. The following options exist:
PATHSTRING/SDS counts -rank 3 -dim {64,64,712} -type DFNT_INT32 \ -attr {Units,Counts}
One additional data type is needed for this API:
NXDclose deletes and writes a NeXus dictionary. If filename is not NULL, the dictionary specified by handle is written to the file specified by filename. In any case the dictionary specified by handle will be deleted.
NXDadd adds a new alias - Definition String pair to the dictionary specified by handle.
NXDget retrieves the definition string for the alias specified as the second parameter from the dictionary handle. The definition string is copied to pBuffer. Maximum iBufLen characters will be copied.
NXDupdate replaces the definition for the alias specified as second parameter with the new value supplied as last parameter.
If a special dictionary vGroup as extension to NeXus would be accepted, two more functions need to be defined which read and write the dictionary from the NeXus file.
NXDputalias, NXDputdef write the data element specified by the alias or the definition string to the NeXus file specified as first parameter. pData is a pointer to the data to be written. These routines will check for the existence of all vGroups required in the path part of the definition string. If a vGroup is missing it will be created. These routines step back to the same vGroup level from which they were called.
NXDgetalias, NXDgetdef read a data item from file. pData MUST point to a data area large enough to hold the data read. If a vGroup is missing in the path for one of these routines an error is generated because it is assumed that the data is present if a program wants to read it. These routines step back to the same vGroup level from which they were called.
NXDaliaslink, NXDdeflink links the alias or definition given as fourth parameter to the vGroup specified by the third parameter. pAlias1 or pDef1 MUST refer to a vGroup because HDF can only link items into vGroups. The item being linked against MUST exist, otherwise the software will complain. The vGroup into which the link is installed will be created on the fly, if not present. Please note, that bot aliases or definition strings must refer to the same starting point in the vGroup hierarchy of the NeXus file. These routines step back to the same vGroup level from which they were called.
NXDopenalias, NXDopendef open the specified data items specified by the alias or the definition string. Then the usual NeXus functions can be used to interact with the data. These routines use the same scheme for creating vGroups on the fly as the put routines above. The status in the vGroup hierarchy after this call is dependent on the nature of the terminal symbol. If it is a SDS, the vGroup hierarchy will be stepped back to the level from which the call occurred. The SDS will be left open. If the terminal symbol is a vGroup, then the this vGroup will be made the current vGroup. No back stepping in the vGroup hierarchy occurs.
NXUentergroup tries to open the group specified by name and class. If it not present, it will be created and opened.
NXUenterdata tries to open the SDS specified by label. If it not present, it will be created and opened.
NXUallocSDS allocates enough space for the currently open SDS. The pointer created is returned in pData.
NXUfreeSDS returns memory allocated by NXUallocSDS to the system.
NXDLL may prove useful as a tool for discussing data structures for instruments or data analysis tools in its own right. It may seem useful to store a data dictionary, when available, in the NeXus file and to create a tool which extracts the dictionary from the NeXus file. Such a scheme would make the distribution of data dictionaries easier and would solve the problem of possibly existing different versions for data dictionaries.