RigolWFM Package

Package Root

RigolWFM Package

Utilities for reading oscilloscope waveform files.

RigolWFM started with Rigol .wfm support and now includes normalized parsers for Rigol, Tektronix, LeCroy, Agilent / Keysight, Siglent, Yokogawa, and Rohde & Schwarz waveform exports.

For full documentation see <https://RigolWFM.readthedocs.io>

Example:

>>> import matplotlib.pyplot as plt
>>> from RigolWFM import Wfm
>>> w = Wfm.from_file('example.wfm')
>>> w.plot()
>>> plt.show()

Info waveform class:

>>> from RigolWFM import Wfm
>>> help(Wfm)

Info about channel class:

>>> from RigolWFM import Channel
>>> help(Channel)

Scope family aliases:

>>> from RigolWFM import DS4000_scopes
>>> print(DS4000_scopes)

Much of the binary parsing code is auto-generated by kaitai-struct-compiler from .ksy schemas. Handwritten adapter modules normalize those low-level parsers into the common Wfm and Channel interfaces.

Functions

detect_model(filename)

Detect the oscilloscope model from a waveform file's binary signature.

valid_scope_list()

List all supported oscilloscope model strings.

Classes

Wfm(file_name)

Class with parsed data from a waveform file.

Channel(w, channel_number, scope[, selected])

Base class for a single channel.

Core Interfaces

RigolWFM.channel Module

Class structure and methods for an oscilloscope channel.

The idea is to collect all the relevant information from all the Rigol scope waveforms into a single structure that can be handled in a uniform and consistent manner.

Specifically this lets one do:

channel.times   : numpy array of signal times
channel.volts   : numpy array of signal voltages

or the stringification method to describe a channel:

print(channel)

Functions

best_scale(number)

Scale and units for a number with proper prefix.

engineering_string(number, n_digits)

Format number with proper prefix.

Classes

UnitEnum(*values)

Enumerated units for scopes without them.

Channel(w, channel_number, scope[, selected])

Base class for a single channel.

RigolWFM.wfm Module

Parse and convert oscilloscope waveform files.

Supports Rigol (DS1000B/C/D/E/Z, DS2000, DS4000, DS6000, MSO5000, MSO5074, MSO7000/8000, DHO800/DHO1000), Agilent / Keysight (AGxx .bin), Siglent (.bin waveform revisions), Rohde & Schwarz RTP (.bin + .Wfm.bin), Teledyne LeCroy (.trc), Tektronix (.wfm/.isf), and Yokogawa (.wfm) scope families via Wfm.from_file().

Example

>>> import RigolWFM.wfm as wfm
>>> waveform = wfm.Wfm.from_file("file_name.wfm")
>>> description = waveform.describe()
>>> print(description)

Functions

detect_model(filename)

Detect the oscilloscope model from a waveform file's binary signature.

dho_from_file(file_name)

Backward-compatible wrapper around RigolWFM.dho.from_file().

valid_scope_list()

List all supported oscilloscope model strings.

Classes

Channel_Not_In_WFM_Error

The channel is not in the .wfm file.

Invalid_URL

URL scheme is not http or https.

Parse_WFM_Error

Generic Parse Error.

Read_WFM_Error

Generic Read Error.

Unknown_Scope_Error

Not one of the listed oscilloscope models.

Wfm(file_name)

Class with parsed data from a waveform file.

Write_WAV_Error

Something went wrong while writing the .wave file.

RigolWFM.wfmconvert Module

Command line utility to convert oscilloscope waveform files.

Examples:

prompt> wfmconvert info DS1102E-A.wfm

prompt> wfmconvert csv DS1102E-A.wfm

prompt> wfmconvert wav DS1102E-A.wfm

Functions

csv(args, scope_data, infile)

Create a file with comma separated values.

info(_args, scope_data, _infile)

Print a text summary describing a waveform file.

main()

Parse console command line arguments.

mat(args, scope_data, infile)

Create a MATLAB .mat file.

npz(args, scope_data, infile)

Create a NumPy .npz archive.

png(args, scope_data, infile)

Save a PNG plot of the waveform.

sigrok(args, scope_data, infile)

Create a Sigrok (.sr) file.

wav(args, scope_data, infile)

Create an audible .wav file for use in LTspice.

Rigol Family Helpers

RigolWFM.rigol Module

Rigol-specific scope lists, trigger helpers, and file-parser dispatch.

This module owns everything that is unique to Rigol oscilloscope families: the model-string lists used for dispatch, the trigger-metadata helpers, and the parse_file() entry-point that wfm.Wfm.from_file() delegates to for all Rigol families.

Non-Rigol vendors (LeCroy, Tektronix) are handled directly in wfm.py.

Functions

describe_trigger_block(d[, indent])

Format a trigger info dict as indented text.

dho_from_file(file_name)

Backward-compatible wrapper around RigolWFM.dho.from_file().

parse_file(umodel, file_name)

Parse a Rigol waveform file and return normalised metadata.

RigolWFM.dho Module

Adapter layer for Rigol DHO800/DHO1000 waveform files.

This module is the handwritten bridge between the generated DHO parsers and the rest of RigolWFM. It normalizes both DHO .bin and proprietary DHO .wfm inputs into the header/data shape expected by RigolWFM.wfm.Wfm and RigolWFM.channel.

The generated Kaitai modules are intentionally not called directly by RigolWFM.wfm.Wfm.from_file():

  • RigolWFM.rigol_dho800_1000_bin only knows the official DHO .bin export format. It parses per-channel float32 sample buffers, but it does not produce the common header.ch, header.channel_data, header.raw_data, header.model_number structure used by the rest of the project.

  • RigolWFM.rigol_dho800_1000_wfm only knows the low-level proprietary .wfm block layout. It is still not a complete project-level waveform reader because DHO .wfm files need runtime work after the Kaitai parse: decompress block payloads, scan past the zero-padding region, locate the sample header, de-interleave channel data, and apply per-channel calibration.

If wfm.py called either generated module directly, all of that DHO-specific normalization logic would leak back into wfm.py or channel.py, and callers would have to care whether the source file was .bin or .wfm. Keeping the adapter in dho.py lets the generated files stay generated, keeps the handwritten DHO interpretation in one place, and gives the rest of the project one stable DHO entry point.

Functions

dho_from_file(file_name)

Backward-compatible alias for older callers of the DHO adapter.

family_label(model, *[, is_bin, fallback])

Return a user-facing DHO family label.

from_file(file_name)

Parse and normalize either DHO .bin or .wfm input.

is_bin_file(file_name)

Public wrapper used by higher-level display code.

Classes

ChannelHeader(name, enabled[, unit_code])

Normalized per-channel metadata for DHO captures.

CouplingEnum(*values)

Coupling modes used by DHO waveforms.

DhoWaveform()

Normalized DHO parser result consumed by Channel.

Header()

Normalized header used by Wfm.from_file() for DHO captures.

UnitEnum(*values)

Unit types used by DHO waveforms.

RigolWFM.mso5000 Module

Adapter layer for Rigol MSO5000-family binary waveform exports.

RigolWFM.rigol_mso5000_bin is the generated low-level Kaitai parser for the exported .bin container, but the rest of RigolWFM expects a normalized object with fixed analog channel slots, common timing fields, and decoded sample arrays.

This module performs that normalization for standard RG01 captures, including analog float32 records and logic-analyzer records such as the checked-in MSO5074-C.bin fixture.

Functions

from_file(file_name)

Parse a Rigol MSO5000 .bin file and normalize it for Wfm.from_file().

Classes

ChannelHeader(name, enabled[, unit_code])

Normalized per-channel metadata for MSO5000 captures.

Header()

Normalized header used by Wfm.from_file() for MSO5000 captures.

Mso5000Waveform()

Normalized MSO5000 parser result consumed by Channel.

UnitEnum(*values)

Unit types used by MSO5000 waveform exports.

RigolWFM.mso5074 Module

Adapter layer for Rigol MSO5074 binary waveform exports.

The MSO5074 firmware writes a non-standard variant of the MSO5000 .bin format with several bugs:

  • The waveform header is 144 bytes (not the standard 140).

  • Nearly all metadata fields contain wrong/default values:

    file_size = 4168 (always) n_waveforms = 1 (always, even for multi-channel captures) n_pts = 1000 (always) x_increment = 1e-12 (always) buffer_size = 4000 (always) bytes_per_point = 4 (always, but data is actually uint8) waveform_label = “” (always empty)

  • Sample data is raw uint8 ADC counts, not calibrated float32 volts.

  • Multi-channel captures are stored as concatenated RG01 blocks in a single file. The channel order matches the physical channel order (CH1 first).

This adapter corrects for all of the above. Voltage values are expressed in approximate volts using a default 1 V/div scale because the file contains no calibration coefficients.

Functions

from_file(file_name)

Parse a Rigol MSO5074 .bin file and normalize it for Wfm.from_file().

RigolWFM.mso7000_8000 Module

Adapter layer for Rigol MSO7000/DS7000 and MSO8000 binary waveform exports.

RigolWFM.rigol_7000_8000_bin is the generated low-level Kaitai parser for the UltraVision .bin container documented in the 7000 and 8000 manuals, but the rest of RigolWFM expects a normalized object with fixed channel slots, common timing fields, and calibrated sample arrays.

This module performs that normalization for analog float32 records. Logic and other non-analog buffers are detected and rejected explicitly until we have checked-in fixtures that exercise those paths.

The 7000/8000 binary container is structurally identical to the MSO5000 one. Shared helper types (ChannelHeader, Header, _channel_slot, etc.) are imported from RigolWFM.mso5000 rather than duplicated here.

Functions

from_file(file_name)

Parse a Rigol 7000/8000 .bin file and normalize it for Wfm.from_file().

Classes

Mso7000_8000Waveform()

Normalized parser result consumed by Channel.

Vendor Adapters

RigolWFM.agilent Module

Adapter layer for Agilent / Keysight oscilloscope binary waveform exports.

This module bridges the generated agilent_agxx_bin Kaitai parser and the rest of RigolWFM. The container layout is described by the checked-in vendor parsers, the wavebin sample corpus, and the Agilent 6000 / InfiniiVision 2000 manuals.

The AGxx file family stores one or more waveform records in a simple binary container. Analog traces are already calibrated and stored as float32 sample arrays. Peak Detect captures can store multiple analog buffers per waveform header, and segmented-memory captures can repeat the same channel label for multiple segments.

Functions

from_file(file_name)

Parse an Agilent / Keysight AGxx .bin file and normalize it.

Classes

AgilentWaveform()

Normalized parser result consumed by RigolWFM.channel.Channel.

Header()

Normalized header used by Wfm.from_file() for AGxx captures.

RigolWFM.siglent Module

Adapter layer for Siglent oscilloscope binary waveform exports.

Siglent’s documented .bin formats span several distinct revisions:

  • Old Platform: SDS1000X / SDS2000X

  • V0.1

  • V0.2

  • V1.0

  • V2.0

  • V3.0

  • V4.0

  • V5.0

  • V6.0

This module provides two pieces:

  1. Revision detection and low-level parser dispatch for all documented revisions.

  2. Normalized waveform loading for the revisions whose voltage/time conversion rules are documented unambiguously enough for Wfm.from_file().

The old-platform format is exposed at the low-level Kaitai layer but is not normalized here because the Siglent PDF leaves family-dependent scale constants ambiguous between SDS1000X and SDS2000X captures.

Functions

detect_revision(file_name)

Detect the documented Siglent waveform revision from a file.

detect_revision_from_bytes(data, file_size)

Detect the documented Siglent waveform revision from a file prefix.

from_file(file_name[, model_hint])

Parse a Siglent waveform .bin file and normalize supported revisions.

parse_low_level(file_name)

Parse a Siglent waveform file into its revision-specific Kaitai object.

Classes

ChannelHeader(name, enabled)

Normalized per-channel metadata for a Siglent capture.

Header()

Normalized header used by Wfm.from_file() for Siglent captures.

SiglentWaveform()

Normalized Siglent parser result consumed by RigolWFM.channel.Channel.

RigolWFM.lecroy Module

Adapter layer for Teledyne LeCroy oscilloscope waveform files (.trc).

This module bridges the generated LeCroy KSY parsers and the rest of RigolWFM. It normalises the binary data into the header/data shape expected by RigolWFM.wfm.Wfm and RigolWFM.channel.

Two template versions are supported:

LECROY_2_3 (346-byte WAVEDESC):

ksy/lecroy_2_3_le_trc.ksy → RigolWFM/lecroy_2_3_le_trc.py (LOFIRST / LE) ksy/lecroy_2_3_be_trc.ksy → RigolWFM/lecroy_2_3_be_trc.py (HIFIRST / BE)

LECROY_1_0 (320-byte WAVEDESC, older format):

ksy/lecroy_1_0_le_trc.ksy → RigolWFM/lecroy_1_0_le_trc.py (LOFIRST / LE) ksy/lecroy_1_0_be_trc.ksy → RigolWFM/lecroy_1_0_be_trc.py (HIFIRST / BE)

SCPI prefix

Files transferred via GPIB/SCPI may carry an IEEE 488.2 block-data prefix of the form #N<N digits of byte count> before the WAVEDESC marker. This module searches for WAVEDESC and strips any such prefix before handing the bytes to the KSY parser.

Endianness detection

COMM_ORDER is a u2 at offset 34 inside the WAVEDESC block. The low byte at that position is 0 for big-endian (HIFIRST) and 1 for little-endian (LOFIRST).

LECROY_1_0 calibration:

volts[i] = VERTICAL_GAIN * adc[i] - ACQ_VERT_OFFSET

LECROY_2_3 calibration:

volts[i] = VERTICAL_GAIN * adc[i] - VERTICAL_OFFSET

Time axis (both versions):

t[i] = HORIZ_OFFSET + i * HORIZ_INTERVAL (i = 0 … WAVE_ARRAY_COUNT − 1)

Functions

from_file(file_name)

Parse a LeCroy .trc file and normalize it for Wfm.from_file().

Classes

ChannelHeader(name, enabled)

Normalized per-channel metadata for a LeCroy .trc capture.

Header()

Normalized header used by Wfm.from_file() for LeCroy .trc captures.

LeCroyWaveform()

Normalized LeCroy parser result consumed by Channel.

RigolWFM.tek Module

Adapter layer for Tektronix oscilloscope waveform files (.wfm).

Normalises the parsed KSY data into the header/data shape expected by RigolWFM.wfm.Wfm and RigolWFM.channel.

Two format versions are supported:

WFM#001 (TDS6000/B/C, TDS/CSA7000/B):

ksy/tektronix_wfm_001_le_wfm.ksy → RigolWFM/tektronix_wfm_001_le_wfm.py (LE) ksy/tektronix_wfm_001_be_wfm.ksy → RigolWFM/tektronix_wfm_001_be_wfm.py (BE)

WFM#002/003 (TDS5000B, DPO7000, DPO70000, DSA70000):

ksy/tektronix_wfm_002_le_wfm.ksy → RigolWFM/tektronix_wfm_002_le_wfm.py (LE) ksy/tektronix_wfm_002_be_wfm.ksy → RigolWFM/tektronix_wfm_002_be_wfm.py (BE)

Endianness detection

byte_order at offset 0 of the file is 0x0F0F for little-endian (Intel) and 0xF0F0 for big-endian (PPC).

Version detection

version_number at offset 2 is “WFM#001”, “WFM#002”, or “WFM#003”.

Voltage calibration

volts[i] = exp_dim1.dim_scale * adc[i] + exp_dim1.dim_offset

Time axis

t[i] = imp_dim1.dim_offset + i * imp_dim1.dim_scale

where i = 0 is the first sample in the curve buffer and valid user data starts at curve.first_valid_sample.

Functions

from_file(file_name)

Parse a Tektronix .wfm file and normalize it for Wfm.from_file().

Classes

ChannelHeader(name, enabled)

Normalized per-channel metadata for a Tektronix .wfm capture.

Header()

Normalized header used by Wfm.from_file() for Tektronix .wfm captures.

TekWaveform()

Normalized Tektronix parser result consumed by Channel.

RigolWFM.isf Module

Adapter layer for Tektronix ISF (Internal Save Format) oscilloscope files (.isf).

Normalises the parsed KSY data into the header/data shape expected by RigolWFM.wfm.Wfm and RigolWFM.channel.

File structure

<text_header> ‘#’ <n_digits> <byte_count_str> <curve_data>

The text header is a semicolon-delimited sequence of KEY VALUE pairs. Field names appear in a long form (older firmware) or short form (newer firmware):

Long form: BYT_NR, BIT_NR, ENCDG, BN_FMT, BYT_OR, WFID, NR_PT,

PT_FMT, XUNIT, XINCR, XZERO, PT_OFF, YUNIT, YMULT, YOFF, YZERO

Short form: BYT_N, BIT_N, ENC, BN_F, BYT_O, WFI, NR_P,

PT_F, XUN, XIN, XZE, PT_O, YUN, YMU, YOF, YZE

Voltage calibration

volts[i] = YZERO + YMULT * (adc[i] - YOFF)

Time axis (PT_FMT = “Y”)

t[i] = XZERO + XINCR * (i - PT_OFF) (i = 0 … NR_PT-1)

Envelope mode (PT_FMT = “ENV”)

sample_count = NR_PT / 2 adc_min[i] = adc[2*i] adc_max[i] = adc[2*i + 1] t[i] = XZERO + XINCR * (2*i - PT_OFF)

Functions

from_file(file_name)

Parse a Tektronix ISF file and normalize it for Wfm.from_file().

Classes

ChannelHeader(name, enabled)

Normalized per-channel metadata for a Tektronix ISF capture.

Header()

Normalized header used by Wfm.from_file() for Tektronix ISF captures.

IsfWaveform()

Normalized ISF parser result consumed by Channel.

RigolWFM.rohde_schwarz Module

Adapter layer for Rohde & Schwarz RTP oscilloscope waveform exports.

R&S oscilloscopes represented by the checked-in vendor parsers save waveform captures as an XML metadata file with a .bin extension plus a sibling .Wfm.bin payload file containing the sample bytes. The low-level Kaitai schema only describes the binary payload header and bytes; this module combines that payload with the XML metadata and normalizes single-acquisition analog captures into the existing Wfm / Channel interfaces.

Functions

from_file(file_name)

Parse an R&S RTP XML .bin file and normalize a single-acquisition capture.

Classes

Header()

Normalized header used by Wfm.from_file() for R&S RTP captures.

RohdeSchwarzWaveform()

Normalized parser result consumed by RigolWFM.channel.Channel.

RigolWFM.yokogawa Module

Adapter layer for Yokogawa ASCII-header waveform files (.wfm).

This parser matches the single-file Yokogawa import path used by the vendor MATLAB readers in docs/vendors/SMASHtoolbox: an ASCII header at the start of the file followed by a packed binary sample array.

The second text line contains a whitespace-prefixed, comma-delimited set of KEY:VALUE pairs. The vendor reader uses the following fields:

NR_PT - number of points PT_O - trigger point offset XIN - seconds per point YMU - vertical scale factor YOF - vertical offset BIT - sample width in bits BYT - sample width in bytes

Voltage calibration:

volts[i] = YOF + YMU * raw[i]

Time axis:

t[i] = XIN * (i - PT_O)

The MATLAB implementation reads the binary payload as 32-bit floats. This adapter mirrors that behavior and currently supports only BIT=32 and BYT=4 captures.

Functions

from_file(file_name)

Parse a Yokogawa single-file .wfm capture and normalize it.

Classes

ChannelHeader(name, enabled)

Normalized per-channel metadata for a Yokogawa .wfm capture.

Header()

Normalized header used by Wfm.from_file() for Yokogawa .wfm captures.

YokogawaWaveform()

Normalized Yokogawa parser result consumed by Channel.

RigolWFM.yokogawa_hdr Module

Parser for Yokogawa DL/WE-series oscilloscope .hdr companion metadata files.

The Yokogawa DL/WE-series oscilloscopes produce a two-file waveform package:

<name>.hdr — this file: ASCII text key/value metadata <name>.wvf — companion flat binary sample data

This module parses the .hdr file into a structured HdrInfo object that supplies every parameter needed to read and calibrate the .wvf binary data (byte order, data layout, per-trace calibration, time axis, etc.).

Typical usage:

from RigolWFM.yokogawa_hdr import parse_hdr, wvf_byte_offset

hdr = parse_hdr("capture.hdr")
print(hdr.model, hdr.endian, hdr.data_format)

g, t, b = 0, 0, 0                      # group, trace, block indices (0-origin)
trace = hdr.groups[g].traces[t]
off = wvf_byte_offset(hdr, g, t, b)    # byte offset into .wvf file
dtype = hdr.byte_order + trace.v_data_type.numpy_dtype
Calibration:

volts[i] = v_resolution * raw[i] + v_offset

Time axis (0-origin sample index i):

t[i] = h_offset + h_resolution * i

References

Yokogawa Electric Corporation, IM 707713-61E (WVF File Access Toolkit). Yokogawa DL1640 User Manual, Appendix 3. Erik Benkler, “wvfread v1.7”, Physikalisch-Technische Bundesanstalt, 2011.

Functions

from_hdr_file(path)

Parse a Yokogawa .hdr file and load the companion .wvf binary.

parse_hdr(path)

Parse a Yokogawa .hdr file and return a structured HdrInfo.

parse_hdr_text(text)

Parse .hdr content already loaded as a string.

wvf_byte_offset(hdr, group, trace, block)

Return the byte offset of a (group, trace, block) slice in the .wvf file.

Classes

GroupInfo(trace_number, block_number, traces)

Per-group metadata (one $Group<N> section).

HdrInfo(format_version, model, endian, ...)

Complete parsed contents of a Yokogawa .hdr metadata file.

TraceInfo(name, block_size, v_resolution, ...)

Per-trace metadata within one group.

VDataTypeInfo(raw, byte_num, numpy_dtype, ...)

Decoded vertical data type for one trace (from the VDataType .hdr field).

YokogawaWvfHeader(hdr, channel_data, raw_data)

Normalized header for a Yokogawa .hdr+.wvf pair consumed by channel.Channel.

YokogawaWvfWaveform(header)

Normalized Yokogawa .hdr+.wvf parser result consumed by channel.Channel.

RigolWFM.yokogawa_wdf Module

Convert Yokogawa DL850/DL850V .WDF files to .hdr + .wvf pairs.

Status: Not implemented.

The DL850 WDF format is a proprietary binary format whose structure is not publicly documented. Yokogawa’s only published interface is DL850.dll, a Windows-only shared library described in IM B8074XP-01EN. Because that DLL is Windows-only and not redistributable, this module currently raises NotImplementedError for all operations.

If the binary layout of .WDF files is ever reverse-engineered or officially documented, this module is the intended home for a platform-independent parser and the .hdr + .wvf writer.

Output format goal

The target .hdr / .wvf pair follows the WVF File Access Toolkit format (IM 707713-61E), which is already parsed by yokogawa_dl_we_wvf.ksy:

$PublicInfo
FormatVersion 1.11
Model DL850
Endian Ltl
DataFormat TRACE
GroupNumber 1
TraceTotalNumber <N>
DataOffset 0

$Group1
TraceNumber <N>
BlockNumber <B>

TraceName    CH1 CH2 ...
BlockSize    <S> <S> ...
VResolution  <r> <r> ...
VOffset      <o> <o> ...
VDataType    IS2 IS2 ...
VUnit        V   V   ...
...

The .wvf file contains raw little-endian 16-bit samples (IS2/IU2 per trace) in TRACE layout (all history blocks of each trace written contiguously), with no leading padding (DataOffset = 0).

References

Yokogawa Electric Corporation, “Model DL850/DL850V WDF File Access Library User’s Manual”, IM B8074XP-01EN, 1st Edition, 2010.

Functions

wdf_to_wvf(wdf_path[, output_dir, block_index])

Convert a Yokogawa DL850 .WDF file to a .hdr + .wvf pair.