Source code for SDF.data_model.instrument

from typing import Optional, Union, Iterable
from xml.etree.ElementTree import Element

from SDF.data_model._helper_functions import pop_child_element, element_is_empty, pop_all_child_elements
from SDF.data_model.abstract import XMLWritable
from SDF.data_model.element_set import ElementSet
from SDF.data_model.name import NameElement
from SDF.data_model.parameter import AnonymousParameterSet, ParameterType


[docs]class Instrument(AnonymousParameterSet, XMLWritable): """Represents an SDF <instrument> element""" def __init__(self, name: Optional[Union[str, NameElement]] = None, parameters: Optional[Iterable[ParameterType]] = None): if isinstance(name, NameElement): self.__name = name else: self.__name = NameElement(name) super().__init__(items=parameters) @property def name(self) -> str: return self.__name.name
[docs] def to_xml_element(self) -> Element: element = Element("instrument") element.append(self.__name.to_xml_element()) for parameter in self: element.append(parameter.to_xml_element()) return element
[docs] @classmethod def from_xml_element(cls, element: Element) -> "Instrument": if element.tag != "instrument": raise ValueError(f"Expected an <instrument> element, got {element.tag}") name = NameElement.from_xml_element(pop_child_element(element, 0)) parameters = [] for child in pop_all_child_elements(element): if child.tag == "par": parameters.append(ParameterType.from_xml_element(child)) else: raise ValueError(f"Unexpected child of type '{child.tag}'") if not element_is_empty(element): raise ValueError("Element is not empty") return cls(name, parameters)
def __repr__(self): return f"{self.__class__.__name__}({self.name!r}, {[item for item in self]!r})" def __eq__(self, other): if isinstance(other, Instrument): return self.__name == other.__name and super().__eq__(other) return False
[docs]class InstrumentSet(ElementSet[Instrument]): """Extends `ElementSet[Instrument]` to allow adding parameters more intuitively""" def __init__(self, items: Optional[Iterable[Instrument]] = None): super().__init__(key_func=lambda inst: inst.name, check_func=lambda inst: isinstance(inst, Instrument), items=items) def __setitem__(self, key, value): if key not in self.keys(): self.add(Instrument(name=key)) self[key].add_from_structure(value)