From 43081b4f64b2dae004b133077cd68b9c72aaff48 Mon Sep 17 00:00:00 2001 From: Sebastien Bourdeauducq Date: Mon, 23 May 2016 15:02:28 -0700 Subject: [PATCH] language,gui: support setting unselected scan default values. Closes #417 --- .../master/repository/arguments_demo.py | 7 +++-- artiq/gui/entries.py | 28 +++++++++---------- artiq/language/scan.py | 20 +++++++++---- 3 files changed, 32 insertions(+), 23 deletions(-) diff --git a/artiq/examples/master/repository/arguments_demo.py b/artiq/examples/master/repository/arguments_demo.py index 52dcb7c42..e561349ba 100644 --- a/artiq/examples/master/repository/arguments_demo.py +++ b/artiq/examples/master/repository/arguments_demo.py @@ -5,9 +5,10 @@ from artiq.experiment import * class SubComponent1(HasEnvironment): def build(self): - self.setattr_argument("sc1_scan", Scannable(default=NoScan(3250), - scale=1e3, unit="kHz"), - "Flux capacitor") + self.setattr_argument("sc1_scan", + Scannable(default=[NoScan(3250), RandomScan(10, 20, 6)], + scale=1e3, unit="kHz"), + "Flux capacitor") self.setattr_argument("sc1_enum", EnumerationValue(["1", "2", "3"]), "Flux capacitor") diff --git a/artiq/gui/entries.py b/artiq/gui/entries.py index 70b1026a6..900023ee4 100644 --- a/artiq/gui/entries.py +++ b/artiq/gui/entries.py @@ -273,20 +273,20 @@ class _ScanEntry(LayoutWidget): "ExplicitScan": {"sequence": []} } if "default" in procdesc: - default = procdesc["default"] - ty = default["ty"] - state["selected"] = ty - if ty == "NoScan": - state["NoScan"]["value"] = default["value"] - elif ty == "LinearScan" or ty == "RandomScan": - for d in state["LinearScan"], state["RandomScan"]: - d["start"] = default["start"] - d["stop"] = default["stop"] - d["npoints"] = default["npoints"] - elif ty == "ExplicitScan": - state["ExplicitScan"]["sequence"] = default["sequence"] - else: - logger.warning("unknown default type: %s", ty) + defaults = procdesc["default"] + state["selected"] = defaults[0]["ty"] + for default in defaults: + ty = default["ty"] + if ty == "NoScan": + state[ty]["value"] = default["value"] + elif ty == "LinearScan" or ty == "RandomScan": + state[ty]["start"] = default["start"] + state[ty]["stop"] = default["stop"] + state[ty]["npoints"] = default["npoints"] + elif ty == "ExplicitScan": + state[ty]["sequence"] = default["sequence"] + else: + logger.warning("unknown default type: %s", ty) return state def _scan_type_toggled(self): diff --git a/artiq/language/scan.py b/artiq/language/scan.py index 7ead27f62..c7f6c6a9b 100644 --- a/artiq/language/scan.py +++ b/artiq/language/scan.py @@ -93,6 +93,7 @@ class RandomScan(ScanObject): self.start = start self.stop = stop self.npoints = npoints + self.seed = seed self.sequence = list(LinearScan(start, stop, npoints)) if seed is None: rf = random.random @@ -110,7 +111,8 @@ class RandomScan(ScanObject): def describe(self): return {"ty": "RandomScan", "start": self.start, "stop": self.stop, - "npoints": self.npoints} + "npoints": self.npoints, + "seed": self.seed} class ExplicitScan(ScanObject): @@ -141,6 +143,10 @@ class Scannable: """An argument (as defined in :class:`artiq.language.environment`) that 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 to all scan modes. The user interface takes this value to set the range of its input widgets. @@ -160,7 +166,9 @@ class Scannable: if global_step is None: global_step = scale/10.0 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.scale = scale self.global_step = global_step @@ -169,9 +177,9 @@ class Scannable: self.ndecimals = ndecimals def default(self): - if not hasattr(self, "default_value"): + if not hasattr(self, "default_values"): raise DefaultMissing - return self.default_value + return self.default_values[0] def process(self, x): cls = _ty_to_scan[x["ty"]] @@ -183,8 +191,8 @@ class Scannable: def describe(self): d = {"ty": "Scannable"} - if hasattr(self, "default_value"): - d["default"] = self.default_value.describe() + if hasattr(self, "default_values"): + d["default"] = [d.describe() for d in self.default_values] d["unit"] = self.unit d["scale"] = self.scale d["global_step"] = self.global_step