Fork PyRPL on GitHub

pyrpl package



pyrpl.acquisition_module module

Everything involving asynchronicity in acquisition instruments is in this file.

In particular, this includes getting curves and continuously averaging curves.

Using the coroutine syntax introduced in python 3.4+ would make the code more elegant, but it would not be compatible with python 2.7. Hence we have chosen to implement all asynchronous methods such that a promise is returned (a Future-object in python). The promise implements the following methods:

  • await_result(): returns the acquisition result once it is ready.
  • add_done_callback(func): the function func(value) is used as “done-callback)

All asynchronous methods also have a blocking equivalent that directly returns the result once it is ready:

  • curve_async <—> curve
  • single_async <—> single

Finally, this implmentation using standard python Futures makes it possible to use transparently pyrpl asynchronous methods inside python 3.x coroutines.


This example shows a typical acquisition use case where a sequence of n aquisitions of simultaneous oscilloscope and network analyzer traces are launched

from asyncio import ensure_future, event_loop

async def my_acquisition_routine(n):
    for i in range(n):
        print("acquiring scope")
        fut = ensure_future(p.rp.scope.run_single())
        print("acquiring na")
        data2 = await p.networkanalyzer.run_single()
        # both acquisitions are carried out simultaneously
        data1 = await fut
        print("loop %i"%i, data1, data2)

exception pyrpl.acquisition_module.AcquisitionError[source]

Bases: exceptions.ValueError

class pyrpl.acquisition_module.AcquisitionModule(parent, name=None)[source]

Bases: pyrpl.modules.Module

The asynchronous mode is supported by a sub-object “run” of the module. When an asynchronous acquisition is running and the widget is visible, the current averaged data are automatically displayed. Also, the run object provides a function save_curve to store the current averaged curve on the hard-drive.

The full API of the “run” object is the following.


(All methods return immediately) single(): performs an asynchronous acquisition of trace_average curves.

The function returns a promise of the result: an object with a ready() function, and a get() function that blocks until data is ready.
continuous(): continuously acquires curves, and performs a
moving average over the trace_average last ones.
pause(): stops the current acquisition without restarting the

stop(): stops the current acquisition and restarts the averaging. save_curve(): saves the currently averaged curve (or curves for scope) curve(): the currently averaged curve


curve_name (str): name of the curve to create upon saving trace_average (int): number of averages in single (not to confuse with

averaging per point)

data_avg (array of numbers): array containing the current averaged curve current_avg (int): current number of averages

Setup Attributes:

  • running_state: Indicates whether the instrument is running acquisitions or not. See RunningStateProperty for available options.
  • trace_average: number of curves to average in single mode. In continuous mode, a moving window average is performed.
  • curve_name: name of the curve to save.

continuously acquires curves, and performs a moving average over the trace_average last ones.


Same as curve_async, except:

  • the function will not return until the curve is ready or timeout occurs.
  • the function directly returns an array with the curve instead of a future object

Launches the acquisition for one curve with the current parameters.

  • If running_state is not “stopped”, stops the current acquisition.
  • If rolling_mode is True, raises an exception.
  • Immediately returns a future object representing the curve.
  • The curve can be retrieved by calling result(timeout) on the future object.
  • The future is cancelled if the instrument’s state is changed before the end of the acquisition, or another call to curve_async() or curve() is made on the same instrument.

name of the curve to save.


x-axis of the curves to plot. :return:


Stops the current acquisition without restarting the averaging


Indicates whether the instrument is running acquisitions or not. See RunningStateProperty for available options.


Saves the curve(s) that is (are) currently displayed in the gui in the db_system. Also, returns the list [curve_ch1, curve_ch2]...


Indicates whether the instrument is running acquisitions or not. See RunningStateProperty for available options.


number of curves to average in single mode. In continuous mode, a moving window average is performed.


name of the curve to save.

Same as single_async, except:
  • the function will not return until the averaged curve is ready or timeout occurs.
  • the function directly returns an array with the curve instead of a future object.

Performs an asynchronous acquisition of trace_average curves.

  • If running_state is not stop, stops the current acquisition.
  • Immediately returns a future object representing the curve.
  • The curve can be retrieved by calling result(timeout) on the future object.
  • The future is cancelled if the instrument’s state is changed before the end of the acquisition.

Stops the current acquisition and averaging will be restarted at next run.


number of curves to average in single mode. In continuous mode, a moving window average is performed.

class pyrpl.acquisition_module.CurveFuture(module, min_delay_ms=20)[source]

Bases: pyrpl.async_utils.PyrplFuture

The basic acquisition of instruments is an asynchronous process:

For instance, when the scope acquisition has been launched, we know that the curve won’t be ready before duration(), but if the scope is waiting for a trigger event, this could take much longer. Of course, we want the event loop to stay alive while waiting for a pending curve. That’s the purpose of this future object.

After its creation, it will perform the following actions:

  1. stay inactive for a time given by instrument._remaining_time()
  2. after that, it will check every min_refresh_delay if a new curve is ready with instrument._data_ready()
  3. when data is ready, its result will be set with the instrument data, as returned by instrument._get_data()
class pyrpl.acquisition_module.RunFuture(module, min_delay_ms)[source]

Bases: pyrpl.async_utils.PyrplFuture

Uses several CurveFuture to perform an average.

2 extra functions are provided to control the acquisition:

pause(): stalls the acquisition

start(): (re-)starts the acquisition (needs to be called at the beginning)

The format for curves are:

  • Scope:
    • data_x : self.times
    • data_avg: np.array((ch1, ch2))
  • Specan or NA:
    • data_x : frequencies
    • data_avg: np.array(y_complex)
class pyrpl.acquisition_module.RunningStateProperty(options=['running_single', 'running_continuous', 'paused', 'stopped'], **kwargs)[source]

Bases: pyrpl.attributes.SelectProperty

set_value(obj, val)[source]

This is the master property: changing this value triggers all the logic to change the acquisition mode

class pyrpl.acquisition_module.SignalLauncherAcquisitionModule(module)[source]

Bases: pyrpl.modules.SignalLauncher

class that takes care of emitting signals to update all possible displays

autoscale_x = <MagicMock name='mock.QtCore.Signal()' id='139827380610576'>
clear_curve = <MagicMock name='mock.QtCore.Signal()' id='139827380610576'>
display_curve = <MagicMock name='mock.QtCore.Signal()' id='139827380610576'>
scan_finished = <MagicMock name='mock.QtCore.Signal()' id='139827380610576'>
unit_changed = <MagicMock name='mock.QtCore.Signal()' id='139827380610576'>
update_point = <MagicMock name='mock.QtCore.Signal()' id='139827380610576'>
x_log_toggled = <MagicMock name='mock.QtCore.Signal()' id='139827380610576'>

pyrpl.async_utils module

This file contains a number of methods for asynchronous operations.

class pyrpl.async_utils.PyrplFuture[source]

Bases: <MagicMock id='139827382130128'>.Future

A promise object compatible with the Qt event loop.

We voluntarily use an object that is different from the native QFuture because we want a promise object that is compatible with the python 3.5+ asyncio patterns (for instance, it implements an __await__ method...).


Returns whether the promise has been cancelled.


Blocks until: a. the result is ready –> returns None b. an exception accured in the execution –> returns the exception the Qt event-loop is allowed to run in parallel.


Checks whether the result is ready or not.


callback function – add a callback to execute when result becomes available. The callback function takes 1 argument (the result of the promise).

Methods to implement in derived class:
_set_data_as_result(): set

Return the exception raised by the call that the future represents.


timeout – The number of seconds to wait for the exception if the future isn’t done. If None, then there is no limit on the wait time.


The exception raised by the call that the future represents or None if the call completed without raising.

  • CancelledError – If the future was cancelled.
  • TimeoutError – If the future didn’t finish executing before the
  • given timeout.

Return the result of the call that the future represents. Will not return until either timeout expires or future becomes “done”.

There is one potential deadlock situation here: The deadlock occurs if we await_result while at the same time, this future needs to await_result from another future since the eventloop will be blocked. —> To be safe, don’t use await_result() in a Qt slot. You should rather use result() and add_done_callback() instead.


timeout – The number of seconds to wait for the result if the future isn’t done. If None, then there is no limit on the wait time.


The result of the call that the future represents.

  • CancelledError – If the future was cancelled.
  • TimeoutError – If the future didn’t finish executing before the given timeout.
  • Exception – If the call raised then that exception will be raised.

Cancels the future.


Blocks until the result is ready while running the event-loop in the background.

Returns:The result of the future.

Sleeps for delay seconds + runs the event loop in the background.

  • This function will never return until the specified delay in seconds is elapsed.
  • During the execution of this function, the qt event loop (== asyncio event-loop in pyrpl) continues to process events from the gui, or from other coroutines.
  • Contrary to time.sleep() or async.sleep(), this function will try to achieve a precision much better than 1 millisecond (of course, occasionally, the real delay can be longer than requested), but on average, the precision is in the microsecond range.
  • Finally, care has been taken to use low level system-functions to reduce CPU-load when no events need to be processed.

More details on the implementation can be found on the page:

pyrpl.attributes module

The parameters of any module are controlled by descriptors deriving from BaseAttribute.

An attribute is a field that can be set or get by several means:

  • programmatically: module.attribute = value
  • graphically: attribute.create_widget(module) returns a widget to manipulate the value
  • via loading the value in a config file for permanent value preservation

Of course, the gui/parameter file/actual values have to stay “in sync” each time the attribute value is changed. The necessary mechanisms are happening behind the scene, and they are coded in this file.

class pyrpl.attributes.AttributeList(parent, module, *args, **kwargs)[source]

Bases: list

A list of attributes.

This class is not an attribute/property by itself, but is the object returned by AttributeListProperty that correctly extends list methods to communicate a change in the list throughout pyrpl.

When a list-specific operation is performed that alters the values, the AttributeListProperty object is informed about this and will ensure the correct propagation of the signal.

insert(index, new=None)[source]

selects the element with value, or None if it does not exist

sort(key=None, reverse=False)[source]
class pyrpl.attributes.BaseAttribute[source]

Bases: object

base class for attribute - only used as a placeholder

class pyrpl.attributes.BaseProperty(default=None, doc='', ignore_errors=False, call_setup=False)[source]

Bases: pyrpl.attributes.BaseAttribute

A Property is a special type of attribute that is not mapping a fpga value, but rather an attribute _name of the module. This is used mainly in SoftwareModules

An attribute is a field that can be set or get by several means:

  • programmatically: module.attribute = value
  • graphically: attribute.create_widget(module) returns a widget to manipulate the value
  • via loading the value in a config file for permanence

The concrete derived class need to have certain attributes properly defined:

  • widget_class: the class of the widget to use for the gui (see
  • a function set_value(instance, value) that effectively sets the value (on redpitaya or elsewhere)
  • a function get_value(instance) that reads the value from wherever it is stored internally
default = None
launch_signal(module, new_value, appendix=[])[source]

Updates the widget and other subscribers with the module’s value.

save_attribute(module, value)[source]

Saves the module’s value in the config file.

set_value(obj, val)[source]
validate_and_normalize(obj, value)[source]

This function should raise an exception if the value is incorrect. Normalization can be:

  • returning if attribute “name” exists
  • rounding to nearest multiple of step for float_registers
  • rounding elements to nearest valid_frequencies for FilterAttributes
value_updated(module, value=None, appendix=[])[source]

Once the value has been changed internally, this function is called to perform the following actions:

  • launch the signal module._signal_launcher.attribute_changed (this is used in particular for gui update)
  • saves the new value in the config file (if flag module._autosave_active is True).
  • calls the callback function if the attribute is in module.callback
Note for developers: We might consider moving the 2 last points in a connection behind the signal “attribute_changed”.
widget = None
class pyrpl.attributes.BasePropertyListProperty(*args, **kwargs)[source]

Bases: pyrpl.attributes.BaseProperty

An arbitrary length list of items that behave like BaseProperty.

A derived class FloatPropertyListProperty(BasePropertyListProperty) will behave as a list of FloatProperty-like items.

default = []

the class of the elements of the list

list_changed(module, operation, index, value=None)[source]
set_value(obj, val)[source]
validate_and_normalize(obj, value)[source]

Converts the value into a list.

validate_and_normalize_element(obj, val)[source]
class pyrpl.attributes.BaseRegister(address, bitmask=None, **kwargs)[source]

Bases: pyrpl.attributes.BaseProperty

Registers implement the necessary read/write logic for storing an attribute on the redpitaya. Interface for basic register of type int. To convert the value between register format and python readable format, registers need to implement “from_python” and “to_python” functions

default = None

Retrieves the value that is physically on the redpitaya device.

set_value(obj, val)[source]

Sets the value on the redpitaya device.

class pyrpl.attributes.BoolIgnoreProperty(default=None, doc='', ignore_errors=False, call_setup=False)[source]

Bases: pyrpl.attributes.BoolProperty

An attribute for booleans

default = False
validate_and_normalize(obj, value)[source]

Converts value to bool.

class pyrpl.attributes.BoolProperty(default=None, doc='', ignore_errors=False, call_setup=False)[source]

Bases: pyrpl.attributes.BaseProperty

A property for a boolean value

default = False
validate_and_normalize(obj, value)[source]

Converts value to bool.

class pyrpl.attributes.BoolRegister(address, bit=0, bitmask=None, invert=False, **kwargs)[source]

Bases: pyrpl.attributes.BaseRegister, pyrpl.attributes.BoolProperty

Inteface for boolean values, 1: True, 0: False. invert=True inverts the mapping

from_python(obj, val)[source]
to_python(obj, value)[source]
class pyrpl.attributes.ComplexAttributeListProperty(*args, **kwargs)[source]

Bases: pyrpl.attributes.BasePropertyListProperty, pyrpl.attributes.ComplexProperty

class pyrpl.attributes.ComplexProperty(min=<MagicMock name='mock.inf.__neg__()' id='139827380281936'>, max=<MagicMock name='mock.inf' id='139827380218960'>, increment=0, log_increment=False, **kwargs)[source]

Bases: pyrpl.attributes.FloatProperty

validate_and_normalize(obj, val)[source]
class pyrpl.attributes.ConstantIntRegister(address, bits=32, bitmask=None, **kwargs)[source]

Bases: pyrpl.attributes.IntRegister

Implements an int register that only interacts with the FPGA once and subsequently returns the first read value from python memory.

class pyrpl.attributes.CurveProperty(no_curve_first=False, show_childs=False, **kwargs)[source]

Bases: pyrpl.attributes.CurveSelectProperty

property for a curve whose widget plots the corresponding curve.

Unfortunately, the widget does not allow to select the curve, i.e. selection must be implemented with another CurveSelectProperty.

class pyrpl.attributes.CurveSelectListProperty(no_curve_first=False, show_childs=False, **kwargs)[source]

Bases: pyrpl.attributes.CurveSelectProperty

same as above, but widget is a list to select from

class pyrpl.attributes.CurveSelectProperty(no_curve_first=False, show_childs=False, **kwargs)[source]

Bases: pyrpl.attributes.SelectProperty

An attribute to select a curve from all available ones.

The curve object is loaded to instance._name_object, where ‘name’ stands for the name of this attribute. The property can be set by either passing a CurveDB object, or a curve id.

set_value(obj, pk)[source]
validate_and_normalize(obj, value)[source]
class pyrpl.attributes.DataProperty(default=None, doc='', ignore_errors=False, call_setup=False)[source]

Bases: pyrpl.attributes.BaseProperty

Property for a dataset (real or complex), that can be plotted.

class pyrpl.attributes.FilterProperty(default=None, doc='', ignore_errors=False, call_setup=False)[source]

Bases: pyrpl.attributes.BaseProperty

An attribute for a list of bandwidth. Each bandwidth has to be chosen in a list given by self.valid_frequencies(module) (evaluated at runtime). If floats are provided, they are normalized to the nearest values in the list. Individual floats are also normalized to a singleton. The number of elements in the list are also defined at runtime. A property for a list of float values to be chosen in valid_frequencies(module).

set_value(obj, value)[source]
validate_and_normalize(obj, value)[source]

Returns a list with the closest elements in module.valid_frequencies

class pyrpl.attributes.FilterRegister(address, filterstages, shiftbits, minbw, **kwargs)[source]

Bases: pyrpl.attributes.BaseRegister, pyrpl.attributes.FilterProperty

Interface for up to 4 low-/highpass filters in series (filter_block.v)

correction_factors = {0.5: 0.7, 0.25: 1.65, 0.001953125: 1.0, 0.00390625: 1.0, 0.125: 1.17, 0.015625: 1.02, 0.03125: 1.04, 0.0078125: 1.01, 0.0625: 1.08}
from_python(obj, value)[source]
read_and_save(obj, attr_name)[source]
to_python(obj, value)[source]

returns a list of bandwidths for the low-pass filter cascade before the module negative bandwidth stands for high-pass instead of lowpass, 0 bandwidth for bypassing the filter


returns a list of all valid filter cutoff frequencies

class pyrpl.attributes.FloatAttributeListProperty(*args, **kwargs)[source]

Bases: pyrpl.attributes.BasePropertyListProperty, pyrpl.attributes.FloatProperty

class pyrpl.attributes.FloatProperty(min=<MagicMock name='mock.inf.__neg__()' id='139827380281936'>, max=<MagicMock name='mock.inf' id='139827380218960'>, increment=0, log_increment=False, **kwargs)[source]

Bases: pyrpl.attributes.NumberProperty

An attribute for a float value.

default = 0.0
validate_and_normalize(obj, value)[source]

Try to convert to float, then saturates with min and max

class pyrpl.attributes.FloatRegister(address, bits=14, bitmask=None, norm=1.0, signed=True, invert=False, **kwargs)[source]

Bases: pyrpl.attributes.IntRegister, pyrpl.attributes.FloatProperty

Implements a fixed point register, seen like a (signed) float from python

from_python(obj, value)[source]
to_python(obj, value)[source]
validate_and_normalize(obj, value)[source]

For unsigned registers, takes the absolute value of the given value. Rounds to the nearest value authorized by the register granularity, then does the same as FloatProperty (==NumberProperty).

class pyrpl.attributes.FrequencyProperty(**kwargs)[source]

Bases: pyrpl.attributes.FloatProperty

An attribute for frequency values Same as FloatAttribute, except it cannot become negative.

class pyrpl.attributes.FrequencyRegister(address, **kwargs)[source]

Bases: pyrpl.attributes.FloatRegister, pyrpl.attributes.FrequencyProperty

Registers that contain a frequency as a float in units of Hz

CLOCK_FREQUENCY = 125000000.0
from_python(obj, value)[source]
to_python(obj, value)[source]
validate_and_normalize(obj, value)[source]

Same as FloatRegister, except the value should be positive.

class pyrpl.attributes.GainRegister(address, bits=14, bitmask=None, norm=1.0, signed=True, invert=False, **kwargs)[source]

Bases: pyrpl.attributes.FloatRegister

A register used mainly for gains, that replaces round-off to zero by round-off to the lowest-possible value.

avoid_round_off_to_zero = True
validate_and_normalize(obj, value)[source]
class pyrpl.attributes.IORegister(read_address, write_address, direction_address, outputmode=True, **kwargs)[source]

Bases: pyrpl.attributes.BoolRegister

Interface for digital outputs if argument outputmode is True, output mode is set, else input mode

direction(obj, v=None)[source]

sets the direction (inputmode/outputmode) for the Register

set_value(obj, val)[source]
class pyrpl.attributes.IntProperty(min=<MagicMock name='mock.inf.__neg__()' id='139827380281936'>, max=<MagicMock name='mock.inf' id='139827380218960'>, increment=1, log_increment=False, **kwargs)[source]

Bases: pyrpl.attributes.NumberProperty

validate_and_normalize(obj, value)[source]

Accepts float, but rounds to integer

class pyrpl.attributes.IntRegister(address, bits=32, bitmask=None, **kwargs)[source]

Bases: pyrpl.attributes.BaseRegister, pyrpl.attributes.IntProperty

Register for integer values encoded on less than 32 bits.

from_python(obj, value)[source]
to_python(obj, value)[source]
class pyrpl.attributes.LedProperty(true_function=None, false_function=None, **kwargs)[source]

Bases: pyrpl.attributes.BoolProperty

set_value(obj, val)[source]
class pyrpl.attributes.LongRegister(address, bits=32, bitmask=None, **kwargs)[source]

Bases: pyrpl.attributes.IntRegister

Interface for register of python type int/long with arbitrary length ‘bits’ (effectively unsigned)

set_value(obj, val)[source]
class pyrpl.attributes.ModuleAttribute(default=None, doc='', ignore_errors=False, call_setup=False)[source]

Bases: pyrpl.attributes.BaseProperty

This is the base class for handling submodules of a module.

The actual implementation is found in module_attributes.ModuleProperty. This object is only used inside the Module class

class pyrpl.attributes.NumberProperty(min=<MagicMock name='mock.inf.__neg__()' id='139827380281936'>, max=<MagicMock name='mock.inf' id='139827380218960'>, increment=0, log_increment=False, **kwargs)[source]

Bases: pyrpl.attributes.BaseProperty

Abstract class for ints and floats

default = 0
validate_and_normalize(obj, value)[source]

Saturates value with min and max.

class pyrpl.attributes.PWMRegister(address, CFG_BITS=24, PWM_BITS=8, **kwargs)[source]

Bases: pyrpl.attributes.FloatRegister

FloatRegister that defines the PWM voltage similar to setting a float.

from_python(obj, value)[source]
to_python(obj, value)[source]
class pyrpl.attributes.PhaseProperty(min=<MagicMock name='mock.inf.__neg__()' id='139827380281936'>, max=<MagicMock name='mock.inf' id='139827380218960'>, increment=0, log_increment=False, **kwargs)[source]

Bases: pyrpl.attributes.FloatProperty

An attribute to represent a phase

validate_and_normalize(obj, value)[source]

Rejects anything that is not float, and takes modulo 360

class pyrpl.attributes.PhaseRegister(address, bits=32, bitmask=None, invert=False, **kwargs)[source]

Bases: pyrpl.attributes.FloatRegister, pyrpl.attributes.PhaseProperty

Registers that contain a phase as a float in units of degrees.

from_python(obj, value)[source]
to_python(obj, value)[source]
validate_and_normalize(obj, value)[source]

Rounds to nearest authorized register value and take modulo 360

class pyrpl.attributes.Plotter(legend='value')[source]

Bases: pyrpl.attributes.BaseProperty

property for plotting in the GUI window.

passing a value, list of values, or a dict of color-value pairs results in plotting the values as a function of time in the GUI

class pyrpl.attributes.ProxyProperty(path_to_target, **kwargs)[source]

Bases: pyrpl.attributes.BaseProperty

An attribute that is a proxy to another attribute.

This attribute essentially behaves like the one that is reached by instance.path_to_target, always staying in synch.

change_options(obj, new_options)[source]

function that takes care of forwarding signals from target to signal_launcher of proxy module

class pyrpl.attributes.SelectProperty(options=[], **kwargs)[source]

Bases: pyrpl.attributes.BaseProperty

change_options(instance, new_options)[source]

Changes the possible options acceptable by the Attribute:

  • New validation takes effect immediately (otherwise a script involving 1. changing the options / 2. selecting one of the new options could not be executed at once)
  • Update of the ComboxBox is performed behind a signal-slot mechanism to be thread-safe
  • If the current value is not in the new_options, then value is changed to some available option
default = None

returns the default value. default is pre-defined value if that is not a valid option. Otherwise the first valid option is taken, and if that is not possible (no options), None is taken.


options are evaluated at run time. options may be callable with instance as optional argument.

set_value(obj, value)[source]
validate_and_normalize(obj, value)[source]
class pyrpl.attributes.SelectRegister(address, bitmask=None, options={}, **kwargs)[source]

Bases: pyrpl.attributes.BaseRegister, pyrpl.attributes.SelectProperty

Implements a selection register, such as for multiplexers.

The options must be a dict, where the keys indicate the available options and the values indicate the corresponding fpga register values. If different keys point to the same register value, the keys are nevertheless distinguished (allows implementing aliases that may vary over time if options is a callable object).

from_python(obj, value)[source]
set_value(obj, value)[source]
to_python(obj, value)[source]
class pyrpl.attributes.StringProperty(default=None, doc='', ignore_errors=False, call_setup=False)[source]

Bases: pyrpl.attributes.BaseProperty

An attribute for string (there is no corresponding StringRegister).

default = ''
validate_and_normalize(obj, value)[source]

Convert argument to string

class pyrpl.attributes.TextProperty(default=None, doc='', ignore_errors=False, call_setup=False)[source]

Bases: pyrpl.attributes.StringProperty

Same as StringProperty, but the gui displays it as multi-line text.

pyrpl.curvedb module

class pyrpl.curvedb.CurveDB(name='some_curve')[source]

Bases: object

classmethod all()[source]
Returns:A list of all CurveDB objects on the computer.
Return type:list of CurveDB
classmethod all_pks()[source]
Returns:A list of the primary keys of all CurveDB objects on the computer.
Return type:list of int
classmethod create(*args, **kwds)[source]

Creates a new curve, first arguments should be either Series(y, index=x) or x, y. kwds will be passed to self.params

file_extension = '.dat'

prototype for fitting a curve

classmethod get(curve)[source]

Returns the child of the curve with name ‘name’

Parameters:name (str) – Name of the child curve to be retrieved. If several childs have the same name, the first one is returned.
Returns:the child curve
Return type:CurveDB

(int) – The primary Key of the


numerically sorts the data series so that indexing can be used

pyrpl.errors module

exception pyrpl.errors.ExpectedPyrplError(message='', **kwargs)[source]

Bases: exceptions.Exception

Raise when an unexpected error occurs that should be reported

ENDC = '\x1b[0m'
STARTC = '\x1b[35m'
pyrpl_error_message = '\x1b[35m\n\n\n An expected error occured in PyRPL. Please follow the instructions\n in this error message and retry! \x1b[0m'
exception pyrpl.errors.NotReadyError[source]

Bases: exceptions.ValueError

exception pyrpl.errors.UnexpectedPyrplError(message='', **kwargs)[source]

Bases: exceptions.Exception

Raise when an unexpected error occurs that should be reported

ENDC = '\x1b[0m'
STARTC = '\x1b[35m'
pyrpl_error_message = '\x1b[35m\n\n\n An unexpected error occured in PyRPL. Please help us to improve the\n program by copy-pasting the full error message and optionally some\n additional information regarding your setup on\n as a new issue. It is\n possible that we can help you to get rid of the error. If your error\n is related to improper usage of the PyRPL API, your report will\n help us improve the documentation. Thanks! \x1b[0m'

pyrpl.memory module

class pyrpl.memory.MemoryBranch(parent, branch)[source]

Bases: object

Represents a branch of a memoryTree

All methods are preceded by an underscore to guarantee that tab expansion of a memory branch only displays the available subbranches or leaves. A memory tree is a hierarchical structure. Nested dicts are interpreted as subbranches.

  • parent (MemoryBranch) – parent is the parent MemoryBranch
  • branch (str) – branch is a string with the name of the branch to create
  • defaults (list) – list of default branches that are used if requested data is not found in the current branch
  • members (Class) –
  • -----------
  • properties without preceeding underscore are config file entries (all) –
  • _data (the raw data underlying the branch. Type depends on the) – loader and can be dict, OrderedDict or CommentedMap
  • _dict (similar to _data, but the dict contains all default) – branches
  • _defaults (list of MemoryBranch objects in order of decreasing) – priority that are used as defaults for the Branch. Changing the default values from the software will replace the default values in the current MemoryBranch but not alter the underlying default branch. Changing the default branch when it is not overridden by the current MemoryBranch results in an effective change in the branch.
  • _keys (same as _dict._keys()) –
  • _update (updates the branch with another dict) –
  • _pop (removes a value/subbranch from the branch) –
  • _root (the MemoryTree object (root) of the tree) –
  • _parent (the parent of the branch) –
  • _branch (the name of the branch) –
  • _get_or_create (creates a new branch and returns it. Same as branch[newname]=dict(), but also supports nesting,) – e.g. newname=”lev1.lev2.level3”
  • _fullbranchname (returns the full path from root to the branch) –
  • _getbranch (returns a branch by specifying its path, e.g. 'b1.c2.d3') –
  • _rename (renames the branch) –
  • _reload (attempts to reload the data from disc) –
  • _save (attempts to save the data to disc) –
  • a subbranch or a value is requested but does not exist in the current MemoryTree, a KeyError is raised. (If) –
class pyrpl.memory.MemoryTree(filename=None, source=None, _loadsavedeadtime=3.0)[source]

Bases: pyrpl.memory.MemoryBranch

The highest level of a MemoryBranch construct. All attributes of this object that do not start with ‘_’ are other MemoryBranch objects or Leaves, i.e. key - value pairs.

Parameters:filename (str) – The filename of the .yml file defining the MemoryTree structure.
exception pyrpl.memory.UnexpectedSaveError[source]

Bases: exceptions.RuntimeError

pyrpl.memory.get_config_file(filename=None, source=None)[source]

returns the path to a valid, existing config file with possible source specification

pyrpl.memory.load(stream, Loader=<class 'yaml.loader.SafeLoader'>, object_pairs_hook=<class 'collections.OrderedDict'>)[source], stream=None, Dumper=<class 'yaml.dumper.SafeDumper'>, default_flow_style=False, encoding='utf-8', **kwds)[source]

pyrpl.module_attributes module

class pyrpl.module_attributes.ModuleDict(parent, name=None)[source]

Bases: pyrpl.modules.Module

container class that loosely resembles a dictionary which contains submodules

Setup Attributes:


same as __delattr__ (does not return a value)

Sets the module up for acquisition with the current setup attribute values.
class pyrpl.module_attributes.ModuleDictProperty(module_cls=None, default=None, doc='', ignore_errors=False, **kwargs)[source]

Bases: pyrpl.module_attributes.ModuleProperty


alias of Module

class pyrpl.module_attributes.ModuleList(parent, name=None, element_cls=<class 'pyrpl.modules.Module'>, default=[])[source]

Bases: pyrpl.modules.Module, list

a list of modules Setup Attributes:

insert(index, new)[source]
Sets the module up for acquisition with the current setup attribute values.
class pyrpl.module_attributes.ModuleListProperty(element_cls, default=None, doc='', ignore_errors=False)[source]

Bases: pyrpl.module_attributes.ModuleProperty

A property for a list of submodules.

default = []

alias of ModuleList

validate_and_normalize(obj, value)[source]

ensures that only list-like values are passed to the ModuleProperty

class pyrpl.module_attributes.ModuleProperty(module_cls, default=None, doc='', ignore_errors=False, call_setup=False, **kwargs)[source]

Bases: pyrpl.attributes.ModuleAttribute

A property for a submodule.

The ModuleAttribute is declared with: ModuleAttribute(module_cls, default, doc)

The module_cls is instantiated in the __init__ of the parent module

For the moment, the following actions are supported:
  • module.sub = dict(...) : module.sub.set_setup_attributes(dict(...))
  • module.sub: returns the submodule.
default = {}
set_value(obj, val)[source]

Use the dictionnary val to set_setup_attributes :param obj: :param val: :return:

pyrpl.modules module

Modules are the basic building blocks of Pyrpl.

The internal structure of the FPGA is made of individual modules, each performing a well defined task. Each of these FPGA modules are represented in python by a HardwareModule.

Higher-level operations, for instance those that need a coordinated operation of several HardwareModules is performed by a SoftwareModule, defined in a class derived from Module.

Thus, all modules (both HardwareModule and Software modules inherit from Module which gives them basic capabilities such as displaying their attributes in the GUI having their state load and saved in the config file.

class pyrpl.modules.DoSetup(parent)[source]

Bases: object

A context manager that allows to nicely write Module setup functions.

Usage example in Module._setup():

def _setup(self):
    # _setup_ongoing is False by default
    assert self._setup_ongoing == False
    with self.do_setup:
        # now _setup_ongoing is True
        assert self._setup_ongoing == True
        # do stuff that might fail
        raise BaseException()
    # even if _setup fails, _setup_ongoing is False afterwards or in
    # the next call to _setup()
    assert self._setup_ongoing == False
class pyrpl.modules.HardwareModule(parent, name=None)[source]

Bases: pyrpl.modules.Module

Module that directly maps a FPGA module. In addition to BaseModule’s requirements, HardwareModule classes must have the following class attributes:

  • addr_base (int): the base address of the module, such as 0x40300000

Setup Attributes:

parent = None
Sets the module up for acquisition with the current setup attribute values.
class pyrpl.modules.Module(parent, name=None)[source]

Bases: object

A module is a component of pyrpl doing a specific task.

Module is the base class for instruments such as the Scope/Lockbox/NetworkAnalyzer. A module can have a widget to build a graphical user interface on top of it. It is composed of attributes (see whose values represent the current state of the module (more precisely, the state is defined by the value of all attributes in _setup_attributes) The module can be slaved or freed by a user or another module. When the module is freed, it goes back to the state immediately before being slaved. To make sure the module is freed, use the syntax:

with pyrpl.mod_mag.pop('owner') as mod:
get_setup_attributes(): returns a dict with the current values of
the setup attributes
set_setup_attributes(**kwds): sets the provided setup_attributes
(setup is not called)
save_state(name): saves the current ‘state’ (using
get_setup_attribute) into the config file
load_state(name): loads the state ‘name’ from the config file (setup
is not called by default)

erase_state(name): erases state ‘name’ from config file create_widget(): returns a widget according to widget_class setup(**kwds): first, performs set_setup_attributes(**kwds),

then calls _setup() to set the module ready for acquisition. This method is automatically created by ModuleMetaClass and it combines the docstring of individual setup_attributes with the docstring of _setup()
free(): sets the module owner to None, and brings the module back the
state before it was slaved equivalent to module.owner = None)
get_yml(state=None): get the yml code representing the state “state’
or the current state if state is None
set_yml(yml_content, state=None): sets the state “state” with the
content of yml_content. If state is None, the state is directly loaded into the module.
name: attributed based on name at instance creation
(also used as a section key in the config file)

states (list): the list of states available in the config file owner (string): a module can be owned (reserved) by a user or another

module. The module is free if and only if owner is None
pyrpl (Pyrpl): recursively looks through parent modules until it
reaches the Pyrpl instance

Class attributes to be implemented in derived class:

  • all individual attributes (instances of BaseAttribute)
  • _setup_attributes: attribute names that are touched by setup(**kwds)/ saved/restored upon module creation
  • _gui_attributes: attribute names to be displayed by the widget
  • _callback_attributes: attribute_names that triggers a callback when their value is changed in the base class, _callback just calls setup()
  • _widget_class: class of the widget to use to represent the module in the gui(a child of ModuleWidget)

Methods to implement in derived class:

  • _setup(): sets the module ready for acquisition/output with the current attribute’s values. The metaclass of the module autogenerates a function like this:

    def setup(self, **kwds):
        _ docstring is the result of the following pseudocode: _
        for attribute in self.setup_attributes:
        return self._setup()
  • _ownership_changed(old, new): this function is called when the module owner changes it can be used to stop the acquisition for instance.

Setup Attributes:


Returns a MemoryBranch object used for storing data in the configuration file.

The branch corresponding to the module is a subbranch of the parent module’s branch with the name of the module.


Removes the state “name’ from the config file :param name: name of the state to erase :return: None


Change ownership to None


Returns a dict with the current values of the setup attributes.

Recursively calls get_setup_attributes for sub_modules and assembles a hierarchical dictionary.

Returns:contains setup_attributes and their current values.
Return type:dict
Parameters:state – The name of the state to inspect. If state is None–>

then, use the current instrument state. :return: a string containing the yml code


Loads the state with name “name” from the config file. If state_branch is left unchanged, uses the normal class_section.states convention.

name = None

Recursively looks through patent modules untill pyrpl instance is reached.


Saves the current state under the name “name” in the config file. If state_section is left unchanged, uses the normal class_section.states convention.


Sets the values of the setup attributes. Without calling any callbacks

set_yml(yml_content, state=None)[source]
  • yml_content – some yml code to encode the module content.
  • state – The name of the state to set. If state is None–>

then, use the current instrument state and reloads it immediately :return: None

Sets the module up for acquisition with the current setup attribute values.

return – a dict with the current values of the setup attributes. Recursively collects setup_attributes for sub_modules.


Returns the names of all saved states of the module.

class pyrpl.modules.ModuleMetaClass(classname, bases, classDict)[source]

Bases: type

Generate Module classes with two features: - __new__ lets attributes know what name they are referred to in the class that contains them. - __new__ also lists all the submodules. This info will be used when instantiating submodules at module instanciation time. - __init__ auto-generates the function setup() and its docstring


Make a list with all attributes from _setup_attribute in the class docstring

Returns a docstring for the function ‘setup’ that is composed of:
  • the ‘_setup’ docstring
  • the list of all setup_attributes docstrings
class pyrpl.modules.SignalLauncher(module)[source]

Bases: <MagicMock name='mock.QtCore' id='139827381803152'>.QObject

Object that is used to handle signal the emission for a Module.

A QObject that is connected to the widgets to update their value when attributes of a module change. Any timers needed to implement the module functionality shoud be implemented here as well.

change_options = <MagicMock name='mock.QtCore.Signal()' id='139827380610576'>
change_ownership = <MagicMock name='mock.QtCore.Signal()' id='139827380610576'>

Establishes all connections between the module and the widget by name.

emit_signal_by_name(name, *args, **kwds)[source]

Emits signal “name” with the specfified args and kwds.

refresh_filter_options = <MagicMock name='mock.QtCore.Signal()' id='139827380610576'>
update_attribute_by_name = <MagicMock name='mock.QtCore.Signal()' id='139827380610576'>
class pyrpl.modules.SignalModule(parent, name=None)[source]

Bases: pyrpl.modules.Module

any module that can be passed as an input to another module Setup Attributes:

Sets the module up for acquisition with the current setup attribute values.

pyrpl.pyrpl module


A lockbox is a device that converts a number of input signals into a number of output signals suitable to stabilize a physical system in a desired state. This task is generally divided into two steps: 1) bring the system close the desired state where it can be linearized 2) keep it there using linear control.

The task is further divided into several subtasks: 0a) Condition the input signals so that they are suitable for the next steps - offset removal - input filters - demodulation / lockin - inversion 0b) Estimate the system state from the past and present history of input and output signals. 0c) Build a filter for the output signals such that they can be conveniently addressed with higher-level lockbox logic.

1) As above: apply reasonable action to the outputs to approach the system to the desired state. We generally call this the ‘search’ step. - provide a number of algorithms/recipes to do this

2) As above: Turn on linear feedback. We call this the ‘lock’ step. - connect the input signals with appropriate gain to the outputs - the gain depends on the state of the system, so internal state representation will remain useful here

This naturally divides the lockbox object into 3 subcomponents: a) inputs b) internal model c) outputs

which will be interconnected by the algorithms that come with the model and make optimal use of the available inputs and outputs. The job of the configuration file is to provide a maximum of information about the inputs, outputs and the physical system (=internal model) so that the lockbox is effective and robust. The lockbox will usually require both a coarse-tuning and an optimization step for optimum performance, which will both adjust the various parameters for the best match between model and real system.

Let’s make this reasoning more clear with an example:

A Fabry-Perot cavity is to be locked near resonance using a PDH scheme. The incident laser beam goes through a phase modulator. The cavity contains a piezo with estimated bandwidth 10 kHz (appearance of first resonance) and a displacement of 350 nm/V that goes into the piezo amplifier. To limit the effect of amplifier noise, we have inserted an RC lowpass between amplifier and piezo with a cutoff frequency of 100 Hz. The laser contains another piezo with estimated bandwidth of 50 kHz that changes the laser frequency by 5 MHz/V. An RC filter provides a lowpass with 1kHz cutoff. Finally, the cavity can be tuned through its temperature with a bandwidth slower than 0.1 Hz. We estimate from thermal expansion coefficients that 1 V to the Peltier amplifier leading to 3 K heating of the cavity spacer should lead to 30ppm/K*20cm*3K/V = 18 micron/V length change. Both reflection and transmission of the cavity are available error signals. The finesse of the cavity is 5000, and therefore there are large regions of output signals where no useful error signal can be obtained.

We first generate a clean list of available inputs and outputs and some parameters of the cavity that we know already:


# also possible # in2: pdh # for externally generated pdh


# we insert a bias-T with separation frequency around 1 MHz behind out1 # this allows us to use the fast output for both the piezo and PDH modulator:

amplitude: 0.1 frequency: 50e6
# piezo specification: 7 micron/1000V # amplifier gain: 50 # therefore effective DC gain: 350nm/V m_per_V: 350e-9 bandwidth: 100.0
Hz_per_V: 5e6 bandwidth: 1e3
m_per_V: 18e-6 bandwidth: 0.1

type: fabryperot wavelength: 1064e-9 finesse: 5000 # round-trip length in m (= twice the length for ordinary Fabry-Perot) length: 0.72 lock: # lock methods in order of preferrence

pdh reflection transmission

# when approaching a resonance, we can either abruptly jump or smoothly # ramp from one error signal to another. We specify our preferrence with # the order of keywords after transition transition: [ramp, jump] # target value for our lock. The API provides many ways to adjust this at # runtime target:

detuning: 0

# search algorithms to use in order of preferrence, as available in model search:

drift bounce

Having selected fabryperot as modeltype, the code will automatically search for a class named fabryperot in the file to provide for the internal state representation and all algorithms. You can create your own model by adding other classes to this file, or by inheriting from existing ones and adding further functionality. The naming of all other configuration parameters is linked to the model, since all functionality that makes use of these para- meters is implemented there. Another very often used model type is “interferometer”. The only difference is here that

class pyrpl.pyrpl.Pyrpl(config=None, source=None, **kwargs)[source]

Bases: object

Higher level object, in charge of loading the right hardware and software module, depending on the configuration described in a config file.

  • config (str) – Name of the config file. No .yml extension is needed. The file should be located in the config directory.
  • source (str) – If None, it is ignored. Else, the file ‘source’ is taken as a template config file and copied to ‘config’ if that file does not exist.
  • **kwargs (dict) – Additional arguments can be passed and will be written to the redpitaya branch of the config file. See class definition of RedPitaya for possible keywords.

List of all hardware modules loaded in this configuration.


load all software modules defined as root element of the config file.


pyrpl.pyrpl_utils module

class pyrpl.pyrpl_utils.Bijection(*args, **kwargs)[source]

Bases: dict

This class defines a bijection object based on dict

It can be used exactly like dict, but additionally has a property ‘inverse’ which contains the inverted {value: key} dict.

update(*args, **kwargs)[source]
class pyrpl.pyrpl_utils.DuplicateFilter(name='')[source]

Bases: logging.Filter

Prevent multiple repeated logging message from polluting the console


returns a list of all subclasses of cls


returns the base class of module that has the same name as module


returns the class name corresponding to a module_name


returns a list of names using if unique or cls.name1, cls.name2... otherwise. Order of the name list matches order of cls_list, such that iterating over zip(cls_list, name_list) is OK


returns True if Jupyter notebook is runnung

pyrpl.pyrpl_utils.recursive_getattr(root, path)[source]

returns root.path (i.e. root.attr1.attr2)

pyrpl.pyrpl_utils.recursive_setattr(root, path, value)[source]

returns root.path = value (i.e. root.attr1.attr2 = value)

pyrpl.pyrpl_utils.setloglevel(level='info', loggername='pyrpl')[source]

sets the log level to the one specified in config file

pyrpl.pyrpl_utils.sorted_dict(dict_to_sort=None, sort_by_values=True, **kwargs)[source]

returns the time. used instead of time.time for rapid portability


Returns a list where each element of nonunique_list occurs exactly once. The last occurence of an element defines its position in the returned list.

pyrpl.pyrpl_utils.update_with_typeconversion(dictionary, update)[source]

pyrpl.redpitaya module

class pyrpl.redpitaya.RedPitaya(config=None, **kwargs)[source]

Bases: object

cls_modules = [<class ''>, <class 'pyrpl.hardware_modules.ams.AMS'>, <class 'pyrpl.hardware_modules.scope.Scope'>, <class 'pyrpl.hardware_modules.sampler.Sampler'>, <class 'pyrpl.hardware_modules.asg.Asg'>, <class 'pyrpl.hardware_modules.asg.Asg'>, <class 'pyrpl.hardware_modules.pwm.Pwm'>, <class 'pyrpl.hardware_modules.pwm.Pwm'>, <class ''>, <class ''>, <class ''>, <class ''>, <class ''>, <class ''>, <class 'pyrpl.hardware_modules.trig.Trig'>, <class 'pyrpl.hardware_modules.iir.iir.IIR'>]
make_a_slave(port=None, monitor_server_name=None, gui=False)[source]
makemodule(name, cls)[source]

Automatically generates modules from the list RedPitaya.cls_modules


restart the server. usually executed when client encounters an error


Extablishes an ssh connection to the RedPitaya board

returns True if a successful connection has been established

switch_led(gpiopin=0, state=False)[source]

pyrpl.redpitaya_client module

class pyrpl.redpitaya_client.DummyClient[source]

Bases: object

Class for unitary tests without RedPitaya hardware available

class fpgadict[source]

Bases: dict

fpgamemory = {'1074790420': 1}
reads(addr, length)[source]
writes(addr, values)[source]
class pyrpl.redpitaya_client.MonitorClient(hostname='', port=2222, restartserver=None)[source]

Bases: object

reads(addr, length)[source]
try_n_times(function, addr, value, n=5)[source]
writes(addr, values)[source]
pyrpl.redpitaya_client.sine(frequency, duration)[source]

pyrpl.sound module

pyrpl.sshshell module

class pyrpl.sshshell.SshShell(hostname='localhost', user='root', password='root', delay=0.05, timeout=3, sshport=22, shell=True)[source]

Bases: object

This is a wrapper around paramiko.SSHClient and scp.SCPClient I provides a ssh connection with the ability to transfer files over it


returns all MAC addresses of the SSH device.


Module contents