Working with groups

Groups are the fundamental containers in Nexus. They can hold other groups as well as fields.

Creation

To create a new group use the :py:meht There are several ways how to create groups and fields. The most natural one is to use the create_group() method of a group instance. The former one is rather easy to use

from __future__ import print_function
import pni.io.nx.h5 as nexus

f = nexus.create_file("groups_test.nxs",overwrite=True)
root_group = f.root()

e1 = root_group.create_group("entry_1")
e2 = root_group.create_group("entry_2","NXentry")
e3 = root_group.create_group("entry_3:NXentry")
e4 = root_group.create_group("entry_4",nxclass="NXentry")

The first call creates a group of name entry_1 while the second one create a group of name entry_2 of type NXentry. The type of a group is determined by an attribute name NX_class attached to the group (we will learn more about attributes latter). The calls three and four are synonymous to the second call, just the group type is represented in a different way.

The create_group() method can only create groups which are direct children of the their parent group. So using

g = root_group.create_group("entry/instrument/detector")

will fail if entry and/or instrument do not exist. It may sounds strange that one cannot create intermediate groups automatically, a feature the HDF5 library and the h5py wrapper support. However, we cannot use this feature as it creates groups only by name and does not add type information. However, if the intermediate groups exist the above call will succeed

root_group.create_group("entry:NXentry").\
           create_group("instrument:NXinstrument")

root_group.create_group("detector","NXdetector")

Inquery

In order to determine the number of (direct) children of a group we can either use the size attribute of an instance of nxgroup or use the build-in function len() with an instance of nxgroup as its argument.

g = ....
g.size == len(g)

nxgroup exposes some more read-only attributes to obtain more information about a particular instance

Attribute name Description
is_valid True if the group is a valid object
name returns the name of the group
parent returns the groups parent group
size the number of children a group has
filename name of the file the group belongs to
attributes property providing access to the groups’ attributes
path provides the path for the group

Accessing a groups children

The direct children of a group can be accessed by its [] operator where the key can be either the index of the child

for index in range(len(root_group)):
    print(root_group[index].name)

or the name of the child

for name in root_group.names():
    print(root_group[name].name)

The return value of the [] operator is either an instance of nxfield, nxgroup, or nxlink. The latter is returned in situations where a child is a link which cannot be resolved. Thus it is possible to investigate the target of the link and its current status.

for name in root_group.names():
    child = root_group[name]

    if isinstance(child,nexus.nxlink):
        print("link ",child.name," cannot be resolved")

Iteration

As containers, instances of nxgroup expose two different iterator interfaces

  • a simple one directly provided by nxgroup which iterates only over the direct children of a group
  • and a recursive iterator provided by the nxgroup.recursive of an instance of nxgroup.

The latter one iterates over all children of a group and the children of its subgroups. Simple iteration can be done with

for child in group: print(child.path)

while the recursive iterator can be accessed via the recursive attribute of an instance of nxgroup

for child in group.recursive: print(child.path)

Recursive iteration is a quite usefull feature along with list comprehension to generate lists of particular object types. A typical application for recursive iteration would be to find all the fields that have been involved in a measurement. We assume here that for all fields the first dimension indicates the number of scan points. We thus can simply use the following list comprehension

from __future__ import print_function
import pni.io.nx.h5 as nx

f = nx.open_file("test.nxs")

def scanned_field(obj):
    return is_instance(obj,nx.nxfield) and obj.shape[0]>1

scanned_fields = [ obj for obj in f.root().recursive if scanned_field(obj)]

for field in scanned_fields:
    print field.path

Table Of Contents

Previous topic

Working with Nexus files

Next topic

Working with fields

This Page