qcodespp 0.1.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (82) hide show
  1. qcodespp/__init__.py +77 -0
  2. qcodespp/actions.py +237 -0
  3. qcodespp/data/__init__.py +0 -0
  4. qcodespp/data/data_array.py +555 -0
  5. qcodespp/data/data_set.py +926 -0
  6. qcodespp/data/format.py +338 -0
  7. qcodespp/data/gnuplot_format.py +425 -0
  8. qcodespp/data/hdf5_format.py +537 -0
  9. qcodespp/data/hdf5_format_hickle.py +63 -0
  10. qcodespp/data/io.py +241 -0
  11. qcodespp/data/location.py +171 -0
  12. qcodespp/instrument_drivers/Keysight/Keysight_34450A.py +9 -0
  13. qcodespp/instrument_drivers/Keysight/__init__.py +0 -0
  14. qcodespp/instrument_drivers/Keysight/private/Keysight_344xxA.py +456 -0
  15. qcodespp/instrument_drivers/Keysight/private/__init__.py +0 -0
  16. qcodespp/instrument_drivers/Lakeshore/Model_340.py +483 -0
  17. qcodespp/instrument_drivers/Lakeshore/__init__.py +0 -0
  18. qcodespp/instrument_drivers/QDevil/159fit_params_high_latest.json +386 -0
  19. qcodespp/instrument_drivers/QDevil/159fit_params_low_latest.json +386 -0
  20. qcodespp/instrument_drivers/QDevil/QDAC2.py +3229 -0
  21. qcodespp/instrument_drivers/QDevil/QDAC2_Array.py +300 -0
  22. qcodespp/instrument_drivers/QDevil/QSwitch_elab.py +652 -0
  23. qcodespp/instrument_drivers/QDevil/__init__.py +0 -0
  24. qcodespp/instrument_drivers/ZI/ZIHF2LI.py +415 -0
  25. qcodespp/instrument_drivers/ZI/ZIMFLI.py +764 -0
  26. qcodespp/instrument_drivers/ZI/ZIMFLI_sync.py +108 -0
  27. qcodespp/instrument_drivers/ZI/ZIUHFLI.py +2179 -0
  28. qcodespp/instrument_drivers/ZI/__init__.py +1 -0
  29. qcodespp/instrument_drivers/__init__.py +0 -0
  30. qcodespp/instrument_drivers/cryogenic/CryogenicSMS120C.py +599 -0
  31. qcodespp/instrument_drivers/cryogenic/__init__.py +0 -0
  32. qcodespp/instrument_drivers/instrument_mocks.py +379 -0
  33. qcodespp/instrument_drivers/multiplexer_instrument.py +287 -0
  34. qcodespp/instrument_drivers/national_instruments/PXI_4461.py +451 -0
  35. qcodespp/instrument_drivers/national_instruments/PXI_4462.py +290 -0
  36. qcodespp/instrument_drivers/national_instruments/PXI_6259.py +436 -0
  37. qcodespp/instrument_drivers/national_instruments/PXI_6733.py +230 -0
  38. qcodespp/instrument_drivers/national_instruments/PXI_6733_e.py +243 -0
  39. qcodespp/instrument_drivers/national_instruments/__init__.py +0 -0
  40. qcodespp/instrument_drivers/oxford/__init__.py +0 -0
  41. qcodespp/instrument_drivers/oxford/mercuryiPS_serial.py +658 -0
  42. qcodespp/instrument_drivers/oxford/triton.py +434 -0
  43. qcodespp/instrument_drivers/tektronix/Keithley_2000_Scan.py +65 -0
  44. qcodespp/instrument_drivers/tektronix/Keithley_2182a.py +190 -0
  45. qcodespp/instrument_drivers/tektronix/Keithley_2400.py +158 -0
  46. qcodespp/instrument_drivers/tektronix/Keithley_2450.py +242 -0
  47. qcodespp/instrument_drivers/tektronix/Keithley_2700.py +397 -0
  48. qcodespp/instrument_drivers/tektronix/Keithley_6500.py +161 -0
  49. qcodespp/instrument_drivers/tektronix/__init__.py +0 -0
  50. qcodespp/instrument_drivers/yokogawa/GS200.py +513 -0
  51. qcodespp/instrument_drivers/yokogawa/__init__.py +0 -0
  52. qcodespp/loops.py +1342 -0
  53. qcodespp/measure.py +310 -0
  54. qcodespp/parameters.py +311 -0
  55. qcodespp/plotting/RemotePlot.py +469 -0
  56. qcodespp/plotting/RemotePlotClient.py +367 -0
  57. qcodespp/plotting/RemoteQtPlotWidgets.py +871 -0
  58. qcodespp/plotting/__init__.py +0 -0
  59. qcodespp/plotting/analysis_tools.py +195 -0
  60. qcodespp/plotting/colors.py +135 -0
  61. qcodespp/plotting/offline/__init__.py +0 -0
  62. qcodespp/plotting/offline/datatypes.py +999 -0
  63. qcodespp/plotting/offline/design.py +906 -0
  64. qcodespp/plotting/offline/design.ui +1578 -0
  65. qcodespp/plotting/offline/editor.py +2966 -0
  66. qcodespp/plotting/offline/filters.py +561 -0
  67. qcodespp/plotting/offline/fits.py +1171 -0
  68. qcodespp/plotting/offline/helpers.py +288 -0
  69. qcodespp/plotting/offline/iconGadget.png +0 -0
  70. qcodespp/plotting/offline/main.py +55 -0
  71. qcodespp/plotting/offline/popupwindows.py +1848 -0
  72. qcodespp/plotting/offline/qcodes_pp_extension.py +328 -0
  73. qcodespp/plotting/offline/sidebars.py +1108 -0
  74. qcodespp/station.py +290 -0
  75. qcodespp/utils/__init__.py +0 -0
  76. qcodespp/utils/helpers.py +618 -0
  77. qcodespp/utils/visa_helpers.py +61 -0
  78. qcodespp/version.py +12 -0
  79. qcodespp-0.1.0.dist-info/METADATA +91 -0
  80. qcodespp-0.1.0.dist-info/RECORD +82 -0
  81. qcodespp-0.1.0.dist-info/WHEEL +4 -0
  82. qcodespp-0.1.0.dist-info/licenses/LICENSE +21 -0
@@ -0,0 +1,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')