Skip to content

Scope Module

The Scope Module corresponds to the functionality available in the Scope tab in the LabOne User Interface and provides API users with an interface to acquire assembled and scaled scope data from the instrument programmatically.

example_scope_module_freq_time_combined
Figure 1: example_scope_module_freq_time_combined

Introduction to Scope Data Transfer

In general, an instrument's scope can generate a large amount of data which requires special treatment by the instrument's firmware, the Data Server, LabOne API and API client in order to process it correctly and efficiently. The Scope Module was introduced in LabOne 16.12 to simplify scope data acquisition for the user. This section provides a top-level overview of how scope data can be acquired and define the terminology used in subsequent sections before looking at the special and more simplified case when the Scope Module is used.

There are three methods of obtaining scope data from the device:

  1. By subscribing directly to the instrument node /DEV..../SCOPES/n/WAVE and using the poll() command. This refers to the lower-level interface provided by the ziDAQServer class subscribe() and poll() commands.
  2. By subscribing to the instrument node /DEV..../SCOPES/n/WAVE in the Scope Module and using using the Scope Module's read() command.
  3. By subscribing to the instrument's scope streaming node /DEV..../SCOPES/n/STREAM/SAMPLE which continuously streams scope data as a block stream. This is only available on MF and UHF instruments with the DIG Option enabled. The Scope Module does not support acquisition from the scope streaming node.

Segmented Mode

Additionally, MF and UHF instruments which have the DIG option enabled can optionally record data in "segmented" mode which allows back-to-back measurements with very small hold-off times between measurements. Segmented mode enables the user to make a fixed number of measurements (the segments), which are stored completely in the memory of the instrument, before they are transferred to the Data Server (this overcomes the data transfer rate limitation of the device's connected physical interface, e.g., USB or 1GbE for a fixed number of measurements). The advantage to this mode is precisely that the hold-off time, i.e. the delay between two measurements, can be very low. Data recorded in segmented mode is still available from the instrument node /DEV..../SCOPES/n/WAVE as for non-segmented data, but requires an additional reshaping described in Segmented Recording.

Scope Data Nomenclature

We'll use the following terminology to describe the scope data streamed from the device:

Wave

The name of the leaf (/DEV..../SCOPES/n/WAVE) in the device node tree that contains scope data pushed from the instrument's firmware to the Data Server. The data structure returned by this node is defined by the API Level of the connected session. It is also the name of the structure member in scope data structures that holds the actual scope data samples.

Record

Refers to one complete scope data element returned by the Scope Module. It may consist of one or multiple segments.

Segment

A segment is a completely assembled and scaled wave. If the instrument's scope is used in segmented mode, each record will consist of multiple segments. If not used in segmented mode, each record comprises of a single segment and the terms record and segment can be used interchangeably.

Block

When the length of data (/DEV..../SCOPES/n/LENGTH) in a scope segment is very large the segment returned by the device node (/DEV..../SCOPES/n/WAVE) is split into multiple blocks. When using the poll/subscribe method the user must assemble these blocks; the Scope Module assembles them for the user into complete segments.

Shot

The term shot is often used when discussing data acquired from laboratory oscilloscopes, we try to avoid it in the following in order to more easily distinguish between records and segments when recording in segmented mode.

Advantages of the Scope Module

Although it is possible to acquire scope data using the lower-level subscribe/poll method, the Scope Module provides API users with several advantages. Specifically, the Scope Module:

  1. Provides a uniform interface to acquire scope data from all instrument classes (HF2 scope usage differs from and MF and UHF devices, especially with regards to scaling).
  2. Scales and offsets the scope wave data to get physically meaningful values. If data is polled from the device node using subscribe/poll the scaling and offset must be applied manually.
  3. Assembles large multi-block transferred scope data into single complete records. When the scope is configured to record large scope lengths and data is directly polled from the device node /DEV.../SCOPES/n/WAVE the data is split into multiple blocks for efficient transfer of data from the Data Server to the API; these must then be programmatically reassembled. The Scope Module performs this assembly and returns complete scope records (unless used in pass-through mode, mode=0).
  4. Can be configured to return the FFT of the acquired scope records (with mode=3) as provided by the Scope Tab in the LabOne UI. FFT data is not available from the device nodes in the /DEV/..../SCOPES/ branch using subscribe/poll.
  5. Can be configured to average the acquired scope records the averager/ parameters.
  6. Can be configured to return a specific number of scope records using the historylength parameter.

Working with Scope Module

It is important to note that the instrument's scope is implemented in the firmware of the instrument itself and most of the parameters relevant to scope data recording are configured as device nodes under the /DEV.../SCOPES/ branch. Please refer to the instrument-specific User Manual for a description of the Scope functionality and a list of the available nodes.

The Scope Module does not modify the instrument's scope configuration and, as such, processes the data arriving from the instrument in a somewhat passive manner. The Scope Module simply reassembles data transferred in multiple blocks into complete segments (so that they consist of the configured /DEV..../SCOPES/n/LENGTH) and applies the offset and scaling required to get physically meaningful values to the (integer) data sent by the instrument.

The following steps should be used as a guideline for a Scope Module work-flow:

  1. Create an instance of the Scope Module. This instance may be re-used for recording data with different instrument settings or Scope Module configurations.
  2. Subscribe in the Scope Module to the scope's streaming block node (/DEV..../SCOPES/n/WAVE) to specify which device and scope to acquire data from. Data will only be acquired after enabling the scope and calling Scope Module execute().
  3. Configure the instrument ready for the experiment. When acquiring data from the signal inputs it is important to specify an appropriate value the for input range (/DEV..../SIGINS/n/RANGE) to obtain the best bit resolution in the scope. The signal input range on MF and UHF instruments can be adjusted automatically, see the /DEV..../SIGINS/n/AUTORANGE node and API utility functions demonstrating its use (e.g. 4zhinst.utils.sigin_autorange() in the LabOne Python API). Configure the instrument's scope as required for the measurement. If recording signals other than hardware channel signals (such as a PID's error or a demodulator R output), be sure to configure the /DEV..../SCOPES/n/CHANNELS/n/LIMIT\{LOWER UPPER} accordingly to obtain the best bit resolution in the scope).
  4. Configure the * parameters as required, in particular:
  5. Set mode in order to specify whether to return time or frequency domain data. See Scope Module Modes for more information on the Scope Module's modes.
  6. Set the historylength parameter to tell the Scope Module to only return a certain number of records. Note, as the Scope Module is acquiring data the records output parameter may grow larger than historylength; the Scope Module will return the last number of records acquired.
  7. Set averager/weight to a value larger than 1 to enable averaging of scope records, see Averaging.
  8. Enable the scope (if not previously enabled) and call Scope Module execute() to start acquiring data.
  9. Wait for the Scope Module to acquire the specified number of records. Note, if certain scope parameters are modified during recording, the history of the Scope Module will be cleared, Scope Parameters that reset the Scope Module for the list of parameters that trigger a Scope Module reset.
  10. Call Scope Module read() to transfer data from the Module to the client. Data may be read out using read() before acquisition is complete (advanced use). Note, an intermediate read will create a copy in the client of the incomplete record which could be critical for memory consumption in the case of very long scope lengths or high segment counts. The data structure returned by read() is of type ZIScopeWaveEx.
  11. Check the flags of each record indicating whether any problems occurred during acquisition.
  12. Extract the data for each recorded scope channel and, if recording data in segmented mode, reshape t4he wave data to allow easier access to multi-segment records (see Segmented Recording) Note, the scope data structure only returns data for enabled scope channels.

Data Acquisition and Transfer Speed

It is important to note that the time to transfer long scope segments from the device to the Data Server can be much longer than the duration of the scope record itself. This is not due to the Scope Module but rather due to the limitation of the physical interface that the device is connected on (USB, 1GbE). Please ensure that the PC being used has adequate memory to hold the scope records.

Scope Module Modes

The mode is applied for all scope channels returned by the Scope Module. Although it is not possible to return both time and frequency domain data in one instance of the Scope Module, multiple instances may be used to obtain both.

The Scope Module does not return an array consisting of the points in time (time mode) or frequencies (FFT mode) corresponding to the samples in ZIScopeWaveEx. These can be constructed as arrays of n points, where n is the configured scope length (/DEV.../SCOPES/n/LENGTH)) spanning the intervals:

Time mode

[0, dt*totalsamples], where dt and totalsamples are fields in ZIScopeWaveEx. In order to get a time array relative to the trigger position, (timestamp - triggertimestamp)/float(clockbase) must be subtracted from the times in the interval, where timestamp and triggerstamp are fields inZIScopeWaveEx

FFT mode

[0, (clockbase/2^scope_time)/2], where scope_time is the value of the device node /DEV..../SCOPES/n/TIME and clockbase is the value of /DEV..../CLOCKBASE.

Averaging

When averager/weight is set to be greater than 1, then each new scope record in the history element is an exponential moving average of all the preceding records since either execute() was called or averager/restart was set to 1. The average is calculated by the Scope Module as following:

alpha = 2/(weight + 1)
newVal = alpha * lastRecord + (1 - alpha) * history
history = newVal

where newVal becomes the last record in the Scope Module's history. If the scope is in Single mode, no averaging is performed. The weight corresponds to the number of segments to achieve 63% settling, doubling the value of weight achieves 86% settling.

It is important to note that the averaging functionality is performed by the Scope Module on the PC where the API client runs, not on the device. Enabling averaging does not mean that less data is sent from the instrument to the Data Server.

The average calculation can be restarted by setting averager/restart to 1. It is currently not possible to tell how many scope segments have been averaged (since the reset). In general, however, the way to track the current scope record is via the sequenceNumber field in ZIScopeWaveEx.

Segmented Recording

When the instrument's scope runs segmented mode the wave structure member in the ZIScopeWaveEx is an array consisting of length*segment_count where length is the value of /DEV..../SCOPES/0/LENGTH and num_segments is /DEV..../SCOPES/n/SEGMENTS/COUNT. This is equal to the value of the totalsamples structure member.

The Scope Module's progress() method can be used to check the progress of the acquisition of a single segmented recording. It is possible to read out intermediate data before the segmented recording has finished. This will however, perform a copy of the data; the user should ensure that adequate memory is available.

If the segment count in the instrument's scope is changed, the Scope Module must be re-executed. It is not possible to read multiple records consisting of different numbers of segments within one Scope Module execution.

Scope Parameters that reset the Scope Module

The Scope Module parameter records and progress are reset and all records are cleared from the Scope Module's history when the following critical instrument scope settings are changed:

  • /DEV.../SCOPES/n/LENGTH
  • /DEV.../SCOPES/n/RATE
  • /DEV.../SCOPES/n/CHANNEL
  • /DEV..../SCOPES/n/SEGMENTS/COUNT
  • /DEV..../SCOPES/n/SEGMENTS/ENABLE

Scope Module Use on HF2 Instruments

The HF2 scope is supported by the Scope Module, in which case the API connects to the HF2 Data Server using API Level 1 (the HF2 Data Server does not support higher levels). When using the Scope Module with HF2 Instruments the parameter externalscaling must be additionally configured based on the currently configured scope signal's input/output hardware range, see the /externalscaling node for more details. This is not necessary for other instrument classes.

Node Documentation

This section describes all the nodes in the Scope Module node tree organized by branch.

averager

/averager/resamplingmode

Properties: Read, Write
Type: Integer (enumerated)
Unit: None

Specifies the resampling mode. When averaging scope data recorded at a low sampling rate that is aligned by a high resolution trigger, scope data must be resampled to keep the corresponding samples between averaged recordings aligned correctly in time relative to the trigger time.

Value Description
0 "linear": Linear interpolation
1 "pchip": PCHIP interpolation
/averager/restart

Properties: Read, Write
Type: Integer (64 bit)
Unit: None

Set to 1 to reset the averager. The module sets averager/restart back to 0 automatically.

/averager/weight

Properties: Read, Write
Type: Integer (64 bit)
Unit: None

Specify the averaging behaviour. weight=0: Averaging disabled. weight>1: Moving average, updating last history entry.

clearhistory

/clearhistory

Properties: Read, Write
Type: Integer (64 bit)
Unit: None

Remove all records from the history list.

error

/error

Properties: Read
Type: Integer (64 bit)
Unit: None

Indicates whether an error occurred whilst processing the current scope record; set to non-zero when a scope flag indicates an error. The value indicates the accumulated error for all the processed segments in the current record and is reset for every new incoming scope record. It corresponds to the status LED in the LabOne User Interface's Scope tab - API users are recommended to use the flags structure member in ZIScopeWaveEx instead of this output parameter.

externalscaling

/externalscaling

Properties: Read, Write
Type: Double
Unit: None

Scaling to apply to the scope data transferred over API level 1 connection. Only relevant for HF2 Instruments.

fft

/fft/power

Properties: Read, Write
Type: Integer (64 bit)
Unit: None

Enable calculation of the power value.

/fft/spectraldensity

Properties: Read, Write
Type: Integer (64 bit)
Unit: None

Enable calculation of the spectral density value.

/fft/window

Properties: Read, Write
Type: Integer (enumerated)
Unit: None

FFT Window

Value Description
0 "rectangular": Rectangular
1 "hann": Hann (default)
2 "hamming": Hamming
3 "blackman_harris": Blackman Harris
16 "exponential": Exponential (ring-down)
17 "cos": Cosine (ring-down)
18 "cos_squared": Cosine squared (ring-down)

historylength

/historylength

Properties: Read, Write
Type: Integer (64 bit)
Unit: None

Maximum number of entries stored in the measurement history.

lastreplace

/lastreplace

Properties: Read, Write
Type: Integer (64 bit)
Unit: None

Reserved for LabOne User Interface use.

mode

/mode

Properties: Read, Write
Type: Integer (enumerated)
Unit: None

The Scope Module's data processing mode.

Value Description
0 "passthrough": Passthrough: scope segments assembled and returned unprocessed, non-interleaved.
1 "exp_moving_average": Moving average: entire scope recording assembled, scaling applied, averager if enabled (see averager/weight), data returned in float non-interleaved format.
2 Reserved for future use (average n segments).
3 "fft": FFT, same as mode 1, except an FFT is applied to every segment of the scope recording before averaging. See the fft/* parameters for FFT parameters.

records

/records

Properties: Read
Type: Integer (64 bit)
Unit: None

The number of scope records that have been processed by the Scope Module since execute() was called or a critical scope setting has been modified (see manual for a list of scope settings that trigger a reset).

save

/save/csvlocale

Properties: Read, Write
Type: String
Unit: None

The locale to use for the decimal point character and digit grouping character for numerical values in CSV files: "C": Dot for the decimal point and no digit grouping (default); "" (empty string): Use the symbols set in the language and region settings of the computer.

/save/csvseparator

Properties: Read, Write
Type: String
Unit: None

The character to use as CSV separator when saving files in this format.

/save/directory

Properties: Read, Write
Type: String
Unit: None

The base directory where files are saved.

/save/fileformat

Properties: Read, Write
Type: Integer (enumerated)
Unit: None

The format of the file for saving data.

Value Description
0 "mat": MATLAB
1 "csv": CSV
2 "zview": ZView (Impedance data only)
3 "sxm": SXM (Image format)
4 "hdf5": HDF5
/save/filename

Properties: Read, Write
Type: String
Unit: None

Defines the sub-directory where files are saved. The actual sub-directory has this name with a sequence count (per save) appended, e.g. daq_000.

/save/save

Properties: Read, Write
Type: Integer (64 bit)
Unit: None

Initiate the saving of data to file. The saving is done in the background. When the save has finished, the module resets this parameter to 0.

/save/saveonread

Properties: Read, Write
Type: Integer (64 bit)
Unit: None

Automatically save the data to file immediately before reading out the data from the module using the read() command. Set this parameter to 1 if you want to save data to file when running the module continuously and performing intermediate reads.