Source code for nxtomomill.utils.nexus

from typing import Iterable

import h5py
import numpy
from silx.io.utils import h5py_read_dataset
from silx.io.utils import open as open_hdf5
from tomoscan.io import HDF5File

from nxtomo.nxobject.nxobject import NXobject


[docs]def cast_and_check_array_1D(array, array_name): if not isinstance(array, (type(None), numpy.ndarray, Iterable)): raise TypeError( f"{array_name} is expected to be None, or an Iterable. Not {type(array)}" ) if array is not None and not isinstance(array, numpy.ndarray): array = numpy.asarray(array) if array is not None and array.ndim > 1: raise ValueError(f"{array_name} is expected to be 0 or 1d not {array.ndim}") return array
[docs]def create_nx_data_group(file_path: str, entry_path: str, axis_scale: list): """ Create the 'Nxdata' group at entry level with soft links on the NXDetector and NXsample. :param file_path: :param entry_path: :param axis_scale: :return: """ if not isinstance(file_path, str): raise TypeError("file_path is expected to be a file") if not isinstance(entry_path, str): raise TypeError("entry_path is expected to be a file") if not isinstance(axis_scale, Iterable): raise TypeError("axis_scale is expected to be an Iterable") with HDF5File(file_path, mode="a") as h5f: entry_group = h5f[entry_path] nx_data_grp = entry_group.require_group("data") # link detector datasets: if not entry_path.startswith("/"): entry_path = "/" + entry_path for dataset in ("data", "image_key", "image_key_control"): dataset_path = "/".join((entry_path, "instrument", "detector", dataset)) nx_data_grp[dataset] = h5py.SoftLink(dataset_path) # link rotation angle nx_data_grp["rotation_angle"] = h5py.SoftLink( "/".join((entry_path, "sample", "rotation_angle")) ) # write NX attributes nx_data_grp.attrs["NX_class"] = "NXdata" nx_data_grp.attrs["signal"] = "data" nx_data_grp.attrs["SILX_style/axis_scale_types"] = axis_scale nx_data_grp["data"].attrs["interpretation"] = "image"
[docs]def get_data_and_unit(file_path, data_path, default_unit): with open_hdf5(file_path) as h5f: if data_path in h5f and isinstance(h5f[data_path], h5py.Dataset): dataset = h5f[data_path] unit = None if "unit" in dataset.attrs: unit = dataset.attrs["unit"] elif "units" in dataset.attrs: unit = dataset.attrs["units"] else: unit = default_unit if hasattr(unit, "decode"): # handle Diamond dataset unit = unit.decode() return h5py_read_dataset(dataset), unit else: return None, default_unit
[docs]def get_data(file_path, data_path): with open_hdf5(file_path) as h5f: if data_path in h5f: return h5py_read_dataset(h5f[data_path]) else: return None
[docs]def concatenate(nx_objects: Iterable, **kwargs): if len(nx_objects) == 0: return None else: if not isinstance(nx_objects[0], NXobject): raise TypeError("nx_objects are expected to be instances of NXobject") return type(nx_objects[0]).concatenate(nx_objects=nx_objects, **kwargs)