spec2nexus.eznx#

(Easy NeXus) support library for reading & writing NeXus HDF5 files using h5py

How to use spec2nexus.eznx#

Here is a simple example to write a NeXus data file using eznx:

 1#!/usr/bin/env python
 2# -*- coding: utf-8 -*-
 3
 4"""
 5Writes a simple NeXus HDF5 file using h5py with links.
 6
 7This example is based on ``writer_2_1`` of the NeXus Manual:
 8https://download.nexusformat.org/doc/html/examples/h5py/index.html
 9"""
10
11from spec2nexus import eznx
12
13
14HDF5_FILE = "eznx_example.hdf5"
15
16I_v_TTH_DATA = """
1717.92608    1037
1817.92558    2857
1917.92508    23819
2017.92458    49087
2117.92408    66802
2217.92358    66206
2317.92308    64129
2417.92258    56795
2517.92208    29315
2617.92158    6622
2717.92108    1321
28"""
29# ---------------------------
30
31tthData, countsData = zip(
32    *[map(float, _.split()) for _ in I_v_TTH_DATA.strip().splitlines()]
33)
34
35f = eznx.makeFile(HDF5_FILE)  # create the HDF5 NeXus file
36f.attrs["default"] = "entry"
37
38nxentry = eznx.makeGroup(f, "entry", "NXentry", default="data")
39nxinstrument = eznx.makeGroup(nxentry, "instrument", "NXinstrument")
40nxdetector = eznx.makeGroup(nxinstrument, "detector", "NXdetector")
41
42tth = eznx.makeDataset(nxdetector, "two_theta", tthData, units="degrees")
43counts = eznx.makeDataset(nxdetector, "counts", countsData, units="counts")
44
45nxdata = eznx.makeGroup(
46    nxentry,
47    "data",
48    "NXdata",
49    signal=1,
50    axes="two_theta",
51    two_theta_indices=0,
52)
53eznx.makeLink(nxdetector, tth, nxdata.name + "/two_theta")
54eznx.makeLink(nxdetector, counts, nxdata.name + "/counts")
55
56f.close()  # be CERTAIN to close the file
57
58# -----------------------------------------------------------------------------
59# :author:    Pete R. Jemian
60# :email:     prjemian@gmail.com
61# :copyright: (c) 2014-2022, Pete R. Jemian
62#
63# Distributed under the terms of the Creative Commons Attribution 4.0 International Public License.
64#
65# The full license is in the file LICENSE.txt, distributed with this software.
66# -----------------------------------------------------------------------------

The output of this code is an HDF5 file (binary). It has this structure:

 1    eznx_example.hdf5:NeXus data file
 2      @default = entry
 3      entry:NXentry
 4        @NX_class = NXentry
 5        @default = data
 6        data:NXdata
 7          @NX_class = NXdata
 8          @signal = counts
 9          @axes = two_theta
10          @two_theta_indices = 0
11          counts --> /entry/instrument/detector/counts
12          two_theta --> /entry/instrument/detector/two_theta
13        instrument:NXinstrument
14          @NX_class = NXinstrument
15          detector:NXdetector
16            @NX_class = NXdetector
17            counts:NX_FLOAT64[11] = __array
18              @units = counts
19              @target = /entry/instrument/detector/counts
20              __array = [1037.0, 2857.0, 23819.0, '...', 1321.0]
21            two_theta:NX_FLOAT64[11] = __array
22              @units = degrees
23              @target = /entry/instrument/detector/two_theta
24              __array = [17.926079999999999, 17.92558, 17.925080000000001, '...', 17.92108]

NeXus HDF5 File Structure#

The output of this code is an HDF5 file (binary). It has this general structure (indentation shows HDF5 groups, @ signs describe attributes of the preceding item):

 1  hdf5_file:NeXus data file
 2     @default = S1
 3     S1:NXentry     (one NXentry for each scan)
 4        @default = data
 5        title = #S
 6        T or M: #T or #M
 7        comments: #C for entire scan
 8        date: #D
 9        scan_number: #S
10        G:NXcollection
11           @description = SPEC geometry arrays, meanings defined by SPEC diffractometer support
12           G0:NX_FLOAT64[] #G0
13           G1:NX_FLOAT64[] #G1
14           ...
15        data:NXdata
16           @description = SPEC scan data (content from #L and data lines)
17           @signal = I0
18           @axes = mr
19           @mr_indices = 0
20           Epoch:NX_FLOAT64[]
21           I0:NX_FLOAT64[]         (last data column)
22             @spec_name = I0
23           mr:NX_FLOAT64[]         (first data column)
24           ...
25        metadata:NXcollection
26           @description = SPEC metadata (UNICAT-style #H & #V lines)
27           ARenc_0:NX_FLOAT64 = 0.0
28           ...
29        positioners:NXcollection
30           @description = SPEC positioners (#P & #O lines)
31           mr:NX_FLOAT64
32           ...

APIs provided:


source code methods#

addAttributes

add attributes to an h5py data item

makeFile

create and open an empty NeXus HDF5 file using h5py

makeDataset

create and write data to a dataset in the HDF5 file hierarchy

makeExternalLink

create an external link from sourceFile, sourcePath to targetPath in hdf5FileObject

makeGroup

create a NeXus group

openGroup

open or create the NeXus HDF5 group, return the object

makeLink

create an internal NeXus (hard) link in an HDF5 file

read_nexus_field

get a dataset from the HDF5 parent group

read_nexus_group_fields

return the fields in the NeXus group as a dict(name=dataset)

write_dataset

write to the NeXus HDF5 dataset, create it if necessary, return the object

source code documentation#

(Easy NeXus) support reading & writing NeXus HDF5 files using h5py

predecessor

NeXus h5py example code: my_lib.py 1

1

https://download.nexusformat.org/doc/html/examples/h5py/index.html#mylib-support-module

Dependencies

  • h5py: interface to HDF5 file format

Exceptions raised

  • None

Example

root = eznx.makeFile('test.h5', creator='eznx', default='entry')
nxentry = eznx.makeGroup(root, 'entry', 'NXentry', default='data')
ds = eznx.write_dataset(nxentry, 'title', 'simple test data')
nxdata = eznx.makeGroup(nxentry, 'data', 'NXdata', signal='counts', axes='tth', tth_indices=0)
ds = eznx.write_dataset(nxdata, 'tth', [10.0, 10.1, 10.2, 10.3], units='degrees')
ds = eznx.write_dataset(nxdata, 'counts', [1, 50, 1000, 5], units='counts', axes="tth")
root.close()

The resulting (binary) data file has this structure:

test.h5:NeXus data file
  @creator = eznx
  @default = 'entry'
  entry:NXentry
    @NX_class = NXentry
    @default = 'data'
    title:NX_CHAR = simple test data
    data:NXdata
      @NX_class = NXdata
      @signal = 'counts'
      @axes = 'tth'
      @tth_indices = 0
      counts:NX_INT64[4] = [1, 50, 1000, 5]
        @units = counts
        @axes = tth
      tth:NX_FLOAT64[4] = [10.0, 10.1, 10.199999999999999, 10.300000000000001]
        @units = degrees

Classes and Methods

spec2nexus.eznx.addAttributes(parent, **attr)[source]#

add attributes to an h5py data item

Parameters
  • parent (obj) – h5py parent object

  • attr (dict) – optional dictionary of attributes

spec2nexus.eznx.makeDataset(parent, name, data=None, **attr)[source]#

create and write data to a dataset in the HDF5 file hierarchy

Any named parameters in the call to this method will be saved as attributes of the dataset.

Parameters
  • parent (obj) – parent group

  • name (str) – valid NeXus dataset name

  • data (obj) – the information to be written

  • attr (dict) – optional dictionary of attributes

Returns

h5py dataset object

create an external link from sourceFile, sourcePath to targetPath in hdf5FileObject

Parameters
  • hdf5FileObject (obj) – open HDF5 file object

  • sourceFile (str) – file containing existing HDF5 object at sourcePath

  • sourcePath (str) – path to existing HDF5 object in sourceFile

  • targetPath (str) – full node path to be created in current open HDF5 file, such as /entry/data/data

Note

Since the object retrieved is in a different file, its “.file” and “.parent” properties will refer to objects in that file, not the file in which the link resides.

See

https://www.h5py.org/docs-1.3/guide/group.html#external-links

This routine is provided as a reminder how to do this simple operation.

spec2nexus.eznx.makeFile(filename, **attr)[source]#

create and open an empty NeXus HDF5 file using h5py

Any named parameters in the call to this method will be saved as attributes of the root of the file. Note that **attr is a dictionary of named parameters.

Parameters
  • filename (str) – valid file name

  • attr (dict) – optional dictionary of attributes

Returns

h5py file object

spec2nexus.eznx.makeGroup(parent, name, nxclass, **attr)[source]#

create a NeXus group

Any named parameters in the call to this method will be saved as attributes of the group. Note that **attr is a dictionary of named parameters.

Parameters
  • parent (obj) – parent group

  • name (str) – valid NeXus group name

  • nxclass (str) – valid NeXus class name

  • attr (dict) – optional dictionary of attributes

Returns

h5py group object

create an internal NeXus (hard) link in an HDF5 file

Parameters
  • parent (obj) – parent group of source

  • sourceObject (obj) – existing HDF5 object

  • targetName (str) – HDF5 node path to be created, such as /entry/data/data

spec2nexus.eznx.openGroup(parent, name, nx_class, **attr)[source]#

open or create the NeXus HDF5 group, return the object

Parameters
  • parent (obj) – h5py parent object

  • name (str) – valid NeXus group name to open or create

  • nxclass (str) – valid NeXus class name (base class or application definition)

  • attr (dict) – optional dictionary of attributes

spec2nexus.eznx.read_nexus_field(parent, dataset_name, astype=None)[source]#

get a dataset from the HDF5 parent group

Parameters
  • parent (obj) – h5py parent object

  • dataset_name (str) – name of the dataset (NeXus field) to be read

  • astype (obj) – option to return as different data type

spec2nexus.eznx.read_nexus_group_fields(parent, name, fields)[source]#

return the fields in the NeXus group as a dict(name=dataset)

This routine provides a mass way to read a directed list of datasets (NeXus fields) in an HDF5 group.

Parameters
  • parent (obj) – h5py parent object

  • name (str) – name of the group containing the fields

  • fields ([name]) – list of field names to be read

Returns

dictionary of {name:dataset}

Raises

KeyError – if a field is not found

spec2nexus.eznx.write_dataset(parent, name, data, **attr)[source]#

write to the NeXus HDF5 dataset, create it if necessary, return the object

Parameters
  • parent (obj) – h5py parent object

  • name (str) – valid NeXus dataset name to write

  • data (obj) – the information to be written

  • attr (dict) – optional dictionary of attributes