Skip to content

Commit

Permalink
replace BasicEln (#451)
Browse files Browse the repository at this point in the history
* code for being added when NOMAD GUI supports mixed use of use_full_storage in quantities

* removing NXsuffices; removing nexus section and using it inside data

* fixing tests

* fix for handling problem where NO NXentry found

* rename group names if they are used in the BaseSection class

* restructure nomad tests

* temporarily install nomad feature branch in tests

* add test for schema

* ignore myp error on nexus_schema.NeXus

* use renaming function in tests

* bring XML_NAMESPACES back to schema

* rename to __XML_NAMESPACES

* include field and attribute renaming, capitalization

* small docs change

* remove capitalization

* temporarily install nomad feature branch in tests

* capitalise NX class names in NOMAD

* instead of using the buggy m_set_quantity_attribute of a section, use m_set_attribute directly on the quantity

* update nomad branch to check against

* code simplification according to review suggestion

---------

Co-authored-by: Lukas Pielsticker <[email protected]>
  • Loading branch information
sanbrock and lukaspie authored Oct 25, 2024
1 parent 2d2cb9e commit 6f7b703
Show file tree
Hide file tree
Showing 9 changed files with 282 additions and 197 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/pytest.yml
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ jobs:
- name: Install nomad
if: "${{ matrix.python_version != '3.8' && matrix.python_version != '3.12'}}"
run: |
uv pip install nomad-lab@git+https://gitlab.mpcdf.mpg.de/nomad-lab/nomad-FAIR.git
uv pip install nomad-lab@git+https://gitlab.mpcdf.mpg.de/nomad-lab/nomad-FAIR.git@Sprint_Nomad_BaseSection
- name: Install pynx
run: |
uv pip install ".[dev]"
Expand Down
7 changes: 4 additions & 3 deletions src/pynxtools/nexus/nexus.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,7 @@
import os
import sys
from functools import lru_cache

from typing import Optional, Union, List, Any
from typing import Any, List, Optional, Union

import click
import h5py
Expand All @@ -16,6 +15,7 @@
from pynxtools.definitions.dev_tools.utils.nxdl_utils import (
add_base_classes,
check_attr_name_nxdl,
decode_or_not,
get_best_child,
get_hdf_info_parent,
get_local_name_from_xml,
Expand All @@ -29,7 +29,6 @@
try_find_units,
walk_elist,
write_doc_string,
decode_or_not,
)


Expand Down Expand Up @@ -378,6 +377,8 @@ def get_inherited_hdf_nodes(
# let us start with the given definition file
if hdf_node is None:
raise ValueError("hdf_node must not be None")
if nx_name == "NO NXentry found":
return (None, [], [])
elist = [] # type: ignore[var-annotated]
add_base_classes(elist, nx_name, elem)
nxdl_elem_path = [elist[0]]
Expand Down
72 changes: 21 additions & 51 deletions src/pynxtools/nomad/parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,8 @@
try:
from ase.data import chemical_symbols
from nomad.atomutils import Formula
from nomad.datamodel import EntryArchive
from nomad.datamodel import EntryArchive, EntryMetadata
from nomad.datamodel.data import EntryData
from nomad.datamodel.results import Material, Results
from nomad.metainfo import MSection
from nomad.metainfo.util import MQuantity, MSubSectionList, resolve_variadic_name
Expand All @@ -39,33 +40,16 @@

import pynxtools.nomad.schema as nexus_schema
from pynxtools.nexus.nexus import HandleNexus

__REPLACEMENT_FOR_NX = "BS"
__REPLACEMENT_LEN = len(__REPLACEMENT_FOR_NX)


def _rename_nx_to_nomad(name: str) -> Optional[str]:
"""
Rename the NXDL name to NOMAD.
For example: NXdata -> BSdata,
except NXobject -> NXobject
"""
if name == "NXobject":
return name
if name is not None:
if name.startswith("NX"):
return name.replace("NX", __REPLACEMENT_FOR_NX)
return name
from pynxtools.nomad.utils import __REPLACEMENT_FOR_NX
from pynxtools.nomad.utils import __rename_nx_for_nomad as rename_nx_for_nomad


def _to_group_name(nx_node: ET.Element):
"""
Normalise the given group name
"""
# assuming always upper() is incorrect, e.g. NXem_msr is a specific one not EM_MSR!
grp_nm = nx_node.attrib.get(
"name", nx_node.attrib["type"][__REPLACEMENT_LEN:].upper()
)
grp_nm = nx_node.attrib.get("name", nx_node.attrib["type"][2:].upper())

return grp_nm

Expand Down Expand Up @@ -109,6 +93,8 @@ def _to_section(
# no need to change section for quantities and attributes
return current

nomad_def_name = rename_nx_for_nomad(nomad_def_name, is_group=True)

# for groups, get the definition from the package
new_def = current.m_def.all_sub_sections[nomad_def_name]

Expand Down Expand Up @@ -233,9 +219,7 @@ def _populate_data(
raise Warning(
"setting attribute attempt before creating quantity"
)
current.m_set_quantity_attribute(
quantity.name, attr_name, attr_value
)
quantity.m_set_attribute(attr_name, attr_value)
except Exception as e:
self._logger.warning(
"error while setting attribute",
Expand Down Expand Up @@ -307,28 +291,16 @@ def _populate_data(
# may need to check if the given unit is in the allowable list
try:
current.m_set(metainfo_def, field)
current.m_set_quantity_attribute(
data_instance_name, "m_nx_data_path", hdf_node.name
)
current.m_set_quantity_attribute(
data_instance_name, "m_nx_data_file", self.nxs_fname
)
field.m_set_attribute("m_nx_data_path", hdf_node.name)
field.m_set_attribute("m_nx_data_file", self.nxs_fname)
if field_stats is not None:
# TODO _add_additional_attributes function has created these nx_data_*
# attributes speculatively already so if the field_stats is None
# this will cause unpopulated attributes in the GUI
current.m_set_quantity_attribute(
data_instance_name, "nx_data_mean", field_stats[0]
)
current.m_set_quantity_attribute(
data_instance_name, "nx_data_var", field_stats[1]
)
current.m_set_quantity_attribute(
data_instance_name, "nx_data_min", field_stats[2]
)
current.m_set_quantity_attribute(
data_instance_name, "nx_data_max", field_stats[3]
)
field.m_set_attribute("nx_data_mean", field_stats[0])
field.m_set_attribute("nx_data_var", field_stats[1])
field.m_set_attribute("nx_data_min", field_stats[2])
field.m_set_attribute("nx_data_max", field_stats[3])
except Exception as e:
self._logger.warning(
"error while setting field",
Expand All @@ -349,7 +321,8 @@ def __nexus_populate(self, params: dict, attr=None): # pylint: disable=W0613
hdf_path: str = hdf_info["hdf_path"]
hdf_node = hdf_info["hdf_node"]
if nx_def is not None:
nx_def = _rename_nx_to_nomad(nx_def)
nx_def = rename_nx_for_nomad(nx_def)

if nx_path is None:
return

Expand Down Expand Up @@ -489,8 +462,9 @@ def parse(
child_archives: Dict[str, EntryArchive] = None,
) -> None:
self.archive = archive
self.archive.m_create(nexus_schema.NeXus) # type: ignore # pylint: disable=no-member
self.nx_root = self.archive.nexus
self.nx_root = nexus_schema.NeXus() # type: ignore # pylint: disable=no-member

self.archive.data = self.nx_root
self._logger = logger if logger else get_logger(__name__)
self._clear_class_refs()

Expand All @@ -500,14 +474,10 @@ def parse(

# TODO: domain experiment could also be registered
if archive.metadata is None:
return
archive.metadata = EntryMetadata()

# Normalise experiment type
app_def: str = ""
for var in dir(archive.nexus):
if getattr(archive.nexus, var, None) is not None:
app_def = var
break
app_def = str(self.nx_root).split("(")[1].split(")")[0].split(",")[0]
if archive.metadata.entry_type is None:
archive.metadata.entry_type = app_def
archive.metadata.domain = "nexus"
Expand Down
Loading

0 comments on commit 6f7b703

Please sign in to comment.