Package reflectometry :: Package reduction :: Module nexus

Module nexus

source code


High level interface to NeXus files.

Unlike the nxs routines which implement the NeXus API directly, the
nexus routines preload the entire file structure into memory and use
a natural syntax for navigating the data hierarchy.  Large datasets
are not read until they are needed, and may be read or written one
slab at a time.

There are a number of functions which operate on files::

  * tree = read(file)   loads a structure from a file
  * write(file, tree)   saves a structure to a file
  * dir(file)           display the contents of a file

The tree returned from read() has an entry for each group, field and
attribute.  You can traverse the hierarchy using the names of the
groups.  For example, tree.Histogram1.instrument.detector.distance
is a field containing the distance to each pixel in the detector.
NeXus attribute names are tagged with a leading 'A', so for example,
tree.Histogram1.instrument.detector.distance.Aunits contains the
units attribute for the detector distances.

Properties of the nodes in the tree are referenced by nx attributes.
Depending on the node type, different nx attributes may be available.

Nodes (class NXnode) have attributes shared by both groups and fields::
    * nxname     node name
    * nxclass    node class for groups, 'SDS' for fields
    * nxgroup    group containing the entry, or None for the root
    * nxattrs    dictionary of NeXus attributes for the node

Groups (class NXgroup) have attributes for accessing children::
    * nxentries  dictionary of entries within the group
    * nxcomponent('nxclass')  return group entries of a particular class
    * nxdir()    print the list of entries in the group
    * nxtree()   print the list of entries and subentries in the group
    * nxplot()   plot signal and axes for the group, if available

Fields (class SDS) have attributes for accessing data:
    * nxdims     dimensions of data in the field
    * nxtype     data type
    * nxdata     data in the field
    * nxdata_as('units')      data returned in particular units
    * nxslab     slab context for the field

Linked fields (class NXlink) have attributes for accessing the link::
    * nxlink     reference to the linked field

Unknown fields (class Unknown) are groups with a name that doesn't
start with 'NX'.  These groups are not read or written.

NeXus attributes (class NXattr) have a type and a value only::
    * nxtype     attribute type
    * nxdata     attribute data

Data can be stored in the NeXus file in a variety of units, depending
on which facility is storing the file.  This makes life difficult
for reduction and analysis programs which must know the units they
are working with.  Our solution to this problem is to allow you to
retrieve data from the file in particular units.  For example, if
detector distance is stored in the file using millimeters you can
retrieve them in meters using::
    entry.instrument.detector.distance.nxdata_as('m')
See help for nxsunit for more details on the unit formats supported.

The slab interface to field data works by opening the file handle
and keeping it open as long as the slab interface is needed.  This
is done in python 2.5 using the with statement.  Once the context
is entered, get() and put() methods on the node allow you to read
and write data a slab at a time.  For example::

    # Read a Ni x Nj x Nk array one vector at a time
    with node.nxslab:
        size = [1,1,node.nxdims[2]]
        for i in range(node.nxdims[0]):
            for j in range(node.nxdims[1]):
                value = node.nxslab.get([i,j,0],size) # Read counts

The equivalent can be done in Python 2.4 and lower using the context
functions __enter__ and __exit__::

    node.nxslab.__enter__()
    ... do the slab functions ...
    node.nxslab.__exit__()

You can traverse the tree by component class instead of component name.
Since there may be multiple components of the same class in one group
you will need to specify which one to use.  For example,
tree.NXentry[0].NXinstrument[0].NXdetector[0].distance references the
first detector of the first instrument of the first entry.  Unfortunately,
there is no guarantee regarding the order of the entries, and it may vary
from call to call, so the above is of limited utility.

The nxplot() method for groups uses matplotlib to plot the data.  You
can replace this with your own plotter by setting nexus.NXgroup._plotter
to your own plotter class.  The plotter class has one method::

    plot(signal, axes, entry, title)

where signal is the field containing the data, axes are the fields
listing the signal sample points, entry is file/path within the file
to the data group and title is the title of the NXentry, if available.

The read() and write() functions are implemented within a specialized
NeXus class which allows all the usual API functions.  You can subclass
this with your own definitions for NXgroup(), NXattr(), SDS() and NXlink()
if you want to change the nature of the tree.  The properties of these
classes are closely coupled to the behaviour of read/write so refer to
the source if you need to do this.

Functions
 
read(filename, mode='r')
Read a NeXus file, returning a tree of nodes
source code
 
write(filename, tree)
Write a NeXus file from a tree of nodes
source code
 
dir(file)
Read and summarize the named nexus file.
source code