[Previous Page | Next Page | NeXus Home Page | NeXus Site Map]

The NeXus Application Program Interface

An Application Program Interface (API) has been developed to facilitate the reading and writing of NeXus files. Those writing utilities to produce NeXus files are encouraged to use the API, rather than lower-level HDF routines, in order to ensure compliance with the NeXus standard. The latest version supports the reading and writing of both HDF4 and HDF5 files. The routines have been written in C although we also provide Fortran 77 and 90 wrappers. The API was defined in the SoftNeSS'96 workshop.



[Previous Page | Next Page | NeXus Home Page | NeXus Site Map]

Purpose of API

The NeXus Application Program Interface is a suite of subroutines, written in C but with wrappers in Fortran 77 and 90. The subroutines call HDF routines to read and write the NeXus files with the correct structure. An API serves a number of useful purposes:

  1. It simplifies the reading and writing of NeXus files.
  2. It ensures a certain degree of compliance with the NeXus standard.
  3. It allows the development of sophisticated input/output features such as automatic unit conversion. This has not been implemented yet.
  4. It hides the implementation details of the format. In particular, the API can read and write both HDF4 and HDF5 files using the same routines.

For these reasons, we request that all NeXus files are written using the supplied API. We cannot be sure that anything written using the underlying HDF API will be recognized by NeXus-aware utilities.


[Previous Page | Next Page | NeXus Home Page | NeXus Site Map]

Description of Core API

The core API provides the basic routines for reading, writing and navigating NeXus files. It is designed to be modal; there is a hidden state that determines which groups and data sets are open at any given moment, and subsequent operations are implicitly performed on these entities. This cuts down the number of parameters to pass around in API calls, at the cost of forcing a certain pre-approved mode d'emploi. This mode d'emploi will be familiar to most: it is very similar to navigating a directory hierarchy; in our case, NeXus groups are the directories, which contain data sets and/or other directories.

The core API comprises the following functional groups:

  1. General initialization and shutdown: opening and closing the file, creating or opening an existing group or dataset, and closing them.
  2. Reading and writing data and attributes to previously opened datasets.
  3. Routines to obtain meta-data and to iterate over component datasets and attributes.
  4. Handling of linking and group hierarchy.

List of NeXus Core API Routines
General Initialization and Shutdown
NXopenOpens NeXus file and returns file id
NXcloseCloses NeXus file
NXmakegroupCreates NeXus group
NXopengroupOpens existing NeXus group for input/output
NXclosegroupCloses NeXus group
NXmakedataCreates NeXus data set
NXcompmakedataCreates a compressed NeXus data set
NXopendataOpens existing NeXus data set for input/output
NXcompressMarks the NeXus data set for compression
NXclosedataCloses NeXus data set
Reading and Writing
NXgetdataReads data from currently open data set
NXgetslabReads a subset of the currently open data set
NXgetattrReads sdata attribute from open data set
NXputdataWrites data into the currently open data set
NXputslabWrites a subset of data into the currently open data set
NXputattrWrites an attribute of the currently open data set
NXflushFlushes output to a data file
Meta-Data Routines
NXgetinfoGets rank, dimensions and type of currently open data set
NXgetgroupinfoReturns the number of items, and the name and class of the current group
NXinitgroupdirInitializes a group's directory search
NXgetnextentryImplements a directory search of the currently open group
NXgetattrinfoReturns the number of attributes of the current data set
NXinitattrdirInitializes a data set's attribute search
NXgetnextattrImplements a search of all the attributes of the currently open data set
Linking and Group Hierarchy
NXgetgroupIDReturns the identifier of the currently open group as an NXlink structure
NXgetdataIDReturns the identifier of the currently open data set
NXmakelinkLinks a data item (group or set) to another group

Although the NeXus API is considerably simpler than the underlying HDF code, writing NeXus files still involves much repetitive code. Mark Koennecke has therefore proposed a Data Dictionary Language to reduce the amount of programming.


[Previous Page | Next Page | NeXus Home Page | NeXus Site Map]

Fortran 77 Interface

Wrapper routines to interface the Fortran and C code have been developed by Freddie Akeroyd. The routines have the same names and argument lists as the corresponding C routines, although we have added extra routines for the input/output of character data and attributes. Care must be taken to ensure enough space is allocated for the input/output operations being performed.

It is necessary to reverse the order of indices in multidimensional arrays, compared to an equivalent C program, so that data are stored in the same order in the NeXus file.

Any program using the F77 API needs to include the following line near the top in order to define the required constants (NXHANDLESIZE, NXLINKSIZE, etc.) :


      include 'NAPIF.INC'


List of NeXus Core API F77 Routines
General Initialization and Shutdown
NXopenOpens NeXus file and returns file id
NXcloseCloses NeXus file
NXmakegroupCreates NeXus group
NXopengroupOpens existing NeXus group for input/output
NXclosegroupCloses NeXus group
NXmakedataCreates NeXus data set
NXcompmakedataCreates a compressed NeXus data set
NXopendataOpens existing NeXus data set for input/output
NXcompressMarks the NeXus data set for compression
NXclosedataCloses NeXus data set
Reading and Writing
NXgetdataReads numeric data from currently open data set
NXgetchardataReads character data from currently open data set
NXgetslabReads a subset of the currently open data set
NXgetattrReads a numeric attribute from the open data set
NXgetcharattrReads a character attribute from the open data set
NXputdataWrites numeric data into the currently open data set
NXputchardataWrites character data into the currently open data set
NXputslabWrites a subset of data into the currently open data set
NXputattrWrites a numeric attribute of the currently open data set
NXputcharattrWrites a character attribute of the currently open data set
NXflushFlushes output to a data file
Meta-Data Routines
NXgetinfoGets rank, dimensions and type of currently open data set
NXgetgroupinfoReturns the number of items, and the name and class of the current group
NXinitgroupdirInitializes a group's directory search
NXgetnextentryImplements a directory search of the currently open group
NXgetattrinfoReturns the number of attributes of the current data set
NXinitattrdirInitializes a data set's attribute search
NXgetnextattrImplements a search of all the attributes of the currently open data set
Linking and Group Hierarchy
NXgetgroupIDReturns the identifier of the currently open group as an NXlink structure
NXgetdataIDReturns the identifier of the currently open data set
NXmakelinkLinks a data item (group or set) to another group

Here is a comparison of the types used in the C and F77 interface.

CFortran
int a, int* aINTEGER A
char* aCHARACTER*(*) A
NXhandle a, NXhandle* aINTEGER A(NXHANDLESIZE)
NXstatusINTEGER
int[] aINTEGER A(*)
void* aREAL A(*) or DOUBLE A(*) or INTEGER A(*)
NXlink a, NXlink* aINTEGER A(NXLINKSIZE)

[Previous Page | Next Page | NeXus Home Page | NeXus Site Map]

Fortran 90 Interface

The Fortran 90 interface is a wrapper to the C interface with nearly identical routine definitions. As with the Fortran 77 interface, it is necessary to reverse the order of indices in multidimensional arrays, compared to an equivalent C program, so that data are stored in the same order in the NeXus file.

Furthermore, we have developed a set of utility functions which are designed to make the reading and writing of NeXus data files even easier to code. When the manpower is available, equivalent functions will be ported back to C.

Any program using the F90 API needs to put the following line at the top (after the PROGRAM statement) :


   use NXmodule


List of NeXus Core API F90 Routines
General Initialization and Shutdown
NXopenOpens NeXus file and returns file id
NXcloseCloses NeXus file
NXmakegroupCreates NeXus group
NXopengroupOpens existing NeXus group for input/output
NXclosegroupCloses NeXus group
NXmakedataCreates NeXus data set
NXopendataOpens existing NeXus data set for input/output
NXcompressMarks the NeXus data set for compression
NXclosedataCloses NeXus data set
Reading and Writing
NXgetdataReads data from currently open data set
NXgetslabReads a subset of the currently open data set
NXgetattrReads sdata attribute from open data set
NXputdataWrites data into the currently open data set
NXputslabWrites a subset of data into the currently open data set
NXputattrWrites an attribute of the currently open data set
NXflushFlushes output to a data file
Meta-Data Routines
NXgetinfoGets rank, dimensions and type of currently open data set
NXgetgroupinfoReturns the number of items, and the name and class of the current group
NXinitgroupdirInitializes directory searches of the current group
NXgroupdirReturns a list of items in the current group
NXgetnextentryImplements a directory search of the currently open group
NXgetattrinfoReturns the number of attributes of the current data set
NXinitattrdirInitializes attribute searches of the current data set
NXattrdirReturns a list of attributes of the current data set
NXgetnextattrImplements a search of all the attributes of the currently open data set
Linking and Group Hierarchy
NXgetgroupIDReturns the identifier of the currently open group as an NXlink structure
NXgetdataIDReturns the identifier of the currently open data set
NXmakelinkLinks a data item (group or set) to another group

The current version has been tested with Digital Fortran 90 on Alpha/VMS, Digital Visual Fortran on Windows NT and Absoft Pro Fortran on Linux. Please check the README.FORTRAN90 file for a discussion of compatibility issues and send details of any problems you encounter to <ROsborn@anl.gov>.

As an example of using the F90 API, NXdump.f90 prints a list of all the groups and data items stored in a NeXus file. A more powerful NeXus browser is described in the next section.


[Previous Page | Next Page | NeXus Home Page | NeXus Site Map]

Fortran 90 Utility API

The NeXus F90 Utility API provides a number of routines that combine the operations of various core API routines in order to simplify the reading and writing of NeXus files. At present, they are only available (in alpha version) as a Fortran 90 module.

The utility API comprises the following functional groups:

  1. Routines to read or write data.
  2. Routines to find if groups, data, or attributes exist, and to find data with specific signal or axis attributes i.e. to identify valid data or axes.
  3. Routines to open other groups to which NXdata items are linked, and to return again.

Any program using the F90 Utility API needs to put the following line near the top of the program (N.B. do not put USE statements for both NXmodule and NXUmodule; the former is included in the latter) :


   use NXUmodule


List of NeXus Utility API Routines
Reading and Writing
NXUwriteglobalsWrites all the valid global attributes of a file.
NXUwritegroupOpens a group (creating it if necessary).
NXUwritedataOpens a data item (creating it if necessary) and writes data and its units.
NXUreaddataOpens and reads a data item and its units.
NXUwritehistogramOpens one dimensional data item (creating it if necessary) and writes histogram centers and their units.
NXUreadhistogramOpens and reads a one dimensional data item and converts it to histogram bin boundaries.
NXUsetcompressDefines the compression algorithm and minimum dataset size for subsequent write operations.
Finding Groups, Data, and Attributes
NXUfindgroupChecks whether a group of the specified name is contained within the currently open group.
NXUfindclassReturns the name of a group of the specified class if it is contained within the currently open group.
NXUfinddataChecks whether a data item of the specified name is contained within the currently open group.
NXUfindattrChecks whether the currently open data item has the specified attribute.
NXUfindsignalSearches the currently open group for a data item with the specified SIGNAL attribute.
NXUfindaxisSearches the currently open group for a data item with the specified AXIS attribute.
Finding Linked Groups
NXUfindlinkFinds another link to the specified NeXus data item and opens the group it is in.
NXUresumelinkReopens the original group from which NXUfindlink was used.

Currently, the F90 utility API will only write character strings, 4-byte integers and reals, and 8-byte reals. It can read other integer sizes into four-byte integers, but does not differentiate between signed and unsigned integers.

Here are two example programs which make heavy use of the Utility API.


[Previous Page | Next Page | NeXus Home Page | NeXus Site Map]

Example NeXus program

The following code reads a two-dimensional set 'counts' with dimension scales of 't' and 'phi' using local routines, and then writes a NeXus file containing a single NXentry group and a single NXdata group. This is the simplest data file that conforms to the NeXus standard.

C Version


#include "napi.h"

int main()
{
    int counts[50][1000], n_t, n_p, dims[2], i;
    float t[1000], phi[50];
    NXhandle file_id;
/* Read in data using local routines */
    getdata (n_t, t, n_p, phi, counts);
/* Open output file and output global attributes */
    NXopen ('NXfile.nxs', NXACC_CREATE, &file_id);
      NXputattr (file_id, "user_name", "Joe Bloggs", 10, NX_CHAR);
/* Open top-level NXentry group */
      NXmakegroup (file_id, "Entry1", "NXentry");
      NXopengroup (file_id, "Entry1", "NXentry");
/* Open NXdata group within NXentry group */
        NXmakegroup (file_id, "Data1", "NXdata");
        NXopengroup (file_id, "Data1", "NXdata");
/* Output time channels */
          NXmakedata (file_id, "time_of_flight", NX_FLOAT32, 1, &n_t);
          NXopendata (file_id, "time_of_flight")
            NXputdata (file_id, t);
            NXputattr (file_id, "units", "microseconds", 12, NX_CHAR);
            i = 1;
            NXputattr (file_id, "axis", &i, 1, NX_INT32);
          NXclosedata (file_id);
/* Output detector angles */
          NXmakedata (file_id, "phi", NX_FLOAT32, 1, &n_p);
          NXopendata (file_id, "phi")
            NXputdata (file_id, phi);
            NXputattr (file_id, "units", "degrees", 7, NX_CHAR);
            i = 2;
            NXputattr (file_id, "axis", &i, 1, NX_INT32);
          NXclosedata (file_id);
/* Output data */
          dims[0] = n_t;
          dims[1] = n_p;
          NXmakedata (file_id, "counts", NX_INT32, 2, dims);
          NXopendata (file_id, "counts")
            NXputdata (file_id, counts);
            i = 1;
            NXputattr (file_id, "signal", &i, 1, NX_INT32);
          NXclosedata (file_id);
/* Close NXentry and NXdata groups and close file */
        NXclosegroup (file_id);
      NXclosegroup (file_id);
    NXclose (&file_id);
    return;
}

Fortran 77 Version


      program WRITEDATA
      
      include 'NAPIF.INC'
      integer*4 status, file_id(NXHANDLESIZE), counts(1000,50), n_p, n_t, dims(2)
      real*4 t(1000), phi(50)

!Read in data using local routines
      call getdata (n_t, t, n_p, phi, counts)
!Open output file
      status = NXopen ('NXFILE.NXS', NXACC_CREATE, file_id)
        status = NXputcharattr 
     +         (file_id, 'user', 'Joe Bloggs', 10, NX_CHAR)
!Open top-level NXentry group
        status = NXmakegroup (file_id, 'Entry1', 'NXentry')
        status = NXopengroup (file_id, 'Entry1', 'NXentry')
!Open NXdata group within NXentry group
          status = NXmakegroup (file_id, 'Data1', 'NXdata')
          status = NXopengroup (file_id, 'Data1', 'NXdata')
!Output time channels
            status = NXmakedata 
     +         (file_id, 'time_of_flight', NX_FLOAT32, 1, n_t)
            status = NXopendata (file_id, 'time_of_flight')
              status = NXputdata (file_id, t)
              status = NXputcharattr 
     +         (file_id, 'units', 'microseconds', 12, NX_CHAR)
              status = NXputattr (file_id, 'axis', 1, 1, NX_INT32)
            status = NXclosedata (file_id)
!Output detector angles
            status = NXmakedata (file_id, 'phi', NX_FLOAT32, 1, n_p)
            status = NXopendata (file_id, 'phi')
              status = NXputdata (file_id, phi)
              status = NXputcharattr (file_id, 'units', 'degrees', 7, NX_CHAR)
              status = NXputattr (file_id, 'axis', 2, 1, NX_INT32)
            status = NXclosedata (file_id)
!Output data
            dims(1) = n_t
            dims(2) = n_p
            status = NXmakedata (file_id, 'counts', NX_INT32, 2, dims)
            status = NXopendata (file_id, 'counts')
              status = NXputdata (file_id, counts)
              status = NXputattr (file_id, 'signal', 1, 1, NX_INT32)
            status = NXclosedata (file_id)
!Close NXdata and NXentry groups and close file
          status = NXclosegroup (file_id)
        status = NXclosegroup (file_id)
      status = NXclose (file_id)

      stop
      end

Fortran 90 Version


program WRITEDATA
      
   use NXUmodule

   type(NXhandle) :: file_id
   integer, pointer :: counts(:,:)
   real, pointer :: t(:), phi(:)

!Use local routines to allocate pointers and fill in data
   call getlocaldata (t, phi, counts)
!Open output file
   if (NXopen ("NXfile.nxs", NXACC_CREATE, file_id) /= NX_OK) stop
   if (NXUwriteglobals (file_id, user="Joe Bloggs") /= NX_OK) stop
!Set compression parameters
   if (NXUsetcompress (file_id, NX_COMP_LZW, 1000) /= NX_OK) stop
!Open top-level NXentry group
   if (NXUwritegroup (file_id, "Entry1", "NXentry") /= NX_OK) stop
   !Open NXdata group within NXentry group
      if (NXUwritegroup (file_id, "Data1", "NXdata") /= NX_OK) stop
   !Output time channels
         if (NXUwritedata (file_id, "time_of_flight", t, "microseconds") /= NX_OK) stop
            if (NXputattr (file_id, "axis", 1) /= NX_OK) stop
   !Output detector angles
         if (NXUwritedata (file_id, "phi", phi, "degrees") /= NX_OK) stop
            if (NXputattr (file_id, "axis", 2) /= NX_OK) stop
   !Output data
         if (NXUwritedata (file_id, "counts", counts, "counts") /= NX_OK) stop
            if (NXputattr (file_id, "signal", 1) /= NX_OK) stop
   !Close NXdata group
      if (NXclosegroup (file_id) /= NX_OK) stop
!Close NXentry group
   if (NXclosegroup (file_id) /= NX_OK) stop
!Close NeXus file
   if (NXclose (file_id) /= NX_OK) stop

end program WRITEDATA

[Previous Page | Next Page | NeXus Home Page | NeXus Site Map]

Java Interface

NeXus for Java provides access to NeXus data files for programs written in Java. This API was implemented by Java code calling the original C language NeXus API through the Java Native Methods Interface.


[Previous Page | Next Page | NeXus Home Page | NeXus Site Map]

IDL Interface

IDL is an interactive data evaluation environment developed by Research Systems. It is an interpreted language for data manipulation and visualization. Part of IDL is an HDF-interface. In order to facilitate the import of NeXus files into this popular data manipulation package, the NeXus-API was reimplemented in the IDL language by Mark Koennecke. The package may be downloaded as a tar file from <ftp://ftp.neutron.anl.gov/nexus/nidl.tar>.


[Previous Page | Next Page | NeXus Home Page | NeXus Site Map]

Downloading the API

Since NeXus uses HDF as the underlying binary format, it is necessary first to install the HDF subroutine libraries and include files before installing the NeXus API. It is not usually necessary to download the HDF source code since precompiled object libraries exist for a variety of operating systems including VMS, Macintosh, Windows and various flavors of Unix. Check the following URL for more information:

The current version of the NeXus API is 2.0.0, which is the first version to read and write both HDF4 and HDF5 files, provided both sets of libraries are installed. It was written by Mark Koennecke, Przemek Klosowski, Freddie Akeroyd and Ray Osborn, and is available for downloading under the terms of the GNU Lesser General Public License.


[Previous Page | Next Page | NeXus Home Page | NeXus Site Map]

Comments to: Ray Osborn <ROsborn@anl.gov>
Revised: Saturday, September 14, 2002

Copyright © 1996-2002 NeXus Design Team. All rights reserved.