diff --git a/Untitled.ipynb b/Untitled.ipynb
new file mode 100644
index 000000000..5b9dd1cb2
--- /dev/null
+++ b/Untitled.ipynb
@@ -0,0 +1,467 @@
+{
+ "cells": [
+ {
+ "cell_type": "code",
+ "execution_count": 1,
+ "metadata": {
+ "collapsed": false
+ },
+ "outputs": [
+ {
+ "data": {
+ "application/javascript": [
+ "/*\r\n",
+ " * Qcodes Jupyter/IPython widgets\r\n",
+ " */\r\n",
+ "require([\r\n",
+ " 'nbextensions/widgets/widgets/js/widget',\r\n",
+ " 'nbextensions/widgets/widgets/js/manager'\r\n",
+ "], function (widget, manager) {\r\n",
+ "\r\n",
+ " var UpdateView = widget.DOMWidgetView.extend({\r\n",
+ " render: function() {\r\n",
+ " window.MYWIDGET = this;\r\n",
+ " this._interval = 0;\r\n",
+ " this.update();\r\n",
+ " },\r\n",
+ " update: function() {\r\n",
+ " this.display(this.model.get('_message'));\r\n",
+ " this.setInterval();\r\n",
+ " },\r\n",
+ " display: function(message) {\r\n",
+ " /*\r\n",
+ " * display method: override this for custom display logic\r\n",
+ " */\r\n",
+ " this.el.innerHTML = message;\r\n",
+ " },\r\n",
+ " remove: function() {\r\n",
+ " clearInterval(this._updater);\r\n",
+ " },\r\n",
+ " setInterval: function(newInterval) {\r\n",
+ " var me = this;\r\n",
+ " if(newInterval===undefined) newInterval = me.model.get('interval');\r\n",
+ " if(newInterval===me._interval) return;\r\n",
+ "\r\n",
+ " me._interval = newInterval;\r\n",
+ "\r\n",
+ " if(me._updater) clearInterval(me._updater);\r\n",
+ "\r\n",
+ " if(me._interval) {\r\n",
+ " me._updater = setInterval(function() {\r\n",
+ " me.send({myupdate: true});\r\n",
+ " if(!me.model.comm_live) {\r\n",
+ " console.log('missing comm, canceling widget updates', me);\r\n",
+ " clearInterval(me._updater);\r\n",
+ " }\r\n",
+ " }, me._interval * 1000);\r\n",
+ " }\r\n",
+ " }\r\n",
+ " });\r\n",
+ " manager.WidgetManager.register_widget_view('UpdateView', UpdateView);\r\n",
+ "\r\n",
+ " var HiddenUpdateView = UpdateView.extend({\r\n",
+ " display: function(message) {\r\n",
+ " this.$el.hide();\r\n",
+ " }\r\n",
+ " });\r\n",
+ " manager.WidgetManager.register_widget_view('HiddenUpdateView', HiddenUpdateView);\r\n",
+ "\r\n",
+ " var SubprocessView = UpdateView.extend({\r\n",
+ " render: function() {\r\n",
+ " var me = this;\r\n",
+ " me._interval = 0;\r\n",
+ " me._minimize = '';\r\n",
+ " me._restore = '';\r\n",
+ "\r\n",
+ " // max lines of output to show\r\n",
+ " me.maxOutputLength = 500;\r\n",
+ "\r\n",
+ " // in case there is already an outputView present,\r\n",
+ " // like from before restarting the kernel\r\n",
+ " $('.qcodes-output-view').not(me.$el).remove();\r\n",
+ "\r\n",
+ " me.$el\r\n",
+ " .addClass('qcodes-output-view')\r\n",
+ " .attr('qcodes-state', 'docked')\r\n",
+ " .html(\r\n",
+ " '
' +\r\n",
+ " ''\r\n",
+ " );\r\n",
+ "\r\n",
+ " me.clearButton = me.$el.find('.qcodes-clear-output');\r\n",
+ " me.minButton = me.$el.find('.qcodes-minimize');\r\n",
+ " me.outputArea = me.$el.find('pre');\r\n",
+ " me.subprocessList = me.$el.find('.qcodes-process-list');\r\n",
+ " me.abortButton = me.$el.find('.qcodes-abort-loop');\r\n",
+ " me.processLinesButton = me.$el.find('.qcodes-processlines')\r\n",
+ "\r\n",
+ " me.outputLines = [];\r\n",
+ "\r\n",
+ " me.clearButton.click(function() {\r\n",
+ " me.outputArea.html('');\r\n",
+ " me.clearButton.addClass('disabled');\r\n",
+ " });\r\n",
+ "\r\n",
+ " me.abortButton.click(function() {\r\n",
+ " me.send({abort: true});\r\n",
+ " });\r\n",
+ "\r\n",
+ " me.processLinesButton.click(function() {\r\n",
+ " // toggle multiline process list display\r\n",
+ " me.subprocessesMultiline = !me.subprocessesMultiline;\r\n",
+ " me.showSubprocesses();\r\n",
+ " });\r\n",
+ "\r\n",
+ " me.$el.find('.js-state').click(function() {\r\n",
+ " var state = this.className.substr(this.className.indexOf('qcodes'))\r\n",
+ " .split('-')[1].split(' ')[0];\r\n",
+ " me.model.set('_state', state);\r\n",
+ " });\r\n",
+ "\r\n",
+ " $(window)\r\n",
+ " .off('resize.qcodes')\r\n",
+ " .on('resize.qcodes', function() {me.clipBounds();});\r\n",
+ "\r\n",
+ " me.update();\r\n",
+ " },\r\n",
+ "\r\n",
+ " updateState: function() {\r\n",
+ " var me = this,\r\n",
+ " oldState = me.$el.attr('qcodes-state'),\r\n",
+ " state = me.model.get('_state');\r\n",
+ "\r\n",
+ " if(state === oldState) return;\r\n",
+ "\r\n",
+ " setTimeout(function() {\r\n",
+ " // not sure why I can't pop it out of the widgetarea in render, but it seems that\r\n",
+ " // some other bit of code resets the parent after render if I do it there.\r\n",
+ " // To be safe, just do it on every state click.\r\n",
+ " me.$el.appendTo('body');\r\n",
+ "\r\n",
+ " if(oldState === 'floated') {\r\n",
+ " console.log('here');\r\n",
+ " me.$el.draggable('destroy').css({left:'', top: ''});\r\n",
+ " }\r\n",
+ "\r\n",
+ " me.$el.attr('qcodes-state', state);\r\n",
+ "\r\n",
+ " if(state === 'floated') {\r\n",
+ " me.$el\r\n",
+ " .draggable({stop: function() { me.clipBounds(); }})\r\n",
+ " .css({\r\n",
+ " left: window.innerWidth - me.$el.width() - 15,\r\n",
+ " top: window.innerHeight - me.$el.height() - 10\r\n",
+ " });\r\n",
+ " }\r\n",
+ "\r\n",
+ " // any previous highlighting is now moot\r\n",
+ " me.$el.removeClass('qcodes-highlight');\r\n",
+ " }, 0);\r\n",
+ "\r\n",
+ " },\r\n",
+ "\r\n",
+ " clipBounds: function() {\r\n",
+ " var me = this;\r\n",
+ " if(me.$el.attr('qcodes-state') === 'floated') {\r\n",
+ " var bounds = me.$el[0].getBoundingClientRect(),\r\n",
+ " minVis = 40,\r\n",
+ " maxLeft = window.innerWidth - minVis,\r\n",
+ " minLeft = minVis - bounds.width,\r\n",
+ " maxTop = window.innerHeight - minVis;\r\n",
+ "\r\n",
+ " if(bounds.left > maxLeft) me.$el.css('left', maxLeft);\r\n",
+ " else if(bounds.left < minLeft) me.$el.css('left', minLeft);\r\n",
+ "\r\n",
+ " if(bounds.top > maxTop) me.$el.css('top', maxTop);\r\n",
+ " else if(bounds.top < 0) me.$el.css('top', 0);\r\n",
+ " }\r\n",
+ " },\r\n",
+ "\r\n",
+ " display: function(message) {\r\n",
+ " var me = this;\r\n",
+ " if(message) {\r\n",
+ " var initialScroll = me.outputArea.scrollTop();\r\n",
+ " me.outputArea.scrollTop(me.outputArea.prop('scrollHeight'));\r\n",
+ " var scrollBottom = me.outputArea.scrollTop();\r\n",
+ "\r\n",
+ " if(me.$el.attr('qcodes-state') === 'minimized') {\r\n",
+ " // if we add text and the box is minimized, highlight the\r\n",
+ " // title bar to alert the user that there are new messages.\r\n",
+ " // remove then add the class, so we get the animation again\r\n",
+ " // if it's already highlighted\r\n",
+ " me.$el.removeClass('qcodes-highlight');\r\n",
+ " setTimeout(function(){\r\n",
+ " me.$el.addClass('qcodes-highlight');\r\n",
+ " }, 0);\r\n",
+ " }\r\n",
+ "\r\n",
+ " var newLines = message.split('\\n'),\r\n",
+ " out = me.outputLines,\r\n",
+ " outLen = out.length;\r\n",
+ " if(outLen) out[outLen - 1] += newLines[0];\r\n",
+ " else out.push(newLines[0]);\r\n",
+ "\r\n",
+ " for(var i = 1; i < newLines.length; i++) {\r\n",
+ " out.push(newLines[i]);\r\n",
+ " }\r\n",
+ "\r\n",
+ " if(out.length > me.maxOutputLength) {\r\n",
+ " out.splice(0, out.length - me.maxOutputLength + 1,\r\n",
+ " '<<< Output clipped >>>');\r\n",
+ " }\r\n",
+ "\r\n",
+ " me.outputArea.text(out.join('\\n'));\r\n",
+ " me.clearButton.removeClass('disabled');\r\n",
+ "\r\n",
+ " // if we were scrolled to the bottom initially, make sure\r\n",
+ " // we stay that way.\r\n",
+ " me.outputArea.scrollTop(initialScroll === scrollBottom ?\r\n",
+ " me.outputArea.prop('scrollHeight') : initialScroll);\r\n",
+ " }\r\n",
+ "\r\n",
+ " me.showSubprocesses();\r\n",
+ " me.updateState();\r\n",
+ " },\r\n",
+ "\r\n",
+ " showSubprocesses: function() {\r\n",
+ " var me = this,\r\n",
+ " replacer = me.subprocessesMultiline ? '
' : ', ',\r\n",
+ " processes = (me.model.get('_processes') || '')\r\n",
+ " .replace(/\\n/g, '>' + replacer + '<');\r\n",
+ "\r\n",
+ " if(processes) processes = '<' + processes + '>';\r\n",
+ " else processes = 'No subprocesses';\r\n",
+ "\r\n",
+ " me.abortButton.toggleClass('disabled', processes.indexOf('Measurement')===-1);\r\n",
+ "\r\n",
+ " me.subprocessList.html(processes);\r\n",
+ " }\r\n",
+ " });\r\n",
+ " manager.WidgetManager.register_widget_view('SubprocessView', SubprocessView);\r\n",
+ "});\r\n"
+ ],
+ "text/plain": [
+ ""
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "text/html": [
+ ""
+ ],
+ "text/plain": [
+ ""
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ }
+ ],
+ "source": [
+ "import qcodes as qc"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 2,
+ "metadata": {
+ "collapsed": false
+ },
+ "outputs": [],
+ "source": [
+ "qc.show_subprocess_widget()"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 1,
+ "metadata": {
+ "collapsed": false
+ },
+ "outputs": [],
+ "source": [
+ "import ipympl"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 2,
+ "metadata": {
+ "collapsed": true
+ },
+ "outputs": [],
+ "source": [
+ "from matplotlib import pyplot as plt"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {
+ "collapsed": true
+ },
+ "outputs": [],
+ "source": []
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {
+ "collapsed": true
+ },
+ "outputs": [],
+ "source": [
+ "%matplotlib notebook"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 3,
+ "metadata": {
+ "collapsed": false
+ },
+ "outputs": [
+ {
+ "ename": "AttributeError",
+ "evalue": "'FigureCanvasNbAgg' object has no attribute '_png_buffer'",
+ "output_type": "error",
+ "traceback": [
+ "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
+ "\u001b[0;31mAttributeError\u001b[0m Traceback (most recent call last)",
+ "\u001b[0;32mC:\\Users\\lab.BluG12Meas\\Anaconda3\\lib\\site-packages\\ipympl\\backend_nbagg.py\u001b[0m in \u001b[0;36m_handle_message\u001b[0;34m(self, object, message, buffers)\u001b[0m\n\u001b[1;32m 164\u001b[0m \u001b[0mself\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0msend_json\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;34m'refresh'\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m 165\u001b[0m \u001b[1;32melse\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m--> 166\u001b[0;31m \u001b[0mself\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mmanager\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mhandle_json\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mmessage\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 167\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m 168\u001b[0m \u001b[1;32mdef\u001b[0m \u001b[0msend_json\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mself\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mcontent\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n",
+ "\u001b[0;32mC:\\Users\\lab.BluG12Meas\\Anaconda3\\lib\\site-packages\\matplotlib\\backends\\backend_webagg_core.py\u001b[0m in \u001b[0;36mhandle_json\u001b[0;34m(self, content)\u001b[0m\n\u001b[1;32m 467\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m 468\u001b[0m \u001b[1;32mdef\u001b[0m \u001b[0mhandle_json\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mself\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mcontent\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m--> 469\u001b[0;31m \u001b[0mself\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mcanvas\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mhandle_event\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mcontent\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 470\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m 471\u001b[0m \u001b[1;32mdef\u001b[0m \u001b[0mrefresh_all\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mself\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n",
+ "\u001b[0;32mC:\\Users\\lab.BluG12Meas\\Anaconda3\\lib\\site-packages\\matplotlib\\backends\\backend_webagg_core.py\u001b[0m in \u001b[0;36mhandle_event\u001b[0;34m(self, event)\u001b[0m\n\u001b[1;32m 285\u001b[0m \u001b[1;32mpass\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m 286\u001b[0m \u001b[1;32melif\u001b[0m \u001b[0me_type\u001b[0m \u001b[1;33m==\u001b[0m \u001b[1;34m'draw'\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m--> 287\u001b[0;31m \u001b[0mself\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mdraw\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 288\u001b[0m elif e_type in ('button_press', 'button_release', 'motion_notify',\n\u001b[1;32m 289\u001b[0m 'figure_enter', 'figure_leave', 'scroll'):\n",
+ "\u001b[0;32mC:\\Users\\lab.BluG12Meas\\Anaconda3\\lib\\site-packages\\matplotlib\\backends\\backend_webagg_core.py\u001b[0m in \u001b[0;36mdraw\u001b[0;34m(self)\u001b[0m\n\u001b[1;32m 180\u001b[0m \u001b[0mbackend_agg\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mRendererAgg\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mlock\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mrelease\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m 181\u001b[0m \u001b[1;31m# Swap the frames\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m--> 182\u001b[0;31m \u001b[0mself\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mmanager\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mrefresh_all\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 183\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m 184\u001b[0m \u001b[1;32mdef\u001b[0m \u001b[0mdraw_idle\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mself\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n",
+ "\u001b[0;32mC:\\Users\\lab.BluG12Meas\\Anaconda3\\lib\\site-packages\\matplotlib\\backends\\backend_webagg_core.py\u001b[0m in \u001b[0;36mrefresh_all\u001b[0;34m(self)\u001b[0m\n\u001b[1;32m 471\u001b[0m \u001b[1;32mdef\u001b[0m \u001b[0mrefresh_all\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mself\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m 472\u001b[0m \u001b[1;32mif\u001b[0m \u001b[0mself\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mweb_sockets\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m--> 473\u001b[0;31m \u001b[0mdiff\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mself\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mcanvas\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mget_diff_image\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 474\u001b[0m \u001b[1;32mfor\u001b[0m \u001b[0ms\u001b[0m \u001b[1;32min\u001b[0m \u001b[0mself\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mweb_sockets\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m 475\u001b[0m \u001b[0ms\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0msend_binary\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mdiff\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n",
+ "\u001b[0;32mC:\\Users\\lab.BluG12Meas\\Anaconda3\\lib\\site-packages\\matplotlib\\backends\\backend_webagg_core.py\u001b[0m in \u001b[0;36mget_diff_image\u001b[0;34m(self)\u001b[0m\n\u001b[1;32m 230\u001b[0m \u001b[1;31m# each time. This reduces the number of memory\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m 231\u001b[0m \u001b[1;31m# (de)allocations.\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m--> 232\u001b[0;31m \u001b[0mself\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0m_png_buffer\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mtruncate\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 233\u001b[0m \u001b[0mself\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0m_png_buffer\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mseek\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;36m0\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m 234\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n",
+ "\u001b[0;31mAttributeError\u001b[0m: 'FigureCanvasNbAgg' object has no attribute '_png_buffer'"
+ ]
+ }
+ ],
+ "source": [
+ "plt.figure()\n",
+ "plt.show()"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": null,
+ "metadata": {
+ "collapsed": true
+ },
+ "outputs": [],
+ "source": [
+ "\n"
+ ]
+ }
+ ],
+ "metadata": {
+ "anaconda-cloud": {},
+ "kernelspec": {
+ "display_name": "Python [Root]",
+ "language": "python",
+ "name": "Python [Root]"
+ },
+ "language_info": {
+ "codemirror_mode": {
+ "name": "ipython",
+ "version": 3
+ },
+ "file_extension": ".py",
+ "mimetype": "text/x-python",
+ "name": "python",
+ "nbconvert_exporter": "python",
+ "pygments_lexer": "ipython3",
+ "version": "3.5.2"
+ }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 0
+}
diff --git a/qcodesrc.json b/qcodesrc.json
new file mode 100644
index 000000000..92f171d15
--- /dev/null
+++ b/qcodesrc.json
@@ -0,0 +1,68 @@
+{
+ "user": {
+ "data_folder": "E:\\EWJN\\data",
+ "properties": {
+ "frequency_NMR": 66500000.0,
+ "frequency_ESR": 27951000000.0,
+ "t_read": 20,
+ "t_skip": 0.1,
+ "frequencies_ESR": {
+ "down": 27951000000.0,
+ "up": 27852500000.0
+ },
+ "samples": 100,
+ "readout_threshold_voltage": 0.3333333333333333
+ },
+ "pulses": {
+ "adiabatic_ESR": {
+ "duration": 0.15,
+ "frequency_deviation": 1000000.0,
+ "t_start": 3,
+ "power": 0
+ },
+ "steered_initialization_long": {
+ "t_no_blip": 200,
+ "t_max_wait": 1000
+ },
+ "steered_initialization": {
+ "t_no_blip": 120,
+ "enabled": false,
+ "t_max_wait": 400,
+ "t_buffer": 30
+ },
+ "read_long": {
+ "duration": 120
+ },
+ "empty": {
+ "amplitude": -1.5,
+ "duration": 5
+ },
+ "read": {
+ "amplitude": 0,
+ "duration": 40
+ },
+ "plunge": {
+ "amplitude": 2,
+ "duration": 5
+ },
+ "final": {
+ "amplitude": 0,
+ "duration": 2
+ },
+ "adiabatic_NMR": {
+ "duration": 0.5,
+ "frequency_deviation": 100000.0,
+ "t_start": 3,
+ "power": 0
+ }
+ }
+ },
+ "gui": {
+ "plotlib": "matplotlib",
+ "notebook": true
+ },
+ "core": {
+ "loglevel": "DEBUG",
+ "legacy_mp": true
+ }
+}
\ No newline at end of file
diff --git a/qcodesrc_schema.json b/qcodesrc_schema.json
new file mode 100644
index 000000000..f79ce62f8
--- /dev/null
+++ b/qcodesrc_schema.json
@@ -0,0 +1,68 @@
+{
+ "type": "object",
+ "required": [
+ "gui",
+ "core",
+ "user"
+ ],
+ "description": "schema for a qcodes config file",
+ "$schema": "http://json-schema.org/draft-04/schema#",
+ "properties": {
+ "user": {
+ "type": "object",
+ "description": "controls user settings of qcodes",
+ "properties": {}
+ },
+ "gui": {
+ "type": "object",
+ "required": [
+ "notebook",
+ "plotlib"
+ ],
+ "description": "controls gui of qcodes",
+ "properties": {
+ "plotlib": {
+ "type": "string",
+ "default": "matplotlib",
+ "description": "Plotting library",
+ "enum": [
+ "QT",
+ "matplotlib"
+ ]
+ },
+ "notebook": {
+ "type": "boolean",
+ "description": "Use notebook frontend",
+ "default": true
+ }
+ }
+ },
+ "core": {
+ "type": "object",
+ "required": [
+ "legacy_mp",
+ "loglevel"
+ ],
+ "description": "controls core settings of qcodes",
+ "properties": {
+ "loglevel": {
+ "type": "string",
+ "enum": [
+ "CRITICAL",
+ "ERROR",
+ "WARNING",
+ "INFO",
+ "DEBUG"
+ ],
+ "description": "control logging level",
+ "default": "DEBUG"
+ },
+ "legacy_mp": {
+ "type": "boolean",
+ "description": "control legacy buggy multiprocess",
+ "default": false
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/silq.egg-info/SOURCES.txt b/silq.egg-info/SOURCES.txt
index 186f6a7b0..a62511035 100644
--- a/silq.egg-info/SOURCES.txt
+++ b/silq.egg-info/SOURCES.txt
@@ -30,6 +30,8 @@ silq/meta_instruments/__init__.py
silq/meta_instruments/chip.py
silq/meta_instruments/hack_instrument.py
silq/meta_instruments/layout.py
+silq/meta_instruments/lockin.py
+silq/meta_instruments/simrack.py
silq/meta_instruments/voltage_control.py
silq/meta_instruments/mock_instruments/__init__.py
silq/meta_instruments/mock_instruments/mock_ATS.py
@@ -46,6 +48,7 @@ silq/pulses/__init__.py
silq/pulses/pulse_modules.py
silq/pulses/pulse_types.py
silq/tests/__init__.py
+silq/tests/test_gui.py
silq/tests/test_instruments.py
silq/tests/test_parameters.py
silq/tools/__init__.py
diff --git a/silq/tests/test_gui.py b/silq/tests/test_gui.py
new file mode 100644
index 000000000..375750676
--- /dev/null
+++ b/silq/tests/test_gui.py
@@ -0,0 +1,58 @@
+import time
+from threading import Thread
+from winsound import Beep
+import sys
+from PyQt4 import QtGui
+
+from qcodes.process.server import BaseServer
+
+
+class GUIServer(BaseServer):
+ def __init__(self, query_queue, response_queue, extras=None):
+ super().__init__(query_queue, response_queue, extras)
+
+ app = QtGui.QApplication(sys.argv)
+ self.gui = ExampleGui(query_queue, response_queue)
+ sys.exit(app.exec_())
+
+ def handle_add_text(self, text):
+ self.example_gui.add_text(text)
+
+class ExampleGui(QtGui.QMainWindow):
+ def __init__(self, query_queue, response_queue):
+ super().__init__()
+
+ self.initUI()
+ self.textEdit.append('hi')
+
+ def initUI(self):
+ textEdit = QtGui.QTextEdit()
+ self.setCentralWidget(textEdit)
+ self.textEdit = textEdit
+
+ exitAction = QtGui.QAction(QtGui.QIcon('exit24.png'), 'Exit', self)
+ exitAction.setShortcut('Ctrl+Q')
+ exitAction.setStatusTip('Exit application')
+ exitAction.triggered.connect(self.close)
+
+ self.statusBar()
+
+ menubar = self.menuBar()
+ fileMenu = menubar.addMenu('&File')
+ fileMenu.addAction(exitAction)
+
+ toolbar = self.addToolBar('Exit')
+ toolbar.addAction(exitAction)
+
+ self.setGeometry(300, 300, 350, 250)
+ self.setWindowTitle('Main window')
+ self.show()
+
+ def add_text(self, text):
+ self.textEdit.append(text)
+
+def create_gui(*args, **kwargs):
+ app = QtGui.QApplication(sys.argv)
+ example_gui = ExampleGui(*args, **kwargs)
+
+ sys.exit(app.exec_())
\ No newline at end of file
diff --git a/silq/tests/test_instruments.py b/silq/tests/test_instruments.py
index 0fa0ef832..78d928823 100644
--- a/silq/tests/test_instruments.py
+++ b/silq/tests/test_instruments.py
@@ -33,4 +33,7 @@ def __init__(self, name, **kwargs):
vals=vals.Anything())
def set_x(self, val):
- self.x = val
\ No newline at end of file
+ self.x = val
+
+ def print(self):
+ print('printing from test instrument')
\ No newline at end of file
diff --git a/silq/tools/gui_tools.py b/silq/tools/gui_tools.py
new file mode 100644
index 000000000..042902c1d
--- /dev/null
+++ b/silq/tools/gui_tools.py
@@ -0,0 +1,101 @@
+import sys
+from datetime import datetime, timedelta
+from queue import Empty
+from traceback import format_exc
+import logging
+
+from PyQt4 import QtGui
+from PyQt4.QtCore import QThread
+
+
+from qcodes.process.server import BaseServer
+
+
+
+class PipeServer(BaseServer):
+ def __init__(self, query_queue, response_queue, extras=None):
+ super().__init__(query_queue, response_queue, extras)
+
+ app = QtGui.QApplication(sys.argv)
+ # ex = GUIServer(query_queue=query_queue,
+ # response_queue=response_queue)
+ ex = GUIServer(query_queue=query_queue, response_queue=response_queue)
+ sys.exit(app.exec_())
+
+
+class GUIClass(QtGui.QMainWindow):
+ def __init__(self, query_queue, response_queue):
+ super().__init__()
+
+ self.initUI()
+ EventLoopServer
+ self.run_event_loop()
+
+ def initUI(self):
+ self.text_box = QtGui.QTextEdit()
+ self.setCentralWidget(self.text_box)
+
+ exitAction = QtGui.QAction(QtGui.QIcon('exit24.png'), 'Exit', self)
+ exitAction.setShortcut('Ctrl+Q')
+ exitAction.setStatusTip('Exit application')
+ exitAction.triggered.connect(self.close)
+
+ self.statusBar()
+
+ menubar = self.menuBar()
+ fileMenu = menubar.addMenu('&File')
+ fileMenu.addAction(exitAction)
+
+ toolbar = self.addToolBar('Exit')
+ toolbar.addAction(exitAction)
+
+ self.setGeometry(300, 300, 350, 250)
+ self.setWindowTitle('Main window')
+ self.show()
+
+
+ def handle_append(self, text):
+ self.text_box.append(text)
+
+
+class EventLoopServer(QThread, BaseServer):
+
+ def __init__(self, query_queue, response_queue):
+ QThread.__init__(self)
+ self.query_queue = query_queue
+ self.response_queue = response_queue
+
+ def __del__(self):
+ self.wait()
+
+ def run_event_loop(self):
+ self.running = True
+ next_store_ts = datetime.now()
+ next_monitor_ts = datetime.now()
+
+ while self.running:
+ read_timeout = self._storage_period / self.queries_per_store
+ try:
+ query = self._query_queue.get(timeout=read_timeout)
+ self.process_query(query)
+ except Empty:
+ pass
+
+ try:
+ now = datetime.now()
+
+ if self._measuring and now > next_store_ts:
+ td = timedelta(seconds=self._storage_period)
+ next_store_ts = now + td
+ self._data.write()
+
+ if now > next_monitor_ts:
+ td = timedelta(seconds=self._monitor_period)
+ next_monitor_ts = now + td
+ # TODO: update the monitor data storage
+
+ except:
+ logging.error(format_exc())
+
+ def run(self):
+ # your logic here
\ No newline at end of file