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-2025, 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, 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#
add attributes to an h5py data item |
|
create and open an empty NeXus HDF5 file using h5py |
|
create and write data to a dataset in the HDF5 file hierarchy |
|
create an external link from sourceFile, sourcePath to targetPath in hdf5FileObject |
|
create a NeXus group |
|
open or create the NeXus HDF5 group, return the object |
|
create an internal NeXus (hard) link in an HDF5 file |
|
get a dataset from the HDF5 parent group |
|
return the fields in the NeXus group as a dict(name=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]
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
- spec2nexus.eznx.makeExternalLink(hdf5FileObject, sourceFile, sourcePath, targetPath)[source]#
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.
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
- spec2nexus.eznx.makeLink(parent, sourceObject, targetName)[source]#
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