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: fc92a66e513d
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: 2f4a83b97ab7
Choose a head ref
  • 3 commits
  • 9 files changed
  • 1 contributor

Commits on Feb 4, 2015

  1. style

    sbourdeauducq committed Feb 4, 2015
    Copy the full SHA
    186aa7f View commit details
  2. sync_struct,gui: refactor Subscriber data distribution to support acc…

    …ess to parameter DB from GUI file
    sbourdeauducq committed Feb 4, 2015
    Copy the full SHA
    1b122dd View commit details
  3. Copy the full SHA
    2f4a83b View commit details
10 changes: 10 additions & 0 deletions artiq/frontend/artiq_gui.py
Original file line number Diff line number Diff line change
@@ -9,6 +9,7 @@

from artiq.protocols.file_db import FlatFileDB
from artiq.protocols.pc_rpc import AsyncioClient
from artiq.protocols.sync_struct import Subscriber
from artiq.gui.tools import LayoutManager
from artiq.gui.scheduler import SchedulerWindow
from artiq.gui.parameters import ParametersWindow
@@ -79,6 +80,15 @@ def exit(*args):
args.server, args.port_notify))
atexit.register(
lambda: loop.run_until_complete(explorer_win.sub_close()))

parameters_sub = Subscriber("parameters",
[parameters_win.init_parameters_store,
explorer_win.init_parameters_dict])
loop.run_until_complete(
parameters_sub.connect(args.server, args.port_notify))
atexit.register(
lambda: loop.run_until_complete(parameters_sub.close()))

scheduler_win.show_all()
parameters_win.show_all()
explorer_win.show_all()
2 changes: 1 addition & 1 deletion artiq/frontend/artiq_master.py
Original file line number Diff line number Diff line change
@@ -41,7 +41,7 @@ def main():
repository = Repository()
explist = FlatFileDB("explist.pyon")

if os.name == 'nt':
if os.name == "nt":
loop = asyncio.ProactorEventLoop()
asyncio.set_event_loop(loop)
else:
32 changes: 32 additions & 0 deletions artiq/gui/explib.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import asyncio

from gi.repository import Gtk


class BaseControls:
def __init__(self, facilities):
self.facilities = facilities

@asyncio.coroutine
def build(self):
self.finalize()

def finalize(self):
pass


class GladeControls(BaseControls):
def __init__(self, facilities, glade_file, top_widget_name="top"):
BaseControls.__init__(self, facilities)
self.glade_file = glade_file
self.top_widget_name = top_widget_name

@asyncio.coroutine
def build(self):
self.builder = Gtk.Builder()
data = yield from self.facilities.get_data(self.glade_file)
self.builder.add_from_string(data)
self.finalize()

def get_top_widget(self):
return self.builder.get_object(self.top_widget_name)
27 changes: 19 additions & 8 deletions artiq/gui/explorer.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import asyncio
import types

from gi.repository import Gtk

@@ -88,28 +89,35 @@ def get_layout_dict(self):
@asyncio.coroutine
def sub_connect(self, host, port):
self.explist_subscriber = Subscriber("explist",
self.init_explist_store)
[self.init_explist_store,
self.init_explist_data])
yield from self.explist_subscriber.connect(host, port)

@asyncio.coroutine
def sub_close(self):
yield from self.explist_subscriber.close()

def init_parameters_dict(self, init):
self.parameters = init
return init

def set_pane_contents(self, widget):
self.pane_contents.destroy()
self.pane_contents = widget
self.pane.pack2(self.pane_contents)
self.pane_contents.show_all()

def init_explist_store(self, init):
self.explist_syncer = _ExplistStoreSyncer(self.explist_store, init,
keep_data=True)
return self.explist_syncer
return _ExplistStoreSyncer(self.explist_store, init)

def init_explist_data(self, init):
self.explist_data = init
return init

def explist_row_activated(self, widget, index, column):
self.controls = None
name = self.explist_store[index][0]
gui_file = self.explist_syncer.data[name]["gui_file"]
gui_file = self.explist_data[name]["gui_file"]
if gui_file is None:
self.set_pane_contents(Gtk.Label("No GUI controls"))
else:
@@ -120,15 +128,18 @@ def load_gui_file(self, gui_file):
gui_mod_data = yield from self.repository.get_data(gui_file)
gui_mod = dict()
exec(gui_mod_data, gui_mod)
self.controls = gui_mod["Controls"]()
yield from self.controls.build(self.repository.get_data)
facilities = types.SimpleNamespace(
get_data=self.repository.get_data,
get_parameter=lambda p: self.parameters[p])
self.controls = gui_mod["Controls"](facilities)
yield from self.controls.build()
self.set_pane_contents(self.controls.get_top_widget())

def run(self, widget):
store, selected = self.explist_tree.get_selection().get_selected()
if selected is not None:
name = store[selected][0]
data = self.explist_syncer.data[name]
data = self.explist_data[name]
if self.controls is None:
arguments = {}
else:
14 changes: 3 additions & 11 deletions artiq/gui/parameters.py
Original file line number Diff line number Diff line change
@@ -59,21 +59,13 @@ def __init__(self, **kwargs):

@asyncio.coroutine
def sub_connect(self, host, port):
self.parameters_subscriber = Subscriber("parameters",
self.init_parameters_store)
yield from self.parameters_subscriber.connect(host, port)
try:
self.lastchanges_subscriber = Subscriber(
"parameters_simplehist", self.init_lastchanges_store)
yield from self.lastchanges_subscriber.connect(host, port)
except:
yield from self.parameters_subscriber.close()
raise
self.lastchanges_subscriber = Subscriber(
"parameters_simplehist", self.init_lastchanges_store)
yield from self.lastchanges_subscriber.connect(host, port)

@asyncio.coroutine
def sub_close(self):
yield from self.lastchanges_subscriber.close()
yield from self.parameters_subscriber.close()

def init_parameters_store(self, init):
return _ParameterStoreSyncer(self.parameters_store, init)
6 changes: 1 addition & 5 deletions artiq/gui/tools.py
Original file line number Diff line number Diff line change
@@ -79,9 +79,7 @@ def convert(self, x):


class DictSyncer:
def __init__(self, store, init, keep_data=False):
if keep_data:
self.data = init
def __init__(self, store, init):
self.store = store
self.store.clear()
self.order = []
@@ -115,8 +113,6 @@ def __setitem__(self, key, value):
self.order.insert(j, (key, ord_el))

def __delitem__(self, key):
if hasattr(self, "data"):
del self.data[key]
i = self._find_index(key)
del self.store[i]
del self.order[i]
14 changes: 10 additions & 4 deletions artiq/protocols/sync_struct.py
Original file line number Diff line number Diff line change
@@ -49,13 +49,18 @@ class Subscriber:
:param target_builder: A function called during initialization that takes
the object received from the publisher and returns the corresponding
local structure to use. Can be identity.
Multiple functions can be specified in a list for the ``Subscriber``
to update several local objects simultaneously.
:param notify_cb: An optional function called every time a mod is received
from the publisher. The mod is passed as parameter.
"""
def __init__(self, notifier_name, target_builder, notify_cb=None):
self.notifier_name = notifier_name
self.target_builder = target_builder
if isinstance(target_builder, list):
self.target_builders = target_builder
else:
self.target_builders = [target_builder]
self.notify_cb = notify_cb

@asyncio.coroutine
@@ -87,17 +92,18 @@ def close(self):

@asyncio.coroutine
def _receive_cr(self):
target = None
targets = []
while True:
line = yield from self._reader.readline()
if not line:
return
mod = pyon.decode(line.decode())

if mod["action"] == "init":
target = self.target_builder(mod["struct"])
targets = [tb(mod["struct"]) for tb in self.target_builders]
else:
process_mod(target, mod)
for target in targets:
process_mod(target, mod)

if self.notify_cb is not None:
self.notify_cb(mod)
46 changes: 31 additions & 15 deletions examples/flopping_f_simulation_gui.glade
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- Generated with glade 3.16.1 -->
<!-- Generated with glade 3.18.3 -->
<interface>
<requires lib="gtk+" version="3.10"/>
<object class="GtkAdjustment" id="F0">
@@ -9,33 +9,49 @@
<property name="step_increment">1</property>
<property name="page_increment">10</property>
</object>
<object class="GtkBox" id="top">
<object class="GtkGrid" id="top">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="halign">center</property>
<property name="valign">center</property>
<property name="orientation">vertical</property>
<property name="row_spacing">6</property>
<property name="column_spacing">6</property>
<child>
<object class="GtkLabel" id="label1">
<object class="GtkSpinButton" id="spinbutton1">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="label" translatable="yes">Simulated flopping frequency</property>
<property name="can_focus">True</property>
<property name="input_purpose">number</property>
<property name="adjustment">F0</property>
<property name="value">1500</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">0</property>
<property name="left_attach">1</property>
<property name="top_attach">0</property>
</packing>
</child>
<child>
<object class="GtkSpinButton" id="spinbutton1">
<object class="GtkButton" id="getparam">
<property name="label" translatable="yes">Get from parameter DB</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="input_purpose">number</property>
<property name="adjustment">F0</property>
<property name="value">1500</property>
<property name="receives_default">True</property>
</object>
<packing>
<property name="left_attach">0</property>
<property name="top_attach">1</property>
<property name="width">2</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="label2">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="label" translatable="yes">Simulated flopping frequency:</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">1</property>
<property name="left_attach">0</property>
<property name="top_attach">0</property>
</packing>
</child>
</object>
21 changes: 11 additions & 10 deletions examples/flopping_f_simulation_gui.py
Original file line number Diff line number Diff line change
@@ -1,17 +1,18 @@
import asyncio
from artiq.gui.explib import GladeControls

from gi.repository import Gtk

class Controls(GladeControls):
def __init__(self, facilities):
GladeControls.__init__(self, facilities,
"flopping_f_simulation_gui.glade")

class Controls:
@asyncio.coroutine
def build(self, get_data):
self.builder = Gtk.Builder()
data = yield from get_data("flopping_f_simulation_gui.glade")
self.builder.add_from_string(data)
def finalize(self):
getparam = self.builder.get_object("getparam")
getparam.connect("clicked", self.getparam)

def get_top_widget(self):
return self.builder.get_object("top")
def getparam(self, widget):
F0 = self.facilities.get_parameter("flopping_freq")
self.builder.get_object("F0").set_value(F0)

def get_arguments(self):
return {