qcodespp 0.1.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- qcodespp/__init__.py +77 -0
- qcodespp/actions.py +237 -0
- qcodespp/data/__init__.py +0 -0
- qcodespp/data/data_array.py +555 -0
- qcodespp/data/data_set.py +926 -0
- qcodespp/data/format.py +338 -0
- qcodespp/data/gnuplot_format.py +425 -0
- qcodespp/data/hdf5_format.py +537 -0
- qcodespp/data/hdf5_format_hickle.py +63 -0
- qcodespp/data/io.py +241 -0
- qcodespp/data/location.py +171 -0
- qcodespp/instrument_drivers/Keysight/Keysight_34450A.py +9 -0
- qcodespp/instrument_drivers/Keysight/__init__.py +0 -0
- qcodespp/instrument_drivers/Keysight/private/Keysight_344xxA.py +456 -0
- qcodespp/instrument_drivers/Keysight/private/__init__.py +0 -0
- qcodespp/instrument_drivers/Lakeshore/Model_340.py +483 -0
- qcodespp/instrument_drivers/Lakeshore/__init__.py +0 -0
- qcodespp/instrument_drivers/QDevil/159fit_params_high_latest.json +386 -0
- qcodespp/instrument_drivers/QDevil/159fit_params_low_latest.json +386 -0
- qcodespp/instrument_drivers/QDevil/QDAC2.py +3229 -0
- qcodespp/instrument_drivers/QDevil/QDAC2_Array.py +300 -0
- qcodespp/instrument_drivers/QDevil/QSwitch_elab.py +652 -0
- qcodespp/instrument_drivers/QDevil/__init__.py +0 -0
- qcodespp/instrument_drivers/ZI/ZIHF2LI.py +415 -0
- qcodespp/instrument_drivers/ZI/ZIMFLI.py +764 -0
- qcodespp/instrument_drivers/ZI/ZIMFLI_sync.py +108 -0
- qcodespp/instrument_drivers/ZI/ZIUHFLI.py +2179 -0
- qcodespp/instrument_drivers/ZI/__init__.py +1 -0
- qcodespp/instrument_drivers/__init__.py +0 -0
- qcodespp/instrument_drivers/cryogenic/CryogenicSMS120C.py +599 -0
- qcodespp/instrument_drivers/cryogenic/__init__.py +0 -0
- qcodespp/instrument_drivers/instrument_mocks.py +379 -0
- qcodespp/instrument_drivers/multiplexer_instrument.py +287 -0
- qcodespp/instrument_drivers/national_instruments/PXI_4461.py +451 -0
- qcodespp/instrument_drivers/national_instruments/PXI_4462.py +290 -0
- qcodespp/instrument_drivers/national_instruments/PXI_6259.py +436 -0
- qcodespp/instrument_drivers/national_instruments/PXI_6733.py +230 -0
- qcodespp/instrument_drivers/national_instruments/PXI_6733_e.py +243 -0
- qcodespp/instrument_drivers/national_instruments/__init__.py +0 -0
- qcodespp/instrument_drivers/oxford/__init__.py +0 -0
- qcodespp/instrument_drivers/oxford/mercuryiPS_serial.py +658 -0
- qcodespp/instrument_drivers/oxford/triton.py +434 -0
- qcodespp/instrument_drivers/tektronix/Keithley_2000_Scan.py +65 -0
- qcodespp/instrument_drivers/tektronix/Keithley_2182a.py +190 -0
- qcodespp/instrument_drivers/tektronix/Keithley_2400.py +158 -0
- qcodespp/instrument_drivers/tektronix/Keithley_2450.py +242 -0
- qcodespp/instrument_drivers/tektronix/Keithley_2700.py +397 -0
- qcodespp/instrument_drivers/tektronix/Keithley_6500.py +161 -0
- qcodespp/instrument_drivers/tektronix/__init__.py +0 -0
- qcodespp/instrument_drivers/yokogawa/GS200.py +513 -0
- qcodespp/instrument_drivers/yokogawa/__init__.py +0 -0
- qcodespp/loops.py +1342 -0
- qcodespp/measure.py +310 -0
- qcodespp/parameters.py +311 -0
- qcodespp/plotting/RemotePlot.py +469 -0
- qcodespp/plotting/RemotePlotClient.py +367 -0
- qcodespp/plotting/RemoteQtPlotWidgets.py +871 -0
- qcodespp/plotting/__init__.py +0 -0
- qcodespp/plotting/analysis_tools.py +195 -0
- qcodespp/plotting/colors.py +135 -0
- qcodespp/plotting/offline/__init__.py +0 -0
- qcodespp/plotting/offline/datatypes.py +999 -0
- qcodespp/plotting/offline/design.py +906 -0
- qcodespp/plotting/offline/design.ui +1578 -0
- qcodespp/plotting/offline/editor.py +2966 -0
- qcodespp/plotting/offline/filters.py +561 -0
- qcodespp/plotting/offline/fits.py +1171 -0
- qcodespp/plotting/offline/helpers.py +288 -0
- qcodespp/plotting/offline/iconGadget.png +0 -0
- qcodespp/plotting/offline/main.py +55 -0
- qcodespp/plotting/offline/popupwindows.py +1848 -0
- qcodespp/plotting/offline/qcodes_pp_extension.py +328 -0
- qcodespp/plotting/offline/sidebars.py +1108 -0
- qcodespp/station.py +290 -0
- qcodespp/utils/__init__.py +0 -0
- qcodespp/utils/helpers.py +618 -0
- qcodespp/utils/visa_helpers.py +61 -0
- qcodespp/version.py +12 -0
- qcodespp-0.1.0.dist-info/METADATA +91 -0
- qcodespp-0.1.0.dist-info/RECORD +82 -0
- qcodespp-0.1.0.dist-info/WHEEL +4 -0
- qcodespp-0.1.0.dist-info/licenses/LICENSE +21 -0
|
@@ -0,0 +1,456 @@
|
|
|
1
|
+
# QCoDeS driver for the Keysight 344xxA Digital Multimeter
|
|
2
|
+
|
|
3
|
+
from functools import partial
|
|
4
|
+
import numpy as np
|
|
5
|
+
import logging
|
|
6
|
+
|
|
7
|
+
from qcodes.parameters import ArrayParameter
|
|
8
|
+
import qcodes.utils.validators as vals
|
|
9
|
+
from qcodes import VisaInstrument
|
|
10
|
+
from pyvisa import VisaIOError
|
|
11
|
+
|
|
12
|
+
log = logging.getLogger(__name__)
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
class ArrayMeasurement(ArrayParameter):
|
|
16
|
+
"""
|
|
17
|
+
Class to return several values. Really represents a measurement routine.
|
|
18
|
+
"""
|
|
19
|
+
|
|
20
|
+
def __init__(self, name, shape=(1,), *args, **kwargs):
|
|
21
|
+
|
|
22
|
+
super().__init__(name, shape=shape, *args, **kwargs)
|
|
23
|
+
|
|
24
|
+
self.label = ''
|
|
25
|
+
self.unit = ''
|
|
26
|
+
self.properly_prepared = False
|
|
27
|
+
|
|
28
|
+
def prepare(self):
|
|
29
|
+
"""
|
|
30
|
+
Prepare the measurement, create the setpoints.
|
|
31
|
+
|
|
32
|
+
There is some randomness in the measurement times.
|
|
33
|
+
"""
|
|
34
|
+
|
|
35
|
+
inst = self._instrument
|
|
36
|
+
|
|
37
|
+
N = inst.sample_count()
|
|
38
|
+
|
|
39
|
+
# ensure correct instrument settings
|
|
40
|
+
inst.aperture_mode('OFF') # aperture mode seems slower ON than OFF
|
|
41
|
+
inst.trigger_count(1)
|
|
42
|
+
inst.trigger_delay(0)
|
|
43
|
+
inst.sample_count_pretrigger(0)
|
|
44
|
+
inst.sample_source('TIM')
|
|
45
|
+
inst.autorange('OFF')
|
|
46
|
+
|
|
47
|
+
if inst.trigger_source() is None:
|
|
48
|
+
raise ValueError('Trigger source unspecified! Please set '
|
|
49
|
+
"trigger_source to 'INT' or 'EXT'.")
|
|
50
|
+
|
|
51
|
+
# Final step
|
|
52
|
+
self.time_per_point = inst.sample_timer_minimum()
|
|
53
|
+
inst.sample_timer(self.time_per_point)
|
|
54
|
+
|
|
55
|
+
self.setpoints = (tuple(np.linspace(0, N*self.time_per_point, N)),)
|
|
56
|
+
self.shape = (N,)
|
|
57
|
+
|
|
58
|
+
self.properly_prepared = True
|
|
59
|
+
|
|
60
|
+
def get_raw(self):
|
|
61
|
+
|
|
62
|
+
if not self.properly_prepared:
|
|
63
|
+
raise ValueError('ArrayMeasurement not properly_prepared. '
|
|
64
|
+
'Please run prepare().')
|
|
65
|
+
|
|
66
|
+
N = self._instrument.sample_count()
|
|
67
|
+
log.debug("Acquiring {} samples.".format(N))
|
|
68
|
+
|
|
69
|
+
# Ensure that the measurement doesn't time out
|
|
70
|
+
# TODO (WilliamHPNielsen): What if we wait really long for a trigger?
|
|
71
|
+
old_timeout = self._instrument.visa_handle.timeout
|
|
72
|
+
self._instrument.visa_handle.timeout = N*1000*1.2*self.time_per_point
|
|
73
|
+
self._instrument.visa_handle.timeout += old_timeout
|
|
74
|
+
|
|
75
|
+
# Turn off the display to increase measurement speed
|
|
76
|
+
self._instrument.display_text('Acquiring {} samples'.format(N))
|
|
77
|
+
|
|
78
|
+
self._instrument.init_measurement()
|
|
79
|
+
try:
|
|
80
|
+
rawvals = self._instrument.ask('FETCH?')
|
|
81
|
+
except VisaIOError:
|
|
82
|
+
rawvals = None
|
|
83
|
+
log.error('Could not pull data from DMM. Perhaps no trigger?')
|
|
84
|
+
|
|
85
|
+
self._instrument.visa_handle.timeout = old_timeout
|
|
86
|
+
|
|
87
|
+
# parse the acquired values
|
|
88
|
+
try:
|
|
89
|
+
numvals = np.array(list(map(float, rawvals.split(','))))
|
|
90
|
+
except AttributeError:
|
|
91
|
+
numvals = None
|
|
92
|
+
|
|
93
|
+
self._instrument.display_clear()
|
|
94
|
+
|
|
95
|
+
return numvals
|
|
96
|
+
|
|
97
|
+
|
|
98
|
+
class _Keysight_344xxA(VisaInstrument):
|
|
99
|
+
"""
|
|
100
|
+
Instrument class for Keysight 34460A, 34461A, 34465A and 34470A multimeters.
|
|
101
|
+
|
|
102
|
+
Tested with: 34461A, 34465A.
|
|
103
|
+
|
|
104
|
+
The driver currently only supports using the instrument as a voltmeter.
|
|
105
|
+
|
|
106
|
+
Attributes:
|
|
107
|
+
model (str): The model number of the instrument
|
|
108
|
+
NPLC_list (list): A list of the available Power Line Cycle settings
|
|
109
|
+
ranges (list): A list of the available voltage ranges
|
|
110
|
+
"""
|
|
111
|
+
|
|
112
|
+
def __init__(self, name, address, silent=False,
|
|
113
|
+
**kwargs):
|
|
114
|
+
"""
|
|
115
|
+
Create an instance of the instrument.
|
|
116
|
+
|
|
117
|
+
Args:
|
|
118
|
+
name (str): Name used by QCoDeS. Appears in the DataSet
|
|
119
|
+
address (str): Visa-resolvable instrument address.
|
|
120
|
+
silent (bool): If True, the connect_message of the instrument
|
|
121
|
+
is supressed. Default: False
|
|
122
|
+
Returns:
|
|
123
|
+
_Keysight_344xxA
|
|
124
|
+
"""
|
|
125
|
+
|
|
126
|
+
super().__init__(name, address, terminator='\n', **kwargs)
|
|
127
|
+
|
|
128
|
+
idn = self.IDN.get()
|
|
129
|
+
self.model = idn['model']
|
|
130
|
+
|
|
131
|
+
DIG = 'DIG' in self._licenses()
|
|
132
|
+
|
|
133
|
+
####################################
|
|
134
|
+
# Instrument specifications
|
|
135
|
+
|
|
136
|
+
PLCs = {'34460A': [0.02, 0.2, 1, 10, 100],
|
|
137
|
+
'34461A': [0.02, 0.2, 1, 10, 100],
|
|
138
|
+
'34465A': [0.02, 0.06, 0.2, 1, 10, 100],
|
|
139
|
+
'34470A': [0.02, 0.06, 0.2, 1, 10, 100]
|
|
140
|
+
}
|
|
141
|
+
if DIG:
|
|
142
|
+
PLCs['34465A'] = [0.001, 0.002, 0.006] + PLCs['34465A']
|
|
143
|
+
PLCs['34470A'] = [0.001, 0.002, 0.006] + PLCs['34470A']
|
|
144
|
+
|
|
145
|
+
ranges = {'34460A': [10**n for n in range(-3, 9)], # 1 m to 100 M
|
|
146
|
+
'34461A': [10**n for n in range(-3, 9)], # 1 m to 100 M
|
|
147
|
+
'34465A': [10**n for n in range(-3, 10)], # 1 m to 1 G
|
|
148
|
+
'34470A': [10**n for n in range(-3, 10)], # 1 m to 1 G
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
# The resolution factor order matches the order of PLCs
|
|
152
|
+
res_factors = {'34460A': [300e-6, 100e-6, 30e-6, 10e-6, 3e-6],
|
|
153
|
+
'34461A': [100e-6, 10e-6, 3e-6, 1e-6, 0.3e-6],
|
|
154
|
+
'34465A': [3e-6, 1.5e-6, 0.7e-6, 0.3e-6, 0.1e-6,
|
|
155
|
+
0.03e-6],
|
|
156
|
+
'34470A': [1e-6, 0.5e-6, 0.3e-6, 0.1e-6, 0.03e-6,
|
|
157
|
+
0.01e-6]
|
|
158
|
+
}
|
|
159
|
+
if DIG:
|
|
160
|
+
res_factors['34465A'] = [30e-6, 15e-6, 6e-6] + res_factors['34465A']
|
|
161
|
+
res_factors['34470A'] = [30e-6, 10e-6, 3e-6] + res_factors['34470A']
|
|
162
|
+
|
|
163
|
+
self._resolution_factors = res_factors[self.model]
|
|
164
|
+
self.ranges = ranges[self.model]
|
|
165
|
+
self.NPLC_list = PLCs[self.model]
|
|
166
|
+
|
|
167
|
+
####################################
|
|
168
|
+
# PARAMETERS
|
|
169
|
+
|
|
170
|
+
self.add_parameter('line_frequency',
|
|
171
|
+
get_cmd='SYSTem:LFRequency?',
|
|
172
|
+
get_parser=int,
|
|
173
|
+
set_cmd=False,
|
|
174
|
+
label='Line Frequency',
|
|
175
|
+
unit='Hz',
|
|
176
|
+
docstring=('The frequency of the power line where'
|
|
177
|
+
'the instrument is plugged')
|
|
178
|
+
)
|
|
179
|
+
|
|
180
|
+
self.add_parameter('NPLC',
|
|
181
|
+
get_cmd='SENSe:VOLTage:DC:NPLC?',
|
|
182
|
+
get_parser=float,
|
|
183
|
+
set_cmd=self._set_NPLC,
|
|
184
|
+
vals=vals.Enum(*self.NPLC_list),
|
|
185
|
+
label='Integration time',
|
|
186
|
+
unit='NPLC')
|
|
187
|
+
|
|
188
|
+
self.add_parameter('volt',
|
|
189
|
+
get_cmd=self._get_voltage,
|
|
190
|
+
label='Voltage',
|
|
191
|
+
unit='V')
|
|
192
|
+
|
|
193
|
+
self.add_parameter('range',
|
|
194
|
+
get_cmd='SENSe:VOLTage:DC:RANGe?',
|
|
195
|
+
get_parser=float,
|
|
196
|
+
set_cmd='SENSe:VOLTage:DC:RANGe {:f}',
|
|
197
|
+
vals=vals.Enum(*self.ranges))
|
|
198
|
+
|
|
199
|
+
self.add_parameter('resolution',
|
|
200
|
+
get_cmd='SENSe:VOLTage:DC:RESolution?',
|
|
201
|
+
get_parser=float,
|
|
202
|
+
set_cmd=self._set_resolution,
|
|
203
|
+
label='Resolution',
|
|
204
|
+
unit='V')
|
|
205
|
+
|
|
206
|
+
self.add_parameter('autorange',
|
|
207
|
+
label='Autorange',
|
|
208
|
+
set_cmd='SENSe:VOLTage:DC:RANGe:AUTO {}',
|
|
209
|
+
get_cmd='SENSe:VOLTage:DC:RANGe:AUTO?',
|
|
210
|
+
val_mapping={'ON': 1, 'OFF': 0},
|
|
211
|
+
vals=vals.Enum('ON', 'OFF'))
|
|
212
|
+
|
|
213
|
+
self.add_parameter('display_text',
|
|
214
|
+
label='Display text',
|
|
215
|
+
set_cmd='DISPLAY:TEXT "{}"',
|
|
216
|
+
get_cmd='DISPLAY:TEXT?',
|
|
217
|
+
vals=vals.Strings())
|
|
218
|
+
|
|
219
|
+
self.add_parameter('autozero',
|
|
220
|
+
label='Autozero',
|
|
221
|
+
set_cmd='SENSe:VOLTage:DC:ZERO:AUTO {}',
|
|
222
|
+
get_cmd='SENSe:VOLTage:DC:ZERO:AUTO?',
|
|
223
|
+
val_mapping={'ON': 1, 'OFF': 0, 'ONCE': 'ONCE'},
|
|
224
|
+
vals=vals.Enum('ON', 'OFF', 'ONCE'))
|
|
225
|
+
|
|
226
|
+
# TRIGGERING
|
|
227
|
+
|
|
228
|
+
self.add_parameter('trigger_count',
|
|
229
|
+
label='Trigger Count',
|
|
230
|
+
set_cmd='TRIGger:COUNt {}',
|
|
231
|
+
get_cmd='TRIGger:COUNt?',
|
|
232
|
+
get_parser=float,
|
|
233
|
+
vals=vals.MultiType(vals.Numbers(1, 1e6),
|
|
234
|
+
vals.Enum('MIN', 'MAX', 'DEF',
|
|
235
|
+
'INF')))
|
|
236
|
+
|
|
237
|
+
self.add_parameter('trigger_delay',
|
|
238
|
+
label='Trigger Delay',
|
|
239
|
+
set_cmd='TRIGger:DELay {}',
|
|
240
|
+
get_cmd='TRIGger:DELay?',
|
|
241
|
+
vals=vals.MultiType(vals.Numbers(0, 3600),
|
|
242
|
+
vals.Enum('MIN', 'MAX', 'DEF')),
|
|
243
|
+
get_parser=float)
|
|
244
|
+
|
|
245
|
+
self.add_parameter('trigger_slope',
|
|
246
|
+
label='Trigger Slope',
|
|
247
|
+
set_cmd='TRIGger:SLOPe {}',
|
|
248
|
+
get_cmd='TRIGger:SLOPe?',
|
|
249
|
+
vals=vals.Enum('POS', 'NEG'))
|
|
250
|
+
|
|
251
|
+
self.add_parameter('trigger_source',
|
|
252
|
+
label='Trigger Source',
|
|
253
|
+
set_cmd='TRIGger:SOURce {}',
|
|
254
|
+
get_cmd='TRIGger:SOURce?',
|
|
255
|
+
vals=vals.Enum('IMM', 'EXT', 'BUS', 'INT'))
|
|
256
|
+
|
|
257
|
+
# SAMPLING
|
|
258
|
+
|
|
259
|
+
self.add_parameter('sample_count',
|
|
260
|
+
label='Sample Count',
|
|
261
|
+
set_cmd=partial(self._set_databuffer_setpoints,
|
|
262
|
+
'SAMPle:COUNt {}'),
|
|
263
|
+
get_cmd='SAMPle:COUNt?',
|
|
264
|
+
vals=vals.MultiType(vals.Numbers(1, 1e6),
|
|
265
|
+
vals.Enum('MIN', 'MAX', 'DEF')),
|
|
266
|
+
get_parser=int)
|
|
267
|
+
|
|
268
|
+
if DIG:
|
|
269
|
+
self.add_parameter('sample_count_pretrigger',
|
|
270
|
+
label='Sample Pretrigger Count',
|
|
271
|
+
set_cmd='SAMPle:COUNt:PRETrigger {}',
|
|
272
|
+
get_cmd='SAMPle:COUNt:PRETrigger?',
|
|
273
|
+
vals=vals.MultiType(vals.Numbers(0, 2e6-1),
|
|
274
|
+
vals.Enum('MIN', 'MAX', 'DEF')),
|
|
275
|
+
get_parser=int,
|
|
276
|
+
docstring=('Allows collection of the data '
|
|
277
|
+
'being digitized the trigger. Reserves '
|
|
278
|
+
'memory for pretrigger samples up to the'
|
|
279
|
+
' specified num. of pretrigger samples.')
|
|
280
|
+
)
|
|
281
|
+
|
|
282
|
+
self.add_parameter('sample_source',
|
|
283
|
+
label='Sample Timing Source',
|
|
284
|
+
set_cmd='SAMPle:SOURce {}',
|
|
285
|
+
get_cmd='SAMPle:SOURce?',
|
|
286
|
+
vals=vals.Enum('IMM', 'TIM'),
|
|
287
|
+
docstring=('Determines sampling time, immediate'
|
|
288
|
+
' or using sample_timer'))
|
|
289
|
+
|
|
290
|
+
self.add_parameter('sample_timer',
|
|
291
|
+
label='Sample Timer',
|
|
292
|
+
set_cmd='SAMPle:TIMer {}',
|
|
293
|
+
get_cmd='SAMPle:TIMer?',
|
|
294
|
+
unit='s',
|
|
295
|
+
vals=vals.MultiType(vals.Numbers(0, 3600),
|
|
296
|
+
vals.Enum('MIN', 'MAX', 'DEF')),
|
|
297
|
+
get_parser=float)
|
|
298
|
+
|
|
299
|
+
self.add_parameter('sample_timer_minimum',
|
|
300
|
+
label='Minimal sample time',
|
|
301
|
+
get_cmd='SAMPle:TIMer? MIN',
|
|
302
|
+
get_parser=float,
|
|
303
|
+
unit='s')
|
|
304
|
+
|
|
305
|
+
# The array parameter
|
|
306
|
+
self.add_parameter('data_buffer',
|
|
307
|
+
parameter_class=ArrayMeasurement)
|
|
308
|
+
|
|
309
|
+
####################################
|
|
310
|
+
# Model-specific parameters
|
|
311
|
+
|
|
312
|
+
if self.model in ['34465A', '34470A']:
|
|
313
|
+
# Define the extreme aperture time values for the 34465A and 34470A
|
|
314
|
+
utility_freq = self.line_frequency()
|
|
315
|
+
if utility_freq == 50:
|
|
316
|
+
apt_times = {'34465A': [0.3e-3, 2],
|
|
317
|
+
'34470A': [0.3e-3, 2]}
|
|
318
|
+
elif utility_freq == 60:
|
|
319
|
+
apt_times = {'34465A': [0.3e-3, 1.67],
|
|
320
|
+
'34470A': [0.3e-3, 1.67]}
|
|
321
|
+
if DIG:
|
|
322
|
+
apt_times['34465A'][0] = 20e-6
|
|
323
|
+
apt_times['34470A'][0] = 20e-6
|
|
324
|
+
|
|
325
|
+
self.add_parameter('aperture_mode',
|
|
326
|
+
label='Aperture mode',
|
|
327
|
+
set_cmd='SENSe:VOLTage:DC:APERture:ENABled {}',
|
|
328
|
+
get_cmd='SENSe:VOLTage:DC:APERture:ENABled?',
|
|
329
|
+
val_mapping={'ON': 1, 'OFF': 0},
|
|
330
|
+
vals=vals.Enum('ON', 'OFF'))
|
|
331
|
+
|
|
332
|
+
self.add_parameter('aperture_time',
|
|
333
|
+
label='Aperture time',
|
|
334
|
+
set_cmd=self._set_apt_time,
|
|
335
|
+
get_cmd='SENSe:VOLTage:DC:APERture?',
|
|
336
|
+
get_parser=float,
|
|
337
|
+
vals=vals.Numbers(*apt_times[self.model]),
|
|
338
|
+
docstring=('Setting the aperture time '
|
|
339
|
+
'automatically enables the aperture'
|
|
340
|
+
' mode.'))
|
|
341
|
+
|
|
342
|
+
self.add_function('init_measurement', call_cmd='INIT')
|
|
343
|
+
self.add_function('reset', call_cmd='*RST')
|
|
344
|
+
self.add_function('display_clear', call_cmd=('DISPLay:TEXT:CLEar'))
|
|
345
|
+
self.add_function('abort_measurement', call_cmd='ABORt')
|
|
346
|
+
|
|
347
|
+
if not silent:
|
|
348
|
+
self.connect_message()
|
|
349
|
+
|
|
350
|
+
def _licenses(self):
|
|
351
|
+
licenses_raw = self.ask('SYST:LIC:CAT?')
|
|
352
|
+
licenses_list = [x.strip('"') for x in licenses_raw.split(',')]
|
|
353
|
+
return licenses_list
|
|
354
|
+
|
|
355
|
+
def _get_voltage(self):
|
|
356
|
+
# TODO: massive improvements!
|
|
357
|
+
# The 'READ?' command will return anything the instrument is set up
|
|
358
|
+
# to return, i.e. not necessarily a voltage (might be current or
|
|
359
|
+
# or resistance) and not necessarily a single value. This function
|
|
360
|
+
# should be aware of the configuration.
|
|
361
|
+
|
|
362
|
+
response = self.ask('READ?')
|
|
363
|
+
|
|
364
|
+
return float(response)
|
|
365
|
+
|
|
366
|
+
def _set_databuffer_setpoints(self, cmd, value):
|
|
367
|
+
"""
|
|
368
|
+
set_cmd for all databuffer-setpoint related parameters
|
|
369
|
+
"""
|
|
370
|
+
|
|
371
|
+
self.data_buffer.properly_prepared = False
|
|
372
|
+
self.write(cmd.format(value))
|
|
373
|
+
|
|
374
|
+
def _set_apt_time(self, value):
|
|
375
|
+
self.write('SENSe:VOLTage:DC:APERture {:f}'.format(value))
|
|
376
|
+
|
|
377
|
+
# setting aperture time switches aperture mode ON
|
|
378
|
+
self.aperture_mode.get()
|
|
379
|
+
|
|
380
|
+
def _set_NPLC(self, value):
|
|
381
|
+
self.write('SENSe:VOLTage:DC:NPLC {:f}'.format(value))
|
|
382
|
+
|
|
383
|
+
# This will change data_buffer setpoints (timebase)
|
|
384
|
+
self.data_buffer.properly_prepared = False
|
|
385
|
+
|
|
386
|
+
# resolution settings change with NPLC
|
|
387
|
+
self.resolution.get()
|
|
388
|
+
|
|
389
|
+
# setting NPLC switches off aperture mode
|
|
390
|
+
if self.model in ['34465A', '34470A']:
|
|
391
|
+
self.aperture_mode.get()
|
|
392
|
+
|
|
393
|
+
def _set_range(self, value):
|
|
394
|
+
self.write('SENSe:VOLTage:DC:RANGe {:f}'.format(value))
|
|
395
|
+
|
|
396
|
+
# resolution settings change with range
|
|
397
|
+
|
|
398
|
+
self.resolution.get()
|
|
399
|
+
|
|
400
|
+
def _set_resolution(self, value):
|
|
401
|
+
rang = self.range.get()
|
|
402
|
+
|
|
403
|
+
# convert both value*range and the resolution factors
|
|
404
|
+
# to strings with few digits, so we avoid floating point
|
|
405
|
+
# rounding errors.
|
|
406
|
+
res_fac_strs = ['{:.1e}'.format(v * rang)
|
|
407
|
+
for v in self._resolution_factors]
|
|
408
|
+
if '{:.1e}'.format(value) not in res_fac_strs:
|
|
409
|
+
raise ValueError(
|
|
410
|
+
'Resolution setting {:.1e} ({} at range {}) '
|
|
411
|
+
'does not exist. '
|
|
412
|
+
'Possible values are {}'.format(value, value, rang,
|
|
413
|
+
res_fac_strs))
|
|
414
|
+
|
|
415
|
+
self.write('VOLT:DC:RES {:.1e}'.format(value))
|
|
416
|
+
|
|
417
|
+
# NPLC settings change with resolution
|
|
418
|
+
|
|
419
|
+
self.NPLC.get()
|
|
420
|
+
|
|
421
|
+
def error(self) -> (int, str):
|
|
422
|
+
"""
|
|
423
|
+
Return the first error message in the queue.
|
|
424
|
+
|
|
425
|
+
Returns:
|
|
426
|
+
The error code and the error message.
|
|
427
|
+
"""
|
|
428
|
+
rawmssg = self.ask('SYSTem:ERRor?')
|
|
429
|
+
code = int(rawmssg.split(',')[0])
|
|
430
|
+
mssg = rawmssg.split(',')[1].strip().replace('"', '')
|
|
431
|
+
|
|
432
|
+
return code, mssg
|
|
433
|
+
|
|
434
|
+
def flush_error_queue(self, verbose: bool=True) -> None:
|
|
435
|
+
"""
|
|
436
|
+
Clear the instrument error queue.
|
|
437
|
+
|
|
438
|
+
Args:
|
|
439
|
+
verbose: If true, the error messages are printed.
|
|
440
|
+
Default: True.
|
|
441
|
+
"""
|
|
442
|
+
|
|
443
|
+
log.debug('Flushing error queue...')
|
|
444
|
+
|
|
445
|
+
err_code, err_message = self.error()
|
|
446
|
+
log.debug(' {}, {}'.format(err_code, err_message))
|
|
447
|
+
if verbose:
|
|
448
|
+
print(err_code, err_message)
|
|
449
|
+
|
|
450
|
+
while err_code != 0:
|
|
451
|
+
err_code, err_message = self.error()
|
|
452
|
+
log.debug(' {}, {}'.format(err_code, err_message))
|
|
453
|
+
if verbose:
|
|
454
|
+
print(err_code, err_message)
|
|
455
|
+
|
|
456
|
+
log.debug('...flushing complete')
|
|
File without changes
|