Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Benchmark - Keysight DMM software trigger #729

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,303 @@
{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Benchmark of Keysight 34465A\n",
"\n",
"We benchmark the acquisition of N voltages from a QDac on a Keysight DMM. Two acquisition modes are tested; the \"classical\" set voltage/get voltage and a set voltage / send software trigger method.\n",
"\n",
"The former method is cast as a standard QCoDeS measurement, whereas the latter is just the raw commands. If anything, this should add a bit of extra overhead to the first method.\n",
"\n",
"The QDac sweeps a voltage from 0 V to 1 V.\n",
"\n",
"Conclusion: <span style=\"color:red\">there is **no** speed-up</span>."
]
},
{
"cell_type": "code",
"execution_count": 1,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"import qcodes as qc\n",
"import numpy as np\n",
"import time\n",
"from qcodes.instrument_drivers.Keysight.Keysight_34465A import Keysight_34465A\n",
"from qcodes.instrument_drivers.QDev.QDac import QDac"
]
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Connected to: Keysight Technologies 34465A (serial:MY54505281, firmware:A.02.14-02.40-02.14-00.49-02-01) in 7.14s\n"
]
}
],
"source": [
"dmm = Keysight_34465A('dmm', 'TCPIP0::K-000000-00000.local::hislip0::INSTR')"
]
},
{
"cell_type": "code",
"execution_count": 3,
"metadata": {},
"outputs": [],
"source": [
"qdac = QDac('qdac', 'ASRL7::INSTR')"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Pre-benchmark setting"
]
},
{
"cell_type": "code",
"execution_count": 4,
"metadata": {},
"outputs": [],
"source": [
"ap_time = 1e-3\n",
"dmm.NPLC(0.06) # aperture time of 1 ms\n",
"dmm.range(1) # Voltage range of 1 V\n",
"qdac.ch01_v(0)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## N = 1000, set-get"
]
},
{
"cell_type": "code",
"execution_count": 5,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"# prepare the DMM for get-set mode\n",
"dmm.trigger_source('IMM')\n",
"dmm.sample_count(1)\n",
"dmm.trigger_count(1)"
]
},
{
"cell_type": "code",
"execution_count": 6,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Started at 2017-09-08 11:33:51\n",
"DataSet:\n",
" location = 'data/2017-09-08/#013_N_1000_setget_11-33-51'\n",
" <Type> | <array_id> | <array.name> | <array.shape>\n",
" Setpoint | qdac_ch01_v_set | ch01_v | (1000,)\n",
" Measured | dmm_volt | volt | (1000,)\n",
"Finished at 2017-09-08 11:34:23\n",
"Started at 2017-09-08 11:34:23\n",
"DataSet:\n",
" location = 'data/2017-09-08/#014_N_1000_setget_11-34-23'\n",
" <Type> | <array_id> | <array.name> | <array.shape>\n",
" Setpoint | qdac_ch01_v_set | ch01_v | (1000,)\n",
" Measured | dmm_volt | volt | (1000,)\n",
"Finished at 2017-09-08 11:34:55\n",
"Started at 2017-09-08 11:34:55\n",
"DataSet:\n",
" location = 'data/2017-09-08/#015_N_1000_setget_11-34-55'\n",
" <Type> | <array_id> | <array.name> | <array.shape>\n",
" Setpoint | qdac_ch01_v_set | ch01_v | (1000,)\n",
" Measured | dmm_volt | volt | (1000,)\n",
"Finished at 2017-09-08 11:35:27\n",
"Started at 2017-09-08 11:35:27\n",
"DataSet:\n",
" location = 'data/2017-09-08/#016_N_1000_setget_11-35-27'\n",
" <Type> | <array_id> | <array.name> | <array.shape>\n",
" Setpoint | qdac_ch01_v_set | ch01_v | (1000,)\n",
" Measured | dmm_volt | volt | (1000,)\n",
"Finished at 2017-09-08 11:35:59\n",
"Started at 2017-09-08 11:35:59\n",
"DataSet:\n",
" location = 'data/2017-09-08/#017_N_1000_setget_11-35-59'\n",
" <Type> | <array_id> | <array.name> | <array.shape>\n",
" Setpoint | qdac_ch01_v_set | ch01_v | (1000,)\n",
" Measured | dmm_volt | volt | (1000,)\n",
"Finished at 2017-09-08 11:36:32\n",
"Started at 2017-09-08 11:36:32\n",
"DataSet:\n",
" location = 'data/2017-09-08/#018_N_1000_setget_11-36-32'\n",
" <Type> | <array_id> | <array.name> | <array.shape>\n",
" Setpoint | qdac_ch01_v_set | ch01_v | (1000,)\n",
" Measured | dmm_volt | volt | (1000,)\n",
"Finished at 2017-09-08 11:37:04\n",
"Started at 2017-09-08 11:37:04\n",
"DataSet:\n",
" location = 'data/2017-09-08/#019_N_1000_setget_11-37-04'\n",
" <Type> | <array_id> | <array.name> | <array.shape>\n",
" Setpoint | qdac_ch01_v_set | ch01_v | (1000,)\n",
" Measured | dmm_volt | volt | (1000,)\n",
"Finished at 2017-09-08 11:37:36\n",
"Started at 2017-09-08 11:37:36\n",
"DataSet:\n",
" location = 'data/2017-09-08/#020_N_1000_setget_11-37-36'\n",
" <Type> | <array_id> | <array.name> | <array.shape>\n",
" Setpoint | qdac_ch01_v_set | ch01_v | (1000,)\n",
" Measured | dmm_volt | volt | (1000,)\n",
"Finished at 2017-09-08 11:38:08\n",
"32.2 s ± 110 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)\n"
]
}
],
"source": [
"%%timeit\n",
"\n",
"N = 1000\n",
"\n",
"# remember to turn off the display for better speed\n",
"dmm.display_text('Running set-get for {} points'.format(N))\n",
"\n",
"loop = qc.Loop(qdac.ch01_v.sweep(0, 1, num=N)).each(dmm.volt)\n",
"data = loop.get_data_set(name='N_{}_setget'.format(N))\n",
"_ = loop.run() # run the loop\n",
"\n",
"dmm.display_clear()\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## N = 1000, set-software triggered"
]
},
{
"cell_type": "code",
"execution_count": 9,
"metadata": {
"collapsed": true
},
"outputs": [],
"source": [
"def software_triggered_readings(N: int) -> np.array:\n",
" \"\"\"\n",
" Try to get N measurement points\n",
" \"\"\"\n",
" \n",
" dmm.display_text('Sending {} software triggers'.format(N))\n",
" \n",
" dmm.trigger_source('BUS')\n",
" dmm.sample_count(1) # samples per trigger\n",
" dmm.trigger_count(N) # number of triggers to wait for\n",
" dmm.init_measurement()\n",
" \n",
" qdac_setpoints = np.linspace(0, 1, N)\n",
" \n",
" for n in range(N):\n",
" qdac.ch01_v(qdac_setpoints[n])\n",
" dmm.write('*TRG')\n",
" time.sleep(dmm.sample_timer_minimum()) # Wait to avoid losing triggers\n",
" \n",
" # even if we are losing triggers, can ABORt the measurement\n",
" # and then fetch whatever data the DMM holds\n",
" dmm.abort_measurement() \n",
" raw_vals = dmm.ask('FETCH?')\n",
" dmm.display_clear()\n",
"\n",
" numvals = np.array(list(map(float, raw_vals.split(','))))\n",
" \n",
" print('Requested {} samples, got {}.'.format(N, len(numvals)))\n",
" \n",
" return numvals"
]
},
{
"cell_type": "code",
"execution_count": 8,
"metadata": {
"scrolled": false
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Requested 1000 samples, got 1000.\n",
"Requested 1000 samples, got 1000.\n",
"Requested 1000 samples, got 1000.\n",
"Requested 1000 samples, got 1000.\n",
"Requested 1000 samples, got 1000.\n",
"Requested 1000 samples, got 1000.\n",
"Requested 1000 samples, got 1000.\n",
"Requested 1000 samples, got 1000.\n",
"32.2 s ± 387 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)\n"
]
}
],
"source": [
"%%timeit\n",
"\n",
"data = software_triggered_readings(1000)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Results summary\n",
"\n",
"**N = 1000**\n",
"\n",
"Standard set-get: 32.2 s\n",
"\n",
"Software triggered: 32.2 s"
]
},
{
"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.5.3"
}
},
"nbformat": 4,
"nbformat_minor": 2
}
47 changes: 47 additions & 0 deletions qcodes/instrument_drivers/Keysight/Keysight_34465A.py
Original file line number Diff line number Diff line change
Expand Up @@ -185,6 +185,21 @@ def __init__(self, name, address, DIG=False, utility_freq=50, silent=False,
self.NPLC_list = PLCs[self.model]
self._apt_times = apt_times[self.model]

def errorparser(rawmssg: str) -> (int, str):
"""
Parses the error message.

Args:
rawmssg: The raw return value of 'SYSTem:ERRor?'

Returns:
The error code and the error message.
"""
code = int(rawmssg.split(',')[0])
mssg = rawmssg.split(',')[1].strip().replace('"', '')

return code, mssg

####################################
# PARAMETERS

Expand Down Expand Up @@ -306,6 +321,13 @@ def __init__(self, name, address, DIG=False, utility_freq=50, silent=False,
get_parser=float,
unit='s')

# SYSTEM
self.add_parameter('error',
label='Error message',
get_cmd='SYSTem:ERRor?',
get_parser=errorparser
)

# The array parameter
self.add_parameter('data_buffer',
parameter_class=ArrayMeasurement)
Expand Down Expand Up @@ -335,6 +357,7 @@ def __init__(self, name, address, DIG=False, utility_freq=50, silent=False,
self.add_function('init_measurement', call_cmd='INIT')
self.add_function('reset', call_cmd='*RST')
self.add_function('display_clear', call_cmd=('DISPLay:TEXT:CLEar'))
self.add_function('abort_measurement', call_cmd='ABORt')

if not silent:
self.connect_message()
Expand Down Expand Up @@ -404,3 +427,27 @@ def _set_resolution(self, value):
# NPLC settings change with resolution

self.NPLC.get()

def flush_error_queue(self, verbose: bool=True) -> None:
"""
Clear the instrument error queue.

Args:
verbose: If true, the error messages are printed.
Default: True.
"""

log.debug('Flushing error queue...')

err_code, err_message = self.error()
log.debug(' {}, {}'.format(err_code, err_message))
if verbose:
print(err_code, err_message)

while err_code != 0:
err_code, err_message = self.error()
log.debug(' {}, {}'.format(err_code, err_message))
if verbose:
print(err_code, err_message)

log.debug('...flushing complete')