language,gui: support setting unselected scan default values. Closes #417

This commit is contained in:
Sebastien Bourdeauducq 2016-05-23 15:02:28 -07:00
parent 69ffa21133
commit 43081b4f64
3 changed files with 32 additions and 23 deletions

View File

@ -5,9 +5,10 @@ from artiq.experiment import *
class SubComponent1(HasEnvironment): class SubComponent1(HasEnvironment):
def build(self): def build(self):
self.setattr_argument("sc1_scan", Scannable(default=NoScan(3250), self.setattr_argument("sc1_scan",
scale=1e3, unit="kHz"), Scannable(default=[NoScan(3250), RandomScan(10, 20, 6)],
"Flux capacitor") scale=1e3, unit="kHz"),
"Flux capacitor")
self.setattr_argument("sc1_enum", EnumerationValue(["1", "2", "3"]), self.setattr_argument("sc1_enum", EnumerationValue(["1", "2", "3"]),
"Flux capacitor") "Flux capacitor")

View File

@ -273,20 +273,20 @@ class _ScanEntry(LayoutWidget):
"ExplicitScan": {"sequence": []} "ExplicitScan": {"sequence": []}
} }
if "default" in procdesc: if "default" in procdesc:
default = procdesc["default"] defaults = procdesc["default"]
ty = default["ty"] state["selected"] = defaults[0]["ty"]
state["selected"] = ty for default in defaults:
if ty == "NoScan": ty = default["ty"]
state["NoScan"]["value"] = default["value"] if ty == "NoScan":
elif ty == "LinearScan" or ty == "RandomScan": state[ty]["value"] = default["value"]
for d in state["LinearScan"], state["RandomScan"]: elif ty == "LinearScan" or ty == "RandomScan":
d["start"] = default["start"] state[ty]["start"] = default["start"]
d["stop"] = default["stop"] state[ty]["stop"] = default["stop"]
d["npoints"] = default["npoints"] state[ty]["npoints"] = default["npoints"]
elif ty == "ExplicitScan": elif ty == "ExplicitScan":
state["ExplicitScan"]["sequence"] = default["sequence"] state[ty]["sequence"] = default["sequence"]
else: else:
logger.warning("unknown default type: %s", ty) logger.warning("unknown default type: %s", ty)
return state return state
def _scan_type_toggled(self): def _scan_type_toggled(self):

View File

@ -93,6 +93,7 @@ class RandomScan(ScanObject):
self.start = start self.start = start
self.stop = stop self.stop = stop
self.npoints = npoints self.npoints = npoints
self.seed = seed
self.sequence = list(LinearScan(start, stop, npoints)) self.sequence = list(LinearScan(start, stop, npoints))
if seed is None: if seed is None:
rf = random.random rf = random.random
@ -110,7 +111,8 @@ class RandomScan(ScanObject):
def describe(self): def describe(self):
return {"ty": "RandomScan", return {"ty": "RandomScan",
"start": self.start, "stop": self.stop, "start": self.start, "stop": self.stop,
"npoints": self.npoints} "npoints": self.npoints,
"seed": self.seed}
class ExplicitScan(ScanObject): class ExplicitScan(ScanObject):
@ -141,6 +143,10 @@ class Scannable:
"""An argument (as defined in :class:`artiq.language.environment`) that """An argument (as defined in :class:`artiq.language.environment`) that
takes a scan object. takes a scan object.
:param default: The default scan object. This parameter can be a list of
scan objects, in which case the first one is used as default and the
others are used to configure the default values of scan types that are
not initially selected in the GUI.
:param global_min: The minimum value taken by the scanned variable, common :param global_min: The minimum value taken by the scanned variable, common
to all scan modes. The user interface takes this value to set the to all scan modes. The user interface takes this value to set the
range of its input widgets. range of its input widgets.
@ -160,7 +166,9 @@ class Scannable:
if global_step is None: if global_step is None:
global_step = scale/10.0 global_step = scale/10.0
if default is not NoDefault: if default is not NoDefault:
self.default_value = default if not isinstance(default, (tuple, list)):
default = [default]
self.default_values = default
self.unit = unit self.unit = unit
self.scale = scale self.scale = scale
self.global_step = global_step self.global_step = global_step
@ -169,9 +177,9 @@ class Scannable:
self.ndecimals = ndecimals self.ndecimals = ndecimals
def default(self): def default(self):
if not hasattr(self, "default_value"): if not hasattr(self, "default_values"):
raise DefaultMissing raise DefaultMissing
return self.default_value return self.default_values[0]
def process(self, x): def process(self, x):
cls = _ty_to_scan[x["ty"]] cls = _ty_to_scan[x["ty"]]
@ -183,8 +191,8 @@ class Scannable:
def describe(self): def describe(self):
d = {"ty": "Scannable"} d = {"ty": "Scannable"}
if hasattr(self, "default_value"): if hasattr(self, "default_values"):
d["default"] = self.default_value.describe() d["default"] = [d.describe() for d in self.default_values]
d["unit"] = self.unit d["unit"] = self.unit
d["scale"] = self.scale d["scale"] = self.scale
d["global_step"] = self.global_step d["global_step"] = self.global_step