qcodespp 0.1.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (82) hide show
  1. qcodespp/__init__.py +77 -0
  2. qcodespp/actions.py +237 -0
  3. qcodespp/data/__init__.py +0 -0
  4. qcodespp/data/data_array.py +555 -0
  5. qcodespp/data/data_set.py +926 -0
  6. qcodespp/data/format.py +338 -0
  7. qcodespp/data/gnuplot_format.py +425 -0
  8. qcodespp/data/hdf5_format.py +537 -0
  9. qcodespp/data/hdf5_format_hickle.py +63 -0
  10. qcodespp/data/io.py +241 -0
  11. qcodespp/data/location.py +171 -0
  12. qcodespp/instrument_drivers/Keysight/Keysight_34450A.py +9 -0
  13. qcodespp/instrument_drivers/Keysight/__init__.py +0 -0
  14. qcodespp/instrument_drivers/Keysight/private/Keysight_344xxA.py +456 -0
  15. qcodespp/instrument_drivers/Keysight/private/__init__.py +0 -0
  16. qcodespp/instrument_drivers/Lakeshore/Model_340.py +483 -0
  17. qcodespp/instrument_drivers/Lakeshore/__init__.py +0 -0
  18. qcodespp/instrument_drivers/QDevil/159fit_params_high_latest.json +386 -0
  19. qcodespp/instrument_drivers/QDevil/159fit_params_low_latest.json +386 -0
  20. qcodespp/instrument_drivers/QDevil/QDAC2.py +3229 -0
  21. qcodespp/instrument_drivers/QDevil/QDAC2_Array.py +300 -0
  22. qcodespp/instrument_drivers/QDevil/QSwitch_elab.py +652 -0
  23. qcodespp/instrument_drivers/QDevil/__init__.py +0 -0
  24. qcodespp/instrument_drivers/ZI/ZIHF2LI.py +415 -0
  25. qcodespp/instrument_drivers/ZI/ZIMFLI.py +764 -0
  26. qcodespp/instrument_drivers/ZI/ZIMFLI_sync.py +108 -0
  27. qcodespp/instrument_drivers/ZI/ZIUHFLI.py +2179 -0
  28. qcodespp/instrument_drivers/ZI/__init__.py +1 -0
  29. qcodespp/instrument_drivers/__init__.py +0 -0
  30. qcodespp/instrument_drivers/cryogenic/CryogenicSMS120C.py +599 -0
  31. qcodespp/instrument_drivers/cryogenic/__init__.py +0 -0
  32. qcodespp/instrument_drivers/instrument_mocks.py +379 -0
  33. qcodespp/instrument_drivers/multiplexer_instrument.py +287 -0
  34. qcodespp/instrument_drivers/national_instruments/PXI_4461.py +451 -0
  35. qcodespp/instrument_drivers/national_instruments/PXI_4462.py +290 -0
  36. qcodespp/instrument_drivers/national_instruments/PXI_6259.py +436 -0
  37. qcodespp/instrument_drivers/national_instruments/PXI_6733.py +230 -0
  38. qcodespp/instrument_drivers/national_instruments/PXI_6733_e.py +243 -0
  39. qcodespp/instrument_drivers/national_instruments/__init__.py +0 -0
  40. qcodespp/instrument_drivers/oxford/__init__.py +0 -0
  41. qcodespp/instrument_drivers/oxford/mercuryiPS_serial.py +658 -0
  42. qcodespp/instrument_drivers/oxford/triton.py +434 -0
  43. qcodespp/instrument_drivers/tektronix/Keithley_2000_Scan.py +65 -0
  44. qcodespp/instrument_drivers/tektronix/Keithley_2182a.py +190 -0
  45. qcodespp/instrument_drivers/tektronix/Keithley_2400.py +158 -0
  46. qcodespp/instrument_drivers/tektronix/Keithley_2450.py +242 -0
  47. qcodespp/instrument_drivers/tektronix/Keithley_2700.py +397 -0
  48. qcodespp/instrument_drivers/tektronix/Keithley_6500.py +161 -0
  49. qcodespp/instrument_drivers/tektronix/__init__.py +0 -0
  50. qcodespp/instrument_drivers/yokogawa/GS200.py +513 -0
  51. qcodespp/instrument_drivers/yokogawa/__init__.py +0 -0
  52. qcodespp/loops.py +1342 -0
  53. qcodespp/measure.py +310 -0
  54. qcodespp/parameters.py +311 -0
  55. qcodespp/plotting/RemotePlot.py +469 -0
  56. qcodespp/plotting/RemotePlotClient.py +367 -0
  57. qcodespp/plotting/RemoteQtPlotWidgets.py +871 -0
  58. qcodespp/plotting/__init__.py +0 -0
  59. qcodespp/plotting/analysis_tools.py +195 -0
  60. qcodespp/plotting/colors.py +135 -0
  61. qcodespp/plotting/offline/__init__.py +0 -0
  62. qcodespp/plotting/offline/datatypes.py +999 -0
  63. qcodespp/plotting/offline/design.py +906 -0
  64. qcodespp/plotting/offline/design.ui +1578 -0
  65. qcodespp/plotting/offline/editor.py +2966 -0
  66. qcodespp/plotting/offline/filters.py +561 -0
  67. qcodespp/plotting/offline/fits.py +1171 -0
  68. qcodespp/plotting/offline/helpers.py +288 -0
  69. qcodespp/plotting/offline/iconGadget.png +0 -0
  70. qcodespp/plotting/offline/main.py +55 -0
  71. qcodespp/plotting/offline/popupwindows.py +1848 -0
  72. qcodespp/plotting/offline/qcodes_pp_extension.py +328 -0
  73. qcodespp/plotting/offline/sidebars.py +1108 -0
  74. qcodespp/station.py +290 -0
  75. qcodespp/utils/__init__.py +0 -0
  76. qcodespp/utils/helpers.py +618 -0
  77. qcodespp/utils/visa_helpers.py +61 -0
  78. qcodespp/version.py +12 -0
  79. qcodespp-0.1.0.dist-info/METADATA +91 -0
  80. qcodespp-0.1.0.dist-info/RECORD +82 -0
  81. qcodespp-0.1.0.dist-info/WHEEL +4 -0
  82. qcodespp-0.1.0.dist-info/licenses/LICENSE +21 -0
@@ -0,0 +1,367 @@
1
+ '''
2
+ Back-end functions used in live plotting. Not intended to be used directly.
3
+ '''
4
+
5
+
6
+ import sys
7
+ import os
8
+ import re
9
+ import zmq
10
+ import numpy as np
11
+ import json
12
+ import time
13
+
14
+ from pyqtgraph import dockarea
15
+
16
+ from PyQt5 import QtCore, QtGui, QtWidgets
17
+ from PyQt5.QtWidgets import QWidget, QShortcut, QHBoxLayout
18
+ from PyQt5.QtCore import QBuffer, QIODevice, QByteArray
19
+ from PyQt5.QtCore import QObject, pyqtSlot
20
+
21
+ from RemoteQtPlotWidgets import QtPlot
22
+
23
+
24
+ qtapp = QtWidgets.QApplication([])
25
+
26
+ # set app icon
27
+ app_icon = QtGui.QIcon()
28
+ app_icon.addFile('icons/icon_16.png', QtCore.QSize(16,16))
29
+ app_icon.addFile('icons/icon_24.png', QtCore.QSize(24,24))
30
+ app_icon.addFile('icons/icon_32.png', QtCore.QSize(32,32))
31
+ app_icon.addFile('icons/icon_48.png', QtCore.QSize(48,48))
32
+ app_icon.addFile('icons/icon_256.png', QtCore.QSize(256,256))
33
+ qtapp.setWindowIcon(app_icon)
34
+
35
+ class DataSet():
36
+
37
+ def __init__(self, dataset_id):
38
+ self.id = dataset_id
39
+ self.arrays = {}
40
+ self.metadata = {}
41
+
42
+ def add_metadata(self, metadata):
43
+ self.metadata.update(metadata)
44
+
45
+ def get_array(self, array_id, shape=100):
46
+ if not array_id in self.arrays.keys():
47
+ array = self.new_array(array_id, shape=shape)
48
+ return self.arrays[array_id]
49
+
50
+ def new_array(self, array_id, shape):
51
+ self.arrays[array_id] = np.empty(shape=shape)
52
+ self.arrays[array_id][:] = np.nan
53
+ return self.arrays[array_id]
54
+
55
+ def store(self, array_id, indices, values):
56
+ try:
57
+ self.arrays[array_id][indices] = values
58
+ except:
59
+ pass
60
+
61
+
62
+ class ZeroMQ_Listener(QtCore.QObject):
63
+
64
+ message = QtCore.pyqtSignal(str, str, dict)
65
+
66
+ def __init__(self, topic, port):
67
+
68
+ QtCore.QObject.__init__(self)
69
+
70
+ # Socket to talk to server
71
+ context = zmq.Context()
72
+ self.socket = context.socket(zmq.SUB)
73
+ self.socket.connect("tcp://localhost:%s" % (port))
74
+ self.socket.setsockopt(zmq.SUBSCRIBE, bytes(topic.encode('utf-8')))
75
+
76
+ self.poller = zmq.Poller()
77
+ self.poller.register(self.socket, zmq.POLLIN)
78
+
79
+ self.running = True
80
+
81
+ def loop(self):
82
+ while self.running:
83
+ socks = dict(self.poller.poll(500))
84
+ if socks.get(self.socket) == zmq.POLLIN:
85
+ # try:
86
+ parts = self.socket.recv_multipart()
87
+ topic, uuid, msg = parts[:3]
88
+
89
+ topic = topic.decode()
90
+ uuid = uuid.decode()
91
+ data = json.loads(msg.decode())
92
+
93
+ if len(parts) > 3:
94
+ meta = parts[3]
95
+ meta = json.loads(meta.decode())
96
+ arrays = parts[4:]
97
+
98
+ data_arrays = {}
99
+ for m, a in zip(meta, arrays):
100
+ arr = np.frombuffer(
101
+ a, dtype=m['dtype']).reshape(m['shape'])
102
+
103
+ data_arrays[m['array_id']] = arr
104
+ data['add_plot']['data_arrays'] = data_arrays
105
+
106
+ self.message.emit(topic, uuid, data)
107
+
108
+
109
+ class QtPlotWindow(QtWidgets.QWidget):
110
+
111
+ def __init__(self, topic, port, control_port=None, parent=None, theme=((60, 60, 60), 'w'),):
112
+ QtWidgets.QMainWindow.__init__(self, parent)
113
+ self.control_port = control_port
114
+
115
+ self.stores = {}
116
+ self.plots = []
117
+
118
+ self.theme = theme
119
+
120
+
121
+
122
+ self.set_title('Plot')
123
+ self.title_parts = []
124
+
125
+ self.plot = QtPlot()
126
+
127
+ layout = QHBoxLayout()
128
+ layout.setContentsMargins(0, 0, 0, 0)
129
+ layout.addWidget(self.plot)
130
+ self.setLayout(layout)
131
+
132
+ QShortcut(QtGui.QKeySequence("Ctrl+W"), self, self.close)
133
+ QShortcut(QtGui.QKeySequence("Ctrl+Q"), self, self.close)
134
+
135
+ desktop = QtWidgets.QApplication.desktop()
136
+ screenRect = desktop.screenGeometry(0)
137
+ windowRect = QtCore.QRect(0, 0, 1200, 900)
138
+ windowRect.moveTopRight(screenRect.topRight()-QtCore.QPoint(0, -50))
139
+ self.setGeometry(windowRect)
140
+
141
+ self.thread = QtCore.QThread()
142
+ self.zeromq_listener = ZeroMQ_Listener(topic, port)
143
+ self.zeromq_listener.moveToThread(self.thread)
144
+
145
+ self.thread.started.connect(self.zeromq_listener.loop)
146
+ self.zeromq_listener.message.connect(self.signal_received)
147
+
148
+ QtCore.QTimer.singleShot(0, self.thread.start)
149
+
150
+
151
+ if self.control_port is not None:
152
+ self.control_context = zmq.Context()
153
+ self.control_socket = self.control_context.socket(zmq.PUB)
154
+ self.control_socket.connect(
155
+ "tcp://localhost:%s" % (self.control_port))
156
+
157
+ # Only way on windows to make it open on top of others...
158
+ # And it doesn't really work :O
159
+ self.setWindowFlags(self.windowFlags() &
160
+ QtCore.Qt.WindowStaysOnTopHint)
161
+ self.setWindowFlags(self.windowFlags() & ~
162
+ QtCore.Qt.WindowStaysOnTopHint)
163
+ self.show()
164
+
165
+ self.update_interval = 1
166
+ self._last_update = time.perf_counter()
167
+ self._do_update = False
168
+
169
+ self.update_timer = QtCore.QTimer()
170
+ self.update_timer.timeout.connect(self.auto_update)
171
+ self.update_timer.start(50)
172
+
173
+ self.control_send({'client_ready': True})
174
+ cwd = os.getcwd()
175
+ self.control_send({'client_dir': str(cwd)})
176
+
177
+
178
+ def auto_update(self):
179
+
180
+ # if dt < self.update_interval:
181
+ # QtCore.QTimer.singleShot(0. 1, self._auto_update)
182
+
183
+ if self._do_update:
184
+ for plot in self.plots:
185
+ # TODO only update when there is new data
186
+ plot['plot_item'].update_data()
187
+ self._last_update = time.perf_counter()
188
+ self._do_update = False
189
+
190
+ def control_send(self, data):
191
+ if self.control_port is not None:
192
+ self.control_socket.send_json(data)
193
+
194
+ def get_default_title(self):
195
+ self.title_parts = sorted(list(set(self.title_parts)))
196
+ title = ', '.join(self.title_parts)
197
+ if title == '':
198
+ title = 'Plot'
199
+ return title
200
+
201
+
202
+ def set_title(self, title=None):
203
+
204
+ if title is None:
205
+ title = self.get_default_title()
206
+
207
+ self.setWindowTitle(title)
208
+
209
+
210
+ def signal_received(self, topic, uuid, message):
211
+ if uuid not in self.stores:
212
+ self.stores[uuid] = DataSet(uuid)
213
+ store = self.stores[uuid]
214
+
215
+ for key, msg in message.items():
216
+ if key == 'new_dataset':
217
+ store.add_metadata(msg)
218
+ elif key == 'clear_plot':
219
+ del self.stores
220
+ self.stores = {}
221
+
222
+ for p in self.plots:
223
+ del p
224
+ self.plots = []
225
+ self.title_parts = []
226
+
227
+
228
+ self.plot.clear()
229
+
230
+ elif key == 'metadata':
231
+ store.add_metadata(msg)
232
+
233
+ if 'arrays' in msg:
234
+ arrays = msg['arrays']
235
+ for array_id, value in arrays.items():
236
+ store.get_array(array_id, arrays[array_id]['shape'])
237
+
238
+ elif key == 'add_plot':
239
+ data_arrays = msg.get('data_arrays', None)
240
+ for ax in 'xyz':
241
+ array_info = msg.get(ax+'_info', None)
242
+ if array_info is not None:
243
+ array_id = array_info.get('array_id', None)
244
+ if array_info.get('location', None) is not None:
245
+ self.title_parts.append(array_info['location'])
246
+
247
+ if array_id is not None:
248
+ msg[ax] = store.get_array(array_id, array_info['shape'])
249
+ if data_arrays is not None:
250
+ data = data_arrays.get(array_id, None)
251
+ if data is not None:
252
+ msg[ax] = data
253
+ # print(msg)
254
+ pi = self.plot.add(**msg)
255
+
256
+ msg['plot_item'] = pi
257
+ self.plots.append(msg)
258
+ self.set_title()
259
+
260
+ elif key == 'data':
261
+
262
+ if store.arrays == {}:
263
+ return
264
+ ids_values = msg['values']
265
+ loop_indices = tuple(msg['indices'])
266
+
267
+ for array_id, value in ids_values.items():
268
+ store.store(array_id, loop_indices, value)
269
+ self._do_update = True
270
+
271
+ elif key == 'finalize':
272
+ self.save()
273
+ elif key == 'save_screenshot':
274
+ filename, subplot = msg['filename'], msg['subplot']
275
+ print(filename)
276
+ if subplot == 'all':
277
+ for i in range(len(self.plot.area.docks)):
278
+ self.save(filename, i)
279
+ else:
280
+ self.save(filename, subplot)
281
+ elif key == 'set_title':
282
+ self.setWindowTitle(msg)
283
+ elif key == 'set_cmap':
284
+ for dock in self.plot.area.docks.keys():
285
+ self.plot.area.docks[dock].set_cmap(msg)
286
+
287
+
288
+ else:
289
+ pass
290
+
291
+ self.control_send({'client_ready': True})
292
+
293
+ def update_labels(self):
294
+ # for array_id, plot in self.plots.items():
295
+ pass
296
+
297
+ def save(self, filename=None, subplot=None):
298
+ """
299
+ Save current plot to filename, by default
300
+ to the location corresponding to the default
301
+ title.
302
+
303
+ Args:
304
+ filename (Optional[str]): Location of the file
305
+ """
306
+
307
+ if len(self.title_parts)>0:
308
+ default = "{}".format(self.title_parts[-1])
309
+ else:
310
+ default = 'Plot'
311
+
312
+ if (filename is None) or (filename == 'None'):
313
+ filename = default
314
+
315
+ filename = re.sub(r"\.png$", "", filename)
316
+ filename = filename.rstrip('\\')
317
+ filename = filename.rstrip('/')
318
+ if subplot is None:
319
+ image = self.grab()
320
+ else:
321
+ image = self.plot._get_dock(int(subplot)).grab()
322
+ filename = '%s #%d'%(filename, int(subplot))
323
+
324
+ i = 0
325
+ oldfilename = filename
326
+ while os.path.isfile(filename+'.png'):
327
+ filename = oldfilename + '_%d'%i
328
+ i+=1
329
+ self.control_send({'plot_saved': filename+'.png'})
330
+ print(filename+'.png')
331
+ image.save(filename+'.png', "PNG", 0)
332
+
333
+ def closeEvent(self, event):
334
+ self.zeromq_listener.running = False
335
+ self.thread.quit()
336
+ self.thread.wait()
337
+ self.control_send({'client_closed': True})
338
+ event.accept()
339
+
340
+ if __name__ == '__main__':
341
+ import sys
342
+
343
+ control_port = None
344
+ if len(sys.argv) > 1:
345
+ topic = str(sys.argv[1])
346
+ port = str(sys.argv[2])
347
+ control_port = str(sys.argv[3])
348
+ else:
349
+ port, topic = (8883, 'qcodes.plot.b1c4400fea6546afbae3bfead88bc234')
350
+
351
+ mw = QtPlotWindow(topic=topic, port=port, control_port=control_port)
352
+
353
+ # set app icon
354
+ app_icon = QtGui.QIcon()
355
+ app_icon.addFile('icons/icon_16.png', QtCore.QSize(16,16))
356
+ app_icon.addFile('icons/icon_24.png', QtCore.QSize(24,24))
357
+ app_icon.addFile('icons/icon_32.png', QtCore.QSize(32,32))
358
+ app_icon.addFile('icons/icon_48.png', QtCore.QSize(48,48))
359
+ app_icon.addFile('icons/icon_256.png', QtCore.QSize(256,256))
360
+ mw.setWindowIcon(app_icon)
361
+
362
+ # mw.signal_received(topic=topic, uuid=None, message ={'save_screenshot': {'filename': str('./aafsd/asdfnp'), 'subplot': 'all'}})
363
+
364
+ # mw.save()
365
+
366
+ if (sys.flags.interactive != 1) or not hasattr(QtCore, 'PYQT_VERSION'):
367
+ QtWidgets.QApplication.instance().exec_()