Source code for zhinst.toolkit.driver.nodes.command_table_node

"""Command Table Node adaptions."""
import json
import string
import typing as t
from pathlib import Path

from zhinst.toolkit.command_table import CommandTable
from zhinst.toolkit.nodetree import Node, NodeTree

_CT_RESOURCE_PATH = Path(__file__).parent.parent.parent / "resources"
_CT_FILES = {
    "shfqc": _CT_RESOURCE_PATH / "ct_schema_shfsg.json",
    "shfsg": _CT_RESOURCE_PATH / "ct_schema_shfsg.json",
    "hdawg": _CT_RESOURCE_PATH / "ct_schema_hdawg.json",
}


[docs]class CommandTableNode(Node): """CommandTable node. This class implements the basic functionality of the command table allowing the user to load and upload their own command table. A dedicated class called ``CommandTable`` exists that is the preferred way to create a valid command table. For more information about the ``CommandTable`` refer to the corresponding example or the documentation of that class directly. Args: root: Node used for the upload of the command table tree: Tree (node path as tuple) of the current node device_type: Device type. """ def __init__( self, root: NodeTree, tree: t.Tuple[str, ...], device_type: str ) -> None: Node.__init__(self, root, tree) self._device_type = device_type self._schema: t.Optional[t.Dict[str, t.Any]] = None
[docs] def check_status(self) -> bool: """Check status of the command table. Returns: Flag if a valid command table is loaded into the device. Raises: RuntimeError: If the command table upload into the device failed. """ ct_status = self.status() if ct_status >> 3: raise RuntimeError( "Uploading of data to the command table failed " "due to a JSON parsing error." ) return ct_status == 1
[docs] def load_validation_schema(self) -> t.Dict[str, t.Any]: """Load device command table validation schema. Returns: JSON validation schema for the device command tables. """ if self._schema is None: try: self._schema = json.loads(self.schema()) except KeyError: device_type_striped = self._device_type.lower().rstrip(string.digits) with open(_CT_FILES[device_type_striped], encoding="utf-8") as file_: self._schema = json.load(file_) return self._schema # type: ignore
[docs] def upload_to_device( self, ct: t.Union[CommandTable, str, dict], *, validate: bool = False, check_upload: bool = True, ) -> None: """Upload command table into the device. The command table can either be specified through the dedicated ``CommandTable`` class or in a raw format, meaning a json string or json dict. In the case of a json string or dict the command table is validated by default against the schema provided by the device. Args: ct: Command table. validate: Flag if the command table should be validated. (Only applies if the command table is passed as a raw json string or json dict) check_upload: Flag if the upload should be validated by calling `check_status`. This is not mandatory bat strongly recommended since the device does not raise an error when it rejects the command table. This Flag is ignored when called from within a transaction. Raises: RuntimeError: If the command table upload into the device failed. zhinst.toolkit.exceptions.ValidationError: Incorrect schema. .. versionchanged:: 0.4.2 New Flag `check_upload` that makes the upload check optional. `check_status` is only called when not in a ongoing transaction. """ try: self.data(json.dumps(ct.as_dict())) # type: ignore except AttributeError: if validate: ct_new = CommandTable(self.load_validation_schema()) ct_new.update(ct) self.upload_to_device(ct_new) elif isinstance(ct, str): self.data(ct) else: self.data(json.dumps(ct)) if ( check_upload and not self._root.transaction.in_progress() and not self.check_status() ): raise RuntimeError( "No valid command table reported by the device after upload." )
[docs] def load_from_device(self) -> CommandTable: """Load command table from the device. Returns: command table. """ ct = CommandTable(self.load_validation_schema(), active_validation=True) ct.update(self.data()) return ct