From bb05ed268e546e24d021dab689145182b3677f8d Mon Sep 17 00:00:00 2001 From: Sebastien Bourdeauducq Date: Sun, 19 Jul 2015 16:38:33 +0200 Subject: [PATCH] language/scan: add argument processor --- artiq/language/__init__.py | 4 +- artiq/language/scan.py | 75 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 78 insertions(+), 1 deletion(-) diff --git a/artiq/language/__init__.py b/artiq/language/__init__.py index 7dfe5dba0..6497cda47 100644 --- a/artiq/language/__init__.py +++ b/artiq/language/__init__.py @@ -1,10 +1,12 @@ -from artiq.language import core, environment, units +from artiq.language import core, environment, units, scan from artiq.language.core import * from artiq.language.environment import * from artiq.language.units import * +from artiq.language.scan import * __all__ = [] __all__.extend(core.__all__) __all__.extend(environment.__all__) __all__.extend(units.__all__) +__all__.extend(scan.__all__) diff --git a/artiq/language/scan.py b/artiq/language/scan.py index 522321a16..c1a0182f8 100644 --- a/artiq/language/scan.py +++ b/artiq/language/scan.py @@ -1,6 +1,27 @@ from random import Random, shuffle +import inspect from artiq.language.core import * +from artiq.language.environment import NoDefault, DefaultMissing + + +__all__ = ["NoScan", "LinearScan", "RandomScan", "ExplicitScan", "Scannable"] + + +class NoScan: + def __init__(self, value): + self.value = value + + @portable + def _gen(self): + yield self.value + + @portable + def __iter__(self): + return self._gen() + + def describe(self): + return {"ty": "NoScan", "value": self.value} class LinearScan: @@ -20,6 +41,10 @@ class LinearScan: def __iter__(self): return self._gen() + def describe(self): + return {"ty": "LinearScan", + "min": self.min, "max": self.max, "npoints": self.npoints} + class RandomScan: def __init__(self, min, max, npoints, seed=0): @@ -30,6 +55,11 @@ class RandomScan: def __iter__(self): return iter(self.sequence) + def describe(self): + return {"ty": "RandomScan", + "min": self.min, "max": self.max, "npoints": self.npoints} + + class ExplicitScan: def __init__(self, sequence): @@ -38,3 +68,48 @@ class ExplicitScan: @portable def __iter__(self): return iter(self.sequence) + + def describe(self): + return {"ty": "ExplicitScan", "sequence": self.sequence} + + +_ty_to_scan = { + "NoScan": NoScan, + "LinearScan": LinearScan, + "RandomScan": RandomScan, + "ExplicitScan": ExplicitScan +} + + +class Scannable: + def __init__(self, global_min=None, global_max=None, global_step=None, + unit="", default=NoDefault): + self.global_min = global_min + self.global_max = global_max + self.global_step = global_step + self.unit = unit + if default is not NoDefault: + self.default_value = default + + def default(self): + if not hasattr(self, "default_value"): + raise DefaultMissing + return self.default_value + + def process(self, x): + cls = _ty_to_scan[x["ty"]] + args = dict() + for arg in inspect.getargspec(cls).args[1:]: + if arg in x: + args[arg] = x[arg] + return cls(**args) + + def describe(self): + d = {"ty": "Scannable"} + d["global_min"] = self.global_min + d["global_max"] = self.global_max + d["global_step"] = self.global_step + d["unit"]= self.unit + if hasattr(self, "default_value"): + d["default"] = self.default_value.describe() + return d