The NeXus API consists of routines to read and write NeXus data files. It was written to provide a simple to use and consistent common interface for all supported backends (XML, HDF4 and HDF5) to scientific programmers and other users of the NeXus Data Standard.
Note
It is not necessary to use the NAPI to write or read NeXus data files. The intent of the NAPI is to simplify the programming effort to use the HDF programming interface. There are Examples of writing and reading NeXus data files to help you understand.
This section will provide a brief overview of the available functionality. Further documentation of the NeXus Application Programming Interface (NAPI) for bindings to specific programming language can be found in the NAPI chapter and may be downloaded from the NeXus development site. [1]
For an even more detailed description of the internal workings of NAPI see NeXusIntern.pdf, copied from the NeXus code repository. That document is written for programmers who want to work on the NAPI itself. If you are new to NeXus and just want to implement basic file reading or writing you should not start by reading that.
The NeXus Application Program Interface (NAPI) provides a set of subroutines that make it easy to read and write NeXus files. These subroutines are available in C, Fortran 77, Fortran 90, Java, Python, C++, and IDL.
The API uses a very simple state model to navigate through a NeXus file. (Compare this example with NAPI Simple 2-D Write Example (C, F77, F90), in the NAPI chapter, using the native HDF5 commands.) When you open a file, the API provides a file handle, which stores the current location, i.e. which group and/or field is currently open. Read and write operations then act on the currently open entity. Following the simple example titled Example structure of a simple data file, we walk through a schematic of NeXus program written in C (without any error checking or real data).
Writing a simple NeXus file using NAPI
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | #include "napi.h"
int main()
{
NXhandle fileID;
NXopen ("NXfile.nxs", NXACC_CREATE, &fileID);
NXmakegroup (fileID, "Scan", "NXentry");
NXopengroup (fileID, "Scan", "NXentry");
NXmakegroup (fileID, "data", "NXdata");
NXopengroup (fileID, "data", "NXdata");
/* somehow, we already have arrays tth and counts, each length n*/
NXmakedata (fileID, "two_theta", NX_FLOAT32, 1, &n);
NXopendata (fileID, "two_theta");
NXputdata (fileID, tth);
NXputattr (fileID, "units", "degrees", 7, NX_CHAR);
NXclosedata (fileID); /* two_theta */
NXmakedata (fileID, "counts", NX_FLOAT32, 1, &n);
NXopendata (fileID, "counts");
NXputdata (fileID, counts);
NXclosedata (fileID); /* counts */
NXclosegroup (fileID); /* data */
NXclosegroup (fileID); /* Scan */
NXclose (&fileID);
return;
}
|
program analysis
Open the file NXfile.nxs with create access (implying write access). NAPI [2] returns a file identifier of type NXhandle.
The plottable data is contained within an NXdata group, which must also be created and opened.
To create a field, call NXmakedata(), specifying the data name, type (NX_FLOAT32), rank (in this case, 1), and length of the array (n). Then, it can be opened for writing. [4]
Write the data using NXputdata().
Then we close the field before opening another. In fact, the API will do this automatically if you attempt to open another field, but it is better style to close it yourself.
The remaining fields in this group are added in a similar fashion. Note that the indentation whenever a new field or group are opened is just intended to make the structure of the NeXus file more transparent.
Finally, close the groups (NXdata and NXentry) before closing the file itself.
Reading a NeXus file works in the same way by traversing the tree with the handle.
This schematic C code will read the two-theta array created in the example above. (Again, compare this example with Reading a simple NeXus file using native HDF5 commands in C.)
Reading a simple NeXus file using NAPI
1 2 3 4 5 6 7 8 9 10 11 | NXopen ('NXfile.nxs', NXACC_READ, &fileID);
NXopengroup (fileID, "Scan", "NXentry");
NXopengroup (fileID, "data", "NXdata");
NXopendata (fileID, "two_theta");
NXgetinfo (fileID, &rank, dims, &datatype);
NXmalloc ((void **) &tth, rank, dims, datatype);
NXgetdata (fileID, tth);
NXclosedata (fileID);
NXclosegroup (fileID);
NXclosegroup (fileID);
NXclose (fileID);
|
NeXus files can also be viewed by a command-line browser, nxbrowse, which is included as a helper tool in the NeXus API distribution. The following is an example session of nxbrowse nxbrowse to view a data file.
Using nxbrowse
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 | %> nxbrowse lrcs3701.nxs
NXBrowse 3.0.0. Copyright (C) 2000 R. Osborn, M. Koennecke, P. Klosowski
NeXus_version = 1.3.3
file_name = lrcs3701.nxs
file_time = 2001-02-11 00:02:35-0600
user = EAG/RO
NX> dir
NX Group : Histogram1 (NXentry)
NX Group : Histogram2 (NXentry)
NX> open Histogram1
NX/Histogram1> dir
NX Data : title[44] (NX_CHAR)
NX Data : analysis[7] (NX_CHAR)
NX Data : start_time[24] (NX_CHAR)
NX Data : end_time[24] (NX_CHAR)
NX Data : run_number (NX_INT32)
NX Group : sample (NXsample)
NX Group : LRMECS (NXinstrument)
NX Group : monitor1 (NXmonitor)
NX Group : monitor2 (NXmonitor)
NX Group : data (NXdata)
NX/Histogram1> read title
title[44] (NX_CHAR) = MgB2 PDOS 43.37g 8K 120meV E0@240Hz T0@120Hz
NX/Histogram1> open data
NX/Histogram1/data> dir
NX Data : title[44] (NX_CHAR)
NX Data : data[148,750] (NX_INT32)
NX Data : time_of_flight[751] (NX_FLOAT32)
NX Data : polar_angle[148] (NX_FLOAT32)
NX/Histogram1/data> read time_of_flight
time_of_flight[751] (NX_FLOAT32) = [ 1900.000000 1902.000000 1904.000000 ...]
units = microseconds
long_name = Time-of-Flight [microseconds]
NX/Histogram1/data> read data
data[148,750] (NX_INT32) = [ 1 1 0 ...]
units = counts
signal = 1
long_name = Neutron Counts
axes = polar_angle:time_of_flight
NX/Histogram1/data> close
NX/Histogram1> close
NX> quit
|
program analysis
Start nxbrowse from the UNIX command line and open file lrcs3701.nxs from IPNS/LRMECS.
List the contents of the current group.
Open the NeXus group Histogram1.
Print the contents of the NeXus data labeled title.
Close the current group.
Quits nxbrowse.
The source code of nxbrowse [8] provides an example of how to write a NeXus reader. The test programs included in the NeXus API may also be useful to study.
[1] | http://download.nexusformat.org |
[2] | NAPI: NeXus Application Programmer Interface (frozen) |
[3] | See the chapter Base Class Definitions for more information. |
[4] | The NeXus Data Types section describes the available data types, such as NX_FLOAT32 and NX_CHAR. |
[5] | NeXus Data Units |
[6] | The NeXus rule about data units is described in the NeXus Data Units section. |
[7] | see Data Types allowed in NXDL specifications |
[8] | https://svn.nexusformat.org/code/trunk/applications/NXbrowse/NXbrowse.c |