Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: m-labs/artiq
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: 47f3e7001580
Choose a base ref
...
head repository: m-labs/artiq
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: 5e094528c192
Choose a head ref
  • 7 commits
  • 3 files changed
  • 1 contributor

Commits on May 11, 2016

  1. browser: analyze stubs

    jordens committed May 11, 2016
    Copy the full SHA
    cd13045 View commit details

Commits on May 12, 2016

  1. Copy the full SHA
    5d58258 View commit details
  2. Copy the full SHA
    2a5eaea View commit details
  3. flopping_f_simulation: style

    jordens committed May 12, 2016
    Copy the full SHA
    8185a3d View commit details
  4. browser: style

    jordens committed May 12, 2016
    Copy the full SHA
    1480bb5 View commit details
  5. browser: basic analyze()

    jordens committed May 12, 2016
    Copy the full SHA
    07b80cc View commit details
  6. Copy the full SHA
    5e09452 View commit details
Showing with 84 additions and 23 deletions.
  1. +55 −7 artiq/browser/experiments.py
  2. +16 −14 artiq/examples/master/repository/flopping_f_simulation.py
  3. +13 −2 artiq/frontend/artiq_browser.py
62 changes: 55 additions & 7 deletions artiq/browser/experiments.py
Original file line number Diff line number Diff line change
@@ -11,6 +11,7 @@
from artiq.gui.tools import LayoutWidget, log_level_to_name, get_open_file_name
from artiq.gui.entries import argty_to_entry
from artiq.protocols import pyon
from artiq.protocols.sync_struct import process_mod
from artiq.master.worker import Worker

logger = logging.getLogger(__name__)
@@ -175,6 +176,8 @@ def __init__(self, area, expurl, arguments):
self.layout.setRowStretch(0, 1)

self.options = {"log_level": logging.WARNING}
self._worker = None
self._run_task = None

log_level = QtWidgets.QComboBox()
log_level.addItems(log_levels)
@@ -262,17 +265,49 @@ async def _load_hdf5_task(self, filename):
await self._recompute_arguments(arguments)

def run_clicked(self):
if self._run_task is not None:
logger.error("Analysis already started")
return
class_name, file = self.expurl.split("@", maxsplit=1)
expid = {
"repo_rev": "N/A",
"file": file,
"class_name": class_name,
"log_level": self.options["log_level"],
"arguments": {
name: argty_to_entry[argument["desc"]["ty"]].state_to_value(
argument["state"])
for name, argument in self.arguments.items()},
}
self._run_task = asyncio.ensure_future(self._get_run_task(expid))

def done(fut):
logger.info("Analysis done")
self._run_task = None

self._run_task.add_done_callback(done)

async def _get_run_task(self, expid):
self._worker = Worker(self._area.worker_handlers)
try:
pass # TODO
await self._worker.build(rid=None, pipeline_name="browser",
wd=os.path.abspath("."),
expid=expid, priority=0)
await self._worker.analyze()
except:
# May happen when experiment has been removed
# from repository/explist
logger.error("Failed to run '%s'",
self.expurl, exc_info=True)
finally:
await self._worker.close()
self._worker = None

def terminate_clicked(self):
if self._run_task is None:
return
try:
pass # TODO
self._run_task.cancel()
except:
# May happen when experiment has been removed
# from repository/explist
@@ -296,26 +331,39 @@ def restore_state(self, state):
self.options = state["options"]


class LocalDatasetDB:
def init(self, data):
self._data = data

def get(self, key):
return self._data.backing_store[key][1]

def update(self, mod):
process_mod(self._data, mod)


class ExperimentsArea(QtWidgets.QMdiArea):
def __init__(self, root, datasets_sub):
QtWidgets.QMdiArea.__init__(self)
self.pixmap = QtGui.QPixmap(os.path.join(
artiq_dir, "gui", "logo20.svg"))
self.current_dir = root
self.setToolTip("Click to open experiment")

self.open_experiments = []

self._ddb = LocalDatasetDB()
datasets_sub.add_setmodel_callback(self._ddb.init)

self.worker_handlers = {
"get_device_db": lambda: None,
"get_device": lambda k: None,
"get_dataset": lambda k: 0, # TODO
"update_dataset": lambda k, v: None,
"get_dataset": self._ddb.get,
"update_dataset": self._ddb.update,
}

def mousePressEvent(self, ev):
if ev.button() == QtCore.Qt.LeftButton:
asyncio.ensure_future(self._select_experiment_task())
self.select_experiment()

def paintEvent(self, event):
QtWidgets.QMdiArea.paintEvent(self, event)
@@ -340,7 +388,7 @@ def restore_state(self, state):
ex_state["arguments"])
dock.restore_state(ex_state["dock"])

def _select_experiment(self):
def select_experiment(self):
asyncio.ensure_future(self._select_experiment_task())

async def _select_experiment_task(self):
30 changes: 16 additions & 14 deletions artiq/examples/master/repository/flopping_f_simulation.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
from math import sqrt, cos, pi
import time
import random

@@ -13,14 +12,9 @@ def model(x, F0):
tpi = 0.03
A = 80
B = 40
return A+(B-A)/2/(4*tpi**2*(x-F0)**2+1)*(1-cos(pi*t/tpi*sqrt(4*tpi**2*(x-F0)**2+1)))


def model_numpy(xdata, F0):
r = np.zeros(len(xdata))
for i, x in enumerate(xdata):
r[i] = model(x, F0)
return r
return A + (B - A)/2/(4*tpi**2*(x - F0)**2+1)*(
1 - np.cos(np.pi*t/tpi*np.sqrt(4*tpi**2*(x - F0)**2 + 1))
)


class FloppingF(EnvExperiment):
@@ -31,8 +25,8 @@ def build(self):
default=LinearScan(1000, 2000, 100)))

self.setattr_argument("F0", NumberValue(1500, min=1000, max=2000))
self.setattr_argument("noise_amplitude", NumberValue(0.1, min=0, max=100,
step=0.01))
self.setattr_argument("noise_amplitude", NumberValue(
0.1, min=0, max=100, step=0.01))

self.setattr_device("scheduler")

@@ -57,10 +51,18 @@ def run(self):

def analyze(self):
# Use get_dataset so that analyze can be run stand-alone.
frequency = self.get_dataset("flopping_f_frequency")
brightness = self.get_dataset("flopping_f_brightness")
popt, pcov = curve_fit(model_numpy,
frequency, brightness,
try:
frequency = self.get_dataset("flopping_f_frequency")
except KeyError:
# Since flopping_f_frequency is not saved, it is missing if
# analyze() is run on HDF5 data. But assuming that the arguments
# have been loaded from that same HDF5 file, we can reconstruct it.
frequency = np.fromiter(self.frequency_scan, np.float)
assert frequency.shape == brightness.shape
self.set_dataset("flopping_f_frequency", frequency,
broadcast=True, save=False)
popt, pcov = curve_fit(model, frequency, brightness,
p0=[self.get_dataset("flopping_freq", 1500.0)])
perr = np.sqrt(np.diag(pcov))
if perr < 0.1:
15 changes: 13 additions & 2 deletions artiq/frontend/artiq_browser.py
Original file line number Diff line number Diff line change
@@ -12,8 +12,7 @@
from artiq import __artiq_dir__ as artiq_dir
from artiq.tools import verbosity_args, init_logger, atexit_register_coroutine
from artiq.gui import state, applets, models
from artiq.browser import datasets, files
from artiq.browser import experiments
from artiq.browser import datasets, files, experiments


logger = logging.getLogger(__name__)
@@ -82,6 +81,7 @@ def main():
# initialize main window
main_window = MainWindow()
smgr.register(main_window)
main_window.setUnifiedTitleAndToolBarOnMac(True)
status_bar = QtWidgets.QStatusBar()
main_window.setStatusBar(status_bar)

@@ -106,6 +106,17 @@ def main():
main_window.addDockWidget(QtCore.Qt.BottomDockWidgetArea, d_applets)
main_window.addDockWidget(QtCore.Qt.RightDockWidgetArea, d_datasets)

toolbar = main_window.addToolBar("Experiment")
toolbar.setToolButtonStyle(QtCore.Qt.ToolButtonTextBesideIcon)

open_action = QtWidgets.QAction("Open Experiment", main_window)
open_action.setIcon(app.style().standardIcon(
QtWidgets.QStyle.SP_DialogOpenButton))
open_action.setShortcuts(QtGui.QKeySequence.Open)
open_action.setStatusTip("Open existing experiment from file")
open_action.triggered.connect(mdi_area.select_experiment)
toolbar.addAction(open_action)

# load/initialize state
if os.name == "nt":
# HACK: show the main window before creating applets.