master,gui: support recomputation+reset of arguments

This commit is contained in:
Sebastien Bourdeauducq 2015-12-06 17:27:15 +08:00
parent 1cba685326
commit 8467013160
5 changed files with 71 additions and 20 deletions

View File

@ -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)

View File

@ -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()}

View File

@ -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):

View File

@ -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)

View File

@ -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):