Decode AEwin64 .WFS streaming files into numpy arrays
Project description
decode-wfs — GitHub
Decode binary .WFS (Waveform Stream) files produced by Physical Acoustics
AEwin64 / EasyAE acoustic emission software into numpy arrays.
The AEwin64 manual describes a format using message ID 173 (0xAD), but real
streaming captures use ID 174 (0xAE) with a slightly different layout. This
library handles the empirically observed streaming format and has been verified
against real captures. Voltage values are recovered with the calibration factor
used by AEwin64's own ASCII waveform exporter (raw_counts / 16384).
Installation
pip install decode-wfs
Requires Python 3.10+ and numpy.
Quick start
decode_wfs() — full access to every record
from decode_wfs import decode_wfs
wfs = decode_wfs("capture.wfs")
print(f"Sample rate : {wfs.sample_rate_hz:,} Hz")
print(f"Channels : {wfs.channels()}")
print(f"Records : {len(wfs.waveforms)}")
# Iterate individual waveform records
for rec in wfs.waveforms:
print(rec.channel, rec.samples.shape, rec.samples.max())
# Time axis for each record (includes pretrigger offset when present)
t = wfs.waveforms[0].time_axis_s # 1-D float64 array in seconds
# Stack all records from channel 1 into a 2-D array (records × samples)
arr = wfs.to_array(channel=1) # shape (n_records, n_samples), float64 volts
wfs_to_numpy() — one-liner for a 2-D array
from decode_wfs import wfs_to_numpy
# shape: (n_waveforms, n_samples_per_waveform), dtype float64, units volts
arr = wfs_to_numpy("capture.wfs", channel=1)
# Optionally return the per-waveform time axis as well
arr, t = wfs_to_numpy("capture.wfs", channel=1, return_time_axis=True)
load_continuous() — single concatenated time series
Reconstructs the continuous stream from all records, preserving absolute timing when the file contains per-record position pointers.
from decode_wfs import load_continuous
samples, time, sr = load_continuous("capture.wfs", channel=1)
# samples: 1-D float64 array, volts
# time : 1-D float64 array, seconds (negative at pretrigger)
# sr : sample rate in Hz
# Example: compute a power spectrum
import numpy as np
freqs = np.fft.rfftfreq(len(samples), d=1 / sr)
psd = np.abs(np.fft.rfft(samples)) ** 2
API summary
| Function / class | Returns | When to use |
|---|---|---|
decode_wfs(path) |
WFSFile |
Need per-record metadata or multi-channel data |
wfs_to_numpy(path) |
ndarray (n×m) |
Just need the voltage array |
load_continuous(path) |
(samples, time, sr) |
Spectral analysis on a single channel |
WFSFile.to_array(channel) |
ndarray (n×m) |
After decode_wfs, stack records into an array |
WFSFile.waveform_time_axis_s() |
ndarray (m,) |
Shared time axis for all waveform records |
WFSFile.channels() |
list[int] |
Which AE channel numbers are in the file |
WaveformRecord.time_axis_s |
ndarray (m,) |
Per-record time axis including pretrigger |
Logging
decode_wfs uses the standard logging module under the logger name
decode_wfs. To see progress messages:
import logging
logging.basicConfig(level=logging.INFO)
CLI
decode-wfs <file.wfs> [--channel N] [--max-records N]
Example:
$ decode-wfs capture.wfs --channel 1
File : capture.wfs
Sample rate : 1,000,000 Hz (1.000 MSPS)
Sample format : ADT=2 (16-bit signed samples)
Setup blocks : 2
Pretrigger : -256 samples
Total records : 512
Channels : [1, 2]
[0] ch=1 n=4096 samples min=-0.03125000 V max=0.04394531 V std=0.00201416 V
[1] ch=1 n=4096 samples min=-0.02832031 V max=0.03955078 V std=0.00198364 V
...
numpy array shape : (256, 4096) dtype=float64
Done.
Notes
- Voltage calibration — ADC counts are divided by 16384 to match the voltages in AEwin64's ASCII waveform exports. This factor was determined empirically and may not hold for all hardware configurations.
- Pretrigger — when a pretrigger window is configured,
time_axis_sand thetimeaxis fromload_continuousstart at a negative time offset so that t=0 corresponds to the trigger point. - Multi-channel files — records from all channels are interleaved in the
file. Use the
channelparameter to filter, or iterateWFSFile.waveformsand checkrec.channel. - Large files — pass
max_records=Nto any function to stop after reading N waveform records, useful during development.
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file decode_wfs-0.1.3.tar.gz.
File metadata
- Download URL: decode_wfs-0.1.3.tar.gz
- Upload date:
- Size: 12.4 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.9
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
9926620a4f3f00ef370846f33ed2b9afc661a5a5eb18d3a95d3feeb92f544e16
|
|
| MD5 |
6e4d798affb7a1c90ce00c872ad5937e
|
|
| BLAKE2b-256 |
523f3bafaad0e102b8912f24b5981adb717f0de0100ab1c872a1c8fd2fc66d22
|
File details
Details for the file decode_wfs-0.1.3-py3-none-any.whl.
File metadata
- Download URL: decode_wfs-0.1.3-py3-none-any.whl
- Upload date:
- Size: 12.3 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.9
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
8f6a19250a9f74c9967f61d570090136cfd0d386767d8548bb9b74aa8bc3d4d6
|
|
| MD5 |
70e9cef50401288a3cf013d47f7d1770
|
|
| BLAKE2b-256 |
14521847c0af94f2d0f6774d85a7b3c866dbee1b2f00b24e73fffb62072e7978
|