forked from M-Labs/artiq
add MultiScanManager
This commit is contained in:
parent
80cf321233
commit
ec3e7792dc
|
@ -0,0 +1,17 @@
|
||||||
|
from artiq.experiment import *
|
||||||
|
|
||||||
|
|
||||||
|
class MultiScan(EnvExperiment):
|
||||||
|
def build(self):
|
||||||
|
self.setattr_argument("a", Scannable(default=LinearScan(0, 10, 4)))
|
||||||
|
self.setattr_argument("b", Scannable(default=LinearScan(0, 10, 4)))
|
||||||
|
self.setattr_argument("c", Scannable(default=LinearScan(0, 10, 4)))
|
||||||
|
|
||||||
|
def run(self):
|
||||||
|
msm = MultiScanManager(
|
||||||
|
("a", self.a),
|
||||||
|
("b", self.b),
|
||||||
|
("c", self.c),
|
||||||
|
)
|
||||||
|
for point in msm:
|
||||||
|
print("a={} b={} c={}".format(point.a, point.b, point.c))
|
|
@ -3,7 +3,8 @@ Implementation and management of scan objects.
|
||||||
|
|
||||||
A scan object (e.g. :class:`artiq.language.scan.LinearScan`) represents a
|
A scan object (e.g. :class:`artiq.language.scan.LinearScan`) represents a
|
||||||
one-dimensional sweep of a numerical range. Multi-dimensional scans are
|
one-dimensional sweep of a numerical range. Multi-dimensional scans are
|
||||||
constructed by combining several scan objects.
|
constructed by combining several scan objects, for example using
|
||||||
|
:class:`artiq.language.scan.MultiScanManager`.
|
||||||
|
|
||||||
Iterate on a scan object to scan it, e.g. ::
|
Iterate on a scan object to scan it, e.g. ::
|
||||||
|
|
||||||
|
@ -14,12 +15,11 @@ Iterating multiple times on the same scan object is possible, with the scan
|
||||||
yielding the same values each time. Iterating concurrently on the
|
yielding the same values each time. Iterating concurrently on the
|
||||||
same scan object (e.g. via nested loops) is also supported, and the
|
same scan object (e.g. via nested loops) is also supported, and the
|
||||||
iterators are independent from each other.
|
iterators are independent from each other.
|
||||||
|
|
||||||
Scan objects are supported both on the host and the core device.
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
import random
|
import random
|
||||||
import inspect
|
import inspect
|
||||||
|
from itertools import product
|
||||||
|
|
||||||
from artiq.language.core import *
|
from artiq.language.core import *
|
||||||
from artiq.language.environment import NoDefault, DefaultMissing
|
from artiq.language.environment import NoDefault, DefaultMissing
|
||||||
|
@ -28,7 +28,7 @@ from artiq.language import units
|
||||||
|
|
||||||
__all__ = ["ScanObject",
|
__all__ = ["ScanObject",
|
||||||
"NoScan", "LinearScan", "RandomScan", "ExplicitScan",
|
"NoScan", "LinearScan", "RandomScan", "ExplicitScan",
|
||||||
"Scannable"]
|
"Scannable", "MultiScanManager"]
|
||||||
|
|
||||||
|
|
||||||
class ScanObject:
|
class ScanObject:
|
||||||
|
@ -222,3 +222,43 @@ class Scannable:
|
||||||
d["global_max"] = self.global_max
|
d["global_max"] = self.global_max
|
||||||
d["ndecimals"] = self.ndecimals
|
d["ndecimals"] = self.ndecimals
|
||||||
return d
|
return d
|
||||||
|
|
||||||
|
|
||||||
|
class MultiScanManager:
|
||||||
|
"""
|
||||||
|
Makes an iterator that returns elements from the first scan object until
|
||||||
|
it is exhausted, then proceeds to the next iterable, until all of the
|
||||||
|
scan objects are exhausted. Used for treating consecutive scans as a
|
||||||
|
single scan.
|
||||||
|
|
||||||
|
Scan objects must be passed as a list of tuples (name, scan_object).
|
||||||
|
Íteration produces scan points that have attributes that correspond
|
||||||
|
to the names of the scan objects, and have the last value yielded by
|
||||||
|
that scan object.
|
||||||
|
"""
|
||||||
|
def __init__(self, *args):
|
||||||
|
self.names = [a[0] for a in args]
|
||||||
|
self.scan_objects = [a[1] for a in args]
|
||||||
|
|
||||||
|
class ScanPoint:
|
||||||
|
def __init__(self, **kwargs):
|
||||||
|
self.attr = set()
|
||||||
|
for k, v in kwargs.items():
|
||||||
|
setattr(self, k, v)
|
||||||
|
self.attr.add(k)
|
||||||
|
|
||||||
|
def __repr__(self):
|
||||||
|
return ("<ScanPoint " +
|
||||||
|
" ".join("{}={}".format(k, getattr(self, k))
|
||||||
|
for k in self.attr) +
|
||||||
|
">")
|
||||||
|
|
||||||
|
self.scan_point_cls = ScanPoint
|
||||||
|
|
||||||
|
def _gen(self):
|
||||||
|
for values in product(*self.scan_objects):
|
||||||
|
d = {k: v for k, v in zip(self.names, values)}
|
||||||
|
yield self.scan_point_cls(**d)
|
||||||
|
|
||||||
|
def __iter__(self):
|
||||||
|
return self._gen()
|
||||||
|
|
Loading…
Reference in New Issue