Source code for raypyng.rml

###############################################################################
# Reading/Writing/Modifying RML files
from . import xmltools as xml
from .xmltools import XmlAttributedNameElement, XmlElement


###############################################################################
[docs] class BeamlineElement(XmlAttributedNameElement): def __init__(self, name: str, attributes: dict, **kwargs): super().__init__("name", name, attributes, **kwargs)
###############################################################################
[docs] class ObjectElement(XmlAttributedNameElement): def __init__(self, name: str, attributes: dict, **kwargs): super().__init__("id", name, attributes, **kwargs)
###############################################################################
[docs] class ParamElement(XmlElement): def __init__(self, name: str, attributes: dict, **kwargs): super().__init__(name, attributes, **kwargs) def __dir__(self): """enumerating child objects by its attibute name""" children_names = [x._name for x in self._children] attr_name = list(self._attributes.keys()) return children_names + attr_name + ["cdata"] def __getattr__(self, key): matching_children = [x for x in self._children if x._name == key] if key in self._attributes: matching_children.append(self._attributes[key]) if matching_children: if len(matching_children) == 1: self.__dict__[key] = matching_children[0] return matching_children[0] else: self.__dict__[key] = matching_children return matching_children else: raise AttributeError("'%s' has no attribute '%s'" % (self._name, key))
###############################################################################
[docs] class RMLFile: """Read/Write wrapper for the Ray RML files Args: filename (str, optional): path to rml file. Defaults to None. template (str, optional): path to rml file to use as template. Defaults to None. """ def __init__(self, filename: str = None, /, template: str = None) -> None: """ Args: filename (str, optional): path to rml file. Defaults to None. template (str, optional): path to rml file to use as template. Defaults to None. """ self._filename = filename self._template = template if template is not None else filename self.__known_classes = { "beamline": BeamlineElement, "object": ObjectElement, "param": ParamElement, } self.read() @property def template(self): return self._template @property def filename(self): return self._filename @filename.setter def filename(self, value): self._filename = value ###################################
[docs] def read(self, file: str = None): """Read rml file Args: file (str, optional): file name to read. If set to None will use template file name defined during initilizatino of the class. Defaults to None. """ if file is None: file = self._template self._root = xml.parse(file, known_classes=self.__known_classes) self.beamline = self._root.lab.beamline
def xml(self): return xml.serialize(self._root).strip()
[docs] def write(self, file: str = None): """Write the rml to :code:`file` Args: file (str, optional): filename . Defaults to None. """ if file is None: file = self._filename with open(file, "w") as f: f.write(self.xml())
def __str__(self) -> str: return f"RMLFile('{self._filename}',template='{self._template}')" def __repr__(self) -> str: return f"RMLFile('{self._filename}',template='{self._template}')"
############################################################################### # test function for the data parsing def parse(filename: str): __known_classes = {"beamline": BeamlineElement, "object": ObjectElement, "param": ParamElement} xml.parse(filename, known_classes=__known_classes)