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 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 | #!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
Writes a simple NeXus HDF5 file using h5py with links.
This example is based on ``writer_2_1`` of the NeXus Manual:
http://download.nexusformat.org/doc/html/examples/h5py/index.html
"""
from spec2nexus import eznx
HDF5_FILE = "eznx_example.hdf5"
I_v_TTH_DATA = """
17.92608 1037
17.92558 2857
17.92508 23819
17.92458 49087
17.92408 66802
17.92358 66206
17.92308 64129
17.92258 56795
17.92208 29315
17.92158 6622
17.92108 1321
"""
# ---------------------------
tthData, countsData = zip(
*[map(float, _.split()) for _ in I_v_TTH_DATA.strip().splitlines()]
)
f = eznx.makeFile(HDF5_FILE) # create the HDF5 NeXus file
f.attrs["default"] = "entry"
nxentry = eznx.makeGroup(f, "entry", "NXentry", default="data")
nxinstrument = eznx.makeGroup(nxentry, "instrument", "NXinstrument")
nxdetector = eznx.makeGroup(nxinstrument, "detector", "NXdetector")
tth = eznx.makeDataset(nxdetector, "two_theta", tthData, units="degrees")
counts = eznx.makeDataset(nxdetector, "counts", countsData, units="counts")
nxdata = eznx.makeGroup(
nxentry,
"data",
"NXdata",
signal=1,
axes="two_theta",
two_theta_indices=0,
)
eznx.makeLink(nxdetector, tth, nxdata.name + "/two_theta")
eznx.makeLink(nxdetector, counts, nxdata.name + "/counts")
f.close() # be CERTAIN to close the file
# -----------------------------------------------------------------------------
# :author: Pete R. Jemian
# :email: prjemian@gmail.com
# :copyright: (c) 2014-2022, Pete R. Jemian
#
# Distributed under the terms of the Creative Commons Attribution 4.0 International Public License.
#
# The full license is in the file LICENSE.txt, distributed with this software.
# -----------------------------------------------------------------------------
|
The output of this code is an HDF5 file (binary). It has this structure:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | eznx_example.hdf5:NeXus data file
@default = entry
entry:NXentry
@NX_class = NXentry
@default = data
data:NXdata
@NX_class = NXdata
@signal = counts
@axes = two_theta
@two_theta_indices = 0
counts --> /entry/instrument/detector/counts
two_theta --> /entry/instrument/detector/two_theta
instrument:NXinstrument
@NX_class = NXinstrument
detector:NXdetector
@NX_class = NXdetector
counts:NX_FLOAT64[11] = __array
@units = counts
@target = /entry/instrument/detector/counts
__array = [1037.0, 2857.0, 23819.0, '...', 1321.0]
two_theta:NX_FLOAT64[11] = __array
@units = degrees
@target = /entry/instrument/detector/two_theta
__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 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 | hdf5_file:NeXus data file
@default = S1
S1:NXentry (one NXentry for each scan)
@default = data
title = #S
T or M: #T or #M
comments: #C for entire scan
date: #D
scan_number: #S
G:NXcollection
@description = SPEC geometry arrays, meanings defined by SPEC diffractometer support
G0:NX_FLOAT64[] #G0
G1:NX_FLOAT64[] #G1
...
data:NXdata
@description = SPEC scan data (content from #L and data lines)
@signal = I0
@axes = mr
@mr_indices = 0
Epoch:NX_FLOAT64[]
I0:NX_FLOAT64[] (last data column)
@spec_name = I0
mr:NX_FLOAT64[] (first data column)
...
metadata:NXcollection
@description = SPEC metadata (UNICAT-style #H & #V lines)
ARenc_0:NX_FLOAT64 = 0.0
...
positioners:NXcollection
@description = SPEC positioners (#P & #O lines)
mr:NX_FLOAT64
...
|
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] | http://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
-
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.
See: http://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
-
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