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: 168113ce554a
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: 3c624c777aff
Choose a head ref
  • 4 commits
  • 6 files changed
  • 1 contributor

Commits on Mar 23, 2016

  1. gui: add image applet

    sbourdeauducq committed Mar 23, 2016
    Copy the full SHA
    befbab5 View commit details
  2. Copy the full SHA
    0d7d584 View commit details
  3. Copy the full SHA
    e680939 View commit details
  4. Copy the full SHA
    3c624c7 View commit details
Showing with 152 additions and 5 deletions.
  1. +29 −0 artiq/applets/image.py
  2. +2 −0 artiq/gui/applets.py
  3. +15 −5 artiq/master/worker_db.py
  4. +34 −0 artiq/protocols/remote_exec.py
  5. +14 −0 examples/master/device_db.pyon
  6. +58 −0 examples/remote_exec_controller.py
29 changes: 29 additions & 0 deletions artiq/applets/image.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
#!/usr/bin/env python3.5

import numpy as np
import PyQt5 # make sure pyqtgraph imports Qt5
import pyqtgraph

from artiq.applets.simple import SimpleApplet


class Image(pyqtgraph.ImageView):
def __init__(self, args):
pyqtgraph.ImageView.__init__(self)
self.args = args

def data_changed(self, data, mods):
try:
img = data[self.args.img][1]
except KeyError:
return
self.setImage(img)


def main():
applet = SimpleApplet(Image)
applet.add_dataset("img", "image data (2D numpy array)")
applet.run()

if __name__ == "__main__":
main()
2 changes: 2 additions & 0 deletions artiq/gui/applets.py
Original file line number Diff line number Diff line change
@@ -185,6 +185,8 @@ async def restart(self):
"--embed {ipc_address} X_DATASET "
"HIST_BIN_BOUNDARIES_DATASET "
"HISTS_COUNTS_DATASET"),
("Image", "{python} -m artiq.applets.image "
"--embed {ipc_address} IMG_DATASET"),
]


20 changes: 15 additions & 5 deletions artiq/master/worker_db.py
Original file line number Diff line number Diff line change
@@ -102,6 +102,13 @@ def _create_device(desc, device_mgr):
if target_name is None:
target_name = AutoTarget
return cls(desc["host"], desc["port"], target_name)
elif ty == "controller_aux_target":
controller = device_mgr.get_desc(desc["controller"])
if desc.get("best_effort", controller.get("best_effort", False)):
cls = BestEffortClient
else:
cls = Client
return cls(controller["host"], controller["port"], desc["target_name"])
else:
raise ValueError("Unsupported type in device DB: " + ty)

@@ -118,6 +125,13 @@ def get_device_db(self):
"""Returns the full contents of the device database."""
return self.ddb.get_device_db()

def get_desc(self, name):
desc = self.ddb.get(name)
while isinstance(desc, str):
# alias
desc = self.ddb.get(desc)
return desc

def get(self, name):
"""Get the device driver or controller client corresponding to a
device database entry."""
@@ -126,11 +140,7 @@ def get(self, name):
if name in self.active_devices:
return self.active_devices[name]
else:
desc = self.ddb.get(name)
while isinstance(desc, str):
# alias
desc = self.ddb.get(desc)
dev = _create_device(desc, self)
dev = _create_device(self.get_desc(name), self)
self.active_devices[name] = dev
return dev

34 changes: 34 additions & 0 deletions artiq/protocols/remote_exec.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
from functools import partial
import inspect

from artiq.protocols.pc_rpc import simple_server_loop
from artiq.protocols.pc_rpc import Client as RPCClient


__all__ = ["RemoteExecServer", "RemoteExecClient", "simple_rexec_server_loop"]


class RemoteExecServer:
def __init__(self, target):
self.target = target
self.namespace = dict()

def add_code(self, code):
exec(code, self.namespace)

def call(self, function, *args, **kwargs):
return self.namespace[k](self, *args, **kwargs)


class RemoteExecClient(RPCClient):
def transfer_obj_source(self, obj):
self.add_code(self, inspect.getsource(obj))


def simple_rexec_server_loop(target_name, target, host, port,
description=None):
targets = {
target_name: target,
target_name + "_rexec": lambda: RemoteExecServer(target)
}
simple_server_loop(targets, host, port, description)
14 changes: 14 additions & 0 deletions examples/master/device_db.pyon
Original file line number Diff line number Diff line change
@@ -199,6 +199,20 @@
"command": "lda_controller -p {port} --bind {bind} --simulation"
},

"camera_sim": {
"type": "controller",
"host": "::1",
"port": 6283,
"target_name": "camera_sim",
"command": "./remote_exec_controller.py"
},
"camera_sim_rexec": {
"type": "controller_aux_target",
"controller": "camera_sim",
"target_name": "camera_sim_rexec"
},


"ttl_out": "ttl0",
"ttl_out_serdes": "ttl0",

58 changes: 58 additions & 0 deletions examples/remote_exec_controller.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
#!/usr/bin/env python3.5

import numpy as np
from numba import jit

from artiq.protocols.remote_exec import simple_rexec_server_loop


@jit(nopython=True)
def compute_picture(r, img_h, img_w,
gaussian_w, gaussian_h,
gaussian_cx, gaussian_cy,
noise_level):
for y in range(img_h):
for x in range(img_w):
ds = ((gaussian_cx-x)/gaussian_w)**2
ds += ((gaussian_cy-y)/gaussian_h)**2
r[x, y] = np.exp(-ds/2) + noise_level*np.random.random()


class CameraSimulation:
def __init__(self):
self.img_w = 320
self.img_h = 200
self.gaussian_w = 4
self.gaussian_h = 3
self.gaussian_cx = self.img_w//2
self.gaussian_cy = self.img_h//2
self.noise_level = 0.1

def set_gaussian_width(self, wx, wy=None):
if wy is None:
wy = wx
self.gaussian_w = wx
self.gaussian_h = wy

def set_gaussian_center(self, x, y):
self.gaussian_cx = x
self.gaussian_cy = y

def set_noise_level(self, noise_level):
self.noise_level = noise_level

def get_picture(self):
r = np.empty((self.img_w, self.img_h))
compute_picture(r, self.img_h, self.img_w,
self.gaussian_w, self.gaussian_h,
self.gaussian_cx, self.gaussian_cy,
self.noise_level)
return r


def main():
simple_rexec_server_loop("camera_sim", CameraSimulation(),
"::1", 6283)

if __name__ == "__main__":
main()