Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: m-labs/artiq
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: 6a972eb59132
Choose a base ref
...
head repository: m-labs/artiq
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: 38cdeb0a32c3
Choose a head ref
  • 2 commits
  • 4 files changed
  • 1 contributor

Commits on Jan 10, 2016

  1. Copy the full SHA
    e2c7578 View commit details
  2. Copy the full SHA
    38cdeb0 View commit details
Showing with 138 additions and 120 deletions.
  1. +1 −1 artiq/applets/big_number.py
  2. +19 −2 artiq/applets/simple.py
  3. +111 −6 artiq/gui/{scan.py → entries.py}
  4. +7 −111 artiq/gui/experiments.py
2 changes: 1 addition & 1 deletion artiq/applets/big_number.py
Original file line number Diff line number Diff line change
@@ -11,7 +11,7 @@ def __init__(self, args):
self.setDigitCount(args.digit_count)
self.dataset_name = args.dataset

def data_changed(self, data, mod):
def data_changed(self, data, mods):
try:
n = float(data[self.dataset_name][1])
except (KeyError, ValueError, TypeError):
21 changes: 19 additions & 2 deletions artiq/applets/simple.py
Original file line number Diff line number Diff line change
@@ -8,10 +8,15 @@


class SimpleApplet:
def __init__(self, main_widget_class, cmd_description=None):
def __init__(self, main_widget_class, cmd_description=None,
default_update_delay=0.0):
self.main_widget_class = main_widget_class

self.argparser = argparse.ArgumentParser(description=cmd_description)
self.argparser.add_argument("--update-delay", type=float,
default=default_update_delay,
help="time to wait after a mod (buffering other mods) "
"before updating (default: %(default).2f)")
group = self.argparser.add_argument_group("data server")
group.add_argument(
"--server-notify", default="::1",
@@ -71,8 +76,20 @@ def sub_init(self, data):
self.data = data
return data

def flush_mod_buffer(self):
self.main_widget.data_changed(self.data, self.mod_buffer)
del self.mod_buffer

def sub_mod(self, mod):
self.main_widget.data_changed(self.data, mod)
if self.args.update_delay:
if hasattr(self, "mod_buffer"):
self.mod_buffer.append(mod)
else:
self.mod_buffer = [mod]
asyncio.get_event_loop().call_later(self.args.update_delay,
self.flush_mod_buffer)
else:
self.main_widget.data_changed(self.data, [mod])

def create_subscriber(self):
self.subscriber = Subscriber("datasets",
117 changes: 111 additions & 6 deletions artiq/gui/scan.py → artiq/gui/entries.py
Original file line number Diff line number Diff line change
@@ -10,6 +10,100 @@
logger = logging.getLogger(__name__)


class _StringEntry(QtGui.QLineEdit):
def __init__(self, argument):
QtGui.QLineEdit.__init__(self)
self.setText(argument["state"])
def update(text):
argument["state"] = text
self.textEdited.connect(update)

@staticmethod
def state_to_value(state):
return state

@staticmethod
def default_state(procdesc):
return procdesc.get("default", "")


class _BooleanEntry(QtGui.QCheckBox):
def __init__(self, argument):
QtGui.QCheckBox.__init__(self)
self.setChecked(argument["state"])
def update(checked):
argument["state"] = bool(checked)
self.stateChanged.connect(update)

@staticmethod
def state_to_value(state):
return state

@staticmethod
def default_state(procdesc):
return procdesc.get("default", False)


class _EnumerationEntry(QtGui.QComboBox):
def __init__(self, argument):
QtGui.QComboBox.__init__(self)
disable_scroll_wheel(self)
choices = argument["desc"]["choices"]
self.addItems(choices)
idx = choices.index(argument["state"])
self.setCurrentIndex(idx)
def update(index):
argument["state"] = choices[index]
self.currentIndexChanged.connect(update)

@staticmethod
def state_to_value(state):
return state

@staticmethod
def default_state(procdesc):
if "default" in procdesc:
return procdesc["default"]
else:
return procdesc["choices"][0]


class _NumberEntry(QtGui.QDoubleSpinBox):
def __init__(self, argument):
QtGui.QDoubleSpinBox.__init__(self)
disable_scroll_wheel(self)
procdesc = argument["desc"]
scale = procdesc["scale"]
self.setDecimals(procdesc["ndecimals"])
self.setSingleStep(procdesc["step"]/scale)
if procdesc["min"] is not None:
self.setMinimum(procdesc["min"]/scale)
else:
self.setMinimum(float("-inf"))
if procdesc["max"] is not None:
self.setMaximum(procdesc["max"]/scale)
else:
self.setMaximum(float("inf"))
if procdesc["unit"]:
self.setSuffix(" " + procdesc["unit"])

self.setValue(argument["state"]/scale)
def update(value):
argument["state"] = value*scale
self.valueChanged.connect(update)

@staticmethod
def state_to_value(state):
return state

@staticmethod
def default_state(procdesc):
if "default" in procdesc:
return procdesc["default"]
else:
return 0.0


class _NoScan(LayoutWidget):
def __init__(self, procdesc, state):
LayoutWidget.__init__(self)
@@ -38,7 +132,7 @@ def update(value):
self.value.valueChanged.connect(update)


class _Range(LayoutWidget):
class _RangeScan(LayoutWidget):
def __init__(self, procdesc, state):
LayoutWidget.__init__(self)

@@ -90,7 +184,8 @@ def update_npoints(value):
self.max.valueChanged.connect(update_max)
self.npoints.valueChanged.connect(update_npoints)

class _Explicit(LayoutWidget):

class _ExplicitScan(LayoutWidget):
def __init__(self, state):
LayoutWidget.__init__(self)

@@ -109,7 +204,7 @@ def update(text):
self.value.textEdited.connect(update)


class ScanController(LayoutWidget):
class _ScanEntry(LayoutWidget):
def __init__(self, argument):
LayoutWidget.__init__(self)
self.argument = argument
@@ -121,9 +216,9 @@ def __init__(self, argument):
state = argument["state"]
self.widgets = OrderedDict()
self.widgets["NoScan"] = _NoScan(procdesc, state["NoScan"])
self.widgets["LinearScan"] = _Range(procdesc, state["LinearScan"])
self.widgets["RandomScan"] = _Range(procdesc, state["RandomScan"])
self.widgets["ExplicitScan"] = _Explicit(state["ExplicitScan"])
self.widgets["LinearScan"] = _RangeScan(procdesc, state["LinearScan"])
self.widgets["RandomScan"] = _RangeScan(procdesc, state["RandomScan"])
self.widgets["ExplicitScan"] = _ExplicitScan(state["ExplicitScan"])
for widget in self.widgets.values():
self.stack.addWidget(widget)

@@ -181,3 +276,13 @@ def _scan_type_toggled(self):
self.stack.setCurrentWidget(self.widgets[ty])
self.argument["state"]["selected"] = ty
break


argty_to_entry = {
"PYONValue": _StringEntry,
"BooleanValue": _BooleanEntry,
"EnumerationValue": _EnumerationEntry,
"NumberValue": _NumberEntry,
"StringValue": _StringEntry,
"Scannable": _ScanEntry
}
118 changes: 7 additions & 111 deletions artiq/gui/experiments.py
Original file line number Diff line number Diff line change
@@ -7,117 +7,13 @@

from pyqtgraph import dockarea, LayoutWidget

from artiq.gui.tools import log_level_to_name, disable_scroll_wheel
from artiq.gui.scan import ScanController
from artiq.gui.tools import log_level_to_name
from artiq.gui.entries import argty_to_entry


logger = logging.getLogger(__name__)


class _StringEntry(QtGui.QLineEdit):
def __init__(self, argument):
QtGui.QLineEdit.__init__(self)
self.setText(argument["state"])
def update(text):
argument["state"] = text
self.textEdited.connect(update)

@staticmethod
def state_to_value(state):
return state

@staticmethod
def default_state(procdesc):
return procdesc.get("default", "")


class _BooleanEntry(QtGui.QCheckBox):
def __init__(self, argument):
QtGui.QCheckBox.__init__(self)
self.setChecked(argument["state"])
def update(checked):
argument["state"] = bool(checked)
self.stateChanged.connect(update)

@staticmethod
def state_to_value(state):
return state

@staticmethod
def default_state(procdesc):
return procdesc.get("default", False)


class _EnumerationEntry(QtGui.QComboBox):
def __init__(self, argument):
QtGui.QComboBox.__init__(self)
disable_scroll_wheel(self)
choices = argument["desc"]["choices"]
self.addItems(choices)
idx = choices.index(argument["state"])
self.setCurrentIndex(idx)
def update(index):
argument["state"] = choices[index]
self.currentIndexChanged.connect(update)

@staticmethod
def state_to_value(state):
return state

@staticmethod
def default_state(procdesc):
if "default" in procdesc:
return procdesc["default"]
else:
return procdesc["choices"][0]


class _NumberEntry(QtGui.QDoubleSpinBox):
def __init__(self, argument):
QtGui.QDoubleSpinBox.__init__(self)
disable_scroll_wheel(self)
procdesc = argument["desc"]
scale = procdesc["scale"]
self.setDecimals(procdesc["ndecimals"])
self.setSingleStep(procdesc["step"]/scale)
if procdesc["min"] is not None:
self.setMinimum(procdesc["min"]/scale)
else:
self.setMinimum(float("-inf"))
if procdesc["max"] is not None:
self.setMaximum(procdesc["max"]/scale)
else:
self.setMaximum(float("inf"))
if procdesc["unit"]:
self.setSuffix(" " + procdesc["unit"])

self.setValue(argument["state"]/scale)
def update(value):
argument["state"] = value*scale
self.valueChanged.connect(update)

@staticmethod
def state_to_value(state):
return state

@staticmethod
def default_state(procdesc):
if "default" in procdesc:
return procdesc["default"]
else:
return 0.0


_argty_to_entry = {
"PYONValue": _StringEntry,
"BooleanValue": _BooleanEntry,
"EnumerationValue": _EnumerationEntry,
"NumberValue": _NumberEntry,
"StringValue": _StringEntry,
"Scannable": ScanController
}


# Experiment URLs come in two forms:
# 1. repo:<experiment name>
# (file name and class name to be retrieved from explist)
@@ -153,7 +49,7 @@ def __init__(self, manager, dock, expurl):
self.addTopLevelItem(QtGui.QTreeWidgetItem(["No arguments"]))

for name, argument in arguments.items():
entry = _argty_to_entry[argument["desc"]["ty"]](argument)
entry = argty_to_entry[argument["desc"]["ty"]](argument)
widget_item = QtGui.QTreeWidgetItem([name])
self._arg_to_entry_widgetitem[name] = entry, widget_item

@@ -211,14 +107,14 @@ async def _recompute_argument(self, name):
argument = self.manager.get_submission_arguments(self.expurl)[name]

procdesc = arginfo[name][0]
state = _argty_to_entry[procdesc["ty"]].default_state(procdesc)
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)
entry = argty_to_entry[procdesc["ty"]](argument)
self._arg_to_entry_widgetitem[name] = entry, widget_item
self.setItemWidget(widget_item, 1, entry)

@@ -466,7 +362,7 @@ def get_submission_options(self, expurl):
def initialize_submission_arguments(self, expurl, arginfo):
arguments = OrderedDict()
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] = {
"desc": procdesc,
"group": group,
@@ -510,7 +406,7 @@ def submit(self, expurl):

argument_values = dict()
for name, argument in arguments.items():
entry_cls = _argty_to_entry[argument["desc"]["ty"]]
entry_cls = argty_to_entry[argument["desc"]["ty"]]
argument_values[name] = entry_cls.state_to_value(argument["state"])

expid = {