Source code for ewoksxrpd.tasks.utils.nexus_utils

from __future__ import annotations

from dataclasses import dataclass
from typing import Generator
from typing import Union

import h5py
import numpy
from silx.io.nxdata import NXdata


[docs] @dataclass class IntegratedPattern: """Store one pyFAI integrated pattern""" point: Union[float, int, None] radial: numpy.ndarray radial_name: str radial_units: str intensity: numpy.ndarray intensity_errors: Union[numpy.ndarray, None]
[docs] def read_nexus_integrated_patterns(group: h5py.Group) -> Generator[IntegratedPattern]: """Read integrated patterns from a HDF5 NXdata group. It reads from both single (1D signal) or multi (2D signal) NXdata. """ nxdata = NXdata(group) if not nxdata.is_valid: raise RuntimeError( f"Cannot parse NXdata group: {group.file.filename}::{group.name}" ) if not (nxdata.signal_is_1d or nxdata.signal_is_2d): raise RuntimeError( f"Signal is not a 1D or 2D dataset: {group.file.filename}::{group.name}" ) if nxdata.signal_is_1d: points = [None] else: # 2d if nxdata.axes[0] is None: points = [None] * nxdata.signal.shape[0] else: points = nxdata.axes[0][()] if nxdata.axes[-1] is None: radial = numpy.arange(nxdata.signal.shape[1]) radial_name = "" radial_units = "" else: radial_name = nxdata.axes_dataset_names[-1] axis_dataset = nxdata.axes[-1] radial = axis_dataset[()] radial_units = axis_dataset.attrs.get("units", "") intensities = numpy.atleast_2d(nxdata.signal) if nxdata.errors is None: errors = [None] * intensities.shape[0] else: errors = numpy.atleast_2d(nxdata.errors) if (len(points), len(radial)) != intensities.shape: raise RuntimeError("Shape mismatch between axes and signal") for point, intensity, intensity_errors in zip(points, intensities, errors): yield IntegratedPattern( point, radial, radial_name, radial_units, intensity, intensity_errors )