diff --git a/pynxtools/dataconverter/convert.py b/pynxtools/dataconverter/convert.py index 29ca21b6e..dfef05f0a 100644 --- a/pynxtools/dataconverter/convert.py +++ b/pynxtools/dataconverter/convert.py @@ -131,6 +131,8 @@ def convert(input_file: Tuple[str], path ) + helpers.add_default_root_attributes(data=data, filename=os.path.basename(output)) + Writer(data=data, nxdl_path=nxdl_path, output_path=output).write() logger.info("The output file generated: %s", output) diff --git a/pynxtools/dataconverter/helpers.py b/pynxtools/dataconverter/helpers.py index f6b6fa8c5..199dec181 100644 --- a/pynxtools/dataconverter/helpers.py +++ b/pynxtools/dataconverter/helpers.py @@ -21,9 +21,11 @@ from typing import Tuple, Callable, Union import re import xml.etree.ElementTree as ET +from datetime import datetime, timezone import numpy as np from ase.data import chemical_symbols +import h5py from pynxtools.nexus import nexus from pynxtools.nexus.nexus import NxdlAttributeError @@ -583,12 +585,22 @@ def convert_to_hill(atoms_typ): return atom_list + list(atoms_typ) +def add_default_root_attributes(data, filename): + """Takes a dict/Template and adds NXroot fields/attributes that are inherently available""" + data["/@NX_class"] = "NXroot" + data["/@file_name"] = filename + data["/@file_time"] = str(datetime.now(timezone.utc).astimezone()) + data["/@file_update_time"] = data["/@file_time"] + data["/@NeXus_version"] = "NOT_IMPLEMENTED" + data["/@HDF5_version"] = '.'.join(map(str, h5py.h5.get_libversion())) # pylint: disable=c-extension-no-member + data["/@h5py_version"] = h5py.__version__ + + def extract_atom_types(formula, mode='hill'): """Extract atom types form chemical formula.""" - atom_types: set = set() element: str = "" - # tested with "(C38H54S4)n(NaO2)5(CH4)NH3B" + for char in formula: if char.isalpha(): if char.isupper() and element == "": diff --git a/pynxtools/nexus/nxdl_utils.py b/pynxtools/nexus/nxdl_utils.py index 706390a7c..aa64d5caa 100644 --- a/pynxtools/nexus/nxdl_utils.py +++ b/pynxtools/nexus/nxdl_utils.py @@ -701,6 +701,9 @@ def get_node_at_nxdl_path(nxdl_path: str = None, we are looking for or the root elem from a previously loaded NXDL file and finds the corresponding XML element with the needed attributes.""" try: + if nxdl_path.count("/") == 1 and nxdl_path not in ("/ENTRY", "/entry"): + elem = None + nx_name = "NXroot" (class_path, nxdlpath, elist) = get_inherited_nodes(nxdl_path, nx_name, elem) except ValueError as value_error: if exc: diff --git a/tests/dataconverter/test_helpers.py b/tests/dataconverter/test_helpers.py index a018b92bd..9cfdf60c6 100644 --- a/tests/dataconverter/test_helpers.py +++ b/tests/dataconverter/test_helpers.py @@ -162,6 +162,7 @@ def fixture_filled_test_data(template, tmp_path): TEMPLATE["lone_groups"] = ['/ENTRY[entry]/required_group', '/ENTRY[entry]/required_group2', '/ENTRY[entry]/optional_parent/req_group_in_opt_group'] +TEMPLATE["optional"]["/@default"] = "Some NXroot attribute" @pytest.mark.parametrize("data_dict,error_message", [ diff --git a/tests/dataconverter/test_readers.py b/tests/dataconverter/test_readers.py index 79ec89bf4..d75344541 100644 --- a/tests/dataconverter/test_readers.py +++ b/tests/dataconverter/test_readers.py @@ -105,7 +105,7 @@ def test_has_correct_read_func(reader): @pytest.mark.parametrize("reader_name,nxdl,undocumented_keys", [ - ('mpes', 'NXmpes', ['/@default']) + ('mpes', 'NXmpes', []) ]) def test_shows_correct_warnings(reader_name, nxdl, undocumented_keys): """