mirror of https://github.com/m-labs/artiq.git
Experiment base class, replace __artiq_unit__ with docstring
This commit is contained in:
parent
407477bc5a
commit
f2e3dfb848
|
@ -1,4 +1,5 @@
|
||||||
from artiq.language.core import *
|
from artiq.language.core import *
|
||||||
|
from artiq.language.experiment import Experiment
|
||||||
from artiq.language.db import *
|
from artiq.language.db import *
|
||||||
from artiq.language.units import check_unit
|
from artiq.language.units import check_unit
|
||||||
from artiq.language.units import ps, ns, us, ms, s
|
from artiq.language.units import ps, ns, us, ms, s
|
||||||
|
|
|
@ -40,12 +40,13 @@ def get_argparser():
|
||||||
parser_add.add_argument(
|
parser_add.add_argument(
|
||||||
"-t", "--timeout", default=None, type=float,
|
"-t", "--timeout", default=None, type=float,
|
||||||
help="specify a timeout for the experiment to complete")
|
help="specify a timeout for the experiment to complete")
|
||||||
parser_add.add_argument("-u", "--unit", default=None,
|
parser_add.add_argument("-e", "--experiment", default=None,
|
||||||
help="unit to run")
|
help="experiment to run")
|
||||||
parser_add.add_argument("--rtr-group", default=None, type=str,
|
parser_add.add_argument("--rtr-group", default=None, type=str,
|
||||||
help="real-time result group "
|
help="real-time result group "
|
||||||
"(defaults to filename)")
|
"(defaults to filename)")
|
||||||
parser_add.add_argument("file", help="file containing the unit to run")
|
parser_add.add_argument("file",
|
||||||
|
help="file containing the experiment to run")
|
||||||
parser_add.add_argument("arguments", nargs="*",
|
parser_add.add_argument("arguments", nargs="*",
|
||||||
help="run arguments")
|
help="run arguments")
|
||||||
|
|
||||||
|
@ -103,7 +104,7 @@ def _action_submit(remote, args):
|
||||||
|
|
||||||
run_params = {
|
run_params = {
|
||||||
"file": args.file,
|
"file": args.file,
|
||||||
"unit": args.unit,
|
"experiment": args.experiment,
|
||||||
"timeout": args.timeout,
|
"timeout": args.timeout,
|
||||||
"arguments": arguments,
|
"arguments": arguments,
|
||||||
"rtr_group": args.rtr_group if args.rtr_group is not None \
|
"rtr_group": args.rtr_group if args.rtr_group is not None \
|
||||||
|
@ -147,10 +148,11 @@ def _action_del_parameter(remote, args):
|
||||||
def _show_queue(queue):
|
def _show_queue(queue):
|
||||||
clear_screen()
|
clear_screen()
|
||||||
if queue:
|
if queue:
|
||||||
table = PrettyTable(["RID", "File", "Unit", "Timeout", "Arguments"])
|
table = PrettyTable(["RID", "File", "Experiment", "Timeout",
|
||||||
|
"Arguments"])
|
||||||
for rid, run_params in queue:
|
for rid, run_params in queue:
|
||||||
row = [rid, run_params["file"]]
|
row = [rid, run_params["file"]]
|
||||||
for x in run_params["unit"], run_params["timeout"]:
|
for x in run_params["experiment"], run_params["timeout"]:
|
||||||
row.append("" if x is None else x)
|
row.append("" if x is None else x)
|
||||||
row.append(format_arguments(run_params["arguments"]))
|
row.append(format_arguments(run_params["arguments"]))
|
||||||
table.add_row(row)
|
table.add_row(row)
|
||||||
|
@ -162,13 +164,13 @@ def _show_queue(queue):
|
||||||
def _show_timed(timed):
|
def _show_timed(timed):
|
||||||
clear_screen()
|
clear_screen()
|
||||||
if timed:
|
if timed:
|
||||||
table = PrettyTable(["Next run", "TRID", "File", "Unit",
|
table = PrettyTable(["Next run", "TRID", "File", "Experiment",
|
||||||
"Timeout", "Arguments"])
|
"Timeout", "Arguments"])
|
||||||
sp = sorted(timed.items(), key=lambda x: (x[1][0], x[0]))
|
sp = sorted(timed.items(), key=lambda x: (x[1][0], x[0]))
|
||||||
for trid, (next_run, run_params) in sp:
|
for trid, (next_run, run_params) in sp:
|
||||||
row = [time.strftime("%m/%d %H:%M:%S", time.localtime(next_run)),
|
row = [time.strftime("%m/%d %H:%M:%S", time.localtime(next_run)),
|
||||||
trid, run_params["file"]]
|
trid, run_params["file"]]
|
||||||
for x in run_params["unit"], run_params["timeout"]:
|
for x in run_params["experiment"], run_params["timeout"]:
|
||||||
row.append("" if x is None else x)
|
row.append("" if x is None else x)
|
||||||
row.append(format_arguments(run_params["arguments"]))
|
row.append(format_arguments(run_params["arguments"]))
|
||||||
table.add_row(row)
|
table.add_row(row)
|
||||||
|
|
|
@ -3,13 +3,13 @@
|
||||||
import argparse
|
import argparse
|
||||||
import sys
|
import sys
|
||||||
import time
|
import time
|
||||||
from inspect import isclass
|
|
||||||
from operator import itemgetter
|
from operator import itemgetter
|
||||||
from itertools import chain
|
from itertools import chain
|
||||||
|
|
||||||
import h5py
|
import h5py
|
||||||
|
|
||||||
from artiq.language.db import *
|
from artiq.language.db import *
|
||||||
|
from artiq.language.experiment import is_experiment
|
||||||
from artiq.protocols import pyon
|
from artiq.protocols import pyon
|
||||||
from artiq.protocols.file_db import FlatFileDB
|
from artiq.protocols.file_db import FlatFileDB
|
||||||
from artiq.master.worker_db import DBHub, ResultDB
|
from artiq.master.worker_db import DBHub, ResultDB
|
||||||
|
@ -68,15 +68,15 @@ def get_argparser():
|
||||||
parser.add_argument("-p", "--pdb", default="pdb.pyon",
|
parser.add_argument("-p", "--pdb", default="pdb.pyon",
|
||||||
help="parameter database file")
|
help="parameter database file")
|
||||||
|
|
||||||
parser.add_argument("-e", "--elf", default=False, action="store_true",
|
parser.add_argument("-E", "--elf", default=False, action="store_true",
|
||||||
help="run ELF binary")
|
help="run ELF binary")
|
||||||
parser.add_argument("-u", "--unit", default=None,
|
parser.add_argument("-e", "--experiment", default=None,
|
||||||
help="unit to run")
|
help="experiment to run")
|
||||||
parser.add_argument("-o", "--hdf5", default=None,
|
parser.add_argument("-o", "--hdf5", default=None,
|
||||||
help="write results to specified HDF5 file"
|
help="write results to specified HDF5 file"
|
||||||
" (default: print them)")
|
" (default: print them)")
|
||||||
parser.add_argument("file",
|
parser.add_argument("file",
|
||||||
help="file containing the unit to run")
|
help="file containing the experiment to run")
|
||||||
parser.add_argument("arguments", nargs="*",
|
parser.add_argument("arguments", nargs="*",
|
||||||
help="run arguments")
|
help="run arguments")
|
||||||
|
|
||||||
|
@ -105,27 +105,31 @@ def main():
|
||||||
if args.arguments:
|
if args.arguments:
|
||||||
print("Run arguments are not supported in ELF mode")
|
print("Run arguments are not supported in ELF mode")
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
unit_inst = ELFRunner(dps)
|
exp_inst = ELFRunner(dps)
|
||||||
unit_inst.run(args.file)
|
exp_inst.run(args.file)
|
||||||
else:
|
else:
|
||||||
module = file_import(args.file)
|
module = file_import(args.file)
|
||||||
if args.unit is None:
|
if args.experiment is None:
|
||||||
units = [(k, v) for k, v in module.__dict__.items()
|
exps = [(k, v) for k, v in module.__dict__.items()
|
||||||
if isclass(v) and hasattr(v, "__artiq_unit__")]
|
if is_experiment(v)]
|
||||||
l = len(units)
|
l = len(exps)
|
||||||
if l == 0:
|
if l == 0:
|
||||||
print("No units found in module")
|
print("No experiments found in module")
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
elif l > 1:
|
elif l > 1:
|
||||||
print("More than one unit found in module:")
|
print("More than one experiment found in module:")
|
||||||
for k, v in sorted(units, key=itemgetter(0)):
|
for k, v in sorted(experiments, key=itemgetter(0)):
|
||||||
print(" {} ({})".format(k, v.__artiq_unit__))
|
if v.__doc__ is None:
|
||||||
print("Use -u to specify which unit to use.")
|
print(" {}".format(k))
|
||||||
|
else:
|
||||||
|
print(" {} ({})".format(
|
||||||
|
k, v.__doc__.splitlines()[0].strip()))
|
||||||
|
print("Use -u to specify which experiment to use.")
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
else:
|
else:
|
||||||
unit = units[0][1]
|
exp = exps[0][1]
|
||||||
else:
|
else:
|
||||||
unit = getattr(module, args.unit)
|
exp = getattr(module, args.experiment)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
arguments = _parse_arguments(args.arguments)
|
arguments = _parse_arguments(args.arguments)
|
||||||
|
@ -135,17 +139,16 @@ def main():
|
||||||
|
|
||||||
run_params = {
|
run_params = {
|
||||||
"file": args.file,
|
"file": args.file,
|
||||||
"unit": args.unit,
|
"experiment": args.experiment,
|
||||||
"timeout": None,
|
"timeout": None,
|
||||||
"arguments": arguments
|
"arguments": arguments
|
||||||
}
|
}
|
||||||
unit_inst = unit(dbh,
|
exp_inst = exp(dbh,
|
||||||
scheduler=DummyScheduler(),
|
scheduler=DummyScheduler(),
|
||||||
run_params=run_params,
|
run_params=run_params,
|
||||||
**run_params["arguments"])
|
**run_params["arguments"])
|
||||||
unit_inst.run()
|
exp_inst.run()
|
||||||
if hasattr(unit_inst, "analyze"):
|
exp_inst.analyze()
|
||||||
unit_inst.analyze()
|
|
||||||
|
|
||||||
if args.hdf5 is not None:
|
if args.hdf5 is not None:
|
||||||
f = h5py.File(args.hdf5, "w")
|
f = h5py.File(args.hdf5, "w")
|
||||||
|
|
|
@ -146,7 +146,7 @@ class ExplorerWindow(Window):
|
||||||
arguments = self.controls.get_arguments()
|
arguments = self.controls.get_arguments()
|
||||||
run_params = {
|
run_params = {
|
||||||
"file": data["file"],
|
"file": data["file"],
|
||||||
"unit": data["unit"],
|
"experiment": data["experiment"],
|
||||||
"timeout": None,
|
"timeout": None,
|
||||||
"arguments": arguments,
|
"arguments": arguments,
|
||||||
"rtr_group": data["file"]
|
"rtr_group": data["file"]
|
||||||
|
|
|
@ -12,7 +12,7 @@ class _QueueStoreSyncer(ListSyncer):
|
||||||
def convert(self, x):
|
def convert(self, x):
|
||||||
rid, run_params = x
|
rid, run_params = x
|
||||||
row = [rid, run_params["file"]]
|
row = [rid, run_params["file"]]
|
||||||
for e in run_params["unit"], run_params["timeout"]:
|
for e in run_params["experiment"], run_params["timeout"]:
|
||||||
row.append("" if e is None else str(e))
|
row.append("" if e is None else str(e))
|
||||||
row.append(format_arguments(run_params["arguments"]))
|
row.append(format_arguments(run_params["arguments"]))
|
||||||
return row
|
return row
|
||||||
|
@ -27,7 +27,7 @@ class _TimedStoreSyncer(DictSyncer):
|
||||||
next_run, run_params = x
|
next_run, run_params = x
|
||||||
row = [time.strftime("%m/%d %H:%M:%S", time.localtime(next_run)),
|
row = [time.strftime("%m/%d %H:%M:%S", time.localtime(next_run)),
|
||||||
trid, run_params["file"]]
|
trid, run_params["file"]]
|
||||||
for e in run_params["unit"], run_params["timeout"]:
|
for e in run_params["experiment"], run_params["timeout"]:
|
||||||
row.append("" if e is None else str(e))
|
row.append("" if e is None else str(e))
|
||||||
row.append(format_arguments(run_params["arguments"]))
|
row.append(format_arguments(run_params["arguments"]))
|
||||||
return row
|
return row
|
||||||
|
@ -57,7 +57,7 @@ class SchedulerWindow(Window):
|
||||||
|
|
||||||
self.queue_store = Gtk.ListStore(int, str, str, str, str)
|
self.queue_store = Gtk.ListStore(int, str, str, str, str)
|
||||||
self.queue_tree = Gtk.TreeView(self.queue_store)
|
self.queue_tree = Gtk.TreeView(self.queue_store)
|
||||||
for i, title in enumerate(["RID", "File", "Unit", "Timeout", "Arguments"]):
|
for i, title in enumerate(["RID", "File", "Experiment", "Timeout", "Arguments"]):
|
||||||
renderer = Gtk.CellRendererText()
|
renderer = Gtk.CellRendererText()
|
||||||
column = Gtk.TreeViewColumn(title, renderer, text=i)
|
column = Gtk.TreeViewColumn(title, renderer, text=i)
|
||||||
self.queue_tree.append_column(column)
|
self.queue_tree.append_column(column)
|
||||||
|
@ -81,7 +81,7 @@ class SchedulerWindow(Window):
|
||||||
|
|
||||||
self.timed_store = Gtk.ListStore(str, int, str, str, str, str)
|
self.timed_store = Gtk.ListStore(str, int, str, str, str, str)
|
||||||
self.timed_tree = Gtk.TreeView(self.timed_store)
|
self.timed_tree = Gtk.TreeView(self.timed_store)
|
||||||
for i, title in enumerate(["Next run", "TRID", "File", "Unit",
|
for i, title in enumerate(["Next run", "TRID", "File", "Experiment",
|
||||||
"Timeout", "Arguments"]):
|
"Timeout", "Arguments"]):
|
||||||
renderer = Gtk.CellRendererText()
|
renderer = Gtk.CellRendererText()
|
||||||
column = Gtk.TreeViewColumn(title, renderer, text=i)
|
column = Gtk.TreeViewColumn(title, renderer, text=i)
|
||||||
|
|
|
@ -0,0 +1,40 @@
|
||||||
|
from inspect import isclass
|
||||||
|
|
||||||
|
|
||||||
|
class Experiment:
|
||||||
|
"""Base class for experiments.
|
||||||
|
|
||||||
|
Deriving from this class enables automatic experiment discovery in
|
||||||
|
Python modules.
|
||||||
|
"""
|
||||||
|
def run(self):
|
||||||
|
"""The main entry point of the experiment.
|
||||||
|
|
||||||
|
This method must be overloaded by the user to implement the main
|
||||||
|
control flow of the experiment.
|
||||||
|
"""
|
||||||
|
raise NotImplementedError
|
||||||
|
|
||||||
|
def analyze(self):
|
||||||
|
"""Entry point for analyzing the results of the experiment.
|
||||||
|
|
||||||
|
This method may be overloaded by the user to implement the analysis
|
||||||
|
phase of the experiment, for example fitting curves.
|
||||||
|
|
||||||
|
Splitting this phase from ``run`` enables tweaking the analysis
|
||||||
|
algorithm on pre-existing data, and CPU-bound analyses to be run
|
||||||
|
overlapped with the next experiment in a pipelined manner.
|
||||||
|
|
||||||
|
This method must not interact with the hardware.
|
||||||
|
"""
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
def has_analyze(experiment):
|
||||||
|
"""Checks if an experiment instance overloaded its ``analyze`` method."""
|
||||||
|
return experiment.analyze.__func__ is not Experiment.analyze
|
||||||
|
|
||||||
|
|
||||||
|
def is_experiment(o):
|
||||||
|
"""Checks if a Python object is an instantiable experiment."""
|
||||||
|
return isclass(o) and issubclass(o, Experiment) and o is not Experiment
|
|
@ -1,8 +1,8 @@
|
||||||
import os
|
import os
|
||||||
from inspect import isclass
|
|
||||||
|
|
||||||
from artiq.protocols.sync_struct import Notifier
|
from artiq.protocols.sync_struct import Notifier
|
||||||
from artiq.tools import file_import
|
from artiq.tools import file_import
|
||||||
|
from artiq.language.experiment import is_experiment
|
||||||
|
|
||||||
|
|
||||||
def scan_experiments():
|
def scan_experiments():
|
||||||
|
@ -14,13 +14,19 @@ def scan_experiments():
|
||||||
except:
|
except:
|
||||||
continue
|
continue
|
||||||
for k, v in m.__dict__.items():
|
for k, v in m.__dict__.items():
|
||||||
if isclass(v) and hasattr(v, "__artiq_unit__"):
|
if is_experiment(v):
|
||||||
|
if v.__doc__ is None:
|
||||||
|
name = k
|
||||||
|
else:
|
||||||
|
name = v.__doc__.splitlines()[0].strip()
|
||||||
|
if name[-1] == ".":
|
||||||
|
name = name[:-1]
|
||||||
entry = {
|
entry = {
|
||||||
"file": os.path.join("repository", f),
|
"file": os.path.join("repository", f),
|
||||||
"unit": k,
|
"experiment": k,
|
||||||
"gui_file": getattr(v, "__artiq_gui_file__", None)
|
"gui_file": getattr(v, "__artiq_gui_file__", None)
|
||||||
}
|
}
|
||||||
r[v.__artiq_unit__] = entry
|
r[name] = entry
|
||||||
return r
|
return r
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
import sys
|
import sys
|
||||||
import time
|
import time
|
||||||
from inspect import isclass
|
|
||||||
import traceback
|
import traceback
|
||||||
|
|
||||||
from artiq.protocols import pyon
|
from artiq.protocols import pyon
|
||||||
|
@ -65,23 +64,24 @@ class Scheduler:
|
||||||
cancel_timed = make_parent_action("scheduler_cancel_timed", "trid")
|
cancel_timed = make_parent_action("scheduler_cancel_timed", "trid")
|
||||||
|
|
||||||
|
|
||||||
def get_unit(file, unit):
|
def get_exp(file, exp):
|
||||||
module = file_import(file)
|
module = file_import(file)
|
||||||
if unit is None:
|
if exp is None:
|
||||||
units = [v for k, v in module.__dict__.items()
|
exps = [v for k, v in module.__dict__.items()
|
||||||
if isclass(v) and hasattr(v, "__artiq_unit__")]
|
if is_experiment(v)]
|
||||||
if len(units) != 1:
|
if len(exps) != 1:
|
||||||
raise ValueError("Found {} units in module".format(len(units)))
|
raise ValueError("Found {} experiments in module"
|
||||||
return units[0]
|
.format(len(exps)))
|
||||||
|
return exps[0]
|
||||||
else:
|
else:
|
||||||
return getattr(module, unit)
|
return getattr(module, exp)
|
||||||
|
|
||||||
|
|
||||||
def run(rid, run_params):
|
def run(rid, run_params):
|
||||||
start_time = time.localtime()
|
start_time = time.localtime()
|
||||||
unit = get_unit(run_params["file"], run_params["unit"])
|
exp = get_exp(run_params["file"], run_params["experiment"])
|
||||||
|
|
||||||
realtime_results = unit.realtime_results()
|
realtime_results = exp.realtime_results()
|
||||||
init_rt_results(realtime_results)
|
init_rt_results(realtime_results)
|
||||||
|
|
||||||
realtime_results_set = set()
|
realtime_results_set = set()
|
||||||
|
@ -97,13 +97,12 @@ def run(rid, run_params):
|
||||||
dbh = DBHub(ParentDDB, ParentPDB, rdb)
|
dbh = DBHub(ParentDDB, ParentPDB, rdb)
|
||||||
try:
|
try:
|
||||||
try:
|
try:
|
||||||
unit_inst = unit(dbh,
|
exp_inst = exp(dbh,
|
||||||
scheduler=Scheduler,
|
scheduler=Scheduler,
|
||||||
run_params=run_params,
|
run_params=run_params,
|
||||||
**run_params["arguments"])
|
**run_params["arguments"])
|
||||||
unit_inst.run()
|
exp_inst.run()
|
||||||
if hasattr(unit_inst, "analyze"):
|
exp_inst.analyze()
|
||||||
unit_inst.analyze()
|
|
||||||
except Exception:
|
except Exception:
|
||||||
put_object({"action": "report_completed",
|
put_object({"action": "report_completed",
|
||||||
"status": "failed",
|
"status": "failed",
|
||||||
|
@ -114,7 +113,7 @@ def run(rid, run_params):
|
||||||
finally:
|
finally:
|
||||||
dbh.close()
|
dbh.close()
|
||||||
|
|
||||||
f = get_hdf5_output(start_time, rid, unit.__name__)
|
f = get_hdf5_output(start_time, rid, exp.__name__)
|
||||||
try:
|
try:
|
||||||
rdb.write_hdf5(f)
|
rdb.write_hdf5(f)
|
||||||
finally:
|
finally:
|
||||||
|
|
|
@ -2,15 +2,16 @@ from artiq import *
|
||||||
|
|
||||||
import pulse_rate, rtio_skew, rpc_timing
|
import pulse_rate, rtio_skew, rpc_timing
|
||||||
|
|
||||||
_units = [pulse_rate.PulseRate, rtio_skew.RTIOSkew, rpc_timing.RPCTiming]
|
|
||||||
|
|
||||||
class AllBenchmarks(AutoDB):
|
_exps = [pulse_rate.PulseRate, rtio_skew.RTIOSkew, rpc_timing.RPCTiming]
|
||||||
__artiq_unit__ = "All benchmarks"
|
|
||||||
|
class AllBenchmarks(Experiment, AutoDB):
|
||||||
|
"""All benchmarks"""
|
||||||
|
|
||||||
def build(self):
|
def build(self):
|
||||||
self.se = []
|
self.se = []
|
||||||
for unit in _units:
|
for exp in _exps:
|
||||||
self.se.append(unit(self.dbh))
|
self.se.append(exp(self.dbh))
|
||||||
|
|
||||||
def run(self):
|
def run(self):
|
||||||
for se in self.se:
|
for se in self.se:
|
||||||
|
|
|
@ -2,8 +2,8 @@ from artiq import *
|
||||||
from artiq.coredevice.runtime_exceptions import RTIOUnderflow
|
from artiq.coredevice.runtime_exceptions import RTIOUnderflow
|
||||||
|
|
||||||
|
|
||||||
class PulseRate(AutoDB):
|
class PulseRate(Experiment, AutoDB):
|
||||||
__artiq_unit__ = "Pulse rate"
|
"""Sustained pulse rate"""
|
||||||
|
|
||||||
class DBKeys:
|
class DBKeys:
|
||||||
core = Device()
|
core = Device()
|
||||||
|
|
|
@ -3,8 +3,8 @@ from math import sqrt
|
||||||
from artiq import *
|
from artiq import *
|
||||||
|
|
||||||
|
|
||||||
class RPCTiming(AutoDB):
|
class RPCTiming(Experiment, AutoDB):
|
||||||
__artiq_unit__ = "RPC timing"
|
"""RPC timing"""
|
||||||
|
|
||||||
class DBKeys:
|
class DBKeys:
|
||||||
core = Device()
|
core = Device()
|
||||||
|
|
|
@ -5,8 +5,8 @@ class PulseNotReceived(Exception):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
class RTIOSkew(AutoDB):
|
class RTIOSkew(Experiment, AutoDB):
|
||||||
__artiq_unit__ = "RTIO skew"
|
"""RTIO skew"""
|
||||||
|
|
||||||
class DBKeys:
|
class DBKeys:
|
||||||
core = Device()
|
core = Device()
|
||||||
|
|
|
@ -9,9 +9,7 @@ As a very first step, we will turn on a LED on the core device. Create a file ``
|
||||||
from artiq import *
|
from artiq import *
|
||||||
|
|
||||||
|
|
||||||
class LED(AutoDB):
|
class LED(Experiment, AutoDB):
|
||||||
__artiq_unit__ = "ARTIQ tutorial"
|
|
||||||
|
|
||||||
class DBKeys:
|
class DBKeys:
|
||||||
core = Device()
|
core = Device()
|
||||||
led = Device()
|
led = Device()
|
||||||
|
@ -23,8 +21,6 @@ As a very first step, we will turn on a LED on the core device. Create a file ``
|
||||||
|
|
||||||
The central part of our code is our ``LED`` class, that derives from :class:`artiq.language.db.AutoDB`. ``AutoDB`` is part of the mechanism that attaches device drivers and retrieves parameters according to a database. Our ``DBKeys`` class lists the devices (and parameters) that ``LED`` needs in order to operate, and the names of the attributes (e.g. ``led``) are used to search the database. ``AutoDB`` replaces them with the actual device drivers (and parameter values). Finally, the ``@kernel`` decorator tells the system that the ``run`` method must be executed on the core device (instead of the host).
|
The central part of our code is our ``LED`` class, that derives from :class:`artiq.language.db.AutoDB`. ``AutoDB`` is part of the mechanism that attaches device drivers and retrieves parameters according to a database. Our ``DBKeys`` class lists the devices (and parameters) that ``LED`` needs in order to operate, and the names of the attributes (e.g. ``led``) are used to search the database. ``AutoDB`` replaces them with the actual device drivers (and parameter values). Finally, the ``@kernel`` decorator tells the system that the ``run`` method must be executed on the core device (instead of the host).
|
||||||
|
|
||||||
The ``__artiq_unit__`` attribute tells the ARTIQ tools that our class is a "unit" (an entry point for an experiment) and gives it a name. The name can be any string, and its purpose is to name the experiment in user interfaces.
|
|
||||||
|
|
||||||
Copy the files ``ddb.pyon`` and ``pdb.pyon`` (containing the device and parameter databases) from the ``examples`` folder of ARTIQ into the same directory as ``led.py`` (alternatively, you can use the ``-d`` and ``-p`` options of ``artiq_run.py``). You can open the database files using a text editor - their contents are in a human-readable format.
|
Copy the files ``ddb.pyon`` and ``pdb.pyon`` (containing the device and parameter databases) from the ``examples`` folder of ARTIQ into the same directory as ``led.py`` (alternatively, you can use the ``-d`` and ``-p`` options of ``artiq_run.py``). You can open the database files using a text editor - their contents are in a human-readable format.
|
||||||
|
|
||||||
Run your code using ``artiq_run.py``, which is part of the ARTIQ front-end tools: ::
|
Run your code using ``artiq_run.py``, which is part of the ARTIQ front-end tools: ::
|
||||||
|
@ -43,9 +39,7 @@ Modify the code as follows: ::
|
||||||
def input_led_state():
|
def input_led_state():
|
||||||
return int(input("Enter desired LED state: "))
|
return int(input("Enter desired LED state: "))
|
||||||
|
|
||||||
class LED(AutoDB):
|
class LED(Experiment, AutoDB):
|
||||||
__artiq_unit__ = "ARTIQ tutorial"
|
|
||||||
|
|
||||||
class DBKeys:
|
class DBKeys:
|
||||||
core = Device()
|
core = Device()
|
||||||
led = Device()
|
led = Device()
|
||||||
|
@ -89,9 +83,7 @@ Create a new file ``rtio.py`` containing the following: ::
|
||||||
|
|
||||||
from artiq import *
|
from artiq import *
|
||||||
|
|
||||||
class Tutorial(AutoDB):
|
class Tutorial(Experiment, AutoDB):
|
||||||
__artiq_unit__ = "ARTIQ tutorial"
|
|
||||||
|
|
||||||
class DBKeys:
|
class DBKeys:
|
||||||
core = Device()
|
core = Device()
|
||||||
ttl0 = Device()
|
ttl0 = Device()
|
||||||
|
@ -114,9 +106,7 @@ Try reducing the period of the generated waveform until the CPU cannot keep up w
|
||||||
def print_underflow():
|
def print_underflow():
|
||||||
print("RTIO underflow occured")
|
print("RTIO underflow occured")
|
||||||
|
|
||||||
class Tutorial(AutoDB):
|
class Tutorial(Experiment, AutoDB):
|
||||||
__artiq_unit__ = "ARTIQ tutorial"
|
|
||||||
|
|
||||||
class DBKeys:
|
class DBKeys:
|
||||||
core = Device()
|
core = Device()
|
||||||
led = Device()
|
led = Device()
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
{"flopping_freq": 1500.0294421161527}
|
{"flopping_freq": 1500.0164816344934}
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
from artiq import *
|
from artiq import *
|
||||||
|
|
||||||
|
|
||||||
class DDSTest(AutoDB):
|
class DDSTest(Experiment, AutoDB):
|
||||||
__artiq_unit__ = "DDS test"
|
"""DDS test"""
|
||||||
|
|
||||||
class DBKeys:
|
class DBKeys:
|
||||||
core = Device()
|
core = Device()
|
||||||
|
|
|
@ -23,8 +23,8 @@ def model_numpy(xdata, F0):
|
||||||
return r
|
return r
|
||||||
|
|
||||||
|
|
||||||
class FloppingF(AutoDB):
|
class FloppingF(Experiment, AutoDB):
|
||||||
__artiq_unit__ = "Flopping F simulation"
|
"""Flopping F simulation"""
|
||||||
__artiq_gui_file__ = "flopping_f_simulation_gui.py"
|
__artiq_gui_file__ = "flopping_f_simulation_gui.py"
|
||||||
|
|
||||||
class DBKeys:
|
class DBKeys:
|
||||||
|
|
|
@ -3,8 +3,8 @@ import sys
|
||||||
from artiq import *
|
from artiq import *
|
||||||
|
|
||||||
|
|
||||||
class Mandelbrot(AutoDB):
|
class Mandelbrot(Experiment, AutoDB):
|
||||||
__artiq_unit__ = "Mandelbrot set demo"
|
"""Mandelbrot set demo"""
|
||||||
|
|
||||||
class DBKeys:
|
class DBKeys:
|
||||||
core = Device()
|
core = Device()
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
from artiq import *
|
from artiq import *
|
||||||
|
|
||||||
|
|
||||||
class PhotonHistogram(AutoDB):
|
class PhotonHistogram(Experiment, AutoDB):
|
||||||
__artiq_unit__ = "Photon histogram"
|
"""Photon histogram"""
|
||||||
|
|
||||||
class DBKeys:
|
class DBKeys:
|
||||||
core = Device()
|
core = Device()
|
||||||
|
|
|
@ -10,8 +10,8 @@ transport_data = dict(
|
||||||
# 4 devices, 3 board each, 3 dacs each
|
# 4 devices, 3 board each, 3 dacs each
|
||||||
)
|
)
|
||||||
|
|
||||||
class Transport(AutoDB):
|
class Transport(Experiment, AutoDB):
|
||||||
__artiq_unit__ = "Transport"
|
"""Transport"""
|
||||||
|
|
||||||
class DBKeys:
|
class DBKeys:
|
||||||
core = Device()
|
core = Device()
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
from artiq import *
|
from artiq import *
|
||||||
|
|
||||||
|
|
||||||
class AluminumSpectroscopy(AutoDB):
|
class AluminumSpectroscopy(Experiment, AutoDB):
|
||||||
__artiq_unit__ = "Aluminum spectroscopy (simulation)"
|
"""Aluminum spectroscopy (simulation)"""
|
||||||
|
|
||||||
class DBKeys:
|
class DBKeys:
|
||||||
core = Device()
|
core = Device()
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
from artiq import *
|
from artiq import *
|
||||||
|
|
||||||
|
|
||||||
class SimpleSimulation(AutoDB):
|
class SimpleSimulation(Experiment, AutoDB):
|
||||||
__artiq_unit__ = "Simple simulation"
|
"""Simple simulation"""
|
||||||
|
|
||||||
class DBKeys:
|
class DBKeys:
|
||||||
core = Device()
|
core = Device()
|
||||||
|
|
Loading…
Reference in New Issue