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