import numpy as np
from qcodes.instrument.parameter import Parameter, ArrayParameter, MultiParameter, ManualParameter
from qcodes.utils import validators
Logging hadn't been started. Activating auto-logging. Current session state plus future input saved. Filename : C:\Users\Jens-Work\.qcodes\logs\command_history.log Mode : append Output logging : True Raw input log : False Timestamping : True State : active Qcodes Logfile : C:\Users\Jens-Work\.qcodes\logs\200416-6812-qcodes.log
QCoDeS provides the following classes of built-in parameters:
Parameter
represents a single value at a timeParameterWithSetpoints
is intended for array-values parameters.
This Parameter class is intended for anything where a call to the instrument
returns an array of values. This notebook
gives more detailed examples of how this parameter can be used.ArrayParameter
represents an array of values of all the same type that are returned all at once.ParameterWithSetpoints
class which is both more flexible and significantly easier to use. Refer to notebook on writing drivers with ParameterWithSetpointsMultiParameter
represents a collection of values with different meaning and possibly different dimensionParameters are described in detail in the Creating Instrument Drivers tutorial.
Most of the time you can use Parameter
directly; even if you have custom get
/set
functions, but sometimes it's useful to subclass Parameter
. Note that since the superclass Parameter
actually wraps these functions (to include some extra nice-to-have functionality), your subclass should define get_raw
and set_raw
rather than get
and set
.
class MyCounter(Parameter):
def __init__(self, name):
# only name is required
super().__init__(name, label='Times this has been read',
vals=validators.Ints(min_value=0),
docstring='counts how many times get has been called '
'but can be reset to any integer >= 0 by set')
self._count = 0
# you must provide a get method, a set method, or both.
def get_raw(self):
self._count += 1
return self._count
def set_raw(self, val):
self._count = val
c = MyCounter('c')
c2 = MyCounter('c2')
# c() is equivalent to c.get()
print('first call:', c())
print('second call:', c())
first call: 1 second call: 2
# c2(val) is equivalent to c2.set(val)
c2(22)
The gettable and settable attributes on the parameter should be used to detect if the parameter is settable or gettable.
print(f"c is gettable {c.gettable}")
print(f"c is settable {c.settable}")
c is gettable True c is settable True
NOTE: This is an older base class for array-valued parameters. For any new driver we strongly recommend using ParameterWithSetpoints
class which is both more flexible and significantly easier to use. Refer to notebook on writing drivers with ParameterWithSetpoints.
We have kept the documentation shown below of ArrayParameter
for the legacy purpose.
For actions that create a whole array of values at once. When you use it in a Loop
, it makes a single DataArray
with the array returned by get
nested inside extra dimension(s) for the loop.
While storing the ArrayParameter
data in the database using datasaver.add_result()
, be informed that it is stored as BLOB in one row of sqlite database. Where the BLOB in sqlite has a default max length limit set at 1 billion (1,000,000,000) bytes.
ArrayParameter
is, for now, only gettable.
class ArrayCounter(ArrayParameter):
def __init__(self):
# only name and shape are required
# the setpoints I'm giving here are identical to the defaults
# this param would get but I'll give them anyway for
# demonstration purposes
super().__init__('array_counter', shape=(3, 2),
label='Total number of values provided',
unit='',
# first setpoint array is 1D, second is 2D, etc...
setpoints=((0, 1, 2), ((0, 1), (0, 1), (0, 1))),
setpoint_names=('index0', 'index1'),
setpoint_labels=('Outer param index', 'Inner param index'),
docstring='fills a 3x2 array with increasing integers')
self._val = 0
def get_raw(self):
# here I'm returning a nested list, but any sequence type will do.
# tuple, np.array, DataArray...
out = [[self._val + 2 * i + j for j in range(2)] for i in range(3)]
self._val += 6
return out
array_counter = ArrayCounter()
# simple get
print('first call:', array_counter())
first call: [[0, 1], [2, 3], [4, 5]]
Return multiple items at once, where each item can be a single value or an array.
NOTE: Most of the kwarg names here are the plural of those used in Parameter
and ArrayParameter
. In particular, MultiParameter
is the ONLY one that uses units
, all the others use unit
.
MultiParameter
is, for now, only gettable.
class SingleIQPair(MultiParameter):
def __init__(self, scale_param):
# only name, names, and shapes are required
# this version returns two scalars (shape = `()`)
super().__init__('single_iq', names=('I', 'Q'), shapes=((), ()),
labels=('In phase amplitude', 'Quadrature amplitude'),
units=('V', 'V'),
# including these setpoints is unnecessary here, but
# if you have a parameter that returns a scalar alongside
# an array you can represent the scalar as an empty sequence.
setpoints=((), ()),
docstring='param that returns two single values, I and Q')
self._scale_param = scale_param
def get_raw(self):
scale_val = self._scale_param()
return (scale_val, scale_val / 2)
scale = ManualParameter('scale', initial_value=2)
iq = SingleIQPair(scale_param=scale)
# simple get
print('simple get:', iq())
simple get: (2, 1.0)
class IQArray(MultiParameter):
def __init__(self, scale_param):
# names, labels, and units are the same
super().__init__('iq_array', names=('I', 'Q'), shapes=((5,), (5,)),
labels=('In phase amplitude', 'Quadrature amplitude'),
units=('V', 'V'),
# note that EACH item needs a sequence of setpoint arrays
# so a 1D item has its setpoints wrapped in a length-1 tuple
setpoints=(((0, 1, 2, 3, 4),), ((0, 1, 2, 3, 4),)),
docstring='param that returns two single values, I and Q')
self._scale_param = scale_param
self._indices = np.array([0, 1, 2, 3, 4])
def get_raw(self):
scale_val = self._scale_param()
return (self._indices * scale_val, self._indices * scale_val / 2)
iq_array = IQArray(scale_param=scale)
# simple get
print('simple get', iq_array())
simple get (array([0, 2, 4, 6, 8]), array([0., 1., 2., 3., 4.]))