openrri package¶
openrri.daq module¶
- class openrri.daq.DAQFactory¶
Bases:
objectFactory that creates an RRI communication interface for a specific board from an RRI configuration.
- static from_config(rri_config)¶
Create an interface instance from an RRI configuration.
rri_config = { "interface": <interface_config>, "board": <board_config>, } interface_config = { "interface": <interface_type>, # InterfaceType "ip": <ip>, # IP address "port": <port>, # Port (optional) <interface-specific-options> } board_config = { "board": <board_type>, # BoardType "fpga_version": "1.0.a", # RRI IP version "hardware_id": 123, # Hardware ID "adc_base_freq": 125_000_000, # ADC sample rate in Hz (optional) "adc_store_bits": 16, # ADC storage bits (optional) "adc_real_bits": -14, # ADC real bits, negative values signify signed data type (optional) "adc_channel_count": 2, # ADC channel count (optional) "adc_channel_mask": 0x3, # ADC channel mask for available channels (optional) "adc_channel_default": 0x1, # ADC channel mask for default channels (optional) "adc_min_hw_decimation: 1, # ADC minimum hardware decimation factor (optional) "adc_min_sw_decimation: 4, # ADC minimum software decimation factor (optional) "adc_step_sw_decimation: 4, # ADC software decimation factor step size (optional) "adc_max_sw_decimation: 128, # ADC maximum software decimation factor (optional) "adc_zero_scale": -1.0, # ADC zero-scale voltage in V (optional) "adc_full_scale": 1.0, # ADC full-scale voltage in V (optional) "dac_base_freq": 125_000_000, # DAC sample rate in Hz (optional) "dac_store_bits": 16, # DAC storage bits (optional) "dac_real_bits": -14, # DAC real bits, negative values signify signed data type (optional) "dac_channel_count": 2, # DAC channel count (optional) "dac_channel_mask": 0x3, # DAC channel mask for available channels (optional) "dac_channel_default": 0x1, # DAC channel mask for default channels (optional) "dac_channel_caps": [], # List of DAC channel capability masks, one entry per channel (optional) "dac_min_hw_decimation": 1, # DAC minimum hardware decimation factor (optional) "dac_zero_scale": -1.0, # DAC zero-scale voltage in V (optional) "dac_full_scale": 1.0, # DAC full-scale voltage in V (optional) <board-specific-options> }
openrri.daq.board module¶
Board module that contains interface classes to various hardware boards.
- class openrri.daq.board.Board(board_type, board_config, *args, **kwargs)¶
Bases:
objectBoard base class that defines the mandatory interface every board class must implement and provides implementations for common functionality.
Board constructor
- property adc_base_freq¶
ADC sampling frequency in Hz
- property adc_bits¶
ADC (storage) bit-width
- property adc_channel_count¶
Number of ADC channels
- property adc_channel_default¶
Bitmask of default ADC channel configuration
- property adc_channel_mask¶
Bitmask of available ADC channels
- property adc_max_sw_decimation¶
Maximum ADC software decimation factor
- property adc_min_sw_decimation¶
Minimum ADC software decimation factor
- property adc_step_sw_decimation¶
ADC software decimation factor step size
- property board_type¶
Board type of the board object (read-only)
- property dac_base_freq¶
DAC output frequency in Hz
- property dac_bits¶
DAC (storage) bit-width
- property dac_channel_caps¶
DAC channel capabilities (one entry per channel)
- property dac_channel_count¶
Number of DAC channels
- property dac_channel_default¶
Bitmask of default DAC channel configuration
- property dac_channel_mask¶
Bitmask of available DAC channels
- property dac_full_scale¶
DAC full-scale voltage in V
- property dac_zero_scale¶
DAC zero-scale voltage in V
- static from_config(board_config)¶
Construct a board object from configuration data. If a specific
Boardproperty is not set in the configuration, the boards default value for the property is used.board_config = { "board": BoardType.REDPITAYA, ["<board_property>": <property_value>] }
- Parameters:
board_config (dict) – Board configuration
- Returns:
Board object according to board type specified in
board_config
- class openrri.daq.board.BoardType(*values)¶
Bases:
EnumEnum defining supported board types
- ECLYPSE = 3¶
Eclypse Z7
- NUCLEO = 1¶
Nucleo H743ZI (deprecated since v0.4.0, will be removed in v0.5.0)
- REDPITAYA = 2¶
RedPitaya Stemlab 125-14
- class openrri.daq.board.Eclypse(board_config, *args, **kwargs)¶
Bases:
BoardEclypse Z7 board class
Board constructor
- class openrri.daq.board.Nucleo(board_config, *args, **kwargs)¶
Bases:
BoardNUCLEO-H743ZI board class
Warning
This class is deprecated since v0.4.0 and will be removed in v0.5.0.
Deprecated since version 0.4.0: Use
RedPitayawith the WebSocket interface instead. If you need to continue using the Nucleo board, you can do so with OpenRRI up to and including v0.4.0.Board constructor
- class openrri.daq.board.RedPitaya(board_config, *args, **kwargs)¶
Bases:
BoardRedpitaya STEMlab 125-14 board class
Board constructor
- property soldered¶
RedPitaya-specific board setting controlling the DAC zero- (
dac_zero_scale) and full-scale voltages (dac_full_scale). If set toTrue, DAC output voltage range is from 0 to 2.0 V, if set toFalse, the voltage range is from -1.0 to 1.0 V.Note
The
solderedparameter can be set in the board configuration. If, however, configuration values fordac_zero_scaleanddac_full_scaleare also present in the configuration, these take precedence over thesolderedsetting. In this casesolderedwill be reset toNone.Warning
When updating the
solderedproperty of an already configured board, the values fordac_zero_scaleanddac_full_scaleare implicitly updated to the voltage ranges described above!
openrri.daq.dac module¶
Module containing DAC related types
openrri.daq.interface module¶
Module that contains interface classes to various communication protocols used in OpenRRI.
- class openrri.daq.interface.IPv4Interface(interface_type: InterfaceType, ip: str, port: int, *args, **kwargs)¶
Bases:
InterfaceAbstract IPv4 interface
- property timeout: float | None¶
IP connection timeout (optional)
Note
See
socket.socket.settimeout()documentation for more information.
- class openrri.daq.interface.Interface(interface_type: InterfaceType, *args, **kwargs)¶
Bases:
objectAbstract base class. It defines the mandatory interface every interface class must implement.
- direct_output(channel: int, value: float) bool¶
Directly set DAC output voltage of the specified channel to the specified value.
- static from_config(interface_config: dict, **kwargs)¶
Construct an interface object from configuration data. If a specific
Interfaceproperty is not set in the configuration, the interfaces default value for the property is used.interface_config = { "interface": InterfaceType.WEBSOCKET, ["<interface_property>": <property_value>] }
- Parameters:
interface_config (dict) – Board configuration
- Returns:
Interface object according to interface type specified in
interface_config
- get_data_raw(meas_time: float, channels: list) dict¶
Get raw measurement data from specified ADC channels.
Note
get_data_raw()performs a one-shot data transfer. The transferable amount of data is limited by the board’s memory capacity. For boards like the RedPitaya this limit is in the range of a few hundred megabytes. For larger data transfers or continuous data streaming seestream_data_raw().
- get_modulation_status() bool | None¶
Query the current modulation status from the board.
- Returns:
Trueif modulation is active,Falseif inactive,Noneon failure- Return type:
boolean or None
- property interface_type: InterfaceType¶
Interface type of the
Interfaceobject (read-only)
- start_modulation(f_mod: int, v_low: float, v_high: float, phase: float, channels: list | None = None) bool¶
Start RRI modulation with specified parameters.
This function sends a command to start sine wave modulation using specified parameters. It has options to control the frequency, high and low voltages, and the phase of the sine wave.
- Parameters:
f_mod (int) – Frequency of the sine wave modulation in Hertz. Defaults to 20000.
v_low (float) – Low voltage level of the output wave. It determines the minimum voltage level that the sine wave will reach. Defaults to 0.2.
v_high (float) – High voltage level of the output wave. It specifies the maximum voltage level that the sine wave will achieve. Defaults to 0.4.
phase (float) – Phase shift of the sine wave in rad. Defaults to 0 rad.
channels (list of int) – List of DAC channels to use for modulation. Defaults to [1].
- Returns:
Trueon success,Falseon failure- Return type:
boolean
- stop_modulation() bool¶
Stop RRI modulation
- Returns:
Trueon success,Falseon failure- Return type:
boolean
- stream_data_raw(channels: list | None = None, meas_time: float | None = None, handler: StreamHandler = <openrri.daq.stream.handlers.raw.StreamDataCollector object>, timeout: float | None = 10.0) Any¶
Requests a continuous raw data stream from the RRI core and continuously receive data from it.
Note
The size of each sample depends on the boards
adc_bitsproperty.Note
Currently, data streaming is only supported by the
WebSocketinterface.- Parameters:
channels (list) – List of channel indices to acquire data from (optional). If not specified, data is streamed from the first available ADC channel.
meas_time (float) – Measurement time in seconds (optional). If not specified, a continuous data stream is requested.
handler (
StreamHandler) – Stream handler to use for continuous data streaming (optional). Can be used for processing data while streaming. If not specified, the defaultStreamDataCollectorwill be used, that receives measurement data into an array and performs channel demultiplexing once streaming is finished.timeout (float or None) – Receive timeout in seconds (optional). If no data is received within this time, the stream is aborted. Defaults to 10 seconds.
- Returns:
With the default handler a dictionary where each key corresponds to a channel name (
ch_1,ch_2, etc.) and its value is a NumPy array containing the channel’s data in digits.Note
Custom
StreamHandler’s may return entirely different data or none at all.
- class openrri.daq.interface.InterfaceType(*values)¶
Bases:
EnumEnum defining supported communication protocols
- SSH = 1¶
SSH (deprecated since v0.4.0, will be removed in v0.5.0)
- UDP = 2¶
UDP (deprecated since v0.4.0, will be removed in v0.5.0)
- WEBSOCKET = 3¶
Websocket
- class openrri.daq.interface.SSH(ip: str, *args, port: int = 22, username: str = 'alarm', password: str = 'alarm', **kwargs)¶
Bases:
IPv4InterfaceRRI SSH interface
Warning
This class is deprecated since v0.4.0 and will be removed in v0.5.0.
Deprecated since version 0.4.0: Use
WebSocketinstead. If your board does not support the WebSocket interface, you can continue using this class with OpenRRI up to and including v0.4.0.- get_data_raw(meas_time: float, channels: list | None = None) dict¶
Get raw measurement data from specified ADC channels.
Note
get_data_raw()performs a one-shot data transfer. The transferable amount of data is limited by the board’s memory capacity. For boards like the RedPitaya this limit is in the range of a few hundred megabytes. For larger data transfers or continuous data streaming seestream_data_raw().
- start_modulation(f_mod: int, v_low: float, v_high: float, phase: float, channels: list | None = None) bool¶
Start RRI modulation with specified parameters.
This function sends a command to start sine wave modulation using specified parameters. It has options to control the frequency, high and low voltages, and the phase of the sine wave.
- Parameters:
f_mod (int) – Frequency of the sine wave modulation in Hertz. Defaults to 20000.
v_low (float) – Low voltage level of the output wave. It determines the minimum voltage level that the sine wave will reach. Defaults to 0.2.
v_high (float) – High voltage level of the output wave. It specifies the maximum voltage level that the sine wave will achieve. Defaults to 0.4.
phase (float) – Phase shift of the sine wave in rad. Defaults to 0 rad.
channels (list of int) – List of DAC channels to use for modulation. Defaults to [1].
- Returns:
Trueon success,Falseon failure- Return type:
boolean
- class openrri.daq.interface.UDP(ip: str, port: int, *args, **kwargs)¶
Bases:
IPv4InterfaceRRI UDP interface
Note
Right now, this is specific to the implementation of UDP communications with the Nucleo-H743ZI board.
Warning
This class is deprecated since v0.4.0 and will be removed in v0.5.0.
Deprecated since version 0.4.0: Use
WebSocketinstead. If your board does not support the WebSocket interface, you can continue using this class with OpenRRI up to and including v0.4.0.- get_data_raw(meas_time: float, channels: list | None = None) dict¶
Get raw measurement data from specified ADC channels.
Note
get_data_raw()performs a one-shot data transfer. The transferable amount of data is limited by the board’s memory capacity. For boards like the RedPitaya this limit is in the range of a few hundred megabytes. For larger data transfers or continuous data streaming seestream_data_raw().
- class openrri.daq.interface.WebSocket(ip: str, *args, port: int = 8000, wss: bool = False, **kwargs)¶
Bases:
IPv4InterfaceRRI Websocket interface
- direct_output(channel: int, value: float) bool¶
Directly set DAC output voltage of the specified channel to the specified value.
- get_data_raw(meas_time: float, channels: list) dict¶
Get raw measurement data from specified ADC channels.
Note
get_data_raw()performs a one-shot data transfer. The transferable amount of data is limited by the board’s memory capacity. For boards like the RedPitaya this limit is in the range of a few hundred megabytes. For larger data transfers or continuous data streaming seestream_data_raw().
- get_modulation_status() bool | None¶
Query the current modulation status from the board.
- Returns:
Trueif modulation is active,Falseif inactive,Noneon failure- Return type:
boolean or None
- property protocol_prefix: str¶
Websocket protocol prefix (read-only)
wssfor secure,wsfor unsecure Websocket connections
- property sample_rate: int¶
Effective sample rate (read-only) taking both the ADC base frequency and the currently set decimation factor into account.
- Returns:
Effective sample rate in Hz
- Return type:
- start_modulation(f_mod: int, v_low: float, v_high: float, phase: float, channels: list | None = None) bool¶
Start RRI modulation with specified parameters.
This function sends a command to start sine wave modulation using specified parameters. It has options to control the frequency, high and low voltages, and the phase of the sine wave.
- Parameters:
f_mod (int) – Frequency of the sine wave modulation in Hertz. Defaults to 20000.
v_low (float) – Low voltage level of the output wave. It determines the minimum voltage level that the sine wave will reach. Defaults to 0.2.
v_high (float) – High voltage level of the output wave. It specifies the maximum voltage level that the sine wave will achieve. Defaults to 0.4.
phase (float) – Phase shift of the sine wave in rad. Defaults to 0 rad.
channels (list of int) – List of DAC channels to use for modulation. Defaults to [1].
- Returns:
Trueon success,Falseon failure- Return type:
boolean
- stop_modulation() bool¶
Stop RRI modulation
- Returns:
Trueon success,Falseon failure- Return type:
boolean
- stream_data_raw(channels: list | None = None, meas_time: float | None = None, handler: StreamHandler = <openrri.daq.stream.handlers.raw.StreamDataCollector object>, timeout: float | None = 10.0) Any¶
Requests a continuous raw data stream from the RRI core and continuously receive data from it.
Note
The size of each sample depends on the boards
adc_bitsproperty.Note
Currently, data streaming is only supported by the
WebSocketinterface.- Parameters:
channels (list) – List of channel indices to acquire data from (optional). If not specified, data is streamed from the first available ADC channel.
meas_time (float) – Measurement time in seconds (optional). If not specified, a continuous data stream is requested.
handler (
StreamHandler) – Stream handler to use for continuous data streaming (optional). Can be used for processing data while streaming. If not specified, the defaultStreamDataCollectorwill be used, that receives measurement data into an array and performs channel demultiplexing once streaming is finished.timeout (float or None) – Receive timeout in seconds (optional). If no data is received within this time, the stream is aborted. Defaults to 10 seconds.
- Returns:
With the default handler a dictionary where each key corresponds to a channel name (
ch_1,ch_2, etc.) and its value is a NumPy array containing the channel’s data in digits.Note
Custom
StreamHandler’s may return entirely different data or none at all.
openrri.daq.stream module¶
- class openrri.daq.stream.StreamAggregator(block_size: int, sample_size: int)¶
Bases:
objectClass that implements aggregation of streaming data into fixed-sized blocks.
Stream aggregator constructor.
- Parameters:
- aggregate(data: bytes | str) int¶
Aggregate data into
block_sizesized blocks.- Parameters:
data – Input data to be aggregated.
- Returns:
Number of complete data blocks.
- property blocks¶
Number of complete data blocks.
- reset()¶
Resets block aggregation to its initial state discarding any remaining data.
- class openrri.daq.stream.StreamDataCollector¶
Bases:
StreamHandlerSimple stream handler, that collects the entire stream data into
callback_return.Note
This is the default streaming handler, that is being called when using
Interfacedata streaming methods.Warning
This handler collects data into main memory, so the maximum amount of data that can be collected, is limited by available main memory of the system running the data collection. To acquire data in very long-running measurement scenarios, consider using the
StreamFileWriterhandler instead.Example usage:
from openrri.daq import DAQFactory from openrri.daq.stream import StreamDataCollector config = { # set up board/interface config } daq = DAQFactory.from_config(config) data = daq.stream_data_raw(meas_time=10)
- callback(data: numpy.ndarray) None¶
The handler callback that is being called from
Interfacedata streaming methods, like e.g.stream_data_raw()on blocks of received data.Note
The size of the data blocks can be obtained through
block_size.- Parameters:
data – Block of data to operate on
- property callback_return: Any¶
Optional callback return value that is returned by the
Interfacedata streaming methods, like e.g.stream_data_raw().
- class openrri.daq.stream.StreamDataPlot(rri_instance: RRIModule, win_size=1, update_rate_fps=25, fig_size=(8, 5), block_factor=1.0, **kwargs)¶
Bases:
StreamPlotterMixin,StreamRRIHandlerStream handler, that plots acquired raw on a live plot.
Example usage:
from openrri.daq import DAQFactory from openrri.daq.stream import StreamDataPlot config = { # set up board/interface config } daq = DAQFactory.from_config(config) daq.stream_data_raw( meas_time=30, handler=StreamDataPlot(win_size=1000) )
- Parameters:
rri_instance (
RRIModule) – Configured RRI instance used for data stream processingskip_rate (int) – Number of samples to omit from the plot. A
skip_rateof100will plot every 100th sample.win_size (int) – Number of samples to show in the plot before dropping the oldest samples from the view
debug (bool) – Flag that turns on debugging metrics
block_factor (float) – Multiplier applied to the computed block size. Allows use-case specific tuning trading off latency vs. throughput. (Default:
1.0)
- callback(data: numpy.ndarray) None¶
The handler callback that is being called from
Interfacedata streaming methods, like e.g.stream_data_raw()on blocks of received data.Note
The size of the data blocks can be obtained through
block_size.- Parameters:
data – Block of data to operate on
- class openrri.daq.stream.StreamFileWriter(filename: str, mode: str = 'w', rri_instance: RRIModule | None = None, **h5kwargs)¶
Bases:
StreamHandlerStream handler that continuously writes measurement data samples to a file.
For storage the HDF5 file format is used as it allows very flexible data handling, supporting incremental dataset updates needed in a streaming context.
HDF5 files created by
StreamFileWriterhave the following structure:HDF5 "raw.hdf5" { GROUP "/" { GROUP "sample" { ATTRIBUTE "meta" { DATATYPE H5T_STRING { STRSIZE H5T_VARIABLE; STRPAD H5T_STR_NULLTERM; CSET H5T_CSET_UTF8; CTYPE H5T_C_S1; } DATASPACE SCALAR DATA { (0): "{ "daq": { "channels": [1, 2], "block_size": 1048576, "sample_rate": 25000, "mod_freq": 100, "mod_table_length": 250, "block_mod_periods": 4194.304 }, "rri": { "phase_shift": 0, "sigma": 0.05, "harmonics": {...} }}" } } DATASET "ch_1" { DATATYPE H5T_STD_I16LE DATASPACE SIMPLE { ( 2097152 ) / ( H5S_UNLIMITED ) } DATA { (0): -26833, -26856, -26874, -26889, -26920, -26934, -26950, -26958, ... } }, DATASET "ch_2" { DATATYPE H5T_STD_I16LE DATASPACE SIMPLE { ( 2097152 ) / ( H5S_UNLIMITED ) } DATA { (0): -26833, -26856, -26874, -26889, -26920, -26934, -26950, -26958, ... } }, # ... } }}
Note
The
rrimetadata section and the extendeddaqfields (sample_rate,mod_freq,mod_table_length,block_mod_periods) are only present when anrri_instanceis provided.Example usage:
from openrri.daq import DAQFactory from openrri.daq.stream import StreamFileWriter config = { # set up board/interface config } daq = DAQFactory.from_config(config) daq.stream_data_raw(meas_time=30, handler=StreamFileWriter("./stream_data.hdf5"))
- Parameters:
filename (str) – Name of file to write to
mode (str) – File opening mode (as supported by h5py file objects) (Default:
w)rri_instance (
RRIModuleor None) – Configured RRI instance (optional). If provided, RRI metadata is included in the HDF5 file attributes.h5kwargs – Additional keyword arguments passed to
h5py.File()
- callback(data: numpy.ndarray) None¶
The handler callback that is being called from
Interfacedata streaming methods, like e.g.stream_data_raw()on blocks of received data.Note
The size of the data blocks can be obtained through
block_size.- Parameters:
data – Block of data to operate on
- class openrri.daq.stream.StreamPeakWriter(rri_instance: RRIModule, filename: str, dpca_min, dpca_max, dpca_res, sigma=0.05, average=False, threshold=10, mode: str = 'w', **h5kwargs)¶
Bases:
StreamRangeViewStream handler, that performs live peak detection on an RRI range view and writes the results to a file.
For storage the HDF5 file format is used as it allows very flexible data handling, supporting incremental dataset updates needed in a streaming context.
HDF5 files created by
StreamPeakWriterhave the following structure:HDF5 "peaks.hdf5" { GROUP "/" { GROUP "peak" { ATTRIBUTE "meta" { DATATYPE H5T_STRING { STRSIZE H5T_VARIABLE; STRPAD H5T_STR_NULLTERM; CSET H5T_CSET_UTF8; CTYPE H5T_C_S1; } DATASPACE SCALAR DATA { (0): "{ "daq": { "channels": [1], "sample_rate": 3906250, "mod_freq": 15625, "mod_table_length": 250, "block_size": 1048500, "block_mod_periods": 4194.0 }, "rri": { "phase_shift": 128.3, "sigma": 0.0225, "harmonics": {"2": {"amp": 0.02, "phi": -160}} }, "range_view": { "dpca_min": 15, "dpca_max": 80, "dpca_res": 0.1, "sigma": 0.05, "averaging": false, "threshold": 10 }}" } } DATASET "ch_1" { DATATYPE H5T_VLEN { H5T_COMPOUND { H5T_IEEE_F64LE "range"; H5T_IEEE_F64LE "amp"; } } DATASPACE SIMPLE { ( 37 ) / ( H5S_UNLIMITED ) } DATA { (0): ({ # Block 1 23.7941, # range 45.0495 # amp }, { 44.0913, 24.8169 }, { 65.4393, 45.1373 }), (1): ..., # Block 2 } }, DATASET "ch_2" { ... }, ..., } } }
Example usage:
from openrri import rri from openrri.daq import DAQFactory from openrri.daq.stream import StreamPeakWriter config = { # set up board/interface config } daq = DAQFactory.from_config(config) r = rri.RRIModule() # setup RRI # ... daq.stream_data_raw( meas_time=30, handler=StreamPeakWriter(r, "peaks.hdf5", 15, 80, 0.1, 0.05) )
- Parameters:
rri_instance (
RRIModule) – Configured RRI instance used for data stream processingfilename (str) – Name of file to write to
dpca_min (int) – Demodulation phase carrier amplitude minimum
dpca_max (int) – Demodulation phase carrier amplitude maximum
dpca_res (float) – Resolution of the range view
sigma (float) – Window width parameter
average (bool) – Flag that turns on (
True) averaging prior to range view calculation. With averaging enabled, the i-th sample of all modulation periods present in the data block is averaged.threshold (float) – Peak detection threshold in percentage of the maximum
dpca_ampvaluemode (str) – File opening mode (as supported by h5py file objects) (Default:
w)h5kwargs – Additional keyword arguments passed to
h5py.File()
- callback(data: numpy.ndarray) None¶
The handler callback that is being called from
Interfacedata streaming methods, like e.g.stream_data_raw()on blocks of received data.Note
The size of the data blocks can be obtained through
block_size.- Parameters:
data – Block of data to operate on
- class openrri.daq.stream.StreamPhasePlot(rri_instance: RRIModule, skip_rate=1, win_size=2500, debug=False, block_factor=1.0, **kwargs)¶
Bases:
StreamPlotterMixin,StreamRRIHandlerStream handler, that performs live phase demodulation on the data stream and plots the demodulated signal on a live plot.
Example usage:
from openrri import rri from openrri.daq import DAQFactory from openrri.daq.stream import StreamPhasePlot config = { # set up board/interface config } daq = DAQFactory.from_config(config) r = rri.RRIModule() # setup RRI # ... r.enable_stream_processing() daq.stream_data_raw( meas_time=30, handler=StreamPhasePlot(r, skip_rate=100, win_size=20_000) )
- Parameters:
rri_instance (
RRIModule) – Configured RRI instance used for data stream processingskip_rate (int) – Number of samples to omit from the plot. A
skip_rateof100will plot every 100th sample.win_size (int) – Number of samples to show in the plot before dropping the oldest samples from the view
debug (bool) – Flag that turns on debugging metrics
block_factor (float) – Multiplier applied to the computed block size. Allows use-case specific tuning trading off latency vs. throughput. (Default:
1.0)
- callback(data: numpy.ndarray) None¶
The handler callback that is being called from
Interfacedata streaming methods, like e.g.stream_data_raw()on blocks of received data.Note
The size of the data blocks can be obtained through
block_size.- Parameters:
data – Block of data to operate on
- class openrri.daq.stream.StreamPhaseWriter(rri_instance: RRIModule, filename: str, mode: str = 'w', **h5kwargs)¶
Bases:
StreamRRIHandlerStream handler, that performs live phase demodulation on the data stream and writes demodulated data to a file.
For storage the HDF5 file format is used as it allows very flexible data handling, supporting incremental dataset updates needed in a streaming context.
HDF5 files created by
StreamPhaseWriterhave the following structure:HDF5 "phases.hdf5" { GROUP "/" { GROUP "phase" { ATTRIBUTE "meta" { DATATYPE H5T_STRING { STRSIZE H5T_VARIABLE; STRPAD H5T_STR_NULLTERM; CSET H5T_CSET_UTF8; CTYPE H5T_C_S1; } DATASPACE SCALAR DATA { (0): "{ "daq": { "channels": [1], "sample_rate": 3906250, "mod_freq": 15625, "mod_table_length": 250, "block_size": 1048500, "block_mod_periods": 4194.0 }, "rri": { "range_channel": 54.3, "phase_shift": 128.3, "sigma": 0.0225, "harmonics": {"2": {"amp": 0.02, "phi": -160}} }}" } } DATASET "ch_1" { DATATYPE H5T_IEEE_F64LE DATASPACE SIMPLE { ( 16776 ) / ( H5S_UNLIMITED ) } DATA { (0): -2.67886, -1.43542, -3.03692, -2.26877, -4.08405, -2.93873, ... } } } }}
Example usage:
from openrri import rri from openrri.daq import DAQFactory from openrri.daq.stream import StreamPhaseWriter config = { # set up board/interface config } daq = DAQFactory.from_config(config) r = rri.RRIModule() # setup RRI # ... r.enable_stream_processing() daq.stream_data_raw( meas_time=30, handler=StreamPhaseWriter(r, "phases.hdf5") )
- Parameters:
rri_instance (
RRIModule) – Configured RRI instance used for data stream processingfilename (str) – Name of file to write to
mode (str) – File opening mode (as supported by h5py file objects) (Default:
w)h5kwargs – Additional keyword arguments passed to
h5py.File()
- callback(data: numpy.ndarray) None¶
The handler callback that is being called from
Interfacedata streaming methods, like e.g.stream_data_raw()on blocks of received data.Note
The size of the data blocks can be obtained through
block_size.- Parameters:
data – Block of data to operate on
- class openrri.daq.stream.StreamRangeView(rri_instance: RRIModule, dpca_min, dpca_max, dpca_res, sigma=0.05, average=False)¶
Bases:
StreamRRIHandlerStream handler, that performs a live range-view calculation on the data stream.
Note
As one data block of the stream may contain many samples, for performance reasons, only the samples corresponding to the first modulation period are processed by default. In case you want to make use of all sample data present in a block, consider setting parameter
average=True.- Parameters:
rri_instance (
RRIModule) – Configured RRI instance used for data stream processingdpca_min (int) – Demodulation phase carrier amplitude minimum
dpca_max (int) – Demodulation phase carrier amplitude maximum
dpca_res (float) – Resolution of the range view
sigma (float) – Window width parameter
average (bool) – Flag that turns on (
True) averaging prior to range view calculation. With averaging enabled, the i-th sample of all modulation periods present in the data block is averaged.
- callback(data: numpy.ndarray) None¶
The handler callback that is being called from
Interfacedata streaming methods, like e.g.stream_data_raw()on blocks of received data.Note
The size of the data blocks can be obtained through
block_size.- Parameters:
data – Block of data to operate on
- class openrri.daq.stream.StreamRangeViewPlot(rri_instance: RRIModule, dpca_min, dpca_max, dpca_res, sigma=0.05, average=False, debug=False, block_factor=1.0, **kwargs)¶
Bases:
StreamPlotterMixin,StreamRangeViewStream handler, that displays an RRI range view on a live plot.
Note
As one data block of the stream may contain many samples, for performance reasons, only the samples corresponding to the first modulation period are processed by default. In case you want to make use of all sample data present in a block, consider setting parameter
average=True.- Parameters:
rri_instance (
RRIModule) – Configured RRI instance used for data stream processingdpca_min (int) – Demodulation phase carrier amplitude minimum
dpca_max (int) – Demodulation phase carrier amplitude maximum
dpca_res (float) – Resolution of the range view
sigma (float) – Window width parameter
average (bool) – Flag that turns on (
True) averaging prior to range view calculation. With averaging enabled, the i-th sample of all modulation periods present in the data block is averaged.debug (bool) – Flag that turns on debugging metrics
block_factor (float) – Multiplier applied to the computed block size. Allows use-case specific tuning trading off latency vs. throughput. (Default:
1.0)
- callback(data: numpy.ndarray) None¶
The handler callback that is being called from
Interfacedata streaming methods, like e.g.stream_data_raw()on blocks of received data.Note
The size of the data blocks can be obtained through
block_size.- Parameters:
data – Block of data to operate on
openrri.daq.stream.handlers.base module¶
- class openrri.daq.stream.handlers.base.StreamHandler¶
Bases:
objectBase class defining the interface used by all stream handlers.
Stream handlers can be used to continuously process data streamed using one of the data streaming methods, e.g.
stream_data_raw().- callback(data) None¶
The handler callback that is being called from
Interfacedata streaming methods, like e.g.stream_data_raw()on blocks of received data.Note
The size of the data blocks can be obtained through
block_size.- Parameters:
data – Block of data to operate on
- property callback_return: Any¶
Optional callback return value that is returned by the
Interfacedata streaming methods, like e.g.stream_data_raw().
- reset()¶
- class openrri.daq.stream.handlers.base.StreamPlotterMixin¶
Bases:
objectMixin providing the infrastructure for live-plotting of stream data.
- setup_plot(plot_config: dict = None, debug: bool = False)¶
Plot initialization and setup
- Parameters:
plot_config (dict, optional) –
Dictionary of plot configuration settings, the following dictionary definition shows the supported options with their default values:
plot_config = { "title": "", # Plot title (str) "x_label": "", # X-axis label (str) "y_label": "", # Y-axis label (str) "border_color": "black", # Color of the plot area border (str) "border_width": 1.0, # Width of the plot area border (float) "graph_color": "blue", # Color of the graph (str) "graph_linewidth": 1.5, # Width of the plot lines (float) "fig_size": (10, 6), # (Width, Height) of the figure (tuple) }
debug (bool, optional (default:
False)) – Flag that enables (True) or disables (False) debug outputs on the plot.
- update_plot(x: numpy.typing.ArrayLike, y: numpy.typing.ArrayLike, debug_info: dict = None) None¶
Update the plot with new data.
- Parameters:
x (ArrayLike) – x-axis data
y (ArrayLike) – y-axis data
debug_info (dict, optional) –
Dictionary of debug outputs. Dictionary (key, value) pairs are transformed in separate debug output lines of the form:
"<key1>: <value1>" "<key2>: <value2>" ...
openrri.errors module¶
- exception openrri.errors.ModulationNotActiveError¶
Bases:
ExceptionThis exception is raised when a measurement is attempted but modulation is not active on the board.
openrri.helpers module¶
This module provides helper functions for the OpenRRI library.
- openrri.helpers.calc_amp_and_phase(A, B, uA, uB)¶
Calculate the amplitude and phase from given sine and cosine components and their uncertainties.
- Parameters:
- Returns:
A tuple containing: - amp (float): Calculated amplitude - phase (float): Calculated phase in degrees - uamp (float): Uncertainty in the amplitude - uphase (float): Uncertainty in the phase in degrees
- Return type:
- openrri.helpers.channels_to_bitmask(channels)¶
Generate a channel bitmask from a list of channel numbers.
- openrri.helpers.demux_channels(data: numpy.ndarray, channels: list) dict[str, numpy.ndarray]¶
Convert a flat data array to a dictionary containing demultiplexed channel arrays.
- Parameters:
data – Data containing samples of multiple channels
channels – Channel numbers of channels present in data
- Returns:
Dictionary containing demultiplexed channel arrays with keys
ch_<i>(i >= 1).
- openrri.helpers.ensure_alignment(n, align)¶
Ensure that
nis aligned toalign.
- openrri.helpers.find_zero_cross(x, y)¶
Find zero-crossing of a straight line
- Parameters:
x (
numpy.ndarray) – Array of x-coordinatesy (
numpy.ndarray) – Array of y-coordinates corresponding to the x-coordinates supplied inx
- Returns:
x-coordinate of zero-crossing
Note
In case no zero-crossing is found
Noneis returned.- Return type:
float or None
- openrri.helpers.generate_modulation_sine(f_dac, f_mod, v_low, v_high, phase)¶
Generate a sinusoidal modulation signal from a given frequency, phase and voltage range.
- Parameters:
- Returns:
The generated voltage signal with resolution f_dac/f_mod
- Return type:
- openrri.helpers.sine_fit(t, data, mod_freq, max_harmonics=2)¶
Fit a sinusoidal model with harmonics to the provided data.
- Parameters:
t (
numpy.ndarray) – Time arraydata (
numpy.ndarray) – Data array to fit the model tomod_freq (float) – Modulation frequency of the sinusoidal model
max_harmonics (int) – Maximum harmonic to be included in the model, default is 2
- Returns:
Fitted model parameters
- Return type:
lmfit.parameter.Parameters
- openrri.helpers.sine_model(params, t, max_harmonics=2)¶
Generate model of the sinusoidal phase modulation.
- Parameters:
params (
lmfit.parameter.Parameters) – Model parameterst (
numpy.ndarray) – Time arraymax_harmonics (int) – Maximum harmonic to be calculated
- Returns:
Model
- Return type:
- openrri.helpers.sine_residual(params, t, data, eps_data, max_harmonics=2)¶
Generate model of the sinusoidal phase modulation and calculate residuals using data.
- Parameters:
params (
lmfit.parameter.Parameters) – Model parameterst (
numpy.ndarray) – Time arraydata (
numpy.ndarray) – Data arrayeps_data (
numpy.ndarray) – Estimated errors in the data arraymax_harmonics (int) – Maximum harmonic to be calculated
- Returns:
Residuals of the model compared to the data
- Return type:
- openrri.helpers.to_s_digits(signal, vzs, vfs, bits=16)¶
Convert a voltage signal to a signed (twos complement) DAC code in digits.
- openrri.helpers.to_u_digits(signal, vzs, vfs, bits=16)¶
Convert a voltage signal to an unsigned DAC code in digits.
- openrri.helpers.validate_channels(channels, valid_mask, default_mask)¶
Convert a channel list to a channel mask and validate it against a validation mask. If validation fails, return a default mask.
openrri.rri module¶
- class openrri.rri.RRIModule(sample_rate, mod_freq, max_harmonics=2, phase_shift=None, range_channel=None, sigma=0.0225, **kwargs)¶
Bases:
objectRRI class providing RRI signal processing methods.
Constructor for RRI class.
- Parameters:
sample_rate (float) – ADC sample rate in Hz
mod_freq (float) – Modulation frequency in Hz
max_harmonics (int) – Maximum number of harmonics used in non-linearity correction
phase_shift (float) – Phase delay in degrees
range_channel (float) – Demodulation range channel (DPCA) in rad
sigma (float) – Window width parameter, default 0.0225
- property active_window_side¶
Use RRIWindowSide.RIGHT or RRIWindowSide.LEFT to generate a single-sided window
- amplitude_correction(envelope_correction=False)¶
Perform amplitude correction on the provided data (loaded with
load_data())This function selects the ground sine and subtracts it from the signal to perform amplitude correction. While not the optimal method, it works automatically and is generally sufficient for most RRI applications.
Note
If alternative amplitude correction is desired, apply your own method and pass the data to load_data(). For those looking to correct the residual signal envelope, further correction using the Hilbert transform may be implemented additionally.
- Parameters:
envelope_correction (bool) – when set to
True, also applies envelope correction using the Hilbert transform- Returns:
Corrected data array
- Return type:
- calc_map(dpca_min=20, dpca_max=150, dpca_res=1, sigma=0.05, phase_delay_min=80, phase_delay_max=110, phase_delay_res=0.1)¶
Calculate phase delay map.
- Parameters:
dpca_min (int) – demodulation phase carrier amplitude minimum
dpca_max (int) – demodulation phase carrier amplitude maximum
dpca_res (int) – map resolution in dpca axis
sigma (float) – window width parameter
phase_delay_min (int) – phase delay minimum
phase_delay_max (int) – phase delay maximum
phase_delay_res (float) – map resolution in phase delay axis
- Returns:
phase delay range, dpca range, map values
- Return type:
- calc_modulation_parameter(max_harmonic=2, cycles_to_process=10, plot_phase=False)¶
Calculates and prints modulation non-linearity parameters.
- Parameters:
max_harmonic (int) – Maximum harmonic index to calculate. Default is 2, meaning only parameters of the second harmonic are calculated.
cycles_to_process (int) – Number of central modulation cycles of the reconstructed phase fed to the fit algorithm.
plot_phase (bool) – if True, plots the reconstructed and fitted modulation waveform.
- Returns:
Fitted parameters
- Return type:
lmfit.parameter.Parameters
- property carrier¶
Complex demodulation phase carrier (DPC) function (read-only)
- property data¶
Loaded data (read-only)
- property data_length¶
Length of loaded data (read-only)
- property data_periods¶
Length of loaded data as multiple of the modulation period length (read-only)
- demodulate_phase(flt_zero_phase=False, check_velocity=True)¶
Demodulate phase at the range channel (demodulation phase carrier amplitude) specified in property
range_channel. The value of propertysigmais used as window width parameter for the window function used during demodulation.- Parameters:
flt_zero_phase (bool) – If set to
Trueapply the digital lowpass filter forward and backward to the signal resulting in zero phase delay of the filtered, complex quadrature signal.check_velocity (bool) – If set to
Truecheck whether the demodulated phase is close to the maximum velocity limit and prints a warning if so.
- Returns:
Phase
- Return type:
- disable_stream_processing()¶
Disable RRI streaming mode.
Disabling streaming mode causes the filter used in the demodulation step to operate on default initial conditions and to discard its internal state after application. Disabling streaming mode also discards the internal phase unwrapping state.
- enable_stream_processing(lowpass_filter_state=None)¶
Enable streaming mode and optionally set the initial values for the internal state of the RRI lowpass filter.
The internal state of the filter is preserved between invocations of the demodulation step allowing for filtering of a continuous data stream.
- Parameters:
lowpass_filter_state (array_like) –
Initial conditions for the cascaded filter delays. The default value of
Noneinitializes the filter state to all zeroes.Note
For further information refer to the SciPy documentation for
scipy.signal.sosfilt().
- classmethod from_hdf5(file: h5py.File) RRIModule¶
Create an
RRIModuleinstance from the metadata embedded in a HDF5 measurement file.The following HDF5 groups are searched for a
metaattribute, in order:phase,peak,sample. The first one found is used.import h5py from openrri.rri import RRIModule with h5py.File("phases.hdf5", "r") as f: rri = RRIModule.from_hdf5(f) data = f["phase"]["ch_1"][:] # ...
- Parameters:
file (
h5py.File) – Open HDF5 measurement file containing RRI metadata- Returns:
Configured RRIModule instance
- Return type:
- Raises:
KeyError – If the file contains no recognisable RRI metadata
ValueError – If required RRI parameters are missing from the metadata
- get_harmonic(n)¶
Return amplitude and phase of the n-th harmonic.
- get_harmonics()¶
Return all configured harmonics as a JSON-serializable dictionary.
- Returns:
Harmonics mapping
{"<n>": {"amp": amplitude, "phi": phase}}- Return type:
- get_limits_info(wavelength=1.55e-06, k=2)¶
Calculate and print the maximum limits of DPCA (range channel) and velocity that can be resolved with the specified RRI parameters and wavelength.
- get_peak_positions(dpca_range=None, dpca_amp=None, threshold=10)¶
Calculate peak positions.
All range dependency values below the threshold, where threshold is defined as percentages of maximum amplitude, are set to
Noneto avoid calculation of noise peaks.If range dependency is not given to function, it will call
get_range_view()to calculate the dependency.- Parameters:
dpca_range (
numpy.ndarray) – DPCA values for whichdpca_ampis calculateddpca_amp (
numpy.ndarray) – range dependencythreshold (float) – threshold in percentage of the maximum
dpca_ampvalue
- Returns:
peak positions
- Return type:
- get_range_view(dpca_min=1, dpca_max=150, res=1, sigma=0.05)¶
Calculate range view from
dpca_mintodpca_maxwith resolutionres.- Parameters:
- Returns:
demodulation phase carrier amplitude, range dependency
- Return type:
- property harm_amp¶
Amplitude of the first harmonic of frequency modulation
Deprecated since version 0.3.0: Use
get_harmonic()andset_harmonic()instead.
- property harm_phase¶
Phase shift of the first harmonic of frequency modulation in degrees
Deprecated since version 0.3.0: Use
get_harmonic()andset_harmonic()instead.
- property is_stream_processing_active¶
Indicates if RRI streaming mode is enabled (read-only)
- load_data(data_array)¶
Load data array in class instance variable for further processing.
Note
As data is processed in
mod_table_length-sized chunks excess samples exceeding an integer multiple of the chunk size are not considered for processing.- Parameters:
data_array (
numpy.ndarray) – Data array
- property lowpass_state¶
Internal state of the RRI lowpass filter (read-only)
- property mod_freq¶
Frequency of the main fast high amplitude modulation (read-only; set at construction time)
- property mod_table_length¶
Table length of the modulation output (read-only)
- property phase_shift¶
Phase delay
- property range_channel¶
Demodulation range channel (demodulation phase carrier amplitude)
- property sample_rate¶
Data sample rate (read-only; set at construction time)
- set_harmonic(n, amp, ph)¶
Set amplitude and phase of the n-th harmonic.
- property sigma¶
Window width parameter of demodulation window function
- property window¶
Gaussian window function (read-only)