Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Nexus conversion without Application Definition #433

Open
rettigl opened this issue Sep 19, 2024 · 0 comments
Open

Nexus conversion without Application Definition #433

rettigl opened this issue Sep 19, 2024 · 0 comments

Comments

@rettigl
Copy link
Collaborator

rettigl commented Sep 19, 2024

How can I convert data into nexus using the dataconverter without having a fitting application definition? I would expect it to work with NXentry, but this produces an error:

---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
Cell In[8], line 17
     14 for scan, x, fluence, material in zip(scans, x_data, fluences, materials):
     15     entry_dict[f"{material}"] = {"data": f"root/{material}/{scan}", "ax0": f"root/{material}/{x}", "error": f"root/{material}/{scan}_err", "metadata": {**metadata, **{"sample/chemical_formula": material, "sample/name": f"{material} single crystal", "instrument/beam/pump/fluence": fluence}}}
---> 17 convert(["config_file_delay_scans.json", "Fig3a.pxp"], "igor_fhi", "NXentry", "Fig3a.nxs", objects=entry_dict)

File /mnt/pcshare/users/Laurenz/AreaB/pynxtools/pynxtools/src/pynxtools/dataconverter/convert.py:230, in convert(input_file, reader, nxdl, output, skip_verify, **kwargs)
    202 """The conversion routine that takes the input parameters and calls the necessary functions.
    203 
    204 Parameters
   (...)
    226 None.
    227 """
    228 nxdl_root, nxdl_f_path = helpers.get_nxdl_root_and_path(nxdl)
--> 230 data = transfer_data_into_template(
    231     input_file=input_file,
    232     reader=reader,
    233     nxdl_name=nxdl,
    234     nxdl_root=nxdl_root,
    235     skip_verify=skip_verify,
    236     **kwargs,
    237 )
    239 helpers.add_default_root_attributes(data=data, filename=os.path.basename(output))
    240 Writer(data=data, nxdl_f_path=nxdl_f_path, output_path=output).write()

File /mnt/pcshare/users/Laurenz/AreaB/pynxtools/pynxtools/src/pynxtools/dataconverter/convert.py:179, in transfer_data_into_template(input_file, reader, nxdl_name, nxdl_root, skip_verify, **kwargs)
    177     helpers.write_nexus_def_to_entry(data, entry_name, nxdl_name)
    178 if not skip_verify:
--> 179     valid = validate_dict_against(
    180         nxdl_name,
    181         data,
    182         ignore_undocumented=ignore_undocumented,
    183     )
    185     if fail and not valid:
    186         raise ValidationFailed(
    187             "The data does not match the given NXDL. "
    188             "Please check the log for more information."
    189         )

File /mnt/pcshare/users/Laurenz/AreaB/pynxtools/pynxtools/src/pynxtools/dataconverter/validation.py:566, in validate_dict_against(appdef, mapping, ignore_undocumented)
    553 missing_type_err = {
    554     "field": ValidationProblem.MissingRequiredField,
    555     "group": ValidationProblem.MissingRequiredGroup,
    556     "attribute": ValidationProblem.MissingRequiredAttribute,
    557 }
    559 handling_map = {
    560     "group": handle_group,
    561     "field": handle_field,
    562     "attribute": handle_attribute,
    563     "choice": handle_choice,
    564 }
--> 566 tree = generate_tree_from(appdef)
    567 collector.clear()
    568 nested_keys = build_nested_dict_from(mapping)

File /mnt/pcshare/users/Laurenz/AreaB/pynxtools/pynxtools/src/pynxtools/dataconverter/nexus_tree.py:925, in generate_tree_from(appdef)
    922     child.optionality = "optional"
    924 entry = appdef_xml_root.find("nx:group[@type='NXentry']", namespaces=namespaces)
--> 925 add_children_to(tree, entry)
    927 # Add all fields and attributes from the parent appdefs
    928 if len(appdef_inheritance_chain) > 1:

File /mnt/pcshare/users/Laurenz/AreaB/pynxtools/pynxtools/src/pynxtools/dataconverter/nexus_tree.py:891, in generate_tree_from.<locals>.add_children_to(parent, xml_elem)
    880 def add_children_to(parent: NexusNode, xml_elem: ET._Element) -> None:
    881     """
    882     This adds children from the `xml_elem` xml node to the NexusNode `parent` node.
    883     This only considers `field`, `attribute`, `choice` and `group` xml tags
   (...)
    889         xml_elem (ET._Element): The xml node to get the children from.
    890     """
--> 891     current_elem = parent.add_node_from(xml_elem)
    893     for child in xml_elem.xpath(
    894         (
    895             r"*[self::nx:field or self::nx:group "
   (...)
    898         namespaces=namespaces,
    899     ):
    900         add_children_to(current_elem, child)

File /mnt/pcshare/users/Laurenz/AreaB/pynxtools/pynxtools/src/pynxtools/dataconverter/nexus_tree.py:526, in NexusNode.add_node_from(self, xml_elem)
    512 def add_node_from(self, xml_elem: ET._Element) -> Optional["NexusNode"]:
    513     """
    514     Adds a children node to this node based on an xml element.
    515     The appropriate subclass is chosen based on the xml tag.
   (...)
    524             None if the tag of the xml element is not known.
    525     """
--> 526     default_optionality = "required" if is_appdef(xml_elem) else "optional"
    527     tag = remove_namespace_from_tag(xml_elem.tag)
    528     if tag in ("field", "attribute"):

File /mnt/pcshare/users/Laurenz/AreaB/pynxtools/pynxtools/src/pynxtools/dataconverter/helpers.py:248, in is_appdef(xml_elem)
    238 def is_appdef(xml_elem: ET._Element) -> bool:
    239     """
    240     Check whether the xml element is part of an application definition.
    241 
   (...)
    246         bool: True if the xml_elem is part of an application definition.
    247     """
--> 248     return get_appdef_root(xml_elem).attrib.get("category") == "application"

File /mnt/pcshare/users/Laurenz/AreaB/pynxtools/pynxtools/src/pynxtools/dataconverter/helpers.py:235, in get_appdef_root(xml_elem)
    225 def get_appdef_root(xml_elem: ET._Element) -> ET._Element:
    226     """
    227     Get the root element of the tree of xml_elem
    228 
   (...)
    233         ET._Element: The root element of the tree.
    234     """
--> 235     return xml_elem.getroottree().getroot()

AttributeError: 'NoneType' object has no attribute 'getroottree'

Also, would this parsable by NOMAD?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant