diff --git a/docs/examples/benchmarking/Benchmark of Keithley 2600 lua script versus set-get.ipynb b/docs/examples/benchmarking/Benchmark of Keithley 2600 lua script versus set-get.ipynb new file mode 100644 index 00000000000..8940ad1f467 --- /dev/null +++ b/docs/examples/benchmarking/Benchmark of Keithley 2600 lua script versus set-get.ipynb @@ -0,0 +1,1206 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Benchmark\n", + "\n", + "Below we use two methods of the Keithley 2600 to make an IV-curve.\n", + "Plugged into the terminal is a 5 MOhm resistor. The voltage is swept from 1 V to 10 V.\n", + "\n", + "The two methods are normal \"naive\" QCoDeS set-get and deployed script mode. \n", + "In the former mode, a `set` command is send for each voltage set point and a `get` command is sent for each current value to be measured. In the latter mode, a Lua script is formed and uploaded to the SourceMeter. The script then runs locally on the machine and all data is polled in one go (in a binary format).\n", + "\n", + "## Results\n", + "\n", + "#### NPLC = 0.5 (10 ms ap. time), N = 100\n", + "\n", + "Set-get: 1.29 s\n", + "\n", + "Script: 1.08 s\n", + "\n", + "#### NPLC = 0.5 (10 ms ap. time), N = 1000\n", + "\n", + "Set-get: 12.6 s\n", + "\n", + "Script: 10.5 s\n", + "\n", + "#### NPLC = 0.05 (1ms ap. time), N = 100\n", + "\n", + "Set-get: 370 ms\n", + "\n", + "Script: 182 ms\n", + "\n", + "#### NPLC = 0.05 (1ms ap. time), N = 1000\n", + "\n", + "Set-get: 3.38 s\n", + "\n", + "Script: 1.44 s\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Imports and initialisation" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [], + "source": [ + "import qcodes as qc\n", + "from qcodes.instrument.base import Instrument\n", + "from qcodes.instrument_drivers.tektronix.Keithley_2600 import Keithley_2600\n", + "from qcodes.instrument_drivers.tektronix.Keithley_2600_channels import Keithley_2600 as Keithley_2600_channels\n", + "from typing import List\n", + "from qcodes import DataSet\n", + "from qcodes.instrument.parameter import ArrayParameter\n", + "import struct" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "% matplotlib notebook\n", + "import matplotlib.pyplot as plt\n", + "import numpy as np" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Connected to: Keithley Instruments Inc. 2614B (serial:4084407, firmware:3.2.1) in 0.15s\n" + ] + } + ], + "source": [ + "keith = Keithley_2600_channels('keith', 'TCPIP0::192.168.15.116::inst0::INSTR', model='2614B')" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# NPLC = 0.5, N = 100" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "# Preparation for a simple I-V curve with a 5 MOhm resistor\n", + "\n", + "keith.smua.reset()\n", + "keith.smua.nplc(0.5)\n", + "keith.smua.mode('voltage')\n", + "keith.smua.sourcerange_v(20)\n", + "keith.smua.measurerange_i(100e-6)\n", + "keith.smua.output('on')\n", + "\n", + "N = 100" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## SET-GET" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": { + "scrolled": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Started at 2017-09-18 16:49:59\n", + "DataSet:\n", + " location = 'data/2017-09-18/#076_N_100_setget_16-49-59'\n", + " | | | \n", + " Setpoint | keith_smua_volt_set | volt | (100,)\n", + " Measured | keith_smua_curr | curr | (100,)\n", + "Finished at 2017-09-18 16:50:00\n", + "Started at 2017-09-18 16:50:00\n", + "DataSet:\n", + " location = 'data/2017-09-18/#077_N_100_setget_16-50-00'\n", + " | | | \n", + " Setpoint | keith_smua_volt_set | volt | (100,)\n", + " Measured | keith_smua_curr | curr | (100,)\n", + "Finished at 2017-09-18 16:50:02\n", + "Started at 2017-09-18 16:50:02\n", + "DataSet:\n", + " location = 'data/2017-09-18/#078_N_100_setget_16-50-02'\n", + " | | | \n", + " Setpoint | keith_smua_volt_set | volt | (100,)\n", + " Measured | keith_smua_curr | curr | (100,)\n", + "Finished at 2017-09-18 16:50:03\n", + "Started at 2017-09-18 16:50:03\n", + "DataSet:\n", + " location = 'data/2017-09-18/#079_N_100_setget_16-50-03'\n", + " | | | \n", + " Setpoint | keith_smua_volt_set | volt | (100,)\n", + " Measured | keith_smua_curr | curr | (100,)\n", + "Finished at 2017-09-18 16:50:04\n", + "Started at 2017-09-18 16:50:04\n", + "DataSet:\n", + " location = 'data/2017-09-18/#080_N_100_setget_16-50-04'\n", + " | | | \n", + " Setpoint | keith_smua_volt_set | volt | (100,)\n", + " Measured | keith_smua_curr | curr | (100,)\n", + "Finished at 2017-09-18 16:50:05\n", + "Started at 2017-09-18 16:50:05\n", + "DataSet:\n", + " location = 'data/2017-09-18/#081_N_100_setget_16-50-05'\n", + " | | | \n", + " Setpoint | keith_smua_volt_set | volt | (100,)\n", + " Measured | keith_smua_curr | curr | (100,)\n", + "Finished at 2017-09-18 16:50:07\n", + "Started at 2017-09-18 16:50:07\n", + "DataSet:\n", + " location = 'data/2017-09-18/#082_N_100_setget_16-50-07'\n", + " | | | \n", + " Setpoint | keith_smua_volt_set | volt | (100,)\n", + " Measured | keith_smua_curr | curr | (100,)\n", + "Finished at 2017-09-18 16:50:08\n", + "Started at 2017-09-18 16:50:08\n", + "DataSet:\n", + " location = 'data/2017-09-18/#083_N_100_setget_16-50-08'\n", + " | | | \n", + " Setpoint | keith_smua_volt_set | volt | (100,)\n", + " Measured | keith_smua_curr | curr | (100,)\n", + "Finished at 2017-09-18 16:50:09\n", + "1.29 s ± 15.7 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)\n" + ] + } + ], + "source": [ + "%%timeit\n", + "\n", + "loop = qc.Loop(keith.smua.volt.sweep(1, 10, num=N)).each(keith.smua.curr)\n", + "data = loop.get_data_set(name='N_{}_setget'.format(N))\n", + "_ = loop.run() # run the loop" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## SCRIPT" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "DataSet:\n", + " location = 'data/2017-09-18/#084_{name}_16-50-18'\n", + " | | | \n", + " Measured | keith_smua_iv_sweep | iv_sweep | (100,)\n", + "acquired at 2017-09-18 16:50:19\n", + "DataSet:\n", + " location = 'data/2017-09-18/#085_{name}_16-50-19'\n", + " | | | \n", + " Measured | keith_smua_iv_sweep | iv_sweep | (100,)\n", + "acquired at 2017-09-18 16:50:20\n", + "DataSet:\n", + " location = 'data/2017-09-18/#086_{name}_16-50-20'\n", + " | | | \n", + " Measured | keith_smua_iv_sweep | iv_sweep | (100,)\n", + "acquired at 2017-09-18 16:50:21\n", + "DataSet:\n", + " location = 'data/2017-09-18/#087_{name}_16-50-21'\n", + " | | | \n", + " Measured | keith_smua_iv_sweep | iv_sweep | (100,)\n", + "acquired at 2017-09-18 16:50:22\n", + "DataSet:\n", + " location = 'data/2017-09-18/#088_{name}_16-50-22'\n", + " | | | \n", + " Measured | keith_smua_iv_sweep | iv_sweep | (100,)\n", + "acquired at 2017-09-18 16:50:23\n", + "DataSet:\n", + " location = 'data/2017-09-18/#089_{name}_16-50-23'\n", + " | | | \n", + " Measured | keith_smua_iv_sweep | iv_sweep | (100,)\n", + "acquired at 2017-09-18 16:50:24\n", + "DataSet:\n", + " location = 'data/2017-09-18/#090_{name}_16-50-24'\n", + " | | | \n", + " Measured | keith_smua_iv_sweep | iv_sweep | (100,)\n", + "acquired at 2017-09-18 16:50:26\n", + "DataSet:\n", + " location = 'data/2017-09-18/#091_{name}_16-50-26'\n", + " | | | \n", + " Measured | keith_smua_iv_sweep | iv_sweep | (100,)\n", + "acquired at 2017-09-18 16:50:27\n", + "1.08 s ± 4.67 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)\n" + ] + } + ], + "source": [ + "%%timeit\n", + "\n", + "data = keith.smua.doFastSweep(1, 10, N, mode='IV')" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# NPLC = 0.5, N = 1000" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "# Preparation for a simple I-V curve with a 5 MOhm resistor\n", + "\n", + "keith.smua.reset()\n", + "keith.smua.nplc(0.5)\n", + "keith.smua.mode('voltage')\n", + "keith.smua.sourcerange_v(20)\n", + "keith.smua.measurerange_i(100e-6)\n", + "keith.smua.output('on')\n", + "\n", + "N = 1000" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## SET-GET" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Started at 2017-09-18 16:51:20\n", + "DataSet:\n", + " location = 'data/2017-09-18/#092_N_1000_setget_16-51-20'\n", + " | | | \n", + " Setpoint | keith_smua_volt_set | volt | (1000,)\n", + " Measured | keith_smua_curr | curr | (1000,)\n", + "Finished at 2017-09-18 16:51:32\n", + "Started at 2017-09-18 16:51:32\n", + "DataSet:\n", + " location = 'data/2017-09-18/#093_N_1000_setget_16-51-32'\n", + " | | | \n", + " Setpoint | keith_smua_volt_set | volt | (1000,)\n", + " Measured | keith_smua_curr | curr | (1000,)\n", + "Finished at 2017-09-18 16:51:45\n", + "Started at 2017-09-18 16:51:45\n", + "DataSet:\n", + " location = 'data/2017-09-18/#094_N_1000_setget_16-51-45'\n", + " | | | \n", + " Setpoint | keith_smua_volt_set | volt | (1000,)\n", + " Measured | keith_smua_curr | curr | (1000,)\n", + "Finished at 2017-09-18 16:51:58\n", + "Started at 2017-09-18 16:51:58\n", + "DataSet:\n", + " location = 'data/2017-09-18/#095_N_1000_setget_16-51-58'\n", + " | | | \n", + " Setpoint | keith_smua_volt_set | volt | (1000,)\n", + " Measured | keith_smua_curr | curr | (1000,)\n", + "Finished at 2017-09-18 16:52:10\n", + "Started at 2017-09-18 16:52:10\n", + "DataSet:\n", + " location = 'data/2017-09-18/#096_N_1000_setget_16-52-10'\n", + " | | | \n", + " Setpoint | keith_smua_volt_set | volt | (1000,)\n", + " Measured | keith_smua_curr | curr | (1000,)\n", + "Finished at 2017-09-18 16:52:23\n", + "Started at 2017-09-18 16:52:23\n", + "DataSet:\n", + " location = 'data/2017-09-18/#097_N_1000_setget_16-52-23'\n", + " | | | \n", + " Setpoint | keith_smua_volt_set | volt | (1000,)\n", + " Measured | keith_smua_curr | curr | (1000,)\n", + "Finished at 2017-09-18 16:52:35\n", + "Started at 2017-09-18 16:52:35\n", + "DataSet:\n", + " location = 'data/2017-09-18/#098_N_1000_setget_16-52-35'\n", + " | | | \n", + " Setpoint | keith_smua_volt_set | volt | (1000,)\n", + " Measured | keith_smua_curr | curr | (1000,)\n", + "Finished at 2017-09-18 16:52:48\n", + "Started at 2017-09-18 16:52:48\n", + "DataSet:\n", + " location = 'data/2017-09-18/#099_N_1000_setget_16-52-48'\n", + " | | | \n", + " Setpoint | keith_smua_volt_set | volt | (1000,)\n", + " Measured | keith_smua_curr | curr | (1000,)\n", + "Finished at 2017-09-18 16:53:00\n", + "12.6 s ± 21.6 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)\n" + ] + } + ], + "source": [ + "%%timeit\n", + "\n", + "loop = qc.Loop(keith.smua.volt.sweep(1, 10, num=N)).each(keith.smua.curr)\n", + "data = loop.get_data_set(name='N_{}_setget'.format(N))\n", + "_ = loop.run() # run the loop" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## SCRIPT" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "DataSet:\n", + " location = 'data/2017-09-18/#100_{name}_16-53-14'\n", + " | | | \n", + " Measured | keith_smua_iv_sweep | iv_sweep | (1000,)\n", + "acquired at 2017-09-18 16:53:24\n", + "DataSet:\n", + " location = 'data/2017-09-18/#101_{name}_16-53-24'\n", + " | | | \n", + " Measured | keith_smua_iv_sweep | iv_sweep | (1000,)\n", + "acquired at 2017-09-18 16:53:35\n", + "DataSet:\n", + " location = 'data/2017-09-18/#102_{name}_16-53-35'\n", + " | | | \n", + " Measured | keith_smua_iv_sweep | iv_sweep | (1000,)\n", + "acquired at 2017-09-18 16:53:45\n", + "DataSet:\n", + " location = 'data/2017-09-18/#103_{name}_16-53-45'\n", + " | | | \n", + " Measured | keith_smua_iv_sweep | iv_sweep | (1000,)\n", + "acquired at 2017-09-18 16:53:56\n", + "DataSet:\n", + " location = 'data/2017-09-18/#104_{name}_16-53-56'\n", + " | | | \n", + " Measured | keith_smua_iv_sweep | iv_sweep | (1000,)\n", + "acquired at 2017-09-18 16:54:06\n", + "DataSet:\n", + " location = 'data/2017-09-18/#105_{name}_16-54-06'\n", + " | | | \n", + " Measured | keith_smua_iv_sweep | iv_sweep | (1000,)\n", + "acquired at 2017-09-18 16:54:17\n", + "DataSet:\n", + " location = 'data/2017-09-18/#106_{name}_16-54-17'\n", + " | | | \n", + " Measured | keith_smua_iv_sweep | iv_sweep | (1000,)\n", + "acquired at 2017-09-18 16:54:27\n", + "DataSet:\n", + " location = 'data/2017-09-18/#107_{name}_16-54-27'\n", + " | | | \n", + " Measured | keith_smua_iv_sweep | iv_sweep | (1000,)\n", + "acquired at 2017-09-18 16:54:38\n", + "10.5 s ± 12.8 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)\n" + ] + } + ], + "source": [ + "%%timeit\n", + "\n", + "data = keith.smua.doFastSweep(1, 10, N, mode='IV')" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "# Preparation for a simple I-V curve with a 5 MOhm resistor\n", + "\n", + "keith.smua.reset()\n", + "keith.smua.nplc(0.05)\n", + "keith.smua.mode('voltage')\n", + "keith.smua.sourcerange_v(20)\n", + "keith.smua.measurerange_i(100e-6)\n", + "keith.smua.output('on')\n", + "\n", + "N = 100" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## SET-GET" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Started at 2017-09-18 16:56:13\n", + "DataSet:\n", + " location = 'data/2017-09-18/#108_N_100_setget_16-56-13'\n", + " | | | \n", + " Setpoint | keith_smua_volt_set | volt | (100,)\n", + " Measured | keith_smua_curr | curr | (100,)\n", + "Finished at 2017-09-18 16:56:14\n", + "Started at 2017-09-18 16:56:14\n", + "DataSet:\n", + " location = 'data/2017-09-18/#109_N_100_setget_16-56-14'\n", + " | | | \n", + " Setpoint | keith_smua_volt_set | volt | (100,)\n", + " Measured | keith_smua_curr | curr | (100,)\n", + "Finished at 2017-09-18 16:56:14\n", + "Started at 2017-09-18 16:56:14\n", + "DataSet:\n", + " location = 'data/2017-09-18/#110_N_100_setget_16-56-14'\n", + " | | | \n", + " Setpoint | keith_smua_volt_set | volt | (100,)\n", + " Measured | keith_smua_curr | curr | (100,)\n", + "Finished at 2017-09-18 16:56:14\n", + "Started at 2017-09-18 16:56:14\n", + "DataSet:\n", + " location = 'data/2017-09-18/#111_N_100_setget_16-56-14'\n", + " | | | \n", + " Setpoint | keith_smua_volt_set | volt | (100,)\n", + " Measured | keith_smua_curr | curr | (100,)\n", + "Finished at 2017-09-18 16:56:15\n", + "Started at 2017-09-18 16:56:15\n", + "DataSet:\n", + " location = 'data/2017-09-18/#112_N_100_setget_16-56-15'\n", + " | | | \n", + " Setpoint | keith_smua_volt_set | volt | (100,)\n", + " Measured | keith_smua_curr | curr | (100,)\n", + "Finished at 2017-09-18 16:56:15\n", + "Started at 2017-09-18 16:56:15\n", + "DataSet:\n", + " location = 'data/2017-09-18/#113_N_100_setget_16-56-15'\n", + " | | | \n", + " Setpoint | keith_smua_volt_set | volt | (100,)\n", + " Measured | keith_smua_curr | curr | (100,)\n", + "Finished at 2017-09-18 16:56:15\n", + "Started at 2017-09-18 16:56:15\n", + "DataSet:\n", + " location = 'data/2017-09-18/#114_N_100_setget_16-56-15'\n", + " | | | \n", + " Setpoint | keith_smua_volt_set | volt | (100,)\n", + " Measured | keith_smua_curr | curr | (100,)\n", + "Finished at 2017-09-18 16:56:16\n", + "Started at 2017-09-18 16:56:16\n", + "DataSet:\n", + " location = 'data/2017-09-18/#115_N_100_setget_16-56-16'\n", + " | | | \n", + " Setpoint | keith_smua_volt_set | volt | (100,)\n", + " Measured | keith_smua_curr | curr | (100,)\n", + "Finished at 2017-09-18 16:56:16\n", + "370 ms ± 15.5 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)\n" + ] + } + ], + "source": [ + "%%timeit\n", + "\n", + "loop = qc.Loop(keith.smua.volt.sweep(1, 10, num=N)).each(keith.smua.curr)\n", + "data = loop.get_data_set(name='N_{}_setget'.format(N))\n", + "_ = loop.run() # run the loop" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## SCRIPT" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "DataSet:\n", + " location = 'data/2017-09-18/#116_{name}_16-57-00'\n", + " | | | \n", + " Measured | keith_smua_iv_sweep | iv_sweep | (100,)\n", + "acquired at 2017-09-18 16:57:00\n", + "DataSet:\n", + " location = 'data/2017-09-18/#117_{name}_16-57-00'\n", + " | | | \n", + " Measured | keith_smua_iv_sweep | iv_sweep | (100,)\n", + "acquired at 2017-09-18 16:57:00\n", + "DataSet:\n", + " location = 'data/2017-09-18/#118_{name}_16-57-00'\n", + " | | | \n", + " Measured | keith_smua_iv_sweep | iv_sweep | (100,)\n", + "acquired at 2017-09-18 16:57:01\n", + "DataSet:\n", + " location = 'data/2017-09-18/#119_{name}_16-57-01'\n", + " | | | \n", + " Measured | keith_smua_iv_sweep | iv_sweep | (100,)\n", + "acquired at 2017-09-18 16:57:01\n", + "DataSet:\n", + " location = 'data/2017-09-18/#120_{name}_16-57-01'\n", + " | | | \n", + " Measured | keith_smua_iv_sweep | iv_sweep | (100,)\n", + "acquired at 2017-09-18 16:57:01\n", + "DataSet:\n", + " location = 'data/2017-09-18/#121_{name}_16-57-01'\n", + " | | | \n", + " Measured | keith_smua_iv_sweep | iv_sweep | (100,)\n", + "acquired at 2017-09-18 16:57:01\n", + "DataSet:\n", + " location = 'data/2017-09-18/#122_{name}_16-57-01'\n", + " | | | \n", + " Measured | keith_smua_iv_sweep | iv_sweep | (100,)\n", + "acquired at 2017-09-18 16:57:01\n", + "DataSet:\n", + " location = 'data/2017-09-18/#123_{name}_16-57-01'\n", + " | | | \n", + " Measured | keith_smua_iv_sweep | iv_sweep | (100,)\n", + "acquired at 2017-09-18 16:57:01\n", + "DataSet:\n", + " location = 'data/2017-09-18/#124_{name}_16-57-01'\n", + " | | | \n", + " Measured | keith_smua_iv_sweep | iv_sweep | (100,)\n", + "acquired at 2017-09-18 16:57:02\n", + "DataSet:\n", + " location = 'data/2017-09-18/#125_{name}_16-57-02'\n", + " | | | \n", + " Measured | keith_smua_iv_sweep | iv_sweep | (100,)\n", + "acquired at 2017-09-18 16:57:02\n", + "DataSet:\n", + " location = 'data/2017-09-18/#126_{name}_16-57-02'\n", + " | | | \n", + " Measured | keith_smua_iv_sweep | iv_sweep | (100,)\n", + "acquired at 2017-09-18 16:57:02\n", + "DataSet:\n", + " location = 'data/2017-09-18/#127_{name}_16-57-02'\n", + " | | | \n", + " Measured | keith_smua_iv_sweep | iv_sweep | (100,)\n", + "acquired at 2017-09-18 16:57:02\n", + "DataSet:\n", + " location = 'data/2017-09-18/#128_{name}_16-57-02'\n", + " | | | \n", + " Measured | keith_smua_iv_sweep | iv_sweep | (100,)\n", + "acquired at 2017-09-18 16:57:02\n", + "DataSet:\n", + " location = 'data/2017-09-18/#129_{name}_16-57-02'\n", + " | | | \n", + " Measured | keith_smua_iv_sweep | iv_sweep | (100,)\n", + "acquired at 2017-09-18 16:57:03\n", + "DataSet:\n", + " location = 'data/2017-09-18/#130_{name}_16-57-03'\n", + " | | | \n", + " Measured | keith_smua_iv_sweep | iv_sweep | (100,)\n", + "acquired at 2017-09-18 16:57:03\n", + "DataSet:\n", + " location = 'data/2017-09-18/#131_{name}_16-57-03'\n", + " | | | \n", + " Measured | keith_smua_iv_sweep | iv_sweep | (100,)\n", + "acquired at 2017-09-18 16:57:03\n", + "DataSet:\n", + " location = 'data/2017-09-18/#132_{name}_16-57-03'\n", + " | | | \n", + " Measured | keith_smua_iv_sweep | iv_sweep | (100,)\n", + "acquired at 2017-09-18 16:57:03\n", + "DataSet:\n", + " location = 'data/2017-09-18/#133_{name}_16-57-03'\n", + " | | | \n", + " Measured | keith_smua_iv_sweep | iv_sweep | (100,)\n", + "acquired at 2017-09-18 16:57:03\n", + "DataSet:\n", + " location = 'data/2017-09-18/#134_{name}_16-57-03'\n", + " | | | \n", + " Measured | keith_smua_iv_sweep | iv_sweep | (100,)\n", + "acquired at 2017-09-18 16:57:03\n", + "DataSet:\n", + " location = 'data/2017-09-18/#135_{name}_16-57-03'\n", + " | | | \n", + " Measured | keith_smua_iv_sweep | iv_sweep | (100,)\n", + "acquired at 2017-09-18 16:57:04\n", + "DataSet:\n", + " location = 'data/2017-09-18/#136_{name}_16-57-04'\n", + " | | | \n", + " Measured | keith_smua_iv_sweep | iv_sweep | (100,)\n", + "acquired at 2017-09-18 16:57:04\n", + "DataSet:\n", + " location = 'data/2017-09-18/#137_{name}_16-57-04'\n", + " | | | \n", + " Measured | keith_smua_iv_sweep | iv_sweep | (100,)\n", + "acquired at 2017-09-18 16:57:04\n", + "DataSet:\n", + " location = 'data/2017-09-18/#138_{name}_16-57-04'\n", + " | | | \n", + " Measured | keith_smua_iv_sweep | iv_sweep | (100,)\n", + "acquired at 2017-09-18 16:57:04\n", + "DataSet:\n", + " location = 'data/2017-09-18/#139_{name}_16-57-04'\n", + " | | | \n", + " Measured | keith_smua_iv_sweep | iv_sweep | (100,)\n", + "acquired at 2017-09-18 16:57:04\n", + "DataSet:\n", + " location = 'data/2017-09-18/#140_{name}_16-57-04'\n", + " | | | \n", + " Measured | keith_smua_iv_sweep | iv_sweep | (100,)\n", + "acquired at 2017-09-18 16:57:05\n", + "DataSet:\n", + " location = 'data/2017-09-18/#141_{name}_16-57-05'\n", + " | | | \n", + " Measured | keith_smua_iv_sweep | iv_sweep | (100,)\n", + "acquired at 2017-09-18 16:57:05\n", + "DataSet:\n", + " location = 'data/2017-09-18/#142_{name}_16-57-05'\n", + " | | | \n", + " Measured | keith_smua_iv_sweep | iv_sweep | (100,)\n", + "acquired at 2017-09-18 16:57:05\n", + "DataSet:\n", + " location = 'data/2017-09-18/#143_{name}_16-57-05'\n", + " | | | \n", + " Measured | keith_smua_iv_sweep | iv_sweep | (100,)\n", + "acquired at 2017-09-18 16:57:05\n", + "DataSet:\n", + " location = 'data/2017-09-18/#144_{name}_16-57-05'\n", + " | | | \n", + " Measured | keith_smua_iv_sweep | iv_sweep | (100,)\n", + "acquired at 2017-09-18 16:57:05\n", + "DataSet:\n", + " location = 'data/2017-09-18/#145_{name}_16-57-05'\n", + " | | | \n", + " Measured | keith_smua_iv_sweep | iv_sweep | (100,)\n", + "acquired at 2017-09-18 16:57:05\n", + "DataSet:\n", + " location = 'data/2017-09-18/#146_{name}_16-57-05'\n", + " | | | \n", + " Measured | keith_smua_iv_sweep | iv_sweep | (100,)\n", + "acquired at 2017-09-18 16:57:06\n", + "DataSet:\n", + " location = 'data/2017-09-18/#147_{name}_16-57-06'\n", + " | | | \n", + " Measured | keith_smua_iv_sweep | iv_sweep | (100,)\n", + "acquired at 2017-09-18 16:57:06\n", + "DataSet:\n", + " location = 'data/2017-09-18/#148_{name}_16-57-06'\n", + " | | | \n", + " Measured | keith_smua_iv_sweep | iv_sweep | (100,)\n", + "acquired at 2017-09-18 16:57:06\n", + "DataSet:\n", + " location = 'data/2017-09-18/#149_{name}_16-57-06'\n", + " | | | \n", + " Measured | keith_smua_iv_sweep | iv_sweep | (100,)\n", + "acquired at 2017-09-18 16:57:06\n", + "DataSet:\n", + " location = 'data/2017-09-18/#150_{name}_16-57-06'\n", + " | | | \n", + " Measured | keith_smua_iv_sweep | iv_sweep | (100,)\n", + "acquired at 2017-09-18 16:57:06\n", + "DataSet:\n", + " location = 'data/2017-09-18/#151_{name}_16-57-06'\n", + " | | | \n", + " Measured | keith_smua_iv_sweep | iv_sweep | (100,)\n", + "acquired at 2017-09-18 16:57:06\n", + "DataSet:\n", + " location = 'data/2017-09-18/#152_{name}_16-57-06'\n", + " | | | \n", + " Measured | keith_smua_iv_sweep | iv_sweep | (100,)\n", + "acquired at 2017-09-18 16:57:07\n", + "DataSet:\n", + " location = 'data/2017-09-18/#153_{name}_16-57-07'\n", + " | | | \n", + " Measured | keith_smua_iv_sweep | iv_sweep | (100,)\n", + "acquired at 2017-09-18 16:57:07\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "DataSet:\n", + " location = 'data/2017-09-18/#154_{name}_16-57-07'\n", + " | | | \n", + " Measured | keith_smua_iv_sweep | iv_sweep | (100,)\n", + "acquired at 2017-09-18 16:57:07\n", + "DataSet:\n", + " location = 'data/2017-09-18/#155_{name}_16-57-07'\n", + " | | | \n", + " Measured | keith_smua_iv_sweep | iv_sweep | (100,)\n", + "acquired at 2017-09-18 16:57:07\n", + "DataSet:\n", + " location = 'data/2017-09-18/#156_{name}_16-57-07'\n", + " | | | \n", + " Measured | keith_smua_iv_sweep | iv_sweep | (100,)\n", + "acquired at 2017-09-18 16:57:07\n", + "DataSet:\n", + " location = 'data/2017-09-18/#157_{name}_16-57-07'\n", + " | | | \n", + " Measured | keith_smua_iv_sweep | iv_sweep | (100,)\n", + "acquired at 2017-09-18 16:57:08\n", + "DataSet:\n", + " location = 'data/2017-09-18/#158_{name}_16-57-08'\n", + " | | | \n", + " Measured | keith_smua_iv_sweep | iv_sweep | (100,)\n", + "acquired at 2017-09-18 16:57:08\n", + "DataSet:\n", + " location = 'data/2017-09-18/#159_{name}_16-57-08'\n", + " | | | \n", + " Measured | keith_smua_iv_sweep | iv_sweep | (100,)\n", + "acquired at 2017-09-18 16:57:08\n", + "DataSet:\n", + " location = 'data/2017-09-18/#160_{name}_16-57-08'\n", + " | | | \n", + " Measured | keith_smua_iv_sweep | iv_sweep | (100,)\n", + "acquired at 2017-09-18 16:57:08\n", + "DataSet:\n", + " location = 'data/2017-09-18/#161_{name}_16-57-08'\n", + " | | | \n", + " Measured | keith_smua_iv_sweep | iv_sweep | (100,)\n", + "acquired at 2017-09-18 16:57:08\n", + "DataSet:\n", + " location = 'data/2017-09-18/#162_{name}_16-57-08'\n", + " | | | \n", + " Measured | keith_smua_iv_sweep | iv_sweep | (100,)\n", + "acquired at 2017-09-18 16:57:08\n", + "DataSet:\n", + " location = 'data/2017-09-18/#163_{name}_16-57-08'\n", + " | | | \n", + " Measured | keith_smua_iv_sweep | iv_sweep | (100,)\n", + "acquired at 2017-09-18 16:57:09\n", + "DataSet:\n", + " location = 'data/2017-09-18/#164_{name}_16-57-09'\n", + " | | | \n", + " Measured | keith_smua_iv_sweep | iv_sweep | (100,)\n", + "acquired at 2017-09-18 16:57:09\n", + "DataSet:\n", + " location = 'data/2017-09-18/#165_{name}_16-57-09'\n", + " | | | \n", + " Measured | keith_smua_iv_sweep | iv_sweep | (100,)\n", + "acquired at 2017-09-18 16:57:09\n", + "DataSet:\n", + " location = 'data/2017-09-18/#166_{name}_16-57-09'\n", + " | | | \n", + " Measured | keith_smua_iv_sweep | iv_sweep | (100,)\n", + "acquired at 2017-09-18 16:57:09\n", + "DataSet:\n", + " location = 'data/2017-09-18/#167_{name}_16-57-09'\n", + " | | | \n", + " Measured | keith_smua_iv_sweep | iv_sweep | (100,)\n", + "acquired at 2017-09-18 16:57:09\n", + "DataSet:\n", + " location = 'data/2017-09-18/#168_{name}_16-57-09'\n", + " | | | \n", + " Measured | keith_smua_iv_sweep | iv_sweep | (100,)\n", + "acquired at 2017-09-18 16:57:10\n", + "DataSet:\n", + " location = 'data/2017-09-18/#169_{name}_16-57-10'\n", + " | | | \n", + " Measured | keith_smua_iv_sweep | iv_sweep | (100,)\n", + "acquired at 2017-09-18 16:57:10\n", + "DataSet:\n", + " location = 'data/2017-09-18/#170_{name}_16-57-10'\n", + " | | | \n", + " Measured | keith_smua_iv_sweep | iv_sweep | (100,)\n", + "acquired at 2017-09-18 16:57:10\n", + "DataSet:\n", + " location = 'data/2017-09-18/#171_{name}_16-57-10'\n", + " | | | \n", + " Measured | keith_smua_iv_sweep | iv_sweep | (100,)\n", + "acquired at 2017-09-18 16:57:10\n", + "DataSet:\n", + " location = 'data/2017-09-18/#172_{name}_16-57-10'\n", + " | | | \n", + " Measured | keith_smua_iv_sweep | iv_sweep | (100,)\n", + "acquired at 2017-09-18 16:57:10\n", + "DataSet:\n", + " location = 'data/2017-09-18/#173_{name}_16-57-10'\n", + " | | | \n", + " Measured | keith_smua_iv_sweep | iv_sweep | (100,)\n", + "acquired at 2017-09-18 16:57:11\n", + "DataSet:\n", + " location = 'data/2017-09-18/#174_{name}_16-57-11'\n", + " | | | \n", + " Measured | keith_smua_iv_sweep | iv_sweep | (100,)\n", + "acquired at 2017-09-18 16:57:11\n", + "DataSet:\n", + " location = 'data/2017-09-18/#175_{name}_16-57-11'\n", + " | | | \n", + " Measured | keith_smua_iv_sweep | iv_sweep | (100,)\n", + "acquired at 2017-09-18 16:57:11\n", + "DataSet:\n", + " location = 'data/2017-09-18/#176_{name}_16-57-11'\n", + " | | | \n", + " Measured | keith_smua_iv_sweep | iv_sweep | (100,)\n", + "acquired at 2017-09-18 16:57:11\n", + "DataSet:\n", + " location = 'data/2017-09-18/#177_{name}_16-57-11'\n", + " | | | \n", + " Measured | keith_smua_iv_sweep | iv_sweep | (100,)\n", + "acquired at 2017-09-18 16:57:11\n", + "DataSet:\n", + " location = 'data/2017-09-18/#178_{name}_16-57-11'\n", + " | | | \n", + " Measured | keith_smua_iv_sweep | iv_sweep | (100,)\n", + "acquired at 2017-09-18 16:57:11\n", + "DataSet:\n", + " location = 'data/2017-09-18/#179_{name}_16-57-11'\n", + " | | | \n", + " Measured | keith_smua_iv_sweep | iv_sweep | (100,)\n", + "acquired at 2017-09-18 16:57:12\n", + "DataSet:\n", + " location = 'data/2017-09-18/#180_{name}_16-57-12'\n", + " | | | \n", + " Measured | keith_smua_iv_sweep | iv_sweep | (100,)\n", + "acquired at 2017-09-18 16:57:12\n", + "DataSet:\n", + " location = 'data/2017-09-18/#181_{name}_16-57-12'\n", + " | | | \n", + " Measured | keith_smua_iv_sweep | iv_sweep | (100,)\n", + "acquired at 2017-09-18 16:57:12\n", + "DataSet:\n", + " location = 'data/2017-09-18/#182_{name}_16-57-12'\n", + " | | | \n", + " Measured | keith_smua_iv_sweep | iv_sweep | (100,)\n", + "acquired at 2017-09-18 16:57:12\n", + "DataSet:\n", + " location = 'data/2017-09-18/#183_{name}_16-57-12'\n", + " | | | \n", + " Measured | keith_smua_iv_sweep | iv_sweep | (100,)\n", + "acquired at 2017-09-18 16:57:12\n", + "DataSet:\n", + " location = 'data/2017-09-18/#184_{name}_16-57-12'\n", + " | | | \n", + " Measured | keith_smua_iv_sweep | iv_sweep | (100,)\n", + "acquired at 2017-09-18 16:57:13\n", + "DataSet:\n", + " location = 'data/2017-09-18/#185_{name}_16-57-13'\n", + " | | | \n", + " Measured | keith_smua_iv_sweep | iv_sweep | (100,)\n", + "acquired at 2017-09-18 16:57:13\n", + "DataSet:\n", + " location = 'data/2017-09-18/#186_{name}_16-57-13'\n", + " | | | \n", + " Measured | keith_smua_iv_sweep | iv_sweep | (100,)\n", + "acquired at 2017-09-18 16:57:13\n", + "DataSet:\n", + " location = 'data/2017-09-18/#187_{name}_16-57-13'\n", + " | | | \n", + " Measured | keith_smua_iv_sweep | iv_sweep | (100,)\n", + "acquired at 2017-09-18 16:57:13\n", + "DataSet:\n", + " location = 'data/2017-09-18/#188_{name}_16-57-13'\n", + " | | | \n", + " Measured | keith_smua_iv_sweep | iv_sweep | (100,)\n", + "acquired at 2017-09-18 16:57:13\n", + "DataSet:\n", + " location = 'data/2017-09-18/#189_{name}_16-57-13'\n", + " | | | \n", + " Measured | keith_smua_iv_sweep | iv_sweep | (100,)\n", + "acquired at 2017-09-18 16:57:13\n", + "DataSet:\n", + " location = 'data/2017-09-18/#190_{name}_16-57-13'\n", + " | | | \n", + " Measured | keith_smua_iv_sweep | iv_sweep | (100,)\n", + "acquired at 2017-09-18 16:57:14\n", + "DataSet:\n", + " location = 'data/2017-09-18/#191_{name}_16-57-14'\n", + " | | | \n", + " Measured | keith_smua_iv_sweep | iv_sweep | (100,)\n", + "acquired at 2017-09-18 16:57:14\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "DataSet:\n", + " location = 'data/2017-09-18/#192_{name}_16-57-14'\n", + " | | | \n", + " Measured | keith_smua_iv_sweep | iv_sweep | (100,)\n", + "acquired at 2017-09-18 16:57:14\n", + "DataSet:\n", + " location = 'data/2017-09-18/#193_{name}_16-57-14'\n", + " | | | \n", + " Measured | keith_smua_iv_sweep | iv_sweep | (100,)\n", + "acquired at 2017-09-18 16:57:14\n", + "DataSet:\n", + " location = 'data/2017-09-18/#194_{name}_16-57-14'\n", + " | | | \n", + " Measured | keith_smua_iv_sweep | iv_sweep | (100,)\n", + "acquired at 2017-09-18 16:57:14\n", + "DataSet:\n", + " location = 'data/2017-09-18/#195_{name}_16-57-14'\n", + " | | | \n", + " Measured | keith_smua_iv_sweep | iv_sweep | (100,)\n", + "acquired at 2017-09-18 16:57:15\n", + "DataSet:\n", + " location = 'data/2017-09-18/#196_{name}_16-57-15'\n", + " | | | \n", + " Measured | keith_smua_iv_sweep | iv_sweep | (100,)\n", + "acquired at 2017-09-18 16:57:15\n", + "182 ms ± 6.48 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)\n" + ] + } + ], + "source": [ + "%%timeit\n", + "\n", + "data = keith.smua.doFastSweep(1, 10, N, mode='IV')" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# NPLC = 0.05, N = 1000" + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "# Preparation for a simple I-V curve with a 5 MOhm resistor\n", + "\n", + "keith.smua.reset()\n", + "keith.smua.nplc(0.05)\n", + "keith.smua.mode('voltage')\n", + "keith.smua.sourcerange_v(20)\n", + "keith.smua.measurerange_i(100e-6)\n", + "keith.smua.output('on')\n", + "\n", + "N = 1000" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## SET-GET" + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Started at 2017-09-18 16:59:06\n", + "DataSet:\n", + " location = 'data/2017-09-18/#197_N_1000_setget_16-59-06'\n", + " | | | \n", + " Setpoint | keith_smua_volt_set | volt | (1000,)\n", + " Measured | keith_smua_curr | curr | (1000,)\n", + "Finished at 2017-09-18 16:59:10\n", + "Started at 2017-09-18 16:59:10\n", + "DataSet:\n", + " location = 'data/2017-09-18/#198_N_1000_setget_16-59-10'\n", + " | | | \n", + " Setpoint | keith_smua_volt_set | volt | (1000,)\n", + " Measured | keith_smua_curr | curr | (1000,)\n", + "Finished at 2017-09-18 16:59:13\n", + "Started at 2017-09-18 16:59:13\n", + "DataSet:\n", + " location = 'data/2017-09-18/#199_N_1000_setget_16-59-13'\n", + " | | | \n", + " Setpoint | keith_smua_volt_set | volt | (1000,)\n", + " Measured | keith_smua_curr | curr | (1000,)\n", + "Finished at 2017-09-18 16:59:16\n", + "Started at 2017-09-18 16:59:16\n", + "DataSet:\n", + " location = 'data/2017-09-18/#200_N_1000_setget_16-59-16'\n", + " | | | \n", + " Setpoint | keith_smua_volt_set | volt | (1000,)\n", + " Measured | keith_smua_curr | curr | (1000,)\n", + "Finished at 2017-09-18 16:59:20\n", + "Started at 2017-09-18 16:59:20\n", + "DataSet:\n", + " location = 'data/2017-09-18/#201_N_1000_setget_16-59-20'\n", + " | | | \n", + " Setpoint | keith_smua_volt_set | volt | (1000,)\n", + " Measured | keith_smua_curr | curr | (1000,)\n", + "Finished at 2017-09-18 16:59:23\n", + "Started at 2017-09-18 16:59:23\n", + "DataSet:\n", + " location = 'data/2017-09-18/#202_N_1000_setget_16-59-23'\n", + " | | | \n", + " Setpoint | keith_smua_volt_set | volt | (1000,)\n", + " Measured | keith_smua_curr | curr | (1000,)\n", + "Finished at 2017-09-18 16:59:27\n", + "Started at 2017-09-18 16:59:27\n", + "DataSet:\n", + " location = 'data/2017-09-18/#203_N_1000_setget_16-59-27'\n", + " | | | \n", + " Setpoint | keith_smua_volt_set | volt | (1000,)\n", + " Measured | keith_smua_curr | curr | (1000,)\n", + "Finished at 2017-09-18 16:59:30\n", + "Started at 2017-09-18 16:59:30\n", + "DataSet:\n", + " location = 'data/2017-09-18/#204_N_1000_setget_16-59-30'\n", + " | | | \n", + " Setpoint | keith_smua_volt_set | volt | (1000,)\n", + " Measured | keith_smua_curr | curr | (1000,)\n", + "Finished at 2017-09-18 16:59:33\n", + "3.38 s ± 39.4 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)\n" + ] + } + ], + "source": [ + "%%timeit\n", + "\n", + "loop = qc.Loop(keith.smua.volt.sweep(1, 10, num=N)).each(keith.smua.curr)\n", + "data = loop.get_data_set(name='N_{}_setget'.format(N))\n", + "_ = loop.run() # run the loop" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## SCRIPT" + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "DataSet:\n", + " location = 'data/2017-09-18/#205_{name}_16-59-38'\n", + " | | | \n", + " Measured | keith_smua_iv_sweep | iv_sweep | (1000,)\n", + "acquired at 2017-09-18 16:59:39\n", + "DataSet:\n", + " location = 'data/2017-09-18/#206_{name}_16-59-39'\n", + " | | | \n", + " Measured | keith_smua_iv_sweep | iv_sweep | (1000,)\n", + "acquired at 2017-09-18 16:59:41\n", + "DataSet:\n", + " location = 'data/2017-09-18/#207_{name}_16-59-41'\n", + " | | | \n", + " Measured | keith_smua_iv_sweep | iv_sweep | (1000,)\n", + "acquired at 2017-09-18 16:59:42\n", + "DataSet:\n", + " location = 'data/2017-09-18/#208_{name}_16-59-42'\n", + " | | | \n", + " Measured | keith_smua_iv_sweep | iv_sweep | (1000,)\n", + "acquired at 2017-09-18 16:59:43\n", + "DataSet:\n", + " location = 'data/2017-09-18/#209_{name}_16-59-43'\n", + " | | | \n", + " Measured | keith_smua_iv_sweep | iv_sweep | (1000,)\n", + "acquired at 2017-09-18 16:59:45\n", + "DataSet:\n", + " location = 'data/2017-09-18/#210_{name}_16-59-45'\n", + " | | | \n", + " Measured | keith_smua_iv_sweep | iv_sweep | (1000,)\n", + "acquired at 2017-09-18 16:59:46\n", + "DataSet:\n", + " location = 'data/2017-09-18/#211_{name}_16-59-46'\n", + " | | | \n", + " Measured | keith_smua_iv_sweep | iv_sweep | (1000,)\n", + "acquired at 2017-09-18 16:59:48\n", + "DataSet:\n", + " location = 'data/2017-09-18/#212_{name}_16-59-48'\n", + " | | | \n", + " Measured | keith_smua_iv_sweep | iv_sweep | (1000,)\n", + "acquired at 2017-09-18 16:59:49\n", + "1.44 s ± 13.5 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)\n" + ] + } + ], + "source": [ + "%%timeit\n", + "\n", + "data = keith.smua.doFastSweep(1, 10, N, mode='IV')" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "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.6.0" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/docs/examples/driver_examples/Keithley_example.ipynb b/docs/examples/driver_examples/Keithley_example.ipynb deleted file mode 100644 index e5e3d301500..00000000000 --- a/docs/examples/driver_examples/Keithley_example.ipynb +++ /dev/null @@ -1,483 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": { - "deletable": true, - "editable": true - }, - "source": [ - "# Example script for Keithley driver" - ] - }, - { - "cell_type": "code", - "execution_count": 1, - "metadata": { - "collapsed": false, - "deletable": true, - "editable": true - }, - "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 = window.SPVIEW = this;\r\n", - " me._interval = 0;\r\n", - " me._minimize = '';\r\n", - " me._restore = '';\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", - " '' +\r\n", - " '' +\r\n", - " '' +\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('span');\r\n",
-       "            me.abortButton = me.$el.find('.qcodes-abort-loop');\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.$el.find('.js-state').click(function() {\r\n",
-       "                var oldState = me.$el.attr('qcodes-state'),\r\n",
-       "                    state = this.className.substr(this.className.indexOf('qcodes'))\r\n",
-       "                        .split('-')[1].split(' ')[0];\r\n",
-       "\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",
-       "                    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.draggable().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",
-       "\r\n",
-       "            $(window).resize(function() {\r\n",
-       "                if(me.$el.attr('qcodes-state') === 'floated') {\r\n",
-       "                    var position = me.$el.position(),\r\n",
-       "                        minVis = 20,\r\n",
-       "                        maxLeft = window.innerWidth - minVis,\r\n",
-       "                        maxTop = window.innerHeight - minVis;\r\n",
-       "\r\n",
-       "                    if(position.left > maxLeft) me.$el.css('left', maxLeft);\r\n",
-       "                    if(position.top > maxTop) me.$el.css('top', maxTop);\r\n",
-       "                }\r\n",
-       "            });\r\n",
-       "\r\n",
-       "            me.update();\r\n",
-       "        },\r\n",
-       "\r\n",
-       "        display: function(message) {\r\n",
-       "            if(message) {\r\n",
-       "                var initialScroll = this.outputArea.scrollTop();\r\n",
-       "                this.outputArea.scrollTop(this.outputArea.prop('scrollHeight'));\r\n",
-       "                var scrollBottom = this.outputArea.scrollTop();\r\n",
-       "\r\n",
-       "                if(this.$el.attr('qcodes-state') === 'minimized') {\r\n",
-       "                    this.$el.find('.qcodes-docked').click();\r\n",
-       "                    // always scroll to the bottom if we're restoring\r\n",
-       "                    // because of a new message\r\n",
-       "                    initialScroll = scrollBottom;\r\n",
-       "                }\r\n",
-       "\r\n",
-       "                this.outputArea.append(message);\r\n",
-       "                this.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",
-       "                this.outputArea.scrollTop(initialScroll === scrollBottom ?\r\n",
-       "                    this.outputArea.prop('scrollHeight') : initialScroll);\r\n",
-       "            }\r\n",
-       "\r\n",
-       "            var processes = this.model.get('_processes') || 'No subprocesses';\r\n",
-       "            this.abortButton.toggleClass('disabled', processes.indexOf('Measurement')===-1);\r\n",
-       "            this.subprocessList.text(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 matplotlib.pyplot as plt\n",
-    "import time\n",
-    "import numpy as np\n",
-    "from imp import reload\n",
-    "import qcodes as qc"
-   ]
-  },
-  {
-   "cell_type": "markdown",
-   "metadata": {
-    "deletable": true,
-    "editable": true
-   },
-   "source": [
-    "## Keithley driver\n",
-    "\n",
-    "What to do:\n",
-    "    \n",
-    "* implement add functionality of the driver\n",
-    "* add documentation to the functions\n",
-    "    "
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 12,
-   "metadata": {
-    "collapsed": false,
-    "deletable": true,
-    "editable": true
-   },
-   "outputs": [
-    {
-     "data": {
-      "text/plain": [
-       ""
-      ]
-     },
-     "execution_count": 12,
-     "metadata": {},
-     "output_type": "execute_result"
-    }
-   ],
-   "source": [
-    "import qcodes.instrument_drivers\n",
-    "import qcodes.instrument_drivers.tektronix.Keithley_2700 as keith"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 13,
-   "metadata": {
-    "collapsed": false,
-    "deletable": true,
-    "editable": true
-   },
-   "outputs": [
-    {
-     "name": "stdout",
-     "output_type": "stream",
-     "text": [
-      "Connected to:  KEITHLEY INSTRUMENTS INC., MODEL 2700, 0792116, B06  /A02    in 0.17s\n"
-     ]
-    }
-   ],
-   "source": [
-    "k1 = keith.Keithley_2700('Keithley', 'GPIB1::15::INSTR')\n",
-    "k1.add_parameter('READ', get_cmd='READ?', label='Keithley value', get_parser=float)"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 4,
-   "metadata": {
-    "collapsed": false,
-    "deletable": true,
-    "editable": true
-   },
-   "outputs": [
-    {
-     "name": "stdout",
-     "output_type": "stream",
-     "text": [
-      "current mode: VOLT:DC\n"
-     ]
-    }
-   ],
-   "source": [
-    "print('current mode: %s' % k1.get('mode'))"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 5,
-   "metadata": {
-    "collapsed": false,
-    "deletable": true,
-    "editable": true,
-    "scrolled": true
-   },
-   "outputs": [
-    {
-     "name": "stdout",
-     "output_type": "stream",
-     "text": [
-      "measure: -0.095112\n",
-      "measure: -0.104225\n",
-      "measure: -0.112567\n",
-      "measure: -0.129525\n",
-      "measure: -0.137803\n",
-      "measure: -0.146068\n"
-     ]
-    }
-   ],
-   "source": [
-    "for i in range(6):\n",
-    "    print('measure: %.6f'  % k1.readnext() )"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 6,
-   "metadata": {
-    "collapsed": false,
-    "deletable": true,
-    "editable": true
-   },
-   "outputs": [
-    {
-     "data": {
-      "text/plain": [
-       "[]"
-      ]
-     },
-     "execution_count": 6,
-     "metadata": {},
-     "output_type": "execute_result"
-    }
-   ],
-   "source": [
-    "station = qc.Station('Keithley')\n",
-    "\n",
-    "# could measure any number of things by adding arguments to this\n",
-    "# function call, but here we're just measuring one, the meter mode\n",
-    "station.set_measurement(k1.mode)\n",
-    "\n",
-    "qc.active_children()"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 7,
-   "metadata": {
-    "collapsed": false,
-    "deletable": true,
-    "editable": true
-   },
-   "outputs": [
-    {
-     "data": {
-      "text/plain": [
-       "['VOLT:DC']"
-      ]
-     },
-     "execution_count": 7,
-     "metadata": {},
-     "output_type": "execute_result"
-    }
-   ],
-   "source": [
-    "station.measure()"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 8,
-   "metadata": {
-    "collapsed": false,
-    "deletable": true,
-    "editable": true
-   },
-   "outputs": [
-    {
-     "name": "stdout",
-     "output_type": "stream",
-     "text": [
-      "Get integration time in Number of PowerLine Cycles.\n",
-      "To get the integrationtime in seconds, use get_integrationtime().\r\n",
-      "Parameter class:\n",
-      "* `name` nplc\r\n",
-      "* `label` nplc\r\n",
-      "* `units` APER\r\n",
-      "\n"
-     ]
-    }
-   ],
-   "source": [
-    "print(k1.nplc.__doc__)"
-   ]
-  }
- ],
- "metadata": {
-  "kernelspec": {
-   "display_name": "Python 3",
-   "language": "python",
-   "name": "python3"
-  },
-  "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/docs/examples/driver_examples/Qcodes example with Keithley 2600.ipynb b/docs/examples/driver_examples/Qcodes example with Keithley 2600.ipynb
index 45d545285dd..6ae164cdaa6 100644
--- a/docs/examples/driver_examples/Qcodes example with Keithley 2600.ipynb	
+++ b/docs/examples/driver_examples/Qcodes example with Keithley 2600.ipynb	
@@ -8,682 +8,240 @@
    ]
   },
   {
-   "cell_type": "code",
-   "execution_count": 1,
+   "cell_type": "markdown",
    "metadata": {},
-   "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 = window.SPVIEW = this;\r\n",
-       "            me._interval = 0;\r\n",
-       "            me._minimize = '';\r\n",
-       "            me._restore = '';\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", - " '' +\r\n", - " '' +\r\n", - " '' +\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('span');\r\n",
-       "            me.abortButton = me.$el.find('.qcodes-abort-loop');\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.$el.find('.js-state').click(function() {\r\n",
-       "                var oldState = me.$el.attr('qcodes-state'),\r\n",
-       "                    state = this.className.substr(this.className.indexOf('qcodes'))\r\n",
-       "                        .split('-')[1].split(' ')[0];\r\n",
-       "\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",
-       "                    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.draggable().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",
-       "\r\n",
-       "            $(window).resize(function() {\r\n",
-       "                if(me.$el.attr('qcodes-state') === 'floated') {\r\n",
-       "                    var position = me.$el.position(),\r\n",
-       "                        minVis = 20,\r\n",
-       "                        maxLeft = window.innerWidth - minVis,\r\n",
-       "                        maxTop = window.innerHeight - minVis;\r\n",
-       "\r\n",
-       "                    if(position.left > maxLeft) me.$el.css('left', maxLeft);\r\n",
-       "                    if(position.top > maxTop) me.$el.css('top', maxTop);\r\n",
-       "                }\r\n",
-       "            });\r\n",
-       "\r\n",
-       "            me.update();\r\n",
-       "        },\r\n",
-       "\r\n",
-       "        display: function(message) {\r\n",
-       "            if(message) {\r\n",
-       "                var initialScroll = this.outputArea.scrollTop();\r\n",
-       "                this.outputArea.scrollTop(this.outputArea.prop('scrollHeight'));\r\n",
-       "                var scrollBottom = this.outputArea.scrollTop();\r\n",
-       "\r\n",
-       "                if(this.$el.attr('qcodes-state') === 'minimized') {\r\n",
-       "                    this.$el.find('.qcodes-docked').click();\r\n",
-       "                    // always scroll to the bottom if we're restoring\r\n",
-       "                    // because of a new message\r\n",
-       "                    initialScroll = scrollBottom;\r\n",
-       "                }\r\n",
-       "\r\n",
-       "                this.outputArea.append(message);\r\n",
-       "                this.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",
-       "                this.outputArea.scrollTop(initialScroll === scrollBottom ?\r\n",
-       "                    this.outputArea.prop('scrollHeight') : initialScroll);\r\n",
-       "            }\r\n",
-       "\r\n",
-       "            var processes = this.model.get('_processes') || 'No subprocesses';\r\n",
-       "            this.abortButton.toggleClass('disabled', processes.indexOf('Measurement')===-1);\r\n",
-       "            this.subprocessList.text(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"
-    },
-    {
-     "name": "stdout",
-     "output_type": "stream",
-     "text": [
-      "No loop running\n"
-     ]
-    }
-   ],
    "source": [
-    "%matplotlib nbagg\n",
-    "import matplotlib.pyplot as plt\n",
-    "import time\n",
-    "import numpy as np\n",
-    "\n",
-    "import qcodes as qc\n",
-    "\n",
-    "qc.halt_bg()\n",
-    "qc.set_mp_method('spawn')  # force Windows behavior on mac\n",
-    "\n",
-    "# this makes a widget in the corner of the window to show and control\n",
-    "# subprocesses and any output they would print to the terminal\n",
-    "qc.show_subprocess_widget()"
+    "**NOTE** This example is for the new (as of September 2017) channelised driver. If you are considering using the old driver, please reconsider. There is no functionality of the old driver that is not contained in the new one, but it might have a (slightly) different name."
    ]
   },
   {
    "cell_type": "code",
-   "execution_count": null,
-   "metadata": {},
-   "outputs": [],
-   "source": []
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 2,
+   "execution_count": 1,
    "metadata": {
     "collapsed": true
    },
    "outputs": [],
    "source": [
-    "import qcodes.instrument_drivers.tektronix.Keithley_2600 as keith"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 3,
-   "metadata": {},
-   "outputs": [],
-   "source": [
-    "# spawn doesn't like function or class definitions in the interpreter\n",
-    "# session - had to move them to a file.\n",
-    "\n",
-    "# now create this \"experiment\"\n",
-    "k1 = keith.Keithley_2600('Keithley1', 'GPIB0::15::INSTR',channel='a')#,server_name=None)\n",
-    "k2 = keith.Keithley_2600('Keithley2', 'GPIB0::15::INSTR',channel='b')#,server_name=None)\n",
-    "\n",
-    "station = qc.Station(k1,k2)\n",
-    "\n",
-    "# could measure any number of things by adding arguments to this\n",
-    "# function call, but here we're just measuring one, the meter amplitude\n",
-    "station.set_measurement(k1.curr,k2.curr)\n",
-    "\n",
-    "# it's nice to have the key parameters be part of the global namespace\n",
-    "# that way they're objects that we can easily set, get, and slice\n",
-    "# this could be simplified to a station method that gathers all parameters\n",
-    "# and adds them all as (disambiguated) globals, printing what it did\n",
-    "# something like:\n",
-    "#   station.gather_parameters(globals())\n",
-    "\n",
-    "vsd1, vsd2, curr1, curr2 = k1.volt, k2.volt, k1.curr, k2.curr\n",
+    "import qcodes as qc\n",
     "\n",
-    "# once we have implemented a monitor, defining a station will start a\n",
-    "# DataServer process, and you would see it in the subprocess widget,\n",
-    "# or via active_children() as here:\n",
-    "# qc.active_children()"
+    "from qcodes.instrument_drivers.tektronix.Keithley_2600_channels import Keithley_2600"
    ]
   },
   {
    "cell_type": "code",
-   "execution_count": 4,
-   "metadata": {
-    "scrolled": false
-   },
+   "execution_count": 2,
+   "metadata": {},
    "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "Connected to: Keithley Instruments Inc. 2614B (serial:4084407, firmware:3.2.1) in 0.09s\n"
+     ]
+    },
     {
      "data": {
       "text/plain": [
-       "{'instruments': {'Keithley1': {'functions': {},\n",
-       "   'metadata': {'info': {'model': '2614B',\n",
-       "     'serial_number': '4083825',\n",
-       "     'software_revision': '3.2.1',\n",
-       "     'vendor': 'Keithley Instruments Inc.'}},\n",
-       "   'parameters': {'curr': {'ts': None, 'value': None},\n",
-       "    'limiti': {'ts': None, 'value': None},\n",
-       "    'limitv': {'ts': None, 'value': None},\n",
-       "    'mode': {'ts': None, 'value': None},\n",
-       "    'output': {'ts': None, 'value': None},\n",
-       "    'rangei': {'ts': None, 'value': None},\n",
-       "    'rangev': {'ts': None, 'value': None},\n",
-       "    'volt': {'ts': None, 'value': None}}},\n",
-       "  'Keithley2': {'functions': {},\n",
-       "   'metadata': {'info': {'model': '2614B',\n",
-       "     'serial_number': '4083825',\n",
-       "     'software_revision': '3.2.1',\n",
-       "     'vendor': 'Keithley Instruments Inc.'}},\n",
-       "   'parameters': {'curr': {'ts': None, 'value': None},\n",
-       "    'limiti': {'ts': None, 'value': None},\n",
-       "    'limitv': {'ts': None, 'value': None},\n",
-       "    'mode': {'ts': None, 'value': None},\n",
-       "    'output': {'ts': None, 'value': None},\n",
-       "    'rangei': {'ts': None, 'value': None},\n",
-       "    'rangev': {'ts': None, 'value': None},\n",
-       "    'volt': {'ts': None, 'value': None}}}}}"
+       "'keithley'"
       ]
      },
-     "execution_count": 4,
+     "execution_count": 2,
      "metadata": {},
      "output_type": "execute_result"
     }
    ],
    "source": [
-    "station.snapshot()"
+    "# Create a station to hold all the instruments\n",
+    "\n",
+    "station = qc.Station()\n",
+    "\n",
+    "# instantiate the Keithley and add it to the station\n",
+    "\n",
+    "keith = Keithley_2600('keithley', 'TCPIP0::192.168.15.116::inst0::INSTR')\n",
+    "station.add_component(keith)"
    ]
   },
   {
-   "cell_type": "code",
-   "execution_count": 5,
+   "cell_type": "markdown",
    "metadata": {},
-   "outputs": [
-    {
-     "data": {
-      "text/plain": [
-       "[2.98023e-13, -9.41753e-13]"
-      ]
-     },
-     "execution_count": 5,
-     "metadata": {},
-     "output_type": "execute_result"
-    }
-   ],
    "source": [
-    "# we can get the measured quantities right now\n",
-    "station.measure()"
+    "The Keithley 2600 has two channels, here called `smua` and `smub` in agreement with the instrument manual.\n",
+    "\n",
+    "The two channels are basically two separate instruments with different integration times (`nplc`), operation modes (`mode`) etc."
    ]
   },
   {
    "cell_type": "code",
-   "execution_count": 6,
+   "execution_count": 3,
    "metadata": {},
    "outputs": [
     {
      "name": "stdout",
      "output_type": "stream",
      "text": [
-      "DataSet: DataMode.PULL_FROM_SERVER, location='testsweep'\n",
-      "   curr_0: curr\n",
-      "   curr_1: curr\n",
-      "   volt: volt\n",
-      "started at 2016-04-20 15:37:23\n"
+      "keithley:\n",
+      "\tparameter      value\n",
+      "--------------------------------------------------------------------------------\n",
+      "IDN             :\t{'vendor': 'Keithley Instruments Inc.', 'model': '2614B', '...\n",
+      "display_settext :\tNone \n",
+      "timeout         :\t5 (s)\n",
+      "keithley_smua:\n",
+      "\tparameter     value\n",
+      "--------------------------------------------------------------------------------\n",
+      "curr           :\t3.0994e-07 (A)\n",
+      "fastsweep      :\tNone \n",
+      "limiti         :\t0.1 (A)\n",
+      "limitv         :\t20 (V)\n",
+      "measurerange_i :\t0.1 (A)\n",
+      "measurerange_v :\t2.00000e+01 (V)\n",
+      "mode           :\tvoltage \n",
+      "nplc           :\t0.05 \n",
+      "output         :\ton \n",
+      "sourcerange_i  :\t1e-07 (A)\n",
+      "sourcerange_v  :\t20 (V)\n",
+      "volt           :\t1.9999 (V)\n",
+      "keithley_smub:\n",
+      "\tparameter     value\n",
+      "--------------------------------------------------------------------------------\n",
+      "curr           :\t-3.6955e-13 (A)\n",
+      "fastsweep      :\tNone \n",
+      "limiti         :\t0.1 (A)\n",
+      "limitv         :\t20 (V)\n",
+      "measurerange_i :\t1e-07 (A)\n",
+      "measurerange_v :\t2.00000e-01 (V)\n",
+      "mode           :\tvoltage \n",
+      "nplc           :\t1 \n",
+      "output         :\toff \n",
+      "sourcerange_i  :\t1e-07 (A)\n",
+      "sourcerange_v  :\t0.2 (V)\n",
+      "volt           :\t1.1206e-06 (V)\n"
      ]
     }
    ],
    "source": [
-    "# start a Loop (which by default runs in a seprarate process)\n",
-    "# the sweep values are defined by slicing the parameter object\n",
-    "# but more complicated sweeps (eg nonlinear, or adaptive) can\n",
-    "# easily be used instead\n",
-    "\n",
-    "# Notice that I'm using an explicit location and `overwrite=True` here so that\n",
-    "# running this notebook over and over won't result in extra files.\n",
-    "# But if you leave these out, you get a new timestamped DataSet each time.\n",
-    "data = qc.Loop(vsd1[-5:5:0.5], 0.03).run(location='testsweep', overwrite=True)\n",
-    "\n",
-    "# now there should be two extra processes running, DataServer and a sweep\n",
-    "# I'll omit the active_children call now because you can see them in the\n",
-    "# subprocess widget"
-   ]
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 7,
-   "metadata": {
-    "scrolled": true
-   },
-   "outputs": [
-    {
-     "data": {
-      "text/plain": [
-       "{'curr_0': DataArray[20]: curr_0\n",
-       " array([ nan,  nan,  nan,  nan,  nan,  nan,  nan,  nan,  nan,  nan,  nan,\n",
-       "         nan,  nan,  nan,  nan,  nan,  nan,  nan,  nan,  nan]),\n",
-       " 'curr_1': DataArray[20]: curr_1\n",
-       " array([ nan,  nan,  nan,  nan,  nan,  nan,  nan,  nan,  nan,  nan,  nan,\n",
-       "         nan,  nan,  nan,  nan,  nan,  nan,  nan,  nan,  nan]),\n",
-       " 'volt': DataArray[20]: volt\n",
-       " array([ -5.,  nan,  nan,  nan,  nan,  nan,  nan,  nan,  nan,  nan,  nan,\n",
-       "         nan,  nan,  nan,  nan,  nan,  nan,  nan,  nan,  nan])}"
-      ]
-     },
-     "execution_count": 7,
-     "metadata": {},
-     "output_type": "execute_result"
-    }
-   ],
-   "source": [
-    "# manually bring the data into the main process and display it as numbers\n",
-    "data.sync()\n",
-    "data.arrays"
+    "# Get an overview of the settings\n",
+    "#\n",
+    "# You will notice that the two channels have identical parameters but\n",
+    "# potentially different values for them\n",
+    "#\n",
+    "keith.print_readable_snapshot()"
    ]
   },
   {
-   "cell_type": "code",
-   "execution_count": 8,
-   "metadata": {
-    "scrolled": false
-   },
-   "outputs": [],
+   "cell_type": "markdown",
+   "metadata": {},
    "source": [
-    "# live-updating plot, that syncs the data and stops updating when it's finished\n",
-    "# plot = qc.MatPlot(data.amplitude)\n",
-    "plotQ1 = qc.QtPlot(data.volt, data.curr_0)\n",
-    "plotQ2 = qc.QtPlot(data.volt, data.curr_1)"
+    "## Basic operation\n",
+    "\n",
+    "Each channel operates in either `voltage` or `current` mode. The mode controls the _source_ behaviour of the instrument, i.e. `voltage` mode corresponds to an amp-meter (voltage source, current meter) and vice versa."
    ]
   },
   {
    "cell_type": "code",
-   "execution_count": 9,
-   "metadata": {
-    "scrolled": true
-   },
+   "execution_count": 4,
+   "metadata": {},
    "outputs": [
     {
      "name": "stdout",
      "output_type": "stream",
      "text": [
-      "DataSet: DataMode.PULL_FROM_SERVER, location='test2d'\n",
-      "   curr_1: curr\n",
-      "   volt: volt\n",
-      "   curr_0: curr\n",
-      "   volt_0: volt\n",
-      "started at 2016-04-20 15:22:46\n"
+      "Measured one current value: -1.54972e-06 A\n"
      ]
     }
    ],
    "source": [
-    "data2 = qc.Loop(vsd1[-5:5:0.1],0).each(\n",
-    "                qc.Loop(vsd2[-2:2:.2], 0)\n",
-    ").run(location='test2d', overwrite=True)\n",
+    "# Let's set up a single-shot current measurement\n",
+    "# on channel a\n",
     "\n",
-    "# use the subplot and add features of qc.MatPlot\n",
-    "# plot2 = qc.MatPlot(data2.amplitude_0, cmap=plt.cm.hot, figsize=(12, 4.5), subplots=(1, 2))\n",
-    "# plot2.add(data2.amplitude_3, cmap=plt.cm.hot, subplot=2)\n",
+    "keith.smua.mode('voltage')\n",
+    "keith.smua.nplc(0.05)  # 0.05 Power Line Cycles per measurement. At 50 Hz, this corresponds to 1 ms\n",
+    "keith.smua.sourcerange_v(20) \n",
+    "keith.smua.measurerange_i(0.1)\n",
+    "#\n",
+    "keith.smua.volt(1)  # set the source to output 1 V\n",
+    "keith.smua.output('on')  # turn output on\n",
+    "curr = keith.smua.curr()\n",
+    "keith.smua.output('off')\n",
     "\n",
-    "# the equivalent in QtPlot\n",
-    "plot2Q = qc.QtPlot(data2.curr_1, figsize=(1200, 500))\n",
-    "# plot2Q.add(data2.curr_1, subplot=2)"
+    "print('Measured one current value: {} A'.format(curr))"
    ]
   },
   {
-   "cell_type": "code",
-   "execution_count": 19,
+   "cell_type": "markdown",
    "metadata": {},
-   "outputs": [
-    {
-     "data": {
-      "text/plain": [
-       "{'model': '2614B',\n",
-       " 'serial_number': '4083825',\n",
-       " 'software_revision': '3.2.1',\n",
-       " 'vendor': 'Keithley Instruments Inc.'}"
-      ]
-     },
-     "execution_count": 19,
-     "metadata": {},
-     "output_type": "execute_result"
-    }
-   ],
    "source": [
-    "k1.setattr(('metadata','test'), 11)\n",
-    "k1.getattr('info')"
+    "## Fast IV curves\n",
+    "\n",
+    "Onboard the Keithley 2600 sits a small computer that can interpret `Lua` scripts. This can be used to make fast IV-curves and is supported by the QCoDeS driver."
    ]
   },
   {
    "cell_type": "code",
-   "execution_count": 8,
-   "metadata": {},
-   "outputs": [
-    {
-     "data": {
-      "text/plain": [
-       "'Keithley Instruments Inc., Model 2614B, 4083825, 3.2.1'"
-      ]
-     },
-     "execution_count": 8,
-     "metadata": {},
-     "output_type": "execute_result"
-    }
-   ],
+   "execution_count": 5,
+   "metadata": {
+    "collapsed": true
+   },
+   "outputs": [],
    "source": [
-    "k1.ask_direct('*IDN?')"
+    "# Let's make a fast IV curve by sweeping the voltage from 1 V to 2 V in 500 steps\n",
+    "# (when making this notebook, nothing was connected to the instrument, so we just measure noise)"
    ]
   },
   {
    "cell_type": "code",
-   "execution_count": null,
-   "metadata": {},
-   "outputs": [],
-   "source": []
-  },
-  {
-   "cell_type": "code",
-   "execution_count": 18,
+   "execution_count": 6,
    "metadata": {},
    "outputs": [
     {
-     "data": {
-      "text/plain": [
-       "{'instruments': {'Keithley1': {'functions': {},\n",
-       "   'metadata': {'test': 11},\n",
-       "   'parameters': {'curr': {'ts': '2016-04-20 15:31:51', 'value': -2.14577e-13},\n",
-       "    'limiti': {'ts': '2016-04-20 15:31:51', 'value': 0.1},\n",
-       "    'limitv': {'ts': '2016-04-20 15:31:51', 'value': 20.0},\n",
-       "    'mode': {'ts': '2016-04-20 15:31:51', 'value': 'voltage'},\n",
-       "    'output': {'ts': '2016-04-20 15:31:51', 'value': 'ON'},\n",
-       "    'rangei': {'ts': '2016-04-20 15:31:51', 'value': 1e-07},\n",
-       "    'rangev': {'ts': '2016-04-20 15:31:51', 'value': 20.0},\n",
-       "    'volt': {'ts': '2016-04-20 15:31:51', 'value': 4.90016}}},\n",
-       "  'Keithley2': {'functions': {},\n",
-       "   'parameters': {'curr': {'ts': '2016-04-20 15:31:51', 'value': -1.07288e-12},\n",
-       "    'limiti': {'ts': '2016-04-20 15:31:51', 'value': 0.1},\n",
-       "    'limitv': {'ts': '2016-04-20 15:31:51', 'value': 20.0},\n",
-       "    'mode': {'ts': '2016-04-20 15:31:51', 'value': 'voltage'},\n",
-       "    'output': {'ts': '2016-04-20 15:31:51', 'value': 'ON'},\n",
-       "    'rangei': {'ts': '2016-04-20 15:31:51', 'value': 1e-07},\n",
-       "    'rangev': {'ts': '2016-04-20 15:31:51', 'value': 2.0},\n",
-       "    'volt': {'ts': '2016-04-20 15:31:51', 'value': 1.80006}}}}}"
-      ]
-     },
-     "execution_count": 18,
-     "metadata": {},
-     "output_type": "execute_result"
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "DataSet:\n",
+      "   location = 'data/2017-09-28/#001_{name}_14-43-10'\n",
+      "      |              |  | \n",
+      "   Measured | keithley_smua_iv_sweep | iv_sweep     | (500,)\n",
+      "acquired at 2017-09-28 14:43:11\n"
+     ]
     }
    ],
    "source": [
-    "station.snapshot(update=True)"
+    "# This function performs the fast sweep and returns a QCoDeS DataSet\n",
+    "data = keith.smua.doFastSweep(1, 2, 500, mode='IV')"
    ]
   },
   {
    "cell_type": "code",
-   "execution_count": 12,
-   "metadata": {},
+   "execution_count": 7,
+   "metadata": {
+    "collapsed": true
+   },
    "outputs": [],
    "source": [
-    "plot2Q.add(data2.curr_0, subplot=2)\n"
+    "# The DataSet may be plotted\n",
+    "plot = qc.MatPlot()\n",
+    "plot.add(data.arrays['keithley_smua_iv_sweep'])"
    ]
   },
   {
    "cell_type": "code",
-   "execution_count": 18,
-   "metadata": {},
-   "outputs": [
-    {
-     "name": "stdout",
-     "output_type": "stream",
-     "text": [
-      "DataSet: DataMode.PULL_FROM_SERVER, location='test_multi_d'\n",
-      "   curr_0_1: curr\n",
-      "   volt_0: volt\n",
-      "   curr_0_0: curr\n",
-      "   volt_1: volt\n",
-      "   curr_1_0: curr\n",
-      "   curr_1_1: curr\n",
-      "   volt: volt\n",
-      "started at 2016-04-20 14:09:16\n"
-     ]
-    },
-    {
-     "ename": "AttributeError",
-     "evalue": "'DataSet' object and its delegates have no attribute 'curr_1'",
-     "output_type": "error",
-     "traceback": [
-      "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m",
-      "\u001b[1;31mAttributeError\u001b[0m                            Traceback (most recent call last)",
-      "\u001b[1;32m\u001b[0m in \u001b[0;36m\u001b[1;34m()\u001b[0m\n\u001b[0;32m      8\u001b[0m \u001b[1;31m# plot3b = qc.MatPlot(data3.curr_1_0, cmap=plt.cm.hot, figsize=(12, 4.5), subplots=(1,2))\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m      9\u001b[0m \u001b[1;31m# plot3b.add(data3.curr_0_1, subplot=2)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m---> 10\u001b[1;33m \u001b[0mplot3Q\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mqc\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mQtPlot\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mdata3\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mcurr_1\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m     11\u001b[0m \u001b[0mplot3bQ\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mqc\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mQtPlot\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mdata3\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mcurr_1\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mfigsize\u001b[0m\u001b[1;33m=\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;36m1200\u001b[0m\u001b[1;33m,\u001b[0m \u001b[1;36m500\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m     12\u001b[0m \u001b[0mplot3bQ\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0madd\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mdata3\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mcurr_0\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0msubplot\u001b[0m\u001b[1;33m=\u001b[0m\u001b[1;36m2\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n",
-      "\u001b[1;32mC:\\Github\\Qcodes\\qcodes\\utils\\helpers.py\u001b[0m in \u001b[0;36m__getattr__\u001b[1;34m(self, key)\u001b[0m\n\u001b[0;32m    187\u001b[0m         raise AttributeError(\n\u001b[0;32m    188\u001b[0m             \"'{}' object and its delegates have no attribute '{}'\".format(\n\u001b[1;32m--> 189\u001b[1;33m                 self.__class__.__name__, key))\n\u001b[0m\u001b[0;32m    190\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m    191\u001b[0m     \u001b[1;32mdef\u001b[0m \u001b[0m__dir__\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;31mAttributeError\u001b[0m: 'DataSet' object and its delegates have no attribute 'curr_1'"
-     ]
-    }
-   ],
+   "execution_count": 8,
+   "metadata": {
+    "collapsed": true
+   },
+   "outputs": [],
    "source": [
-    "data3 = qc.Loop(vsd1[-15:15:1], 0).each(\n",
-    "                qc.Loop(vsd2[-5:5:1], 0),\n",
-    "                qc.Loop(vsd2[5:-5:1], 0),\n",
-    ").run(location='test_multi_d', overwrite=True)\n",
-    "\n",
-    "# several plots updating simultaneously\n",
-    "# plot3 = qc.MatPlot(data3.curr_1_1, cmap=plt.cm.hot)\n",
-    "# plot3b = qc.MatPlot(data3.curr_1_0, cmap=plt.cm.hot, figsize=(12, 4.5), subplots=(1,2))\n",
-    "# plot3b.add(data3.curr_0_1, subplot=2)\n",
-    "plot3Q = qc.QtPlot(data3.curr_1)\n",
-    "plot3bQ = qc.QtPlot(data3.curr_1, figsize=(1200, 500))\n",
-    "plot3bQ.add(data3.curr_0, subplot=2)"
+    "# Finally, tear down the instrument\n",
+    "keith.close()"
    ]
   },
   {
    "cell_type": "code",
-   "execution_count": 9,
+   "execution_count": null,
    "metadata": {
-    "scrolled": false
+    "collapsed": true
    },
-   "outputs": [
-    {
-     "name": "stdout",
-     "output_type": "stream",
-     "text": [
-      "DataSet: DataMode.PULL_FROM_SERVER, location='test_complex_param'\n",
-      "   avg_amplitude: avg_amplitude\n",
-      "   chan2: chan2\n",
-      "   chan1: chan1\n",
-      "   amplitude: amplitude\n",
-      "started at 2016-02-02 12:18:09\n"
-     ]
-    }
-   ],
-   "source": [
-    "# An example of a parameter that returns several values of different dimension\n",
-    "# This produces the last two arrays from data3, but only takes the data once.\n",
-    "data4 = qc.Loop(c1[-15:15:1], 0.1).each(\n",
-    "    AverageAndRaw(meter.amplitude, c2[-10:10:0.2], 0.001)\n",
-    ").run(location='test_complex_param', overwrite=True)\n",
-    "\n",
-    "# plot4 = qc.MatPlot(data4.amplitude, cmap=plt.cm.hot, subplots=(1,2), figsize=(12, 4.5))\n",
-    "# plot4.add(data4.avg_amplitude, subplot=2)\n",
-    "plot4Q = qc.QtPlot(data4.amplitude, figsize=(1200, 500))\n",
-    "plot4Q.add(data4.avg_amplitude, subplot=2)"
-   ]
+   "outputs": [],
+   "source": []
   }
  ],
  "metadata": {
@@ -702,9 +260,9 @@
    "name": "python",
    "nbconvert_exporter": "python",
    "pygments_lexer": "ipython3",
-   "version": "3.5.3"
+   "version": "3.6.0"
   }
  },
  "nbformat": 4,
- "nbformat_minor": 1
+ "nbformat_minor": 2
 }
diff --git a/qcodes/instrument_drivers/tektronix/Keithley_2600.py b/qcodes/instrument_drivers/tektronix/Keithley_2600.py
index 7b9128a5b10..b4554599d40 100644
--- a/qcodes/instrument_drivers/tektronix/Keithley_2600.py
+++ b/qcodes/instrument_drivers/tektronix/Keithley_2600.py
@@ -1,22 +1,81 @@
+import warnings
+
 from qcodes import VisaInstrument
+from qcodes.instrument.channel import InstrumentChannel
+from qcodes.instrument.base import Instrument
+import qcodes.utils.validators as vals
 
 
 class Keithley_2600(VisaInstrument):
     """
-    channel: use channel 'a' or 'b'
-
     This is the qcodes driver for the Keithley_2600 Source-Meter series,
     tested with Keithley_2614B
 
     Status: beta-version.
         TODO:
-        - Add all parameters that are in the manual
-        - range and limit should be set according to mode
+        - Make a channelised version for the two channels
         - add ramping and such stuff
 
     """
-    def __init__(self, name, address, channel, **kwargs):
+    def __init__(self, name: str, address: str, channel: str,
+                 model: str=None, **kwargs) -> None:
+        """
+        Args:
+            name: Name to use internally in QCoDeS
+            address: VISA ressource address
+            channel: Either 'a' or 'b'
+            model: The model type, e.g. '2614B'
+        """
+
+        warnings.warn("This Keithley driver is old and will be removed "
+                      "from QCoDeS soon. Use Keithley_2600_channels "
+                      "instead, it is MUCH better.", UserWarning)
+
         super().__init__(name, address, terminator='\n', **kwargs)
+
+        model = self.ask('localnode.model')
+
+        knownmodels = ['2601B', '2602B', '2604B', '2611B', '2612B',
+                       '2614B', '2635B', '2636B']
+        if model not in knownmodels:
+            kmstring = ('{}, '*(len(knownmodels)-1)).format(*knownmodels[:-1])
+            kmstring += 'and {}.'.format(knownmodels[-1])
+            raise ValueError('Unknown model. Known model are: ' +
+                             kmstring)
+
+        self.model = model
+
+        vranges = {'2601B': [0.1, 1, 6, 40],
+                   '2602B': [0.1, 1, 6, 40],
+                   '2604B': [0.1, 1, 6, 40],
+                   '2611B': [0.2, 2, 20, 200],
+                   '2612B': [0.2, 2, 20, 200],
+                   '2614B': [0.2, 2, 20, 200],
+                   '2635B': [0.2, 2, 20, 200],
+                   '2636B': [0.2, 2, 20, 200]
+                   }
+
+        # TODO: In pulsed mode, models 2611B, 2612B, and 2614B
+        # actually allow up to 10 A.
+        iranges = {'2601B': [100e-9, 1e-6, 10e-6, 100e-6,
+                             1e-3, 0.01, 0.1, 1, 3],
+                   '2602B': [100e-9, 1e-6, 10e-6, 100e-6,
+                             1e-3, 0.01, 0.1, 1, 3],
+                   '2604B': [100e-9, 1e-6, 10e-6, 100e-6,
+                             1e-3, 0.01, 0.1, 1, 3],
+                   '2611B': [100e-9, 1e-6, 10e-6, 100e-6,
+                             1e-3, 0.01, 0.1, 1, 1.5],
+                   '2612B': [100e-9, 1e-6, 10e-6, 100e-6,
+                             1e-3, 0.01, 0.1, 1, 1.5],
+                   '2614B': [100e-9, 1e-6, 10e-6, 100e-6,
+                             1e-3, 0.01, 0.1, 1, 1.5],
+                   '2634B': [1e-9, 10e-9, 100e-9, 1e-6, 10e-6, 100e-6,
+                             1e-3, 10e-6, 100e-3, 1, 1.5],
+                   '2635B': [1e-9, 10e-9, 100e-9, 1e-6, 10e-6, 100e-6,
+                             1e-3, 10e-6, 100e-3, 1, 1.5],
+                   '2636B': [1e-9, 10e-9, 100e-9, 1e-6, 10e-6, 100e-6,
+                             1e-3, 10e-6, 100e-3, 1, 1.5]}
+
         self._channel = channel
 
         self.add_parameter('volt',
@@ -35,26 +94,51 @@ def __init__(self, name, address, channel, **kwargs):
                            get_cmd='source.func',
                            get_parser=float,
                            set_cmd='source.func={:d}',
-                           val_mapping={'current': 0, 'voltage': 1})
+                           val_mapping={'current': 0, 'voltage': 1},
+                           docstring='Selects the output source.')
         self.add_parameter('output',
                            get_cmd='source.output',
                            get_parser=float,
                            set_cmd='source.output={:d}',
                            val_mapping={'on':  1, 'off': 0})
-        # Source range
-        # needs get after set
-        self.add_parameter('rangev',
+        self.add_parameter('nplc',
+                           label='Number of power line cycles',
+                           set_cmd='measure.nplc={:.4f}',
+                           get_cmd='measure.nplc',
+                           get_parser=float,
+                           vals=vals.Numbers(0.001, 25))
+        # volt range
+        # needs get after set (WilliamHPNielsen): why?
+        self.add_parameter('sourcerange_v',
+                           label='voltage source range',
                            get_cmd='source.rangev',
                            get_parser=float,
                            set_cmd='source.rangev={:.4f}',
-                           unit='V')
-        # Measure range
+                           unit='V',
+                           vals=vals.Enum(*vranges[self.model]))
+        self.add_parameter('measurerange_v',
+                           label='voltage measure range',
+                           get_cmd='measure.rangev',
+                           set_cmd='measure.rangev={:.4f}',
+                           unit='V',
+                           vals=vals.Enum(*vranges[self.model]))
+        # current range
         # needs get after set
-        self.add_parameter('rangei',
+        self.add_parameter('sourcerange_i',
+                           label='current source range',
                            get_cmd='source.rangei',
                            get_parser=float,
                            set_cmd='source.rangei={:.4f}',
-                           unit='A')
+                           unit='A',
+                           vals=vals.Enum(*iranges[self.model]))
+
+        self.add_parameter('measurerange_i',
+                           label='current measure range',
+                           get_cmd='measure.rangei',
+                           get_parser=float,
+                           set_cmd='measure.rangei={:.4f}',
+                           unit='A',
+                           vals=vals.Enum(*iranges[self.model]))
         # Compliance limit
         self.add_parameter('limitv',
                            get_cmd='source.limitv',
@@ -67,9 +151,16 @@ def __init__(self, name, address, channel, **kwargs):
                            get_parser=float,
                            set_cmd='source.limiti={:.4f}',
                            unit='A')
+        # display
+        self.add_parameter('display_settext',
+                           set_cmd=self._display_settext,
+                           vals=vals.Strings())
 
         self.connect_message()
 
+    def _display_settext(self, text):
+        self.visa_handle.write('display.settext("{}")'.format(text))
+
     def get_idn(self):
         IDN = self.ask_raw('*IDN?')
         vendor, model, serial, firmware = map(str.strip, IDN.split(','))
@@ -79,8 +170,32 @@ def get_idn(self):
                'serial': serial, 'firmware': firmware}
         return IDN
 
+    def display_clear(self):
+        """
+        This function clears the display, but also leaves it in user mode
+        """
+        self.visa_handle.write('display.clear()')
+
+    def display_normal(self):
+        """
+        Set the display to the default mode
+        """
+        self.visa_handle.write('display.screen = display.SMUA_SMUB')
+
+    def exit_key(self):
+        """
+        Get back the normal screen after an error:
+        send an EXIT key press event
+        """
+        self.visa_handle.write('display.sendkey(75)')
+
     def reset(self):
+        """
+        Reset instrument to factory defaults
+        """
         self.write('reset()')
+        # remember to update all the metadata
+        self.snapshot(update=True)
 
     def ask(self, cmd):
         return super().ask('print(smu{:s}.{:s})'.format(self._channel, cmd))
diff --git a/qcodes/instrument_drivers/tektronix/Keithley_2600_channels.py b/qcodes/instrument_drivers/tektronix/Keithley_2600_channels.py
new file mode 100644
index 00000000000..1c675245d4c
--- /dev/null
+++ b/qcodes/instrument_drivers/tektronix/Keithley_2600_channels.py
@@ -0,0 +1,450 @@
+import logging
+import struct
+import numpy as np
+from typing import List, Dict
+
+import qcodes as qc
+from qcodes import VisaInstrument, DataSet
+from qcodes.instrument.channel import InstrumentChannel
+from qcodes.instrument.base import Instrument
+from qcodes.instrument.parameter import ArrayParameter
+import qcodes.utils.validators as vals
+
+
+log = logging.getLogger(__name__)
+
+
+class LuaSweepParameter(ArrayParameter):
+    """
+    Parameter class to hold the data from a
+    deployed Lua script sweep.
+    """
+
+    def __init__(self, name: str, instrument: Instrument) -> None:
+
+        super().__init__(name=name,
+                         shape=(1,),
+                         docstring='Holds a sweep')
+
+        self._instrument = instrument
+
+    def prepareSweep(self, start: float, stop: float, steps: int,
+                     mode: str) -> None:
+        """
+        Builds setpoints and labels
+
+        Args:
+            start: Starting point of the sweep
+            stop: Endpoint of the sweep
+            steps: No. of sweep steps
+            mode: Type of sweep, either 'IV' (voltage sweep)
+                or 'VI' (current sweep)
+        """
+
+        if mode not in ['IV', 'VI']:
+            raise ValueError('mode must be either "VI" or "IV"')
+
+        self.shape = (steps,)
+
+        if mode == 'IV':
+            self.unit = 'A'
+            self.setpoint_names = ('Voltage',)
+            self.setpoint_units = ('V',)
+            self.label = 'current'
+            self.name = 'iv_sweep'
+
+        if mode == 'VI':
+            self.unit = 'V'
+            self.setpoint_names = ('Current',)
+            self.setpoint_units = ('A',)
+            self.label = 'voltage'
+            self.name = 'vi_sweep'
+
+        self.setpoints = (tuple(np.linspace(start, stop, steps)),)
+
+        self.start = start
+        self.stop = stop
+        self.steps = steps
+        self.mode = mode
+
+    def get(self) -> np.ndarray:
+
+        data = self._instrument._fast_sweep(self.start,
+                                            self.stop,
+                                            self.steps,
+                                            self.mode)
+
+        return data
+
+
+class KeithleyChannel(InstrumentChannel):
+    """
+    Class to hold the two Keithley channels, i.e.
+    SMUA and SMUB.
+    """
+
+    def __init__(self, parent: Instrument, name: str, channel: str) -> None:
+        """
+        Args:
+            parent: The Instrument instance to which the channel is
+                to be attached.
+            name: The 'colloquial' name of the channel
+            channel: The name used by the Keithley, i.e. either
+                'smua' or 'smub'
+        """
+
+        if channel not in ['smua', 'smub']:
+            raise ValueError('channel must be either "smub" or "smua"')
+
+        super().__init__(parent, name)
+        self.model = self._parent.model
+        vranges = self._parent._vranges
+        iranges = self._parent._iranges
+
+        self.add_parameter('volt',
+                           get_cmd='{}.measure.v()'.format(channel),
+                           get_parser=float,
+                           set_cmd='{}.source.levelv={}'.format(channel,
+                                                                '{:.12f}'),
+                           label='Voltage',
+                           unit='V')
+
+        self.add_parameter('curr',
+                           get_cmd='{}.measure.i()'.format(channel),
+                           get_parser=float,
+                           set_cmd='{}.source.leveli={}'.format(channel,
+                                                                '{:.12f}'),
+                           label='Current',
+                           unit='A')
+
+        self.add_parameter('mode',
+                           get_cmd='{}.source.func'.format(channel),
+                           get_parser=float,
+                           set_cmd='{}.source.func={}'.format(channel, '{:d}'),
+                           val_mapping={'current': 0, 'voltage': 1},
+                           docstring='Selects the output source.')
+
+        self.add_parameter('output',
+                           get_cmd='{}.source.output'.format(channel),
+                           get_parser=float,
+                           set_cmd='{}.source.output={}'.format(channel,
+                                                                '{:d}'),
+                           val_mapping={'on':  1, 'off': 0})
+
+        self.add_parameter('nplc',
+                           label='Number of power line cycles',
+                           set_cmd='{}.measure.nplc={}'.format(channel,
+                                                               '{:.4f}'),
+                           get_cmd='{}.measure.nplc'.format(channel),
+                           get_parser=float,
+                           vals=vals.Numbers(0.001, 25))
+        # volt range
+        # needs get after set (WilliamHPNielsen): why?
+        self.add_parameter('sourcerange_v',
+                           label='voltage source range',
+                           get_cmd='{}.source.rangev'.format(channel),
+                           get_parser=float,
+                           set_cmd='{}.source.rangev={}'.format(channel,
+                                                                '{:.4f}'),
+                           unit='V',
+                           vals=vals.Enum(*vranges[self.model]))
+        self.add_parameter('measurerange_v',
+                           label='voltage measure range',
+                           get_cmd='{}.measure.rangev'.format(channel),
+                           set_cmd='{}.measure.rangev={}'.format(channel,
+                                                                 '{:.4f}'),
+                           unit='V',
+                           vals=vals.Enum(*vranges[self.model]))
+        # current range
+        # needs get after set
+        self.add_parameter('sourcerange_i',
+                           label='current source range',
+                           get_cmd='{}.source.rangei'.format(channel),
+                           get_parser=float,
+                           set_cmd='{}.source.rangei={}'.format(channel,
+                                                                '{:.4f}'),
+                           unit='A',
+                           vals=vals.Enum(*iranges[self.model]))
+
+        self.add_parameter('measurerange_i',
+                           label='current measure range',
+                           get_cmd='{}.measure.rangei'.format(channel),
+                           get_parser=float,
+                           set_cmd='{}.measure.rangei={}'.format(channel,
+                                                                 '{:.4f}'),
+                           unit='A',
+                           vals=vals.Enum(*iranges[self.model]))
+        # Compliance limit
+        self.add_parameter('limitv',
+                           get_cmd='{}.source.limitv'.format(channel),
+                           get_parser=float,
+                           set_cmd='{}.source.limitv={}'.format(channel,
+                                                                '{:.4f}'),
+                           unit='V')
+        # Compliance limit
+        self.add_parameter('limiti',
+                           get_cmd='{}.source.limiti'.format(channel),
+                           get_parser=float,
+                           set_cmd='{}.source.limiti={}'.format(channel,
+                                                                '{:.4f}'),
+                           unit='A')
+
+        self.add_parameter('fastsweep',
+                           parameter_class=LuaSweepParameter)
+
+        self.channel = channel
+
+    # We need to avoid updating the sweep parameter
+    def snapshot_base(self, update: bool=False) -> Dict:
+        params_to_skip_update = ['fastsweep']
+        dct = super().snapshot_base(update=update,
+                                    params_to_skip_update=params_to_skip_update)
+        return dct
+
+    def reset(self):
+        """
+        Reset instrument to factory defaults.
+        This resets only the relevant channel.
+        """
+        self.write('{}.reset()'.format(self.channel))
+        # remember to update all the metadata
+        log.debug('Reset channel {}.'.format(self.channel) +
+                  'Updating settings...')
+        self.snapshot(update=True)
+
+    def doFastSweep(self, start: float, stop: float,
+                    steps: int, mode: str) -> DataSet:
+        """
+        Perform a fast sweep using a deployed lua script and
+        return a QCoDeS DataSet with the sweep.
+
+        Args:
+            start: starting sweep value (V or A)
+            stop: end sweep value (V or A)
+            steps: number of steps
+            mode: What kind of sweep to make.
+                'IV' (I versus V) or 'VI' (V versus I)
+        """
+        # prepare setpoints, units, name
+        self.fastsweep.prepareSweep(start, stop, steps, mode)
+
+        data = qc.Measure(self.fastsweep).run()
+
+        return data
+
+    def _fast_sweep(self, start: float, stop: float, steps: int,
+                    mode: str='IV') -> np.ndarray:
+        """
+        Perform a fast sweep using a deployed Lua script.
+        This is the engine that forms the script, uploads it,
+        runs it, collects the data, and casts the data correctly.
+
+        Args:
+            start: starting voltage
+            stop: end voltage
+            steps: number of steps
+            mode: What kind of sweep to make.
+                'IV' (I versus V) or 'VI' (V versus I)
+        """
+
+        channel = self.channel
+
+        # an extra visa query, a necessary precaution
+        # to avoid timing out when waiting for long
+        # measurements
+        nplc = self.nplc()
+
+        dV = (stop-start)/(steps-1)
+
+        if mode == 'IV':
+            meas = 'i'
+            sour = 'v'
+            func = '1'
+
+        if mode == 'VI':
+            meas = 'v'
+            sour = 'i'
+            func = '0'
+
+        script = ['{}.measure.nplc = {:.12f}'.format(channel, nplc),
+                  '{}.source.output = 1'.format(channel),
+                  'startX = {:.12f}'.format(start),
+                  'dX = {:.12f}'.format(dV),
+                  '{}.source.output = 1'.format(channel),
+                  '{}.source.func = {}'.format(channel, func),
+                  '{}.measure.count = 1'.format(channel),
+                  '{}.nvbuffer1.clear()'.format(channel),
+                  '{}.nvbuffer1.appendmode = 1'.format(channel),
+                  'for index = 1, {} do'.format(steps),
+                  '  target = startX + (index-1)*dX',
+                  '  {}.source.level{} = target'.format(channel, sour),
+                  '  {}.measure.{}({}.nvbuffer1)'.format(channel, meas,
+                                                         channel),
+                  'end',
+                  'format.data = format.REAL32',
+                  'format.byteorder = format.LITTLEENDIAN',
+                  'printbuffer(1, {}, {}.nvbuffer1.readings)'.format(steps,
+                                                                     channel)]
+
+        self.write(self._parent._scriptwrapper(program=script, debug=True))
+        # we must wait for the script to execute
+        oldtimeout = self._parent.visa_handle.timeout
+        self._parent.visa_handle.timeout = 2*1000*steps*nplc/50 + 5000
+
+        # now poll all the data
+        # The problem is that a '\n' character might by chance be present in
+        # the data
+        fullsize = 4*steps + 3
+        received = 0
+        data = b''
+        while received < fullsize:
+            data_temp = self._parent.visa_handle.read_raw()
+            received += len(data_temp)
+            data += data_temp
+
+        # From the manual p. 7-94, we know that a b'#0' is prepended
+        # to the data and a b'\n' is appended
+        data = data[2:-1]
+
+        outdata = np.array(list(struct.iter_unpack(' None:
+        """
+        Args:
+            name: Name to use internally in QCoDeS
+            address: VISA ressource address
+        """
+        super().__init__(name, address, terminator='\n', **kwargs)
+
+        model = self.ask('localnode.model')
+
+        knownmodels = ['2601B', '2602B', '2604B', '2611B', '2612B',
+                       '2614B', '2635B', '2636B']
+        if model not in knownmodels:
+            kmstring = ('{}, '*(len(knownmodels)-1)).format(*knownmodels[:-1])
+            kmstring += 'and {}.'.format(knownmodels[-1])
+            raise ValueError('Unknown model. Known model are: ' +
+                             kmstring)
+
+        self.model = model
+
+        self._vranges = {'2601B': [0.1, 1, 6, 40],
+                         '2602B': [0.1, 1, 6, 40],
+                         '2604B': [0.1, 1, 6, 40],
+                         '2611B': [0.2, 2, 20, 200],
+                         '2612B': [0.2, 2, 20, 200],
+                         '2614B': [0.2, 2, 20, 200],
+                         '2635B': [0.2, 2, 20, 200],
+                         '2636B': [0.2, 2, 20, 200]}
+
+        # TODO: In pulsed mode, models 2611B, 2612B, and 2614B
+        # actually allow up to 10 A.
+        self._iranges = {'2601B': [100e-9, 1e-6, 10e-6, 100e-6,
+                                   1e-3, 0.01, 0.1, 1, 3],
+                         '2602B': [100e-9, 1e-6, 10e-6, 100e-6,
+                                   1e-3, 0.01, 0.1, 1, 3],
+                         '2604B': [100e-9, 1e-6, 10e-6, 100e-6,
+                                   1e-3, 0.01, 0.1, 1, 3],
+                         '2611B': [100e-9, 1e-6, 10e-6, 100e-6,
+                                   1e-3, 0.01, 0.1, 1, 1.5],
+                         '2612B': [100e-9, 1e-6, 10e-6, 100e-6,
+                                   1e-3, 0.01, 0.1, 1, 1.5],
+                         '2614B': [100e-9, 1e-6, 10e-6, 100e-6,
+                                   1e-3, 0.01, 0.1, 1, 1.5],
+                         '2634B': [1e-9, 10e-9, 100e-9, 1e-6, 10e-6, 100e-6,
+                                   1e-3, 10e-6, 100e-3, 1, 1.5],
+                         '2635B': [1e-9, 10e-9, 100e-9, 1e-6, 10e-6, 100e-6,
+                                   1e-3, 10e-6, 100e-3, 1, 1.5],
+                         '2636B': [1e-9, 10e-9, 100e-9, 1e-6, 10e-6, 100e-6,
+                                   1e-3, 10e-6, 100e-3, 1, 1.5]}
+
+        # Add the channel to the instrument
+        for ch in ['a', 'b']:
+            ch_name = 'smu{}'.format(ch)
+            channel = KeithleyChannel(self, ch_name, ch_name)
+            self.add_submodule(ch_name, channel)
+
+        # display
+        self.add_parameter('display_settext',
+                           set_cmd=self._display_settext,
+                           vals=vals.Strings())
+
+        self.connect_message()
+
+    def _display_settext(self, text):
+        self.visa_handle.write('display.settext("{}")'.format(text))
+
+    def get_idn(self):
+        IDN = self.ask_raw('*IDN?')
+        vendor, model, serial, firmware = map(str.strip, IDN.split(','))
+        model = model[6:]
+
+        IDN = {'vendor': vendor, 'model': model,
+               'serial': serial, 'firmware': firmware}
+        return IDN
+
+    def display_clear(self):
+        """
+        This function clears the display, but also leaves it in user mode
+        """
+        self.visa_handle.write('display.clear()')
+
+    def display_normal(self):
+        """
+        Set the display to the default mode
+        """
+        self.visa_handle.write('display.screen = display.SMUA_SMUB')
+
+    def exit_key(self):
+        """
+        Get back the normal screen after an error:
+        send an EXIT key press event
+        """
+        self.visa_handle.write('display.sendkey(75)')
+
+    def reset(self):
+        """
+        Reset instrument to factory defaults.
+        This resets both channels.
+        """
+        self.write('reset()')
+        # remember to update all the metadata
+        log.debug('Reset instrument. Re-querying settings...')
+        self.snapshot(update=True)
+
+    def ask(self, cmd: str) -> str:
+        """
+        Override of normal ask. This is important, since queries to the
+        instrument must be wrapped in 'print()'
+        """
+        return super().ask('print({:s})'.format(cmd))
+
+    @staticmethod
+    def _scriptwrapper(program: List[str], debug: bool=False) -> str:
+        """
+        wraps a program so that the output can be put into
+        visa_handle.write and run.
+        The script will run immediately as an anonymous script.
+
+        Args:
+            program: A list of program instructions. One line per
+            list item, e.g. ['for ii = 1, 10 do', 'print(ii)', 'end' ]
+        """
+        mainprog = '\r\n'.join(program) + '\r\n'
+        wrapped = 'loadandrunscript\r\n{}endscript\n'.format(mainprog)
+        if debug:
+            log.debug('Wrapped the following script:')
+            log.debug(wrapped)
+        return wrapped