Source code for ewokspdf.tasks.save_nexus

import h5py
import os.path
import json
import re
import numpy as np

from silx.io.dictdump import dicttonx
from ewoksxrpd.tasks.data_access import TaskWithDataAccess

from ewokspdf.tasks.constants import SIGNAL_TYPES

try:
    from diffpy import pdfgetx

    VERSION = pdfgetx.__version__
except ImportError:
    VERSION = None


[docs] class PdfGetXSaveNexus( TaskWithDataAccess, input_names=[ "nxdata_url", "results", "pdfgetx_options", "info", ], optional_input_names=["subscan"], output_names=["output_url"], ): """Saves the PDF results (iq, sq, fq, gr) in a NeXus file Inputs: - nxdata_url: .h5 path with NXData url in which the data will be saved - results: List of PDFGetter object with attributes defined by outputtype. Attributes are tuples with [0] X (radial) and [1] Y (intensity) Outputs: - pdfgetx_options: pdfgetx.PDFConfig object containing the configuration """
[docs] def run(self): full_nxdata_url = self.inputs.nxdata_url detector_name = re.search(r"/([^/]+)_integrate/", full_nxdata_url).group(1) nxdata_url = re.match(r"^(.*?\.h5::/?\d+\.\d+/)", full_nxdata_url).group(1) results = self.inputs.results pdfgetx_options_dict = pdfgetx_config_as_nxdict(self.inputs.pdfgetx_options) nb_avg = {"nb_avg": self.inputs.info["nb_avg"]} collected_data = { signal_type: {"axes": [], "signals": []} for signal_type in SIGNAL_TYPES } for result in results: for signal_type, signal_quantities in SIGNAL_TYPES.items(): axis, signal = getattr(result, signal_type) collected_data[signal_type]["axes"].append(axis) collected_data[signal_type]["signals"].append(signal) for signal_type in collected_data: collected_data[signal_type]["axes"] = np.array( collected_data[signal_type]["axes"] ) collected_data[signal_type]["signals"] = np.array( collected_data[signal_type]["signals"] ) with self.open_h5item(nxdata_url, mode="a", create=True) as data_parent: assert isinstance(data_parent, h5py.Group) nxprocess = data_parent.create_group(f"{detector_name}_PDF") nxprocess.attrs["NX_class"] = "NXprocess" dicttonx( pdfgetx_options_dict, data_parent.file, h5path=f"{nxprocess.name}", update_mode="modify", ) dicttonx( nb_avg, data_parent.file, h5path=f"{nxprocess.name}/averaging_options", update_mode="modify", ) for signal_type, signal_quantities in SIGNAL_TYPES.items(): nxdata = nxprocess.create_group(signal_type) nxdata.attrs["NX_class"] = "NXdata" signal_dset = nxdata.create_dataset( signal_type, data=collected_data[signal_type]["signals"] ) nxdata.attrs["signal"] = signal_type signal_dset.attrs["long_name"] = signal_quantities["y"].name signal_dset.attrs["units"] = signal_quantities["y"].unit axis_name, axis_unit = ( signal_quantities["x"].name, signal_quantities["x"].unit, ) axis_dset = nxdata.create_dataset( axis_name, data=collected_data[signal_type]["axes"] ) axis_dset.attrs["unit"] = axis_unit nxdata.attrs["axes"] = axis_name nxprocess.attrs["default"] = signal_type nxprocess.parent.attrs["default"] = os.path.basename(nxprocess.name) self.outputs.output_url = f"silx://{nxdata_url}{detector_name}_PDF"
def pdfgetx_config_as_nxdict(obj): """ Convert an object's attributes into an NXtree dictionary. Args: obj (object): The object whose attributes are to be converted. Returns: dict: An NXtree dictionary with configuration details. """ if obj is None: raise ValueError("The object cannot be None.") if not hasattr(obj, "__dict__"): raise TypeError( "The provided object does not have attributes accessible via __dict__." ) pdfgetx_config = {key: value for key, value in vars(obj).items()} print(pdfgetx_config) nxtree_dict = { "@NX_class": "NXprocess", "program": "pdfgetx", "version": VERSION, } nxtree_dict["configuration"] = { "@NX_class": "NXnote", "type": "application/json", "data": json.dumps(pdfgetx_config), } return nxtree_dict