From da9f7cb58a10d8d88887886bf265b3d0a4bc0c6f Mon Sep 17 00:00:00 2001 From: Simon Renblad Date: Thu, 21 Sep 2023 17:44:52 +0800 Subject: [PATCH] applet extensions documentation --- artiq/applets/simple.py | 48 ++++++++++++++++++--- doc/manual/conf.py | 2 +- doc/manual/management_system.rst | 71 ++++++++++++++++++++++++++++++++ 3 files changed, 114 insertions(+), 7 deletions(-) diff --git a/artiq/applets/simple.py b/artiq/applets/simple.py index d49223670..580991982 100644 --- a/artiq/applets/simple.py +++ b/artiq/applets/simple.py @@ -17,7 +17,45 @@ from artiq.language.scan import ScanObject logger = logging.getLogger(__name__) -class AppletControlIPC: +class _AppletRequestInterface: + def __init__(self): + raise NotImplementedError + + def set_dataset(self, key, value, unit=None, scale=None, precision=None, persist=None): + """ + Set a dataset. + See documentation of ``artiq.language.environment.set_dataset``. + """ + raise NotImplementedError + + def mutate_dataset(self, key, index, value): + """ + Mutate a dataset. + See documentation of ``artiq.language.environment.mutate_dataset``. + """ + raise NotImplementedError + + def append_to_dataset(self, key, value): + """ + Append to a dataset. + See documentation of ``artiq.language.environment.append_to_dataset``. + """ + raise NotImplementedError + + def set_argument_value(self, expurl, name, value): + """ + Temporarily set the value of an argument in a experiment in the dashboard. + The value resets to default value when recomputing the argument. + + :param expurl: Experiment URL identifying the experiment in the dashboard. Example: 'repo:ArgumentsDemo'. + :param name: Name of the argument in the experiment. + :param value: Object representing the new temporary value of the argument. For ``Scannable`` arguments, this parameter + should be a ``ScanObject``. The type of the ``ScanObject`` will be set as the selected type when this function is called. + """ + raise NotImplementedError + + +class AppletRequestIPC(_AppletRequestInterface): def __init__(self, ipc): self.ipc = ipc @@ -45,7 +83,7 @@ class AppletControlIPC: self.ipc.set_argument_value(expurl, name, value) -class AppletControlRPC: +class AppletRequestRPC(_AppletRequestInterface): def __init__(self, loop, dataset_ctl): self.loop = loop self.dataset_ctl = dataset_ctl @@ -74,8 +112,6 @@ class AppletControlRPC: mod = {"action": "append", "path": [key, 1], "x": value} self._background(self.dataset_ctl.update, mod) - def set_argument_value(self, expurl, name, value): - raise NotImplementedError class AppletIPCClient(AsyncioChildComm): def set_close_cb(self, close_cb): @@ -220,9 +256,9 @@ class SimpleApplet: dataset_ctl = RPCClient() self.loop.run_until_complete(dataset_ctl.connect_rpc( self.args.server, self.args.port_control, "master_dataset_db")) - self.ctl = AppletControlRPC(self.loop, dataset_ctl) + self.ctl = AppletRequestRPC(self.loop, dataset_ctl) else: - self.ctl = AppletControlIPC(self.ipc) + self.ctl = AppletRequestIPC(self.ipc) def ctl_close(self): if self.embed is None: diff --git a/doc/manual/conf.py b/doc/manual/conf.py index df603b7b2..7e06ea680 100644 --- a/doc/manual/conf.py +++ b/doc/manual/conf.py @@ -41,7 +41,7 @@ mock_modules = ["artiq.gui.waitingspinnerwidget", "sipyco", "sipyco.pc_rpc", "sipyco.sync_struct", "sipyco.asyncio_tools", "sipyco.logging_tools", "sipyco.broadcast", "sipyco.packed_exceptions", - "sipyco.keepalive"] + "sipyco.keepalive", "sipyco.pipe_ipc"] for module in mock_modules: sys.modules[module] = Mock() diff --git a/doc/manual/management_system.rst b/doc/manual/management_system.rst index aafbb0361..abb5c2d17 100644 --- a/doc/manual/management_system.rst +++ b/doc/manual/management_system.rst @@ -143,6 +143,77 @@ CCBs are used by experiments to configure applets in the dashboard, for example .. autoclass:: artiq.dashboard.applets_ccb.AppletsCCBDock :members: +Applet request interfaces +************************* + +Applet request interfaces allow applets to perform actions on the master database and set arguments in the dashboard. Applets may inherit from the ``artiq.applets.simple.SimpleApplet`` and call the methods defined below through the `req` attribute. + +Embedded applets should use `AppletRequestIPC` while standalone applets use `AppletRequestRPC`. `SimpleApplet` automatically chooses the correct interface on initialization. + +.. autoclass:: artiq.applets.simple._AppletRequestInterface + :members: + + +Applet entry area +***************** + +Extensions are provided to enable the use of argument widgets in applets through the `EntryArea` class. + +Below is a simple example code snippet using the `EntryArea` class: :: + + # Create the experiment area + entry_area = EntryArea() + + # Create a new widget + entry_area.setattr_argument("bl", BooleanValue(True)) + + # Get the value of the widget (output: True) + print(entry_area.bl) + + # Set the value + entry_area.set_value("bl", False) + + # False + print(entry_area.bl) + +The `EntryArea` object can then be added to a layout and integrated with the applet GUI. Multiple `EntryArea` objects can be used in a single applet. + +.. class:: artiq.gui.applets.EntryArea + + .. method:: setattr_argument(name, proc, group=None, tooltip=None) + + Sets an argument as attribute. The names of the argument and of the + attribute are the same. + + :param name: Argument name + :param proc: Argument processor, for example ``NumberValue`` + :param group: Used to group together arguments in the GUI under a common category + :param tooltip: Tooltip displayed when hovering over the entry widget + + .. method:: get_value(name) + + Get the value of an entry widget. + + :param name: Argument name + + .. method:: get_values() + + Get all values in the ``EntryArea`` as a dictionary. Names are stored as keys, and argument values as values. + + .. method:: set_value(name, value) + + Set the value of an entry widget. The change is temporary and will reset to default when the reset button is clicked. + + :param name: Argument name + :param value: Object representing the new value of the argument. For ``Scannable`` arguments, this parameter + should be a ``ScanObject``. The type of the ``ScanObject`` will be set as the selected type when this function is called. + + .. method:: set_values(values) + + Set multiple values from a dictionary input. Calls ``set_value()`` for each key-value pair. + + :param values: Dictionary with names as keys and new argument values as values. + Front-end tool reference ************************