Utility Functions and Classes

Unit Handling

instruments.util_fns.assume_units(value, units)[source]

If units are not provided for value (that is, if it is a raw float), then returns a Quantity with magnitude given by value and units given by units.

Parameters:
  • value – A value that may or may not be unitful.
  • units – Units to be assumed for value if it does not already have units.
Returns:

A unitful quantity that has either the units of value or units, depending on if value is unitful.

Return type:

Quantity

instruments.util_fns.split_unit_str(s, default_units=Dimensionless('dimensionless', 1.0 * dimensionless), lookup=None)[source]

Given a string of the form “12 C” or “14.7 GHz”, returns a tuple of the numeric part and the unit part, irrespective of how many (if any) whitespace characters appear between.

By design, the tuple should be such that it can be unpacked into pq.Quantity():

>>> pq.Quantity(*split_unit_str("1 s"))
array(1) * s

For this reason, the second element of the tuple may be a unit or a string, depending, since the quantity constructor takes either.

Parameters:
  • s (str) – Input string that will be split up
  • default_units – If no units are specified, this argument is given as the units.
  • lookup (callable) – If specified, this function is called on the units part of the input string. If None, no lookup is performed. Lookups are never performed on the default units.
Return type:

tuple of a float and a str or pq.Quantity

instruments.util_fns.convert_temperature(temperature, base)[source]

Convert the temperature to the specified base. This is needed because the package quantities does not differentiate between degC and degK.

Parameters:
  • temperature (quantities.Quantity) – A quantity with units of Kelvin, Celsius, or Fahrenheit
  • base (unitquantity.UnitTemperature) – A temperature unit to convert to
Returns:

The converted temperature

Return type:

quantities.Quantity

Enumerating Instrument Functionality

To expose parts of an instrument or device in a Python-ic way, the ProxyList class can be used to emulate a list type by calling the initializer for some inner class. This is used to expose everything from channels to axes.

Property Factories

To help expose instrument properties in a consistent and predictable manner, InstrumentKit offers several functions that return instances of property that are backed by the sendcmd() and query() protocol. These factories assume a command protocol that at least resembles the SCPI style:

-> FOO:BAR?
<- 42
-> FOO:BAR 6
-> FOO:BAR?
<- 6

It is recommended to use the property factories whenever possible to help reduce the amount of copy-paste throughout the code base. The factories allow for a centralized location for input/output error checking, units handling, and type conversions. In addition, improvements to the property factories benefit all classes that use it.

Lets say, for example, that you were writing a class for a power supply. This class might require these two properties: output and voltage. The first will be used to enable/disable the output on the power supply, while the second will be the desired output voltage when the output is enabled. The first lends itself well to a bool_property. The output voltage property corresponds with a physical quantity (voltage, of course) and so it is best to use either unitful_property or bounded_unitful_property, depending if you wish to bound user input to some set limits. bounded_unitful_property can take either hard-coded set limits, or it can query the instrument during runtime to determine what those bounds are, and constrain user input to within them.

Examples

These properties, when implemented in your class, might look like this:

output = bool_property(
    "OUT",
    inst_true="1",
    inst_false="0",
    doc="""
    Gets/sets the output status of the power supply

    :type: `bool`
    """
)

voltage, voltage_min, voltage_max = bounded_unitful_property(
    voltage = unitful_property(
    "VOLT",
    pq.volt,
    valid_range=(0*quantities.volt, 10*quantities.volt)
    doc="""
    Gets/sets the output voltage.

    :units: As specified, or assumed to be :math:`\\text{V}` otherwise.
    :type: `float` or `~quantities.Quantity`
    """
)

The most difficult to use parameters for the property factories are input_decoration and output_decoration. These are callable objects that will be applied to the data immediately after receiving it from the instrument (input) or before it is inserted into the string that will be sent out to the instrument (output).

Using enum_property as the simple example, a frequent use case for input_decoration will be to convert a str containing a numeric digit into an actual int so that it can be looked up in enum.IntEnum. Here is an example of this:

class Mode(IntEnum):

    """
    Enum containing valid output modes of the ABC123 instrument
    """
    foo = 0
    bar = 1
    bloop = 2

mode = enum_property(
    "MODE",
    enum=Mode,
    input_decoration=int,
    set_fmt="{}={}",
    doc="""
    Gets/sets the output mode of the ABC123 instrument

    :rtype: `ABC123.Mode`
    """
)

So in this example, when querying the mode property, the string MODE? will first be sent to the instrument, at which point it will return one of "0", "1", or "2". However, before this value can be used to get the correct enum value, it needs to be converted into an int. This is what input_decoration is used for. Since int is callable and can convert a str to an int, this accomplishes exactly what we’re looking for.

Pretty much anything callable can be passed into these parameters. Here is an example using a lambda function with a unitful_property taken from the TC200 class:

temperature = unitful_property(
    "tact",
    units=pq.degC,
    readonly=True,
    input_decoration=lambda x: x.replace(
        " C", "").replace(" F", "").replace(" K", ""),
    doc="""
    Gets the actual temperature of the sensor

    :units: As specified (if a `~quantities.quantity.Quantity`) or assumed
        to be of units degrees C.
    :type: `~quantities.quantity.Quantity` or `int`
    :return: the temperature (in degrees C)
    :rtype: `~quantities.quantity.Quantity`
    """
)

An alternative to lambda functions is passing in static methods (staticmethod).

Bool Property

instruments.util_fns.bool_property(command, set_cmd=None, inst_true='ON', inst_false='OFF', doc=None, readonly=False, writeonly=False, set_fmt='{} {}')[source]

Called inside of SCPI classes to instantiate boolean properties of the device cleanly. For example:

>>> my_property = bool_property(
...     "BEST:PROPERTY",
...     inst_true="ON",
...     inst_false="OFF"
... ) # doctest: +SKIP

This will result in “BEST:PROPERTY ON” or “BEST:PROPERTY OFF” being sent when setting, and “BEST:PROPERTY?” being sent when getting.

Parameters:
  • command (str) – Name of the SCPI command corresponding to this property. If parameter set_cmd is not specified, then this parameter is also used for both getting and setting.
  • set_cmd (str) – If not None, this parameter sets the command string to be used when sending commands with no return values to the instrument. This allows for non-symmetric properties that have different strings for getting vs setting a property.
  • inst_true (str) – String returned and accepted by the instrument for True values.
  • inst_false (str) – String returned and accepted by the instrument for False values.
  • doc (str) – Docstring to be associated with the new property.
  • readonly (bool) – If True, the returned property does not have a setter.
  • writeonly (bool) – If True, the returned property does not have a getter. Both readonly and writeonly cannot both be True.
  • set_fmt (str) – Specify the string format to use when sending a non-query to the instrument. The default is “{} {}” which places a space between the SCPI command the associated parameter. By switching to “{}={}” an equals sign would instead be used as the separator.

Enum Property

instruments.util_fns.enum_property(command, enum, set_cmd=None, doc=None, input_decoration=None, output_decoration=None, readonly=False, writeonly=False, set_fmt='{} {}')[source]

Called inside of SCPI classes to instantiate Enum properties of the device cleanly. The decorations can be functions which modify the incoming and outgoing values for dumb instruments that do stuff like include superfluous quotes that you might not want in your enum. Example: my_property = bool_property(“BEST:PROPERTY”, enum_class)

Parameters:
  • command (str) – Name of the SCPI command corresponding to this property. If parameter set_cmd is not specified, then this parameter is also used for both getting and setting.
  • set_cmd (str) – If not None, this parameter sets the command string to be used when sending commands with no return values to the instrument. This allows for non-symmetric properties that have different strings for getting vs setting a property.
  • enum (type) – Class derived from Enum representing valid values.
  • input_decoration (callable) – Function called on responses from the instrument before passing to user code.
  • output_decoration (callable) – Function called on commands to the instrument.
  • doc (str) – Docstring to be associated with the new property.
  • readonly (bool) – If True, the returned property does not have a setter.
  • writeonly (bool) – If True, the returned property does not have a getter. Both readonly and writeonly cannot both be True.
  • set_fmt (str) – Specify the string format to use when sending a non-query to the instrument. The default is “{} {}” which places a space between the SCPI command the associated parameter. By switching to “{}={}” an equals sign would instead be used as the separator.
  • get_cmd (str) – If not None, this parameter sets the command string to be used when reading/querying from the instrument. If used, the name parameter is still used to set the command for pure-write commands to the instrument.

Unitless Property

instruments.util_fns.unitless_property(command, set_cmd=None, format_code='{:e}', doc=None, readonly=False, writeonly=False, set_fmt='{} {}')[source]

Called inside of SCPI classes to instantiate properties with unitless numeric values.

Parameters:
  • command (str) – Name of the SCPI command corresponding to this property. If parameter set_cmd is not specified, then this parameter is also used for both getting and setting.
  • set_cmd (str) – If not None, this parameter sets the command string to be used when sending commands with no return values to the instrument. This allows for non-symmetric properties that have different strings for getting vs setting a property.
  • format_code (str) – Argument to str.format used in sending values to the instrument.
  • doc (str) – Docstring to be associated with the new property.
  • readonly (bool) – If True, the returned property does not have a setter.
  • writeonly (bool) – If True, the returned property does not have a getter. Both readonly and writeonly cannot both be True.
  • set_fmt (str) – Specify the string format to use when sending a non-query to the instrument. The default is “{} {}” which places a space between the SCPI command the associated parameter. By switching to “{}={}” an equals sign would instead be used as the separator.

Int Property

instruments.util_fns.int_property(command, set_cmd=None, format_code='{:d}', doc=None, readonly=False, writeonly=False, valid_set=None, set_fmt='{} {}')[source]

Called inside of SCPI classes to instantiate properties with unitless numeric values.

Parameters:
  • command (str) – Name of the SCPI command corresponding to this property. If parameter set_cmd is not specified, then this parameter is also used for both getting and setting.
  • set_cmd (str) – If not None, this parameter sets the command string to be used when sending commands with no return values to the instrument. This allows for non-symmetric properties that have different strings for getting vs setting a property.
  • format_code (str) – Argument to str.format used in sending values to the instrument.
  • doc (str) – Docstring to be associated with the new property.
  • readonly (bool) – If True, the returned property does not have a setter.
  • writeonly (bool) – If True, the returned property does not have a getter. Both readonly and writeonly cannot both be True.
  • valid_set – Set of valid values for the property, or None if all int values are valid.
  • set_fmt (str) – Specify the string format to use when sending a non-query to the instrument. The default is “{} {}” which places a space between the SCPI command the associated parameter. By switching to “{}={}” an equals sign would instead be used as the separator.

Unitful Property

instruments.util_fns.unitful_property(command, units, set_cmd=None, format_code='{:e}', doc=None, input_decoration=None, output_decoration=None, readonly=False, writeonly=False, set_fmt='{} {}', valid_range=(None, None))[source]

Called inside of SCPI classes to instantiate properties with unitful numeric values. This function assumes that the instrument only accepts and returns magnitudes without unit annotations, such that all unit information is provided by the units argument. This is not suitable for instruments where the units can change dynamically due to front-panel interaction or due to remote commands.

Parameters:
  • command (str) – Name of the SCPI command corresponding to this property. If parameter set_cmd is not specified, then this parameter is also used for both getting and setting.
  • set_cmd (str) – If not None, this parameter sets the command string to be used when sending commands with no return values to the instrument. This allows for non-symmetric properties that have different strings for getting vs setting a property.
  • units – Units to assume in sending and receiving magnitudes to and from the instrument.
  • format_code (str) – Argument to str.format used in sending the magnitude of values to the instrument.
  • doc (str) – Docstring to be associated with the new property.
  • input_decoration (callable) – Function called on responses from the instrument before passing to user code.
  • output_decoration (callable) – Function called on commands to the instrument.
  • readonly (bool) – If True, the returned property does not have a setter.
  • writeonly (bool) – If True, the returned property does not have a getter. Both readonly and writeonly cannot both be True.
  • set_fmt (str) – Specify the string format to use when sending a non-query to the instrument. The default is “{} {}” which places a space between the SCPI command the associated parameter. By switching to “{}={}” an equals sign would instead be used as the separator.
  • valid_range (tuple or list of int or float) – Tuple containing min & max values when setting the property. Index 0 is minimum value, index 1 is maximum value. Setting None in either disables bounds checking for that end of the range. The default of (None, None) has no min or max constraints. The valid set is inclusive of the values provided.

Bounded Unitful Property

instruments.util_fns.bounded_unitful_property(command, units, min_fmt_str='{}:MIN?', max_fmt_str='{}:MAX?', valid_range=('query', 'query'), **kwargs)[source]

Called inside of SCPI classes to instantiate properties with unitful numeric values which have upper and lower bounds. This function in turn calls unitful_property where all kwargs for this function are passed on to. See unitful_property documentation for information about additional parameters that will be passed on.

Compared to unitful_property, this function will return 3 properties: the one created by unitful_property, one for the minimum value, and one for the maximum value.

Parameters:
  • command (str) – Name of the SCPI command corresponding to this property. If parameter set_cmd is not specified, then this parameter is also used for both getting and setting.
  • set_cmd (str) – If not None, this parameter sets the command string to be used when sending commands with no return values to the instrument. This allows for non-symmetric properties that have different strings for getting vs setting a property.
  • units – Units to assume in sending and receiving magnitudes to and from the instrument.
  • min_fmt_str (str) – Specify the string format to use when sending a minimum value query. The default is "{}:MIN?" which will place the property name in before the colon. Eg: "MOCK:MIN?"
  • max_fmt_str (str) – Specify the string format to use when sending a maximum value query. The default is "{}:MAX?" which will place the property name in before the colon. Eg: "MOCK:MAX?"
  • valid_range (list or tuple of int, float, None, or the string "query".) – Tuple containing min & max values when setting the property. Index 0 is minimum value, index 1 is maximum value. Setting None in either disables bounds checking for that end of the range. The default of ("query", "query") will query the instrument for min and max parameter values. The valid set is inclusive of the values provided.
  • kwargs – All other keyword arguments are passed onto unitful_property
Returns:

Returns a tuple of 3 properties: first is as returned by unitful_property, second is a property representing the minimum value, and third is a property representing the maximum value

String Property

instruments.util_fns.string_property(command, set_cmd=None, bookmark_symbol='"', doc=None, readonly=False, writeonly=False, set_fmt='{} {}{}{}')[source]

Called inside of SCPI classes to instantiate properties with a string value.

Parameters:
  • command (str) – Name of the SCPI command corresponding to this property. If parameter set_cmd is not specified, then this parameter is also used for both getting and setting.
  • set_cmd (str) – If not None, this parameter sets the command string to be used when sending commands with no return values to the instrument. This allows for non-symmetric properties that have different strings for getting vs setting a property.
  • doc (str) – Docstring to be associated with the new property.
  • readonly (bool) – If True, the returned property does not have a setter.
  • writeonly (bool) – If True, the returned property does not have a getter. Both readonly and writeonly cannot both be True.
  • set_fmt (str) – Specify the string format to use when sending a non-query to the instrument. The default is “{} {}{}{}” which places a space between the SCPI command the associated parameter, and places the bookmark symbols on either side of the parameter.
  • bookmark_symbol (str) – The symbol that will flank both sides of the parameter to be sent to the instrument. By default this is ".

Named Structures

The NamedStruct class can be used to represent C-style structures for serializing and deserializing data.

class instruments.named_struct.NamedStruct(**kwargs)[source]

Represents a C-style struct with one or more named fields, useful for packing and unpacking serialized data documented in terms of C examples. For instance, consider a struct of the form:

typedef struct {
    unsigned long a = 0x1234;
    char[12] dummy;
    unsigned char b = 0xab;
} Foo;

This struct can be represented as the following NamedStruct:

class Foo(NamedStruct):
    a = Field('L')
    dummy = Padding(12)
    b = Field('B')

foo = Foo(a=0x1234, b=0xab)
class instruments.named_struct.Field(fmt, strip_null=False)[source]

A named field within a C-style structure.

Parameters:fmt (str) – Format for the field, corresponding to the documentation of the struct standard library package.
class instruments.named_struct.Padding(n_bytes=1)[source]

Represents a field whose value is insignificant, and will not be kept in serialization and deserialization.

Parameters:n_bytes (int) – Number of padding bytes occupied by this field.