mirror of https://github.com/m-labs/artiq.git
master,gui: support recomputation+reset of arguments
This commit is contained in:
parent
1cba685326
commit
8467013160
|
@ -98,7 +98,8 @@ def main():
|
|||
expmgr = experiments.ExperimentManager(status_bar, dock_area,
|
||||
sub_clients["explist"],
|
||||
sub_clients["schedule"],
|
||||
rpc_clients["schedule"])
|
||||
rpc_clients["schedule"],
|
||||
rpc_clients["repository"])
|
||||
smgr.register(expmgr)
|
||||
d_shortcuts = shortcuts.ShortcutsDock(win, expmgr)
|
||||
smgr.register(d_shortcuts)
|
||||
|
|
|
@ -119,7 +119,10 @@ _argty_to_entry = {
|
|||
|
||||
|
||||
class _ArgumentEditor(QtGui.QTreeWidget):
|
||||
def __init__(self, arguments):
|
||||
def __init__(self, manager, expname):
|
||||
self.manager = manager
|
||||
self.expname = expname
|
||||
|
||||
QtGui.QTreeWidget.__init__(self)
|
||||
self.setColumnCount(3)
|
||||
self.header().setStretchLastSection(False)
|
||||
|
@ -132,16 +135,18 @@ class _ArgumentEditor(QtGui.QTreeWidget):
|
|||
self.setVerticalScrollMode(QtGui.QAbstractItemView.ScrollPerPixel)
|
||||
|
||||
self._groups = dict()
|
||||
self._args_to_entries = dict()
|
||||
self._arg_to_entry_widgetitem = dict()
|
||||
|
||||
arguments = self.manager.get_submission_arguments(self.expname)
|
||||
|
||||
if not arguments:
|
||||
self.addTopLevelItem(QtGui.QTreeWidgetItem(["No arguments"]))
|
||||
|
||||
for n, (name, argument) in enumerate(arguments.items()):
|
||||
entry = _argty_to_entry[argument["desc"]["ty"]](argument)
|
||||
self._args_to_entries[name] = entry
|
||||
|
||||
widget_item = QtGui.QTreeWidgetItem([name])
|
||||
self._arg_to_entry_widgetitem[name] = entry, widget_item
|
||||
|
||||
if argument["group"] is None:
|
||||
self.addTopLevelItem(widget_item)
|
||||
else:
|
||||
|
@ -172,8 +177,28 @@ class _ArgumentEditor(QtGui.QTreeWidget):
|
|||
self._groups[name] = group
|
||||
return group
|
||||
|
||||
def _recompute_argument(self, argument):
|
||||
logger.warning("recompute_argument not implemented (%s)", argument)
|
||||
def _recompute_argument(self, name):
|
||||
asyncio.ensure_future(self._recompute_argument_task(name))
|
||||
|
||||
async def _recompute_argument_task(self, name):
|
||||
try:
|
||||
arginfo = await self.manager.recompute_arginfo(self.expname)
|
||||
except:
|
||||
logger.warning("Could not recompute argument '%s' of '%s'",
|
||||
name, self.expname, exc_info=True)
|
||||
argument = self.manager.get_submission_arguments(self.expname)[name]
|
||||
|
||||
procdesc = arginfo[name][0]
|
||||
state = _argty_to_entry[procdesc["ty"]].default_state(procdesc)
|
||||
argument["desc"] = procdesc
|
||||
argument["state"] = state
|
||||
|
||||
old_entry, widget_item = self._arg_to_entry_widgetitem[name]
|
||||
old_entry.deleteLater()
|
||||
|
||||
entry = _argty_to_entry[procdesc["ty"]](argument)
|
||||
self._arg_to_entry_widgetitem[name] = entry, widget_item
|
||||
self.setItemWidget(widget_item, 1, entry)
|
||||
|
||||
def save_state(self):
|
||||
expanded = []
|
||||
|
@ -200,8 +225,7 @@ class _ExperimentDock(dockarea.Dock):
|
|||
self.manager = manager
|
||||
self.expname = expname
|
||||
|
||||
self.argeditor = _ArgumentEditor(
|
||||
manager.get_submission_arguments(expname))
|
||||
self.argeditor = _ArgumentEditor(manager, expname)
|
||||
self.addWidget(self.argeditor, 0, 0, colspan=5)
|
||||
self.layout.setRowStretch(0, 1)
|
||||
|
||||
|
@ -342,10 +366,11 @@ class _ExperimentDock(dockarea.Dock):
|
|||
class ExperimentManager:
|
||||
def __init__(self, status_bar, dock_area,
|
||||
explist_sub, schedule_sub,
|
||||
schedule_ctl):
|
||||
schedule_ctl, repository_ctl):
|
||||
self.status_bar = status_bar
|
||||
self.dock_area = dock_area
|
||||
self.schedule_ctl = schedule_ctl
|
||||
self.repository_ctl = repository_ctl
|
||||
|
||||
self.submission_scheduling = dict()
|
||||
self.submission_options = dict()
|
||||
|
@ -395,8 +420,8 @@ class ExperimentManager:
|
|||
return self.submission_arguments[expname]
|
||||
else:
|
||||
arguments = OrderedDict()
|
||||
arginfo = self.explist[expname]["arguments"]
|
||||
for name, (procdesc, group) in arginfo:
|
||||
arginfo = self.explist[expname]["arginfo"]
|
||||
for name, (procdesc, group) in arginfo.items():
|
||||
state = _argty_to_entry[procdesc["ty"]].default_state(procdesc)
|
||||
arguments[name] = {
|
||||
"desc": procdesc,
|
||||
|
@ -470,6 +495,11 @@ class ExperimentManager:
|
|||
rids.append(rid)
|
||||
asyncio.ensure_future(self._request_term_multiple(rids))
|
||||
|
||||
async def recompute_arginfo(self, expname):
|
||||
expinfo = self.explist[expname]
|
||||
description = await self.repository_ctl.examine(expinfo["file"])
|
||||
return description[expinfo["class_name"]]["arginfo"]
|
||||
|
||||
def save_state(self):
|
||||
docks = {expname: dock.save_state()
|
||||
for expname, dock in self.open_experiments.items()}
|
||||
|
|
|
@ -3,6 +3,7 @@ import os
|
|||
import tempfile
|
||||
import shutil
|
||||
import logging
|
||||
from functools import partial
|
||||
|
||||
from artiq.protocols.sync_struct import Notifier
|
||||
from artiq.master.worker import Worker
|
||||
|
@ -16,7 +17,7 @@ async def _get_repository_entries(entry_dict,
|
|||
root, filename, get_device_db, log):
|
||||
worker = Worker({
|
||||
"get_device_db": get_device_db,
|
||||
"log": lambda message: log("scan", message)
|
||||
"log": partial(log, "scan")
|
||||
})
|
||||
try:
|
||||
description = await worker.examine(os.path.join(root, filename))
|
||||
|
@ -24,7 +25,7 @@ async def _get_repository_entries(entry_dict,
|
|||
await worker.close()
|
||||
for class_name, class_desc in description.items():
|
||||
name = class_desc["name"]
|
||||
arguments = class_desc["arguments"]
|
||||
arginfo = class_desc["arginfo"]
|
||||
if "/" in name:
|
||||
logger.warning("Character '/' is not allowed in experiment "
|
||||
"name (%s)", name)
|
||||
|
@ -39,7 +40,7 @@ async def _get_repository_entries(entry_dict,
|
|||
entry = {
|
||||
"file": filename,
|
||||
"class_name": class_name,
|
||||
"arguments": arguments
|
||||
"arginfo": arginfo
|
||||
}
|
||||
entry_dict[name] = entry
|
||||
|
||||
|
@ -110,6 +111,23 @@ class Repository:
|
|||
def scan_async(self, new_cur_rev=None):
|
||||
asyncio.ensure_future(exc_to_warning(self.scan(new_cur_rev)))
|
||||
|
||||
async def examine(self, filename, use_repository=True):
|
||||
if use_repository:
|
||||
revision = self.cur_rev
|
||||
wd, _ = self.backend.request_rev(revision)
|
||||
filename = os.path.join(wd, filename)
|
||||
worker = Worker({
|
||||
"get_device_db": self.get_device_db_fn,
|
||||
"log": partial(self.log_fn, "examine")
|
||||
})
|
||||
try:
|
||||
description = await worker.examine(filename)
|
||||
finally:
|
||||
await worker.close()
|
||||
if use_repository:
|
||||
self.backend.release_rev(revision)
|
||||
return description
|
||||
|
||||
|
||||
class FilesystemBackend:
|
||||
def __init__(self, root):
|
||||
|
|
|
@ -248,8 +248,8 @@ class Worker:
|
|||
async def examine(self, file, timeout=20.0):
|
||||
await self._create_process(logging.WARNING)
|
||||
r = dict()
|
||||
def register(class_name, name, arguments):
|
||||
r[class_name] = {"name": name, "arguments": arguments}
|
||||
def register(class_name, name, arginfo):
|
||||
r[class_name] = {"name": name, "arginfo": arginfo}
|
||||
self.register_experiment = register
|
||||
await self._worker_action({"action": "examine", "file": file},
|
||||
timeout)
|
||||
|
|
|
@ -2,6 +2,7 @@ import sys
|
|||
import time
|
||||
import os
|
||||
import logging
|
||||
from collections import OrderedDict
|
||||
|
||||
from artiq.protocols import pyon
|
||||
from artiq.tools import file_import
|
||||
|
@ -153,9 +154,10 @@ def examine(device_mgr, dataset_mgr, file):
|
|||
if name[-1] == ".":
|
||||
name = name[:-1]
|
||||
exp_inst = exp_class(device_mgr, dataset_mgr, default_arg_none=True)
|
||||
arguments = [(k, (proc.describe(), group))
|
||||
for k, (proc, group) in exp_inst.requested_args.items()]
|
||||
register_experiment(class_name, name, arguments)
|
||||
arginfo = OrderedDict(
|
||||
(k, (proc.describe(), group))
|
||||
for k, (proc, group) in exp_inst.requested_args.items())
|
||||
register_experiment(class_name, name, arginfo)
|
||||
|
||||
|
||||
def string_to_hdf5(f, key, value):
|
||||
|
|
Loading…
Reference in New Issue