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: 7e2e18231536
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: 356afb045c36
Choose a head ref
  • 3 commits
  • 5 files changed
  • 1 contributor

Commits on Apr 6, 2016

  1. Copy the full SHA
    f530815 View commit details
  2. Copy the full SHA
    485f82b View commit details
  3. Copy the full SHA
    356afb0 View commit details
Showing with 81 additions and 37 deletions.
  1. +2 −1 RELEASE_NOTES.rst
  2. +4 −3 artiq/applets/plot_hist.py
  3. +4 −3 artiq/applets/plot_xy.py
  4. +41 −2 artiq/applets/simple.py
  5. +30 −28 artiq/gui/applets.py
3 changes: 2 additions & 1 deletion RELEASE_NOTES.rst
Original file line number Diff line number Diff line change
@@ -18,7 +18,8 @@ unreleased [2.x]
* The "GUI" has been renamed the "dashboard".
* When flashing NIST boards, use "-m nist_qcX" or "-m nist_clock" instead of
just "-m qcX" or "-m clock" (#290).

* Applet command lines now use templates (e.g. $python) instead of formats
(e.g. {python}).


unreleased [1.0rc3]
7 changes: 4 additions & 3 deletions artiq/applets/plot_hist.py
Original file line number Diff line number Diff line change
@@ -4,15 +4,15 @@
import PyQt5 # make sure pyqtgraph imports Qt5
import pyqtgraph

from artiq.applets.simple import SimpleApplet
from artiq.applets.simple import TitleApplet


class HistogramPlot(pyqtgraph.PlotWidget):
def __init__(self, args):
pyqtgraph.PlotWidget.__init__(self)
self.args = args

def data_changed(self, data, mods):
def data_changed(self, data, mods, title):
try:
y = data[self.args.y][1]
if self.args.x is None:
@@ -28,10 +28,11 @@ def data_changed(self, data, mods):
self.clear()
self.plot(x, y, stepMode=True, fillLevel=0,
brush=(0, 0, 255, 150))
self.setTitle(title)


def main():
applet = SimpleApplet(HistogramPlot)
applet = TitleApplet(HistogramPlot)
applet.add_dataset("y", "Y values")
applet.add_dataset("x", "Bin boundaries", required=False)
applet.run()
7 changes: 4 additions & 3 deletions artiq/applets/plot_xy.py
Original file line number Diff line number Diff line change
@@ -4,15 +4,15 @@
import PyQt5 # make sure pyqtgraph imports Qt5
import pyqtgraph

from artiq.applets.simple import SimpleApplet
from artiq.applets.simple import TitleApplet


class XYPlot(pyqtgraph.PlotWidget):
def __init__(self, args):
pyqtgraph.PlotWidget.__init__(self)
self.args = args

def data_changed(self, data, mods):
def data_changed(self, data, mods, title):
try:
y = data[self.args.y][1]
except KeyError:
@@ -38,6 +38,7 @@ def data_changed(self, data, mods):

self.clear()
self.plot(x, y, pen=None, symbol="x")
self.setTitle(title)
if error is not None:
# See https://github.com/pyqtgraph/pyqtgraph/issues/211
if hasattr(error, "__len__") and not isinstance(error, np.ndarray):
@@ -49,7 +50,7 @@ def data_changed(self, data, mods):


def main():
applet = SimpleApplet(XYPlot)
applet = TitleApplet(XYPlot)
applet.add_dataset("y", "Y values")
applet.add_dataset("x", "X values", required=False)
applet.add_dataset("error", "Error bars for each X value", required=False)
43 changes: 41 additions & 2 deletions artiq/applets/simple.py
Original file line number Diff line number Diff line change
@@ -2,6 +2,7 @@
import argparse
import asyncio
import os
import string

from quamash import QEventLoop, QtWidgets, QtGui, QtCore

@@ -177,8 +178,11 @@ def filter_mod(self, mod):
else:
return False

def emit_data_changed(self, data, mod_buffer):
self.main_widget.data_changed(data, mod_buffer)

def flush_mod_buffer(self):
self.main_widget.data_changed(self.data, self.mod_buffer)
self.emit_data_changed(self.data, self.mod_buffer)
del self.mod_buffer

def sub_mod(self, mod):
@@ -193,7 +197,7 @@ def sub_mod(self, mod):
asyncio.get_event_loop().call_later(self.args.update_delay,
self.flush_mod_buffer)
else:
self.main_widget.data_changed(self.data, [mod])
self.emit_data_changed(self.data, [mod])

def subscribe(self):
if self.args.embed is None:
@@ -224,3 +228,38 @@ def run(self):
self.ipc_close()
finally:
self.loop.close()


class TitleApplet(SimpleApplet):
def __init__(self, *args, **kwargs):
SimpleApplet.__init__(self, *args, **kwargs)
self.argparser.add_argument("--title", default=None,
help="set title (can be a Python format "
"string where field names are dataset "
"names)")

def args_init(self):
SimpleApplet.args_init(self)
if self.args.title is not None:
self.dataset_title = set()
parsed = string.Formatter().parse(self.args.title)
for _, format_field, _, _ in parsed:
if format_field is None:
break
if not format_field:
raise ValueError("Invalid title format string")
self.dataset_title.add(format_field)
self.datasets |= self.dataset_title

def emit_data_changed(self, data, mod_buffer):
if self.args.title is not None:
title_values = {k: data.get(k, (False, None))[1]
for k in self.dataset_title}
try:
title = self.args.title.format(**title_values)
except:
logger.warning("failed to format title", exc_info=True)
title = self.args.title
else:
title = None
self.main_widget.data_changed(data, mod_buffer, title)
58 changes: 30 additions & 28 deletions artiq/gui/applets.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import logging
import asyncio
import sys
import string
import shlex
from functools import partial

@@ -108,25 +109,26 @@ async def start(self):
if self.starting_stopping:
return
self.starting_stopping = True

self.ipc = AppletIPCServer(self.datasets_sub)
if "{ipc_address}" not in self.command:
logger.warning("IPC address missing from command for %s",
self.applet_name)
command = self.command.format(
python=sys.executable.replace("\\", "\\\\"),
ipc_address=self.ipc.get_address().replace("\\", "\\\\")
)
logger.debug("starting command %s for %s", command, self.applet_name)
try:
await self.ipc.create_subprocess(*shlex.split(command),
start_new_session=True)
except:
logger.warning("Applet %s failed to start", self.applet_name,
exc_info=True)
self.ipc.start(self.embed, self.fix_initial_size)

self.starting_stopping = False
self.ipc = AppletIPCServer(self.datasets_sub)
if "$ipc_address" not in self.command:
logger.warning("IPC address missing from command for %s",
self.applet_name)
command_tpl = string.Template(self.command)
command = command_tpl.safe_substitute(
python=sys.executable.replace("\\", "\\\\"),
ipc_address=self.ipc.get_address().replace("\\", "\\\\")
)
logger.info("starting command %s for %s", command, self.applet_name)
try:
await self.ipc.create_subprocess(*shlex.split(command),
start_new_session=True)
except:
logger.warning("Applet %s failed to start", self.applet_name,
exc_info=True)
self.ipc.start(self.embed, self.fix_initial_size)
finally:
self.starting_stopping = False

def embed(self, win_id):
logger.debug("capturing window 0x%x for %s", win_id, self.applet_name)
@@ -175,20 +177,20 @@ async def restart(self):


_templates = [
("Big number", "{python} -m artiq.applets.big_number "
"--embed {ipc_address} NUMBER_DATASET"),
("Histogram", "{python} -m artiq.applets.plot_hist "
"--embed {ipc_address} COUNTS_DATASET "
("Big number", "$python -m artiq.applets.big_number "
"--embed $ipc_address NUMBER_DATASET"),
("Histogram", "$python -m artiq.applets.plot_hist "
"--embed $ipc_address COUNTS_DATASET "
"--x BIN_BOUNDARIES_DATASET"),
("XY", "{python} -m artiq.applets.plot_xy "
"--embed {ipc_address} Y_DATASET --x X_DATASET "
("XY", "$python -m artiq.applets.plot_xy "
"--embed $ipc_address Y_DATASET --x X_DATASET "
"--error ERROR_DATASET --fit FIT_DATASET"),
("XY + Histogram", "{python} -m artiq.applets.plot_xy_hist "
"--embed {ipc_address} X_DATASET "
("XY + Histogram", "$python -m artiq.applets.plot_xy_hist "
"--embed $ipc_address X_DATASET "
"HIST_BIN_BOUNDARIES_DATASET "
"HISTS_COUNTS_DATASET"),
("Image", "{python} -m artiq.applets.image "
"--embed {ipc_address} IMG_DATASET"),
("Image", "$python -m artiq.applets.image "
"--embed $ipc_address IMG_DATASET"),
]