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. The plot was generated by example_scope.py, an example distributed on our public GitHub repository. The example runs the Scope Module in both time and frequency mode with scope record averaging enabled.

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. See Scope Data Structures below for detailed information.

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.

Scope Data Structures

The device node /DEV…​./SCOPES/n/WAVE (and /DEV…​./SCOPES/n/STREAM/SAMPLE DIG Option enabled, API level > 4) return the following data structures based on the API level used by the session:

ScopeWave

API Level 1, HF2 only. The simplest scope data structure. The wave structure member in the data structure always has a fixed length of 2048. Scope records are never split into multiple blocks; no assembly required. The HF2 does not support segmented recording; a segment is equivalent to a record.

ZIScopeWave

API Level 4. An extended scope data structure used with MF and UHF instruments. The data in the wave structure member consists of one scope block; for long scope segments, complete scope segments must be assembled by combining these blocks. The data in wave is not scaled or offset.

ZIScopeWaveEx

API Level > 5. As for ZIScopeWave, but contains the additional structure member channelOffset.

The Scope Module always returns scope data in the ZIScopeWaveEx format, regardless of which supported API level (1, >4) was used in the session where the Scope Module was instantiated. However, the data in the wave structure member always consists of complete segments (it does not need to be reassembled from multiple blocks). More differences between the data returned by the node /DEV…​./SCOPES/n/WAVE and the Scope Module are highlighted in Advantages of the Scope Module.

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. zhinst.utils.sigin_autorange() in the LabOne Python API).

  4. 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).

  5. Configure the * parameters as required, in particular:

    • 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.

    • 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.

    • Set averager/weight to a value larger than 1 to enable averaging of scope records, see Averaging.

  6. Enable the scope (if not previously enabled) and call Scope Module execute() to start acquiring data.

  7. 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.

  8. 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.

  9. Check the flags of each record indicating whether any problems occurred during acquisition.

  10. Extract the data for each recorded scope channel and, if recording data in segmented mode, reshape the 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 in ZIScopeWaveEx.

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

Device-specific considerations

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 LabOne API Levels 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 entry for more details. This is not necessary for other instrument classes.

Scope Module Use on MF and UHF Instruments

For MF and UHF instruments no special considerations must be made except that LabOne API Levels 4 is not supported by the Scope Module; a higher API level must be used.

Whilst not specific to the Scope Module, it should be noted that the instrument’s scope is not affected by loading device presets, in particular, default scope settings are not obtained by loading the instrument’s factory preset.

Scope Module Node Tree

The following section contains reference documentation for the settings and measurement data available on the scope module.

Since these settings and data streams may be written and read using the LabOne APIs (Application Programming Interfaces) this section is of particular interest to users who would like to perform measurements programmatically via LabVIEW, Python, MATLAB, .NET or C.

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.

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

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.

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.

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.