set_argument_value in applets

This commit is contained in:
Simon Renblad 2023-09-18 16:13:45 +08:00 committed by Sébastien Bourdeauducq
parent a2fbcb8bfd
commit 40ac2e03ab
4 changed files with 58 additions and 21 deletions

View File

@ -11,6 +11,8 @@ from sipyco.pc_rpc import AsyncioClient as RPCClient
from sipyco import pyon from sipyco import pyon
from sipyco.pipe_ipc import AsyncioChildComm from sipyco.pipe_ipc import AsyncioChildComm
from artiq.language.scan import ScanObject
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
@ -37,6 +39,11 @@ class AppletControlIPC:
mod = {"action": "append", "path": [key, 1], "x": value} mod = {"action": "append", "path": [key, 1], "x": value}
self.ipc.update_dataset(mod) self.ipc.update_dataset(mod)
def set_argument_value(self, expurl, name, value):
if isinstance(value, ScanObject):
value = value.describe()
self.ipc.set_argument_value(expurl, name, value)
class AppletControlRPC: class AppletControlRPC:
def __init__(self, loop, dataset_ctl): def __init__(self, loop, dataset_ctl):
@ -67,6 +74,8 @@ class AppletControlRPC:
mod = {"action": "append", "path": [key, 1], "x": value} mod = {"action": "append", "path": [key, 1], "x": value}
self._background(self.dataset_ctl.update, mod) self._background(self.dataset_ctl.update, mod)
def set_argument_value(self, expurl, name, value):
raise NotImplementedError
class AppletIPCClient(AsyncioChildComm): class AppletIPCClient(AsyncioChildComm):
def set_close_cb(self, close_cb): def set_close_cb(self, close_cb):
@ -137,6 +146,12 @@ class AppletIPCClient(AsyncioChildComm):
self.write_pyon({"action": "update_dataset", self.write_pyon({"action": "update_dataset",
"mod": mod}) "mod": mod})
def set_argument_value(self, expurl, name, value):
self.write_pyon({"action": "set_argument_value",
"expurl": expurl,
"name": name,
"value": value})
class SimpleApplet: class SimpleApplet:
def __init__(self, main_widget_class, cmd_description=None, def __init__(self, main_widget_class, cmd_description=None,

View File

@ -159,6 +159,23 @@ class _ArgumentEditor(QtWidgets.QTreeWidget):
self._groups[name] = group self._groups[name] = group
return group return group
def update_argument(self, name, argument):
widgets = self._arg_to_widgets[name]
# Qt needs a setItemWidget() to handle layout correctly,
# simply replacing the entry inside the LayoutWidget
# results in a bug.
widgets["entry"].deleteLater()
widgets["entry"] = procdesc_to_entry(argument["desc"])(argument)
widgets["disable_other_scans"].setVisible(
isinstance(widgets["entry"], ScanEntry))
widgets["fix_layout"].deleteLater()
widgets["fix_layout"] = LayoutWidget()
widgets["fix_layout"].addWidget(widgets["entry"])
self.setItemWidget(widgets["widget_item"], 1, widgets["fix_layout"])
self.updateGeometries()
def _recompute_argument_clicked(self, name): def _recompute_argument_clicked(self, name):
asyncio.ensure_future(self._recompute_argument(name)) asyncio.ensure_future(self._recompute_argument(name))
@ -175,22 +192,7 @@ class _ArgumentEditor(QtWidgets.QTreeWidget):
state = procdesc_to_entry(procdesc).default_state(procdesc) state = procdesc_to_entry(procdesc).default_state(procdesc)
argument["desc"] = procdesc argument["desc"] = procdesc
argument["state"] = state argument["state"] = state
self.update_argument(name, argument)
# Qt needs a setItemWidget() to handle layout correctly,
# simply replacing the entry inside the LayoutWidget
# results in a bug.
widgets = self._arg_to_widgets[name]
widgets["entry"].deleteLater()
widgets["entry"] = procdesc_to_entry(procdesc)(argument)
widgets["disable_other_scans"].setVisible(
isinstance(widgets["entry"], ScanEntry))
widgets["fix_layout"].deleteLater()
widgets["fix_layout"] = LayoutWidget()
widgets["fix_layout"].addWidget(widgets["entry"])
self.setItemWidget(widgets["widget_item"], 1, widgets["fix_layout"])
self.updateGeometries()
def _disable_other_scans(self, current_name): def _disable_other_scans(self, current_name):
for name, widgets in self._arg_to_widgets.items(): for name, widgets in self._arg_to_widgets.items():
@ -665,6 +667,20 @@ class ExperimentManager:
self.argument_ui_names[expurl] = ui_name self.argument_ui_names[expurl] = ui_name
return arguments return arguments
def set_argument_value(self, expurl, name, value):
try:
argument = self.submission_arguments[expurl][name]
if argument["desc"]["ty"] == "Scannable":
ty = value["ty"]
argument["state"]["selected"] = ty
argument["state"][ty] = value
else:
argument["state"] = value
if expurl in self.open_experiments.keys():
self.open_experiments[expurl].argeditor.update_argument(name, argument)
except:
logger.warn("Failed to set value for argument \"{}\" in experiment: {}.".format(name, expurl), exc_info=1)
def get_submission_arguments(self, expurl): def get_submission_arguments(self, expurl):
if expurl in self.submission_arguments: if expurl in self.submission_arguments:
return self.submission_arguments[expurl] return self.submission_arguments[expurl]

View File

@ -192,6 +192,7 @@ def main():
d_applets = applets_ccb.AppletsCCBDock(main_window, d_applets = applets_ccb.AppletsCCBDock(main_window,
sub_clients["datasets"], sub_clients["datasets"],
rpc_clients["dataset_db"], rpc_clients["dataset_db"],
expmgr,
extra_substitutes={ extra_substitutes={
"server": args.server, "server": args.server,
"port_notify": args.port_notify, "port_notify": args.port_notify,

View File

@ -21,10 +21,11 @@ logger = logging.getLogger(__name__)
class AppletIPCServer(AsyncioParentComm): class AppletIPCServer(AsyncioParentComm):
def __init__(self, dataset_sub, dataset_ctl): def __init__(self, dataset_sub, dataset_ctl, expmgr):
AsyncioParentComm.__init__(self) AsyncioParentComm.__init__(self)
self.dataset_sub = dataset_sub self.dataset_sub = dataset_sub
self.dataset_ctl = dataset_ctl self.dataset_ctl = dataset_ctl
self.expmgr = expmgr
self.datasets = set() self.datasets = set()
self.dataset_prefixes = [] self.dataset_prefixes = []
@ -83,6 +84,8 @@ class AppletIPCServer(AsyncioParentComm):
await self.dataset_ctl.set(obj["key"], obj["value"], metadata=obj["metadata"], persist=obj["persist"]) await self.dataset_ctl.set(obj["key"], obj["value"], metadata=obj["metadata"], persist=obj["persist"])
elif action == "update_dataset": elif action == "update_dataset":
await self.dataset_ctl.update(obj["mod"]) await self.dataset_ctl.update(obj["mod"])
elif action == "set_argument_value":
self.expmgr.set_argument_value(obj["expurl"], obj["name"], obj["value"])
else: else:
raise ValueError("unknown action in applet message") raise ValueError("unknown action in applet message")
except: except:
@ -108,7 +111,7 @@ class AppletIPCServer(AsyncioParentComm):
class _AppletDock(QDockWidgetCloseDetect): class _AppletDock(QDockWidgetCloseDetect):
def __init__(self, dataset_sub, dataset_ctl, uid, name, spec, extra_substitutes): def __init__(self, dataset_sub, dataset_ctl, expmgr, uid, name, spec, extra_substitutes):
QDockWidgetCloseDetect.__init__(self, "Applet: " + name) QDockWidgetCloseDetect.__init__(self, "Applet: " + name)
self.setObjectName("applet" + str(uid)) self.setObjectName("applet" + str(uid))
@ -118,6 +121,7 @@ class _AppletDock(QDockWidgetCloseDetect):
self.dataset_sub = dataset_sub self.dataset_sub = dataset_sub
self.dataset_ctl = dataset_ctl self.dataset_ctl = dataset_ctl
self.expmgr = expmgr
self.applet_name = name self.applet_name = name
self.spec = spec self.spec = spec
self.extra_substitutes = extra_substitutes self.extra_substitutes = extra_substitutes
@ -136,7 +140,7 @@ class _AppletDock(QDockWidgetCloseDetect):
return return
self.starting_stopping = True self.starting_stopping = True
try: try:
self.ipc = AppletIPCServer(self.dataset_sub, self.dataset_ctl) self.ipc = AppletIPCServer(self.dataset_sub, self.dataset_ctl, self.expmgr)
env = os.environ.copy() env = os.environ.copy()
env["PYTHONUNBUFFERED"] = "1" env["PYTHONUNBUFFERED"] = "1"
env["ARTIQ_APPLET_EMBED"] = self.ipc.get_address() env["ARTIQ_APPLET_EMBED"] = self.ipc.get_address()
@ -333,7 +337,7 @@ class _CompleterDelegate(QtWidgets.QStyledItemDelegate):
class AppletsDock(QtWidgets.QDockWidget): class AppletsDock(QtWidgets.QDockWidget):
def __init__(self, main_window, dataset_sub, dataset_ctl, extra_substitutes={}, *, loop=None): def __init__(self, main_window, dataset_sub, dataset_ctl, expmgr, extra_substitutes={}, *, loop=None):
""" """
:param extra_substitutes: Map of extra ``${strings}`` to substitute in applet :param extra_substitutes: Map of extra ``${strings}`` to substitute in applet
commands to their respective values. commands to their respective values.
@ -346,6 +350,7 @@ class AppletsDock(QtWidgets.QDockWidget):
self.main_window = main_window self.main_window = main_window
self.dataset_sub = dataset_sub self.dataset_sub = dataset_sub
self.dataset_ctl = dataset_ctl self.dataset_ctl = dataset_ctl
self.expmgr = expmgr
self.extra_substitutes = extra_substitutes self.extra_substitutes = extra_substitutes
self.applet_uids = set() self.applet_uids = set()
@ -448,7 +453,7 @@ class AppletsDock(QtWidgets.QDockWidget):
self.table.itemChanged.connect(self.item_changed) self.table.itemChanged.connect(self.item_changed)
def create(self, item, name, spec): def create(self, item, name, spec):
dock = _AppletDock(self.dataset_sub, self.dataset_ctl, item.applet_uid, name, spec, self.extra_substitutes) dock = _AppletDock(self.dataset_sub, self.dataset_ctl, self.expmgr, item.applet_uid, name, spec, self.extra_substitutes)
self.main_window.addDockWidget(QtCore.Qt.RightDockWidgetArea, dock) self.main_window.addDockWidget(QtCore.Qt.RightDockWidgetArea, dock)
dock.setFloating(True) dock.setFloating(True)
asyncio.ensure_future(dock.start(), loop=self._loop) asyncio.ensure_future(dock.start(), loop=self._loop)