8
8
from pyqtgraph import dockarea
9
9
10
10
from artiq .tools import TaskObject
11
+ from artiq .protocols .sync_struct import Subscriber
11
12
12
13
13
14
logger = logging .getLogger (__name__ )
@@ -55,27 +56,30 @@ def __init__(self, send_to_device, channel, force_out, name):
55
56
self ._expctl_action .setCheckable (True )
56
57
menu .addAction (self ._expctl_action )
57
58
self ._value .addAction (self ._expctl_action )
58
- self ._expctl_action .triggered .connect (lambda : self .set_force ("exp" ))
59
+ self ._expctl_action .triggered .connect (lambda : self .set_mode ("exp" ))
60
+ separator = QtGui .QAction (self ._value )
61
+ separator .setSeparator (True )
62
+ self ._value .addAction (separator )
59
63
self ._force1_action = QtGui .QAction ("Force 1" , self ._value )
60
64
self ._force1_action .setCheckable (True )
61
65
menu .addAction (self ._force1_action )
62
66
self ._value .addAction (self ._force1_action )
63
- self ._force1_action .triggered .connect (lambda : self .set_force ("1" ))
67
+ self ._force1_action .triggered .connect (lambda : self .set_mode ("1" ))
64
68
self ._force0_action = QtGui .QAction ("Force 0" , self ._value )
65
69
self ._force0_action .setCheckable (True )
66
70
menu .addAction (self ._force0_action )
67
71
self ._value .addAction (self ._force0_action )
68
- self ._force0_action .triggered .connect (lambda : self .set_force ("0" ))
72
+ self ._force0_action .triggered .connect (lambda : self .set_mode ("0" ))
69
73
self ._forcein_action = QtGui .QAction ("Force input" , self ._value )
70
74
self ._forcein_action .setCheckable (True )
71
75
self ._forcein_action .setEnabled (not force_out )
72
76
menu .addAction (self ._forcein_action )
73
77
self ._value .addAction (self ._forcein_action )
74
- self ._forcein_action .triggered .connect (lambda : self .set_force ("in" ))
78
+ self ._forcein_action .triggered .connect (lambda : self .set_mode ("in" ))
75
79
76
80
self .set_value (0 , False , False )
77
81
78
- def set_force (self , mode ):
82
+ def set_mode (self , mode ):
79
83
data = struct .pack ("bbb" ,
80
84
2 , # MONINJ_REQ_TTLSET
81
85
self .channel , _mode_enc [mode ])
@@ -107,12 +111,75 @@ def set_value(self, value, oe, override):
107
111
self ._expctl_action .setChecked (True )
108
112
109
113
114
+ class _DDSWidget (QtGui .QFrame ):
115
+ def __init__ (self , send_to_device , channel , name ):
116
+ self .send_to_device = send_to_device
117
+ self .channel = channel
118
+ self .name = name
119
+
120
+ QtGui .QFrame .__init__ (self )
121
+
122
+ self .setFrameShape (QtGui .QFrame .Panel )
123
+ self .setFrameShadow (QtGui .QFrame .Raised )
124
+
125
+ grid = QtGui .QGridLayout ()
126
+ self .setLayout (grid )
127
+ label = QtGui .QLabel (name )
128
+ label .setAlignment (QtCore .Qt .AlignCenter )
129
+ grid .addWidget (label , 1 , 1 )
130
+
131
+ self ._override = QtGui .QLabel ()
132
+ self ._override .setAlignment (QtCore .Qt .AlignCenter )
133
+ grid .addWidget (self ._override , 2 , 1 )
134
+
135
+ self ._value = QtGui .QLabel ()
136
+ self ._value .setAlignment (QtCore .Qt .AlignCenter )
137
+ grid .addWidget (self ._value , 3 , 1 , 6 , 1 )
138
+
139
+ self ._value .setContextMenuPolicy (QtCore .Qt .ActionsContextMenu )
140
+ self ._override_action = QtGui .QAction ("Override" , self ._value )
141
+ self ._override_action .setCheckable (True )
142
+ self ._value .addAction (self ._override_action )
143
+ self ._override_action .triggered .connect (self ._override_clicked )
144
+
145
+ self .set_value (0.0 , False )
146
+
147
+ def _override_clicked (self ):
148
+ override_en = self ._override_action .isChecked ()
149
+ if override_en :
150
+ frequency , ok = QtGui .QInputDialog .getDouble (
151
+ None , "DDS override" ,
152
+ "Frequency in MHz for {}:" .format (self .name ),
153
+ value = self ._frequency , min = 0 , decimals = 3 )
154
+ self ._override_action .setChecked (ok )
155
+ if ok :
156
+ print ("override set to" , frequency )
157
+ else :
158
+ print ("override disabled" )
159
+
160
+ def set_value (self , frequency , override ):
161
+ self ._frequency = frequency
162
+ self ._override_action .setChecked (override )
163
+ value_s = "{:.3f} MHz" .format (frequency )
164
+ if override :
165
+ value_s = "<b>" + value_s + "</b>"
166
+ color = " color=\" red\" "
167
+ self ._override .setText ("<font size=\" 1\" color=\" red\" >OVERRIDE</font>" )
168
+ else :
169
+ color = ""
170
+ self ._override .setText ("" )
171
+ self ._value .setText ("<font size=\" 9\" {}>{}</font>"
172
+ .format (color , value_s ))
173
+
174
+
110
175
class _DeviceManager :
111
176
def __init__ (self , send_to_device , init ):
112
177
self .send_to_device = send_to_device
113
178
self .ddb = dict ()
114
179
self .ttl_cb = lambda : None
115
180
self .ttl_widgets = dict ()
181
+ self .dds_cb = lambda : None
182
+ self .dds_widgets = dict ()
116
183
for k , v in init .items ():
117
184
self [k ] = v
118
185
@@ -123,12 +190,19 @@ def __setitem__(self, k, v):
123
190
if not isinstance (v , dict ):
124
191
return
125
192
try :
126
- if v ["type" ] == "local" and v ["module" ] == "artiq.coredevice.ttl" :
127
- channel = v ["arguments" ]["channel" ]
128
- force_out = v ["class" ] == "TTLOut"
129
- self .ttl_widgets [channel ] = _TTLWidget (
130
- self .send_to_device , channel , force_out , k )
131
- self .ttl_cb ()
193
+ if v ["type" ] == "local" :
194
+ if v ["module" ] == "artiq.coredevice.ttl" :
195
+ channel = v ["arguments" ]["channel" ]
196
+ force_out = v ["class" ] == "TTLOut"
197
+ self .ttl_widgets [channel ] = _TTLWidget (
198
+ self .send_to_device , channel , force_out , k )
199
+ self .ttl_cb ()
200
+ if (v ["module" ] == "artiq.coredevice.dds"
201
+ and v ["class" ] == "DDS" ):
202
+ channel = v ["arguments" ]["channel" ]
203
+ self .dds_widgets [channel ] = _DDSWidget (
204
+ self .send_to_device , channel , k )
205
+ self .dds_cb ()
132
206
except KeyError :
133
207
pass
134
208
@@ -148,27 +222,53 @@ def get_core_addr(self):
148
222
return None
149
223
150
224
151
- class MonInjTTLDock (dockarea .Dock , TaskObject ):
152
- def __init__ (self ):
153
- dockarea .Dock .__init__ (self , "TTL" , size = (1500 , 500 ))
154
- self .dm = _DeviceManager (self .send_to_device , dict ())
155
- self .transport = None
225
+ class _MonInjDock (dockarea .Dock ):
226
+ def __init__ (self , name ):
227
+ dockarea .Dock .__init__ (self , name , size = (1500 , 500 ))
156
228
157
229
self .grid = QtGui .QGridLayout ()
158
230
gridw = QtGui .QWidget ()
159
231
gridw .setLayout (self .grid )
160
232
self .addWidget (gridw )
161
233
234
+ def layout_widgets (self , widgets ):
235
+ w = self .grid .itemAt (0 )
236
+ while w is not None :
237
+ self .grid .removeItem (w )
238
+ w = self .grid .itemAt (0 )
239
+ for i , (_ , w ) in enumerate (sorted (widgets , key = itemgetter (0 ))):
240
+ self .grid .addWidget (w , i // 4 , i % 4 )
241
+
242
+
243
+ class MonInj (TaskObject ):
244
+ def __init__ (self ):
245
+ self .ttl_dock = _MonInjDock ("TTL" )
246
+ self .dds_dock = _MonInjDock ("DDS" )
247
+
248
+ self .subscriber = Subscriber ("devices" , self .init_devices )
249
+ self .dm = _DeviceManager (self .send_to_device , dict ())
250
+ self .transport = None
251
+
162
252
@asyncio .coroutine
163
- def start (self ):
253
+ def start (self , server , port ):
164
254
loop = asyncio .get_event_loop ()
165
255
yield from loop .create_datagram_endpoint (lambda : self ,
166
256
family = socket .AF_INET )
167
- TaskObject .start (self )
257
+ try :
258
+ yield from self .subscriber .connect (server , port )
259
+ try :
260
+ TaskObject .start (self )
261
+ except :
262
+ yield from self .subscriber .close ()
263
+ raise
264
+ except :
265
+ self .transport .close ()
266
+ raise
168
267
169
268
@asyncio .coroutine
170
269
def stop (self ):
171
270
yield from TaskObject .stop (self )
271
+ yield from self .subscriber .close ()
172
272
if self .transport is not None :
173
273
self .transport .close ()
174
274
self .transport = None
@@ -205,25 +305,12 @@ def _do(self):
205
305
# MONINJ_REQ_MONITOR
206
306
self .send_to_device (b"\x01 " )
207
307
208
- def layout_ttl_widgets (self ):
209
- w = self .grid .itemAt (0 )
210
- while w is not None :
211
- self .grid .removeItem (w )
212
- w = self .grid .itemAt (0 )
213
- for i , (_ , w ) in enumerate (sorted (self .dm .ttl_widgets .items (),
214
- key = itemgetter (0 ))):
215
- self .grid .addWidget (w , i // 4 , i % 4 )
216
-
217
308
def init_devices (self , d ):
218
309
self .dm = _DeviceManager (self .send_to_device , d )
219
- self .dm .ttl_cb = self .layout_ttl_widgets
220
- self .layout_ttl_widgets ()
310
+ self .dm .ttl_cb = lambda : self .ttl_dock .layout_widgets (
311
+ self .dm .ttl_widgets .items ())
312
+ self .dm .dds_cb = lambda : self .dds_dock .layout_widgets (
313
+ self .dm .dds_widgets .items ())
314
+ self .dm .ttl_cb ()
315
+ self .dm .dds_cb ()
221
316
return self .dm
222
-
223
-
224
- class MonInjDDSDock (dockarea .Dock ):
225
- def __init__ (self ):
226
- dockarea .Dock .__init__ (self , "DDS" , size = (1500 , 500 ))
227
-
228
- def init_devices (self , d ):
229
- return d
0 commit comments