Fork PyRPL on GitHub

# pyrpl.software_modules package¶

## pyrpl.software_modules.curve_viewer module¶

class pyrpl.software_modules.curve_viewer.CurveViewer(parent, name=None)[source]
This Module allows to browse through curves that were taken with pyrpl

Setup Attributes:

curve
curve_name

Name of the currently viewed curve

delete_curve()[source]
params
pk

the pk of the currently viewed curve

refresh_curve_list()[source]
save_params()[source]
setup(**kwds)
pyrpl.software_modules.curve_viewer.all_curves(instance=None)[source]

## pyrpl.software_modules.loop module¶

Defines a number of Loop modules to be used to perform periodically a task

class pyrpl.software_modules.loop.Loop(parent, name='loop', interval=1.0, autostart=True, loop_function=None, setup_function=None, teardown_function=None, **kwargs)[source]

Setup Attributes:

fpga_time

current FPGA time in s since startup

interval
loop()[source]
main_loop()[source]
pause_loop()[source]
setup(**kwds)
Sets the module up for acquisition with the current setup attribute values.
setup_loop()[source]

start_loop()[source]
teardown_loop()[source]

time

time since start of the loop

trigger_time

FPGA time in s when trigger even occured (same frame of reference as self.time())

class pyrpl.software_modules.loop.PlotLoop(*args, **kwargs)[source]

Setup Attributes:

plotappend(*args, **kwargs)[source]
setup(**kwds)
Sets the module up for acquisition with the current setup attribute values.
class pyrpl.software_modules.loop.PlotWindow(title='plotwindow')[source]

Bases: object

makes a plot window where the x-axis is time since startup.

append(color=value) adds new data to the plot for color in (red, green).

close() closes the plot

append(*args, **kwargs)[source]
usage:
append(green=0.1, red=0.5, blue=0.21)
# former, now almost deprecated version:
append(0.5, 0.6)
close()[source]

## pyrpl.software_modules.module_managers module¶

Module managers are lightweight software modules that manage the access to hardware modules. For example, to use the scope:

HOSTNAME = "192.168.1.100"
from pyrpl import Pyrpl
p = Pyrpl(hostname=HOSTNAME)

# directly accessing the scope will not *reserve* it
scope = p.rp.scope
print(scope.owner)
scope.duration = 1.

# using the scope manager changes its ownership
print(scope.owner)
scope.duration =0.01
print(scope.duration)
# The scope is freed (and reset to its previous state) after the with
# construct
print(scope.owner)
print(scope.duration)


In case several identical modules are available on the FPGA, the first one ( starting from the end of the list) is returned by the module manager:

HOSTNAME = "192.168.1.100"
from pyrpl import Pyrpl
p = Pyrpl(hostname=HOSTNAME)

# directly accessing the scope will not *reserve* it
pid2 = p.rp.pid2
pid2.owner = 'foo'

# Pid manager returns the first free pid module (in decreasing order)
print("pid0's owner: ", p.rp.pid0.owner)
print("pid1's owner: ", p.rp.pid1.owner)
print("pid2's owner: ", p.rp.pid2.owner)
print("pid0's owner: ", p.rp.pid0.owner)
print("pid1's owner: ", p.rp.pid1.owner)
print("pid2's owner: ", p.rp.pid2.owner)

class pyrpl.software_modules.module_managers.Asgs(parent, name=None)[source]

Setup Attributes:

setup(**kwds)
Sets the module up for acquisition with the current setup attribute values.
class pyrpl.software_modules.module_managers.Iirs(parent, name=None)[source]
Only one iir, but it should be protected by the slave/owner mechanism.

Setup Attributes:

setup(**kwds)
Sets the module up for acquisition with the current setup attribute values.
exception pyrpl.software_modules.module_managers.InsufficientResourceError[source]

Bases: exceptions.ValueError

This exception is raised when trying to pop a module while there is none left.

class pyrpl.software_modules.module_managers.Iqs(parent, name=None)[source]

Setup Attributes:

setup(**kwds)
Sets the module up for acquisition with the current setup attribute values.
class pyrpl.software_modules.module_managers.ModuleManager(parent, name=None)[source]

Manages access to hardware modules. It is created from a list of hardware_modules to manage. For HardwareModules, ti is the manager module that is actually displayed in the gui.

provides the following functions:
• pop(owner): gives the last module in the list that is currently

available, and locks it with the string “user” as owner of the hardware module - free(module): frees the module by reseting its user to None. (and enabling back its gui if any).

Setup Attributes:

c
free(module)[source]
hardware_module_names

Looks in RedPitaya.modules to find how many modules are present. :return: list of all module names in redpitaya instance with a name looking like:

• some_module
• or some_module1, some_module2, some_module3 ...
n_available()[source]

returns the number of modules still available

n_modules()[source]

returns the total number of modules

pop(owner=None)[source]

returns the first available module (starting from the end of the list) :param owner: (string): name of the module that is reserving the resource leave None if the gui shouldn’t be disabled. If no available module left, returns None.

To make sure the module will be freed afterwards, use the context manager construct: with pyrpl.mod_mag.pop(‘owner’) as mod:

mod.do_something()

# module automatically freed at this point

setup(**kwds)
Sets the module up for acquisition with the current setup attribute values.
class pyrpl.software_modules.module_managers.Pids(parent, name=None)[source]

Setup Attributes:

setup(**kwds)
Sets the module up for acquisition with the current setup attribute values.
class pyrpl.software_modules.module_managers.Scopes(parent, name=None)[source]
Only one scope, but it should be protected by the slave/owner mechanism.

Setup Attributes:

setup(**kwds)
Sets the module up for acquisition with the current setup attribute values.
class pyrpl.software_modules.module_managers.Trigs(parent, name=None)[source]
Only one trig, but it should be protected by the slave/owner mechanism.

Setup Attributes:

setup(**kwds)
Sets the module up for acquisition with the current setup attribute values.

## pyrpl.software_modules.network_analyzer module¶

class pyrpl.software_modules.network_analyzer.LogScaleProperty(default=None, doc='', ignore_errors=False, call_setup=False)[source]
set_value(module, val)[source]
class pyrpl.software_modules.network_analyzer.NaAcBandwidth(default=None, doc='', ignore_errors=False, call_setup=False)[source]
get_value(obj)[source]
set_value(obj, value)[source]
valid_frequencies(obj)[source]
class pyrpl.software_modules.network_analyzer.NaAmplitudeProperty(min=<MagicMock name='mock.inf.__neg__()' id='139827380281936'>, max=<MagicMock name='mock.inf' id='139827380218960'>, increment=0, log_increment=False, **kwargs)[source]
validate_and_normalize(obj, value)[source]
class pyrpl.software_modules.network_analyzer.NaCurveFuture(module, min_delay_ms, autostart=True)[source]
N_POINT_BENCHMARK = 100
cancel()[source]
pause()[source]
start()[source]
class pyrpl.software_modules.network_analyzer.NaPointFuture(module, point_index, min_delay_ms=0)[source]

Future object for a NetworkAnalyzer point.

cancel()[source]
set_exception(exception)[source]
class pyrpl.software_modules.network_analyzer.NaRunFuture(module, min_delay_ms)[source]
class pyrpl.software_modules.network_analyzer.NetworkAnalyzer(parent, name=None)[source]

Using an IQ module, the network analyzer can measure the complex coherent response between an output and any signal in the redpitaya.

Three example ways on how to use the NetworkAnalyzer:

• Example 1:

r = RedPitaya("1.1.1.1")
na = NetworkAnalyzer(r)
curve = na.curve(start=100, stop=1000, rbw=10...)

• Example 2:

na.start = 100
na.stop = 1000
curve = na.curve(rbw=10)

• Example 3:

na.setup(start=100, stop=1000, ...)
for freq, response, amplitude in na.values():
print response


Setup Attributes:

• trace_average: number of curves to average in single mode. In continuous mode, a decaying average with a characteristic memory of ‘trace_average’ curves is performed.
• input:
• output_direct:

Options: [‘off’, ‘out1’, ‘out2’, ‘both’] - acbandwidth: Bandwidth of the input high-pass filter of the na. - start_freq: - stop_freq: - rbw: - avg_per_point: - points: - amplitude: - logscale: - infer_open_loop_tf:

MIN_DELAY_CONTINUOUS_MS = 0
MIN_DELAY_SINGLE_MS = 0
acbandwidth

Bandwidth of the input high-pass filter of the na.

amplitude
avg_per_point
current_freq

current frequency during the scan

current_point
data_avg
data_x

x-data for the network analyzer are computed during setup() and cached in the variable _data_x.

frequencies

alias for data_x

Returns: frequency array
infer_open_loop_tf
input
inputs
iq

underlying iq module.

is_zero_span()[source]

Returns true if start_freq is the same as stop_freq.

last_valid_point
logscale
measured_time_per_point
output_direct

Options – [‘off’, ‘out1’, ‘out2’, ‘both’]

output_directs
points
rbw
setup(**kwds)
trace_average

number of curves to average in single mode. In continuous mode, a decaying average with a characteristic memory of ‘trace_average’ curves is performed.

curve_name

name of the curve to save.

input
output_direct

Options: [‘off’, ‘out1’, ‘out2’, ‘both’]

acbandwidth: Bandwidth of the input high-pass filter of the na. start_freq: stop_freq: rbw: avg_per_point: points: amplitude: logscale: infer_open_loop_tf: running_state: Indicates whether the instrument is running acquisitions or not. See RunningStateProperty for available options.
signal()[source]
start_freq
stop_freq
take_ringdown(frequency, rbw=1000, points=1000, trace_average=1)[source]
threshold_hook(current_val)[source]

A convenience function to stop the run upon some condition (such as reaching of a threshold. current_val is the complex amplitude of the last data point).

To be overwritten in derived class... :param current_val:

trace_average

number of curves to average in single mode. In continuous mode, a decaying average with a characteristic memory of ‘trace_average’ curves is performed.

transfer_function(frequencies, extradelay=0)[source]

Returns a complex np.array containing the transfer function of the current IQ module setting for the given frequency array. The given transfer function is only relevant if the module is used as a bandpass filter, i.e. with the setting (gain != 0). If extradelay = 0, only the default delay is taken into account, i.e. the propagation delay from input to output_signal.

Parameters: frequencies (np.array or float) – Frequencies to compute the transfer function for extradelay (float) – External delay to add to the transfer function (in s). If zero, only the delay for internal propagation from input to output_signal is used. If the module is fed to analog inputs and outputs, an extra delay of the order of 200 ns must be passed as an argument for the correct delay modelisation. tf – The complex open loop transfer function of the module. np.array(.., dtype=np.complex)
class pyrpl.software_modules.network_analyzer.RbwAttribute(default=None, doc='', ignore_errors=False, call_setup=False)[source]
get_value(instance)[source]
set_value(instance, val)[source]
valid_frequencies(obj)[source]

## pyrpl.software_modules.pyrpl_config module¶

class pyrpl.software_modules.pyrpl_config.PyrplConfig(parent, name=None)[source]
This Module allows the Gui to configure the global settins, such as redpitaya and pyrpl

Setup Attributes:

configfile
current_branch
module

this selector allows to choose which module is configured Options: [None]

refresh()[source]
save()[source]
setup(**kwds)
text

## pyrpl.software_modules.software_pid module¶

class pyrpl.software_modules.software_pid.RunningProperty(true_function=None, false_function=None, **kwargs)[source]
false_function(obj)

stops the running loop

get_value(obj)[source]
start(obj)[source]

starts a new loop

stop(obj)[source]

stops the running loop

true_function(obj)

starts a new loop

class pyrpl.software_modules.software_pid.SoftwarePidController(parent, name=None)[source]

Setup Attributes:

• input:
• output:
• p:
• i:
• d:
• setpoint:
• reset_ival_on_restart:
• interval:
• plot:
• running:
d
i
input
interval
output
output_max
output_min
p
plot
plotter
reset_ival_on_restart
running
setpoint
setup(**kwds)
Sets the module up for acquisition with the current setup attribute values.
input
output
p
i
d
setpoint
reset_ival_on_restart
interval
plot
running
start()[source]
stop()[source]
class pyrpl.software_modules.software_pid.SoftwarePidLoop(*args, **kwargs)[source]

Setup Attributes:

input
loop()[source]
output
saturate_output(v)[source]
setup(**kwds)
Sets the module up for acquisition with the current setup attribute values.
setup_loop()[source]

teardown_loop()[source]

## pyrpl.software_modules.spectrum_analyzer module¶

The spectrum analyzer measures the magnitude of an input signal versus frequency. There are two working modes for the spectrum analyzer implemented in pyrpl:

• iq mode: the input signal is demodulated around the center_frequency of the analysis window (using iq2). The slowly varying quadratures are subsequently sent to the 2 channels of the scope. The complex IQ time trace is built from the sum I(t) + iQ(t). The spectrum is then evaluated by performing a Fourier transforom of the the complex iq signal.
• baseband mode: up to 2 channels are available in baseband mode. The channels are digitized by the scope and the real traces are directly Fourier transformed. Since both channels are acquired simultaneously, it is also possible to retrieve the cross spectrum between channel 1 and channel 2 (the relative phase of the fourier transform coefficients is meaningful)

At the moment, the iq mode is deactivated since we haven’t yet implemented the sharp antialiasing filters required to avoid polluting the analysis windows from aliased noise originating from outside the Nyquist frequency of the scope acquisition. However, we are planning on implementing such a filter with the iir module in the near future.

In the following example, we are going to demonstrate how to measure a sinusoidal signal and a white noise originating from an asg

# let's use a module manager for the asg
with p.asgs.pop('user') as asg:
# setup a sine at 100 kHz
asg.setup(frequency=1e5, waveform='sin', trigger_source='immediately', amplitude=1., offset=0)

# setup the spectrumanalyzer in baseband mode
p.spectrumanalyzer.setup(input1_baseband=asg, #note that input1_baseband!=input)
baseband=True, # only mod eavailable right now
span=1e6, # span of the analysis (/2 in iq mode)
window=blackman # filter window)

# the return format is (spectrum for channel 1, spectrum for channel 2,
# real part of cross spectrum, imaginary part of cross spectrum):
ch1, ch2, cross_re, cross_im = p.spectrumanalyzer.curve()

# plot the spectrum
import matplotlib.pyplot as plt
%matplotlib inline
plt.plot(p.spectrumanalyzer.frequencies, ch1)


We notice that the spectrum is peaked around 100 kHz (The width of the peak is given by the residual bandwidth), and the height of the peak is 1.

The internal unit of the spectrum analyzer is V_pk^2, such that a 1 V sine results in a 1 Vpk^2 peak in the spectrum. To convert the spectrum in units of noise spectral density, a utility function is provided: data_to_unit()

# let's use a module manager for the asg
with p.asgs.pop('user') as asg:
# setup a white noise of variance 0.1 V
asg.setup(frequency=1e5, waveform='noise', trigger_source='immediately', amplitude=0.1, offset=0)

# setup the spectrumanalyzer in baseband mode and full span
p.spectrumanalyzer.setup(input1_baseband=asg, baseband=True, span=125e6)

# the return format is (spectrum for channel 1, spectrum for channel 2,
# real part of cross spectrum, imaginary part of cross spectrum):
ch1, ch2, cross_re, cross_im = p.spectrumanalyzer.curve()

# convert to Vrms^2/Hz
data = p.spectrumanalyzer.data_to_unit(ch1, 'Vrms^2/Hz', p.spectrumanalyzer.rbw)

# plot the spectrum
import matplotlib.pyplot as plt
%matplotlib inline
plt.plot(p.spectrumanalyzer.frequencies, data)

# integrate spectrum from 0 to nyquist frequency
df = p.spectrumanalyzer.frequencies[1] - p.spectrumanalyzer.frequencies[0]
print(sum(data)*df)


As expected, the integral of the noise spectrum over the whole frequency range gives the variance of the noise. To know more about spectrum analysis in Pyrpl, and in particular, how the filtering windows are normalized, please refer to the section How a spectrum is computed in PyRPL.

class pyrpl.software_modules.spectrum_analyzer.CenterAttribute(**kwargs)[source]
get_value(instance)[source]
set_value(instance, value)[source]
class pyrpl.software_modules.spectrum_analyzer.DecimationProperty(options=[], **kwargs)[source]

Since the only integer number in [rbw, span, duration, decimation] is decimation, it is better to take it as the master property to avoid rounding problems. We don’t want to use the scope property because when the scope is not slaved, the value could be anything.

set_value(obj, value)[source]
class pyrpl.software_modules.spectrum_analyzer.DisplayUnitProperty(options=[], **kwargs)[source]
set_value(obj, value)[source]
class pyrpl.software_modules.spectrum_analyzer.RbwProperty(default=None, doc='', ignore_errors=False, call_setup=False)[source]
get_value(obj)[source]
set_value(obj, value)[source]
valid_frequencies(module)[source]
class pyrpl.software_modules.spectrum_analyzer.SpanFilterProperty(default=None, doc='', ignore_errors=False, call_setup=False)[source]
get_value(obj)[source]
set_value(obj, value)[source]
valid_frequencies(instance)[source]
class pyrpl.software_modules.spectrum_analyzer.SpecAnAcBandwidth(default=None, doc='', ignore_errors=False, call_setup=False)[source]
valid_frequencies(module)[source]
class pyrpl.software_modules.spectrum_analyzer.SpectrumAnalyzer(parent, name=None)[source]
A spectrum analyzer is composed of an IQ demodulator, followed by a scope. The spectrum analyzer connections are made upon calling the function setup.

Setup Attributes:

• input:
• center:
• baseband:
• span:
Span can only be given by 1./sampling_time where sampling time is a valid scope sampling time.
• window:
• acbandwidth:
• display_unit:
• curve_unit:

Options: [‘Vpk^2’] - display_input1_baseband: should input1 spectrum be displayed in baseband-mode? - display_input2_baseband: should input2 spectrum be displayed in baseband-mode? - input1_baseband: input1 for baseband mode - input2_baseband: input2 for baseband mode - display_cross_amplitude: should cross-spectrum amplitude be displayed in baseband-mode?

PADDING_FACTOR = 16
acbandwidth
baseband
center
curve_ready()[source]
curve_unit

Options – [‘Vpk^2’]

data_length
data_to_dBm(data)[source]
data_to_display_unit(data, rbw)[source]

Converts the array ‘data’, assumed to be in ‘Vpk^2’, into display units. Since some units require a rbw for the conversion, it is an explicit argument of the function.

data_to_unit(data, unit, rbw)[source]

Converts the array ‘data’, assumed to be in ‘Vpk^2’, into the specified unit. Unit can be anything in [‘Vpk^2’, ‘dB(Vpk^2)’, ‘Vrms^2’, ‘dB(Vrms^2)’, ‘Vrms’, ‘Vrms^2/Hz’]. Since some units require a rbw for the conversion, it is an explicit argument of the function.

data_x
decimation

Decimation setting for the scope.

display_cross_amplitude

should cross-spectrum amplitude be displayed in baseband-mode?

display_cross_phase

should cross-spectrum amplitude be displayed in baseband-mode?

display_input1_baseband

should input1 spectrum be displayed in baseband-mode?

display_input2_baseband

should input2 spectrum be displayed in baseband-mode?

display_unit
duration
equivalent_noise_bandwidth()[source]

Returns the equivalent noise bandwidth of the current window. To get the residual bandwidth, this number has to be multiplied by the sample rate.

filter_window()[source]
Returns: filter window
frequencies

return – frequency array

if_filter_bandwidth_per_span = 1.0
input
input1_baseband

input1 for baseband mode

input2_baseband

input2 for baseband mode

inputs
iq
iq_quadraturesignal = 'iq2_2'
nyquist_margin = 1.0
quadrature_factor = 1.0
rbw

Residual Bandwidth, this is a readonly attribute, only span can be changed.

sampling_time
save_curve()[source]

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

scope
setup(**kwds)
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.

input
center
baseband
span

Span can only be given by 1./sampling_time where sampling time is a valid scope sampling time.

window
acbandwidth
display_unit
curve_unit

Options: [‘Vpk^2’]

display_input1_baseband: should input1 spectrum be displayed in baseband-mode? display_input2_baseband: should input2 spectrum be displayed in baseband-mode? input1_baseband: input1 for baseband mode input2_baseband: input2 for baseband mode display_cross_amplitude: should cross-spectrum amplitude be displayed in baseband-mode?
span

Span can only be given by 1./sampling_time where sampling time is a valid scope sampling time.

spans = [124999999.99999999, 62499999.99999999, 31249999.999999996, 15624999.999999998, 7812499.999999999, 3906249.9999999995, 1953124.9999999998, 976562.4999999999, 488281.24999999994, 244140.62499999997, 122070.31249999999, 61035.15624999999, 30517.578124999996, 15258.789062499998, 7629.394531249999, 3814.6972656249995, 1907.3486328124998]
transfer_function(frequencies)[source]

Transfer function from the generation of quadratures to their sampling, including scope decimation. At the moment, delays are not taken into account (and the phase response is not guaranteed to be exact.

transfer_function_iq(frequencies)[source]
transfer_function_scope(frequencies)[source]
useful_index_obsolete()[source]
Returns: a slice containing the portion of the spectrum between start

and stop

window
windows = ['blackman', 'flattop', 'boxcar', 'hamming', 'gaussian']
class pyrpl.software_modules.spectrum_analyzer.WindowProperty(options=[], **kwargs)[source]

Changing the filter window requires to recalculate the bandwidth

set_value(obj, value)[source]

## Module contents¶

exception pyrpl.software_modules.ModuleNotFound[source]

Bases: exceptions.ValueError

pyrpl.software_modules.get_module(name)[source]

Returns the subclass of Module named name (if exists, otherwise None)