mirror of https://github.com/m-labs/artiq.git
gui: basic scan support
This commit is contained in:
parent
1a0dc499dd
commit
179ca36d09
|
@ -87,17 +87,18 @@ def main():
|
||||||
d_ttl_dds = MonInj()
|
d_ttl_dds = MonInj()
|
||||||
loop.run_until_complete(d_ttl_dds.start(args.server, args.port_notify))
|
loop.run_until_complete(d_ttl_dds.start(args.server, args.port_notify))
|
||||||
atexit.register(lambda: loop.run_until_complete(d_ttl_dds.stop()))
|
atexit.register(lambda: loop.run_until_complete(d_ttl_dds.stop()))
|
||||||
area.addDock(d_ttl_dds.dds_dock, "top")
|
|
||||||
area.addDock(d_ttl_dds.ttl_dock, "above", d_ttl_dds.dds_dock)
|
|
||||||
area.addDock(d_results, "above", d_ttl_dds.ttl_dock)
|
|
||||||
area.addDock(d_explorer, "above", d_results)
|
|
||||||
|
|
||||||
d_params = ParametersDock()
|
d_params = ParametersDock()
|
||||||
area.addDock(d_params, "right", d_explorer)
|
|
||||||
loop.run_until_complete(d_params.sub_connect(
|
loop.run_until_complete(d_params.sub_connect(
|
||||||
args.server, args.port_notify))
|
args.server, args.port_notify))
|
||||||
atexit.register(lambda: loop.run_until_complete(d_params.sub_close()))
|
atexit.register(lambda: loop.run_until_complete(d_params.sub_close()))
|
||||||
|
|
||||||
|
area.addDock(d_ttl_dds.dds_dock, "top")
|
||||||
|
area.addDock(d_ttl_dds.ttl_dock, "above", d_ttl_dds.dds_dock)
|
||||||
|
area.addDock(d_results, "above", d_ttl_dds.ttl_dock)
|
||||||
|
area.addDock(d_params, "above", d_results)
|
||||||
|
area.addDock(d_explorer, "above", d_params)
|
||||||
|
|
||||||
d_schedule = ScheduleDock(schedule_ctl)
|
d_schedule = ScheduleDock(schedule_ctl)
|
||||||
loop.run_until_complete(d_schedule.sub_connect(
|
loop.run_until_complete(d_schedule.sub_connect(
|
||||||
args.server, args.port_notify))
|
args.server, args.port_notify))
|
||||||
|
|
|
@ -8,6 +8,7 @@ from pyqtgraph import LayoutWidget
|
||||||
from artiq.protocols.sync_struct import Subscriber
|
from artiq.protocols.sync_struct import Subscriber
|
||||||
from artiq.protocols import pyon
|
from artiq.protocols import pyon
|
||||||
from artiq.gui.tools import DictSyncModel
|
from artiq.gui.tools import DictSyncModel
|
||||||
|
from artiq.gui.scan import ScanController
|
||||||
|
|
||||||
|
|
||||||
class _ExplistModel(DictSyncModel):
|
class _ExplistModel(DictSyncModel):
|
||||||
|
@ -93,7 +94,8 @@ _procty_to_entry = {
|
||||||
"BooleanValue": _BooleanEntry,
|
"BooleanValue": _BooleanEntry,
|
||||||
"EnumerationValue": _EnumerationEntry,
|
"EnumerationValue": _EnumerationEntry,
|
||||||
"NumberValue": _NumberEntry,
|
"NumberValue": _NumberEntry,
|
||||||
"StringValue": _StringEntry
|
"StringValue": _StringEntry,
|
||||||
|
"Scannable": ScanController
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,137 @@
|
||||||
|
from quamash import QtGui
|
||||||
|
from pyqtgraph import LayoutWidget
|
||||||
|
|
||||||
|
|
||||||
|
class _Range(LayoutWidget):
|
||||||
|
def __init__(self, global_min, global_max, global_step, unit):
|
||||||
|
LayoutWidget.__init__(self)
|
||||||
|
|
||||||
|
def apply_properties(spinbox):
|
||||||
|
if global_min is not None:
|
||||||
|
spinbox.setMinimum(global_min)
|
||||||
|
if global_max is not None:
|
||||||
|
spinbox.setMaximum(global_max)
|
||||||
|
if global_step is not None:
|
||||||
|
spinbox.setSingleStep(global_step)
|
||||||
|
if unit:
|
||||||
|
spinbox.setSuffix(" " + unit)
|
||||||
|
|
||||||
|
self.addWidget(QtGui.QLabel("Min:"), 0, 0)
|
||||||
|
self.min = QtGui.QDoubleSpinBox()
|
||||||
|
apply_properties(self.min)
|
||||||
|
self.addWidget(self.min, 0, 1)
|
||||||
|
|
||||||
|
self.addWidget(QtGui.QLabel("Max:"), 0, 2)
|
||||||
|
self.max = QtGui.QDoubleSpinBox()
|
||||||
|
apply_properties(self.max)
|
||||||
|
self.addWidget(self.max, 0, 3)
|
||||||
|
|
||||||
|
self.addWidget(QtGui.QLabel("#Points:"), 0, 4)
|
||||||
|
self.npoints = QtGui.QSpinBox()
|
||||||
|
self.npoints.setMinimum(2)
|
||||||
|
self.npoints.setValue(10)
|
||||||
|
self.addWidget(self.npoints, 0, 5)
|
||||||
|
|
||||||
|
def set_values(self, min, max, npoints):
|
||||||
|
self.min.setValue(min)
|
||||||
|
self.max.setValue(max)
|
||||||
|
self.npoints.setValue(npoints)
|
||||||
|
|
||||||
|
def get_values(self):
|
||||||
|
return {
|
||||||
|
"min": self.min.value(),
|
||||||
|
"max": self.max.value(),
|
||||||
|
"npoints": self.npoints.value()
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
class ScanController(LayoutWidget):
|
||||||
|
def __init__(self, procdesc):
|
||||||
|
LayoutWidget.__init__(self)
|
||||||
|
|
||||||
|
self.stack = QtGui.QStackedWidget()
|
||||||
|
self.addWidget(self.stack, 1, 0, colspan=4)
|
||||||
|
|
||||||
|
gmin, gmax = procdesc["global_min"], procdesc["global_max"]
|
||||||
|
gstep = procdesc["global_step"]
|
||||||
|
unit = procdesc["unit"]
|
||||||
|
|
||||||
|
self.v_noscan = QtGui.QDoubleSpinBox()
|
||||||
|
if gmin is not None:
|
||||||
|
self.v_noscan.setMinimum(gmin)
|
||||||
|
if gmax is not None:
|
||||||
|
self.v_noscan.setMaximum(gmax)
|
||||||
|
if gstep is not None:
|
||||||
|
self.v_noscan.setSingleStep(gstep)
|
||||||
|
if unit:
|
||||||
|
self.v_noscan.setSuffix(" " + unit)
|
||||||
|
self.v_noscan_gr = LayoutWidget()
|
||||||
|
self.v_noscan_gr.addWidget(QtGui.QLabel("Value:"), 0, 0)
|
||||||
|
self.v_noscan_gr.addWidget(self.v_noscan, 0, 1)
|
||||||
|
self.stack.addWidget(self.v_noscan_gr)
|
||||||
|
|
||||||
|
self.v_linear = _Range(gmin, gmax, gstep, unit)
|
||||||
|
self.stack.addWidget(self.v_linear)
|
||||||
|
|
||||||
|
self.v_random = _Range(gmin, gmax, gstep, unit)
|
||||||
|
self.stack.addWidget(self.v_random)
|
||||||
|
|
||||||
|
self.v_explicit = QtGui.QLineEdit()
|
||||||
|
self.v_explicit_gr = LayoutWidget()
|
||||||
|
self.v_explicit_gr.addWidget(QtGui.QLabel("Sequence:"), 0, 0)
|
||||||
|
self.v_explicit_gr.addWidget(self.v_explicit, 0, 1)
|
||||||
|
self.stack.addWidget(self.v_explicit_gr)
|
||||||
|
|
||||||
|
self.noscan = QtGui.QRadioButton("No scan")
|
||||||
|
self.linear = QtGui.QRadioButton("Linear")
|
||||||
|
self.random = QtGui.QRadioButton("Random")
|
||||||
|
self.explicit = QtGui.QRadioButton("Explicit")
|
||||||
|
radiobuttons = QtGui.QButtonGroup()
|
||||||
|
for n, b in enumerate([self.noscan, self.linear,
|
||||||
|
self.random, self.explicit]):
|
||||||
|
self.addWidget(b, 0, n)
|
||||||
|
radiobuttons.addButton(b)
|
||||||
|
b.toggled.connect(self.select_page)
|
||||||
|
|
||||||
|
if "default" in procdesc:
|
||||||
|
d = procdesc["default"]
|
||||||
|
if d["ty"] == "NoScan":
|
||||||
|
self.noscan.setChecked(True)
|
||||||
|
self.v_noscan.setValue(d["value"])
|
||||||
|
elif d["ty"] == "LinearScan":
|
||||||
|
self.linear.setChecked(True)
|
||||||
|
self.v_linear.set_values(d["min"], d["max"], d["step"])
|
||||||
|
elif d["ty"] == "RandomScan":
|
||||||
|
self.random.setChecked(True)
|
||||||
|
self.v_random.set_values(d["min"], d["max"], d["step"])
|
||||||
|
elif d["ty"] == "ExplicitScan":
|
||||||
|
self.explicit.setChecked(True)
|
||||||
|
self.v_explicit.insert(" ".join(
|
||||||
|
[str(x) for x in d["sequence"]]))
|
||||||
|
else:
|
||||||
|
self.noscan.setChecked(True)
|
||||||
|
|
||||||
|
def select_page(self):
|
||||||
|
if self.noscan.isChecked():
|
||||||
|
self.stack.setCurrentWidget(self.v_noscan_gr)
|
||||||
|
elif self.linear.isChecked():
|
||||||
|
self.stack.setCurrentWidget(self.v_linear)
|
||||||
|
elif self.random.isChecked():
|
||||||
|
self.stack.setCurrentWidget(self.v_random)
|
||||||
|
elif self.explicit.isChecked():
|
||||||
|
self.stack.setCurrentWidget(self.v_explicit_gr)
|
||||||
|
|
||||||
|
def get_argument_value(self):
|
||||||
|
if self.noscan.isChecked():
|
||||||
|
return {"ty": "NoScan", "value": self.v_noscan.value()}
|
||||||
|
elif self.linear.isChecked():
|
||||||
|
d = {"ty": "LinearScan"}
|
||||||
|
d.update(self.v_linear.get_values())
|
||||||
|
return d
|
||||||
|
elif self.random.isChecked():
|
||||||
|
d = {"ty": "RandomScan"}
|
||||||
|
d.update(self.v_random.get_values())
|
||||||
|
return d
|
||||||
|
elif self.explicit.isChecked():
|
||||||
|
sequence = [float(x) for x in self.v_explicit.text().split()]
|
||||||
|
return {"ty": "ExplicitScan", "sequence": sequence}
|
|
@ -60,7 +60,6 @@ class RandomScan:
|
||||||
"min": self.min, "max": self.max, "npoints": self.npoints}
|
"min": self.min, "max": self.max, "npoints": self.npoints}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class ExplicitScan:
|
class ExplicitScan:
|
||||||
def __init__(self, sequence):
|
def __init__(self, sequence):
|
||||||
self.sequence = sequence
|
self.sequence = sequence
|
||||||
|
@ -109,7 +108,7 @@ class Scannable:
|
||||||
d["global_min"] = self.global_min
|
d["global_min"] = self.global_min
|
||||||
d["global_max"] = self.global_max
|
d["global_max"] = self.global_max
|
||||||
d["global_step"] = self.global_step
|
d["global_step"] = self.global_step
|
||||||
d["unit"]= self.unit
|
d["unit"] = self.unit
|
||||||
if hasattr(self, "default_value"):
|
if hasattr(self, "default_value"):
|
||||||
d["default"] = self.default_value.describe()
|
d["default"] = self.default_value.describe()
|
||||||
return d
|
return d
|
||||||
|
|
|
@ -9,6 +9,7 @@ class ArgumentsDemo(EnvExperiment):
|
||||||
["foo", "bar", "quux"], "foo"))
|
["foo", "bar", "quux"], "foo"))
|
||||||
self.attr_argument("number", NumberValue(42, unit="s", step=0.1))
|
self.attr_argument("number", NumberValue(42, unit="s", step=0.1))
|
||||||
self.attr_argument("string", StringValue("Hello World"))
|
self.attr_argument("string", StringValue("Hello World"))
|
||||||
|
self.attr_argument("scan", Scannable(global_max=400, default=NoScan(325)))
|
||||||
|
|
||||||
def run(self):
|
def run(self):
|
||||||
print(self.free_value)
|
print(self.free_value)
|
||||||
|
@ -16,3 +17,5 @@ class ArgumentsDemo(EnvExperiment):
|
||||||
print(self.enum)
|
print(self.enum)
|
||||||
print(self.number)
|
print(self.number)
|
||||||
print(self.string)
|
print(self.string)
|
||||||
|
for i in self.scan:
|
||||||
|
print(i)
|
||||||
|
|
Loading…
Reference in New Issue