Getting started

Write a NeXus HDF5 File

In the main code section of simple_example_basic_write.py, the data (mr is similar to “two_theta” and I00 is similar to “counts”) is collated into two Python lists. We use the numpy package to read the file and parse the two-column format.

The new HDF5 file is opened (and created if not already existing) for writing, setting common NeXus attributes in the same command from our support library. Proper HDF5+NeXus groups are created for /entry:NXentry/mr_scan:NXdata. Since we are not using the NAPI, our support library must create and set the NX_class attribute on each group.

Note

We want to create the desired structure of /entry:NXentry/mr_scan:NXdata/.

Examine the example code below for these key actions to create the structure:

action

nexusformat function

h5py function

create file & root (/) structure

with nxopen(fileName, "w") as f:

with h5py.File(fileName, "w") as f:

create /entry group

f["entry"] = NXentry()

nxentry = f.create_group("entry"); nxentry.attrs["NX_class"] = "NXentry"

create /entry/mr_scan group

f["entry/mr_scan"] = NXdata(y, x)

nxdata = nxentry.create_group("mr_scan"); nxdata.attrs["NX_class"] = "NXdata"

store mr data

x = NXfield(mr_arr, units="degrees", ...)

x = nxdata.create_dataset("mr", data=mr_arr); x.attrs["units"] = "degrees"

store I00 data

y = NXfield(i00_arr, units="counts", ...)

y = nxdata.create_dataset("I00", data=i00_arr); y.attrs["units"] = "counts"

add title

f["entry/title"] = ...

nxentry.create_dataset("title", ...)

The title string is added to label the default plot.

The data type of mr and I00, as represented in numpy, will be recognized by h5py and automatically converted to the proper HDF5 type in the file. Engineering units and other metadata needed by NeXus to provide a default plot of this data are provided. The NeXus signal="I00" attribute on the NXdata group identifies I00 as the default y axis for the plot. The axes="mr" attribute on the NXdata group connects the dataset to be used as the x axis.

Since we opened the file with a Python context manager (with .. as f:), it is not necessary to make an explicit call to close the file. The context manager will close the file with the context.

simple_example_basic_write.py: Write a NeXus HDF5 file using Python with h5py

In the nexusformat version, these attributes are added automatically when calling NXdata(y, x) with the first argument defining the signal and the second the axes. With signals of higher rank, the second argument would be a list of axes.

 1#!/usr/bin/env python
 2"""Writes a NeXus HDF5 file using h5py and numpy"""
 3
 4from pathlib import Path
 5
 6import numpy
 7from nexusformat.nexus import NXdata
 8from nexusformat.nexus import NXentry
 9from nexusformat.nexus import NXfield
10from nexusformat.nexus import nxopen
11
12print("Write a NeXus HDF5 file")
13fileName = "simple_example_basic.nexus.hdf5"
14
15# load data from two column format
16data_filename = str(Path(__file__).absolute().parent.parent / "simple_example.dat")
17data = numpy.loadtxt(data_filename).T
18mr_arr = data[0]
19i00_arr = numpy.asarray(data[1], "int32")
20
21# create the HDF5 NeXus file
22with nxopen(fileName, "w") as f:
23
24    # create the NXentry group
25    f["entry"] = NXentry()
26    f["entry/title"] = "1-D scan of I00 v. mr"
27
28    # create the NXdata group
29    x = NXfield(mr_arr, name="mr", units="degrees", long_name="USAXS mr (degrees)")
30    y = NXfield(i00_arr, name="I00", units="counts", long_name="USAXS I00 (counts)")
31    f["entry/mr_scan"] = NXdata(y, x)
32
33print("wrote file:", fileName)

Read a NeXus HDF5 File

The file reader, simple_example_basic_read.py, opens the HDF5 we wrote above, prints the HDF5 attributes from the file, reads the two datasets, and then prints them out as columns. As simple as that. Of course, real code might add some error-handling and extracting other useful stuff from the file.

Note

See that we identified each of the two datasets using HDF5 absolute path references (just using the group and dataset names). Also, while coding this example, we were reminded that HDF5 is sensitive to upper or lowercase. That is, I00 is not the same is i00.

simple_example_basic_read.py: Read a NeXus HDF5 file using Python

The nexusformat version prints the whole file as a tree.

1#!/usr/bin/env python
2"""Reads NeXus HDF5 files using nexusformat and prints the contents"""
3
4from nexusformat.nexus import nxopen
5
6fileName = "simple_example_basic.nexus.hdf5"
7with nxopen(fileName) as f:
8    print(f.tree)

Output from simple_example_basic_read.py is shown next.

Output from simple_example_basic_read.py

The nexusformat version prints the whole file as a tree.

 1root:NXroot
 2  @HDF5_Version = '1.12.1'
 3  @NeXus_version = '4.3.0'
 4  @creator = 'simple_example_basic_write.py'
 5  @default = 'entry'
 6  @file_name = 'simple_example_basic.nexus.hdf5'
 7  @file_time = '2022-06-15T14:31:39.410075+02:00'
 8  @h5py_version = '3.6.0'
 9  @instrument = 'APS USAXS at 32ID-B'
10  entry:NXentry
11    @default = 'mr_scan'
12    mr_scan:NXdata
13      @axes = 'mr'
14      @mr_indices = 0
15      @signal = 'I00'
16      I00 = int32(31)
17        @long_name = 'USAXS I00 (counts)'
18        @units = 'counts'
19      mr = float64(31)
20        @long_name = 'USAXS mr (degrees)'
21        @units = 'degrees'
22    title = '1-D scan of I00 v. mr'

downloads

The Python code and files related to this section may be downloaded from the following table.

file

description

../simple_example.dat

2-column ASCII data used in this section

simple_example_basic_read.py

h5py code to read example simple_example_basic.nexus.hdf5

nexusformat/simple_example_basic_read.py

nexusformat code to read example simple_example_basic.nexus.hdf5

simple_example_basic_write.py

h5py code to write example simple_example_basic.nexus.hdf5

nexusformat/simple_example_basic_write.py

nexusformat code to write example simple_example_basic.nexus.hdf5

simple_example_basic.nexus_h5dump.txt

h5dump analysis of the NeXus file

simple_example_basic.nexus.hdf5

NeXus file written by BasicWriter

simple_example_basic.nexus_structure.txt

punx tree analysis of the NeXus file