pyrpl.software_modules.curve_viewer.
CurveViewer
(parent, name=None)[source]¶Bases: pyrpl.modules.Module
This Module allows to browse through curves that were taken with pyrpl
Setup Attributes:
curve
¶curve_name
¶Name of the currently viewed curve
params
¶pk
¶the pk of the currently viewed curve
setup
(**kwds)¶Defines a number of Loop modules to be used to perform periodically a task
pyrpl.software_modules.loop.
Loop
(parent, name='loop', interval=1.0, autostart=True, loop_function=None, setup_function=None, teardown_function=None, **kwargs)[source]¶Bases: pyrpl.modules.Module
Setup Attributes:
fpga_time
¶current FPGA time in s since startup
interval
¶setup
(**kwds)¶Sets the module up for acquisition with the current setup attribute values.
time
¶time since start of the loop
trigger_time
¶FPGA time in s when trigger even occured (same frame of reference as self.time())
pyrpl.software_modules.loop.
PlotLoop
(*args, **kwargs)[source]¶Bases: pyrpl.software_modules.loop.Loop
Setup Attributes:
setup
(**kwds)¶Sets the module up for acquisition with the current setup attribute values.
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
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
with p.scopes.pop('username') as scope:
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)
with p.pids.pop('username') as pid:
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)
pyrpl.software_modules.module_managers.
Asgs
(parent, name=None)[source]¶Bases: pyrpl.software_modules.module_managers.ModuleManager
Setup Attributes:
setup
(**kwds)¶Sets the module up for acquisition with the current setup attribute values.
pyrpl.software_modules.module_managers.
Iirs
(parent, name=None)[source]¶Bases: pyrpl.software_modules.module_managers.ModuleManager
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.
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.
pyrpl.software_modules.module_managers.
Iqs
(parent, name=None)[source]¶Bases: pyrpl.software_modules.module_managers.ModuleManager
Setup Attributes:
setup
(**kwds)¶Sets the module up for acquisition with the current setup attribute values.
pyrpl.software_modules.module_managers.
ModuleManager
(parent, name=None)[source]¶Bases: pyrpl.modules.Module
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
¶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 ...
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.
pyrpl.software_modules.module_managers.
Pids
(parent, name=None)[source]¶Bases: pyrpl.software_modules.module_managers.ModuleManager
Setup Attributes:
setup
(**kwds)¶Sets the module up for acquisition with the current setup attribute values.
pyrpl.software_modules.module_managers.
Scopes
(parent, name=None)[source]¶Bases: pyrpl.software_modules.module_managers.ModuleManager
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.
pyrpl.software_modules.module_managers.
Trigs
(parent, name=None)[source]¶Bases: pyrpl.software_modules.module_managers.ModuleManager
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.
LogScaleProperty
(default=None, doc='', ignore_errors=False, call_setup=False)[source]¶pyrpl.software_modules.network_analyzer.
NaAcBandwidth
(default=None, doc='', ignore_errors=False, call_setup=False)[source]¶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]¶pyrpl.software_modules.network_analyzer.
NaCurveFuture
(module, min_delay_ms, autostart=True)[source]¶Bases: pyrpl.async_utils.PyrplFuture
N_POINT_BENCHMARK
= 100¶pyrpl.software_modules.network_analyzer.
NaPointFuture
(module, point_index, min_delay_ms=0)[source]¶Bases: pyrpl.async_utils.PyrplFuture
Future object for a NetworkAnalyzer point.
pyrpl.software_modules.network_analyzer.
NaRunFuture
(module, min_delay_ms)[source]¶Bases: pyrpl.software_modules.network_analyzer.NaCurveFuture
pyrpl.software_modules.network_analyzer.
NetworkAnalyzer
(parent, name=None)[source]¶Bases: pyrpl.acquisition_module.AcquisitionModule
, pyrpl.modules.SignalModule
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:
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.
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. SeeRunningStateProperty
for available options.
start_freq
¶stop_freq
¶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: |
|
---|---|
Returns: | tf – The complex open loop transfer function of the module. |
Return type: | np.array(.., dtype=np.complex) |
pyrpl.software_modules.pyrpl_config.
PyrplConfig
(parent, name=None)[source]¶Bases: pyrpl.modules.Module
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]
setup
(**kwds)¶text
¶pyrpl.software_modules.software_pid.
RunningProperty
(true_function=None, false_function=None, **kwargs)[source]¶Bases: pyrpl.attributes.LedProperty
false_function
(obj)¶stops the running loop
true_function
(obj)¶starts a new loop
pyrpl.software_modules.software_pid.
SoftwarePidController
(parent, name=None)[source]¶Bases: pyrpl.modules.Module
Setup Attributes:
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
The spectrum analyzer measures the magnitude of an input signal versus frequency. There are two working modes for the spectrum analyzer implemented in pyrpl:
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.
pyrpl.software_modules.spectrum_analyzer.
DecimationProperty
(options=[], **kwargs)[source]¶Bases: pyrpl.attributes.SelectProperty
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.
pyrpl.software_modules.spectrum_analyzer.
RbwProperty
(default=None, doc='', ignore_errors=False, call_setup=False)[source]¶pyrpl.software_modules.spectrum_analyzer.
SpanFilterProperty
(default=None, doc='', ignore_errors=False, call_setup=False)[source]¶pyrpl.software_modules.spectrum_analyzer.
SpecAnAcBandwidth
(default=None, doc='', ignore_errors=False, call_setup=False)[source]¶pyrpl.software_modules.spectrum_analyzer.
SpectrumAnalyzer
(parent, name=None)[source]¶Bases: pyrpl.acquisition_module.AcquisitionModule
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:
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_unit
¶Options – [‘Vpk^2’]
data_length
¶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.
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.
useful_index_obsolete
()[source]¶Returns: | a slice containing the portion of the spectrum between start |
---|
and stop
window
windows
= ['blackman', 'flattop', 'boxcar', 'hamming', 'gaussian']¶pyrpl.software_modules.spectrum_analyzer.
WindowProperty
(options=[], **kwargs)[source]¶Bases: pyrpl.attributes.SelectProperty
Changing the filter window requires to recalculate the bandwidth