Exporting Waveforms as MATLAB MAT Files

Scott Prahl

Apr 2026

[1]:
%config InlineBackend.figure_format = 'retina'

import os
import shutil
import subprocess
import tempfile
from pathlib import Path

from RigolWFM import Wfm

repo = "https://raw.githubusercontent.com/scottprahl/RigolWFM/main/tests/files/"


def sample_url(relative_path: str) -> str:
    return repo + relative_path


OCTAVE = shutil.which("octave")
OCTAVE
[1]:
'/opt/homebrew/bin/octave'

Introduction

RigolWFM can export parsed waveforms as MATLAB v5 .mat files. The file contains time, start, increment, and one array per channel, so it can be loaded directly in MATLAB or GNU Octave.

This notebook exports a two-channel analog waveform and then demonstrates a simple Octave workflow.

MAT Export From an Analog Capture

We will export a DS1102E waveform to a MATLAB .mat file.

[2]:
analog = Wfm.from_url(sample_url("wfm/DS1102E-D.wfm"))
print(analog.describe())
    General:
        File Model   = DS1000E
        User Model   = auto
        Parser Model = wfm1000e
        Firmware     = unknown
        Filename     = DS1102E-D.wfm
        Channels     = [1, 2]

    Trigger:
        Mode     = edge
        Source   = CH1
        Level    = 1.60  V
        Sweep    = AUTO
        Coupling = DC
        Derived Level     = -1.20  V

     Channel 1:
         Coupling =  unknown
            Scale =     2.00  V/div
           Offset =     2.40  V
            Probe =       1X
         Inverted =    False

        Time Base =  100.000 µs/div
           Offset =    0.000  s
            Delta =  400.000 ns/point
           Points =     8192

         Count    = [        1,        2,        3  ...      8191,     8192]
           Raw    = [       41,       41,       41  ...       110,      110]
           Times  = [-1.638 ms,-1.638 ms,-1.638 ms  ...  1.638 ms, 1.638 ms]
           Volts  = [  4.32  V,  4.32  V,  4.32  V  ...  -1.20  V, -1.20  V]

     Channel 2:
         Coupling =  unknown
            Scale =     5.00  V/div
           Offset =   -15.80  V
            Probe =       1X
         Inverted =    False

        Time Base =  100.000 µs/div
           Offset =    0.000  s
            Delta =  400.000 ns/point
           Points =     8192

         Count    = [        1,        2,        3  ...      8191,     8192]
           Raw    = [      204,      204,      204  ...       178,      178]
           Times  = [-1.638 ms,-1.638 ms,-1.638 ms  ...  1.638 ms, 1.638 ms]
           Volts  = [  0.00  V,  0.00  V,  0.00  V  ...   5.20  V,  5.20  V]


downloading 'https://raw.githubusercontent.com/scottprahl/RigolWFM/main/tests/files/wfm/DS1102E-D.wfm'
[3]:
with tempfile.TemporaryDirectory() as tmpdir:
    mat_path = Path(tmpdir) / "DS1102E-D.mat"
    analog.mat(mat_path)
    mat_size = mat_path.stat().st_size
    exported_path = str(mat_path)

exported_path, mat_size
[3]:
('/var/folders/bk/7msms9wj50nfy_l1gjzfyx480000gn/T/tmpw4g17ho2/DS1102E-D.mat',
 197080)

Simple MATLAB or Octave Usage

Once the file is exported, a minimal MATLAB or Octave workflow looks like this:

data = load('DS1102E-D.mat');
plot(data.time * 1e3, data.CH_1);
xlabel('Time (ms)');
ylabel('Voltage (V)');
grid on

The same field names are available in GNU Octave, so we can test the export with the installed octave command.

[4]:
with tempfile.TemporaryDirectory() as tmpdir:
    mat_path = Path(tmpdir) / "DS1102E-D.mat"
    analog.mat(mat_path)

    if OCTAVE is None:
        print("octave is not installed in this environment, so the live MAT load example is skipped.")
    else:
        octave_code = "\n".join(
            [
                f"data = load('{mat_path.as_posix()}');",
                "printf('fields: %s\\n', strjoin(fieldnames(data), ', '));",
                "printf('points: %d\\n', numel(data.time));",
                "printf('start: %.12g\\n', data.start(1));",
                "printf('increment: %.12g\\n', data.increment(1));",
                "printf('ch1_mean: %.6f\\n', mean(data.CH_1));",
                "printf('ch2_mean: %.6f\\n', mean(data.CH_2));",
            ]
        )
        result = subprocess.run(
            [OCTAVE, "--quiet", "--eval", octave_code],
            check=True,
            capture_output=True,
            text=True,
        )
        print(result.stdout)
fields: time, start, increment, CH_1, CH_2
points: 8192
start: -0.0016384
increment: 4e-07
ch1_mean: 1.504717
ch2_mean: 2.746045

Command-Line Equivalent

The same export is available from wfmconvert:

wfmconvert mat DS1102E-D.wfm

Channel names are lightly sanitized for MAT variable names, so CH 1 becomes CH_1.