Skip to main content

cicwave

docs

Waveform viewer with PyQtGraph backend for high-performance visualization of simulation data.

Full documentation: https://wulffern.github.io/cicwave/

cicwave is a standalone package extracted from cicsim, focused on providing the best possible waveform viewing experience with PyQtGraph and Qt6.

Background

I made my first waveform viewer (https://github.com/wulffern/NextGenLab.Chart) back in 2001 during a summer internship. NextGenLab.Chart evolved into https://github.com/wulffern/SystemDotNet.Report during my Ph.D. In I always had in my plan to port SdnReport to Mac and Linux, but I never really did (no coding time).

In December 2023 I needed a waveform viewer for cicsim (read ngspice raw files), so I wrote one by hand. It was pretty basic.

Enter March 2026, and the advent of agentic coding. It was finally possible to revive SdnReport in the form of a Qt port to cicwave. Initially it lived inside cicsim, however, in May 2026 it became clear that cicwave deserved it's own repo. As such, you're here.

Features

  • High-performance rendering with PyQtGraph and GPU acceleration
  • Multiple file format support:
    • ngspice .raw files
    • Xyce .prn print waveform files
    • Whitespace-separated text (.dat, .spe, .cou, .chi)
    • CSV, TSV, plain .txt, Excel, OpenDocument spreadsheets
    • Parquet, HDF5, Feather for big data
    • JSON, HTML, XML, fixed-width tables
    • Pickle (.pkl) for cached DataFrames
    • VCD digital waveforms
    • LitePoint .iqvsa IQ capture files
    • SigMF IQ recordings (.sigmf-meta + .sigmf-data, or .sigmf archives)
    • STDF (.stdf, .stdf.gz) semiconductor ATE test results
    • Raw uint32 counter captures (.u32) with a JSON sidecar
    • Audio: .wav natively; FLAC, Ogg, AIFF, MP3 with cicwave[audio]
    • Statistical formats: Stata (.dta), SAS (.sas7bdat), SPSS (.sav)
  • URL data sources: load CSV/JSON/Excel/Parquet/... straight from an http(s):// URL — REST APIs, hosted datasets, anything pandas can read
  • API data sources: a pivot spec with a source: block fetches its own data from a JSON REST API — nested records, one request per row of another, no data file — see docs
  • Fetch on demand: a catalog: block builds the wave tree from a cheap listing and downloads a series only when you plot it, so a database of thousands of sweeps opens instantly
  • Multi-dimensional data pivoting with YAML specifications
  • Digital waveform support with separate analog/digital panes
  • Session save/restore with .cicwave.yaml files
  • Export capabilities to PDF, PNG, SVG formats, and the underlying data itself (CSV/TSV/Parquet/Feather/HDF5) via --export-data
  • Engineering unit formatting and auto-detection
  • GPU-accelerated plotting for smooth interaction with large datasets
  • MCP server (cicwave-mcp, optional): plot/analyze tools for an agent driving tests to call directly — see docs
  • Plugins: private file formats, annotations, analyses and constellation presets from separately installed packages, listed under Help → Plugins — see docs and the examples: a UART decoder (examples/cicwave-uart) and a Touchstone reader with Smith chart (examples/cicwave-smith)

Installation

pip install cicwave

For the MCP server (agent-driven plotting/analysis; requires Python 3.10+):

pip install "cicwave[mcp]"

For FLAC, Ogg, AIFF and MP3 audio (WAV works without it):

pip install "cicwave[audio]"

For development installation:

git clone https://github.com/wulffern/cicwave.git
cd cicwave
pip install -e .

Usage

Basic Usage

Open waveform files directly:

# Single file
cicwave data.raw

# Multiple files  
cicwave sim1.csv sim2.csv results.xlsx

# Glob patterns (useful on PowerShell)
cicwave --glob "results/*.csv" --glob "**/*.raw"

# Force a CSV delimiter (disables auto-sniffing for this run)
cicwave --csv-sep ';' european_data.csv
cicwave --csv-sep tab measurements.csv

# Strip comment lines from text files (CSV/TSV/.dat/.spe/.cou/.chi)
cicwave --csv-comment '#' results.csv          # strip '#' banners
cicwave --csv-comment '*' spice_log.csv        # SPICE-style comments
cicwave --csv-comment '//' c_style_dump.csv    # multi-char marker
cicwave --csv-comment '' eldo.cou              # disable default for .cou

Advanced Features

Load data from a URL:

cicwave https://raw.githubusercontent.com/owid/co2-data/master/owid-co2-data.csv

# Extension-less REST endpoint: force the format
cicwave https://api.example.com/v1/measurements --format json

Multi-dimensional data reshaping:

cicwave --pivot analysis.yaml dataset.csv

Fetch from a JSON REST API (spec carries the URL, no data file):

cicwave measurements.yaml

Session management:

# Save your current plot configuration in the GUI (File → Save Session)
cicwave --session my_analysis.cicwave.yaml

# Export plots without opening GUI
cicwave --session config.yaml --export results.pdf

Data exploration:

# Preview pivot dimensions before plotting
cicwave --pivot spec.yaml --pivot-info data.csv

File Format Support

cicwave dispatches on file extension. Any extension not listed below falls through to the ngspice raw reader, so non-standard suffixes (e.g. .raw0, .bin) on ngspice output usually still work.

Simulation / measurement formats

Format Extension Description
ngspice raw .raw (and unknown extensions) Binary simulation results, parsed by ngraw.py
Xyce print .prn Sandia Xyce print/probe waveform output
Whitespace text .dat, .spe, .cou, .chi Eldo .cou/.chi, ngspice .dat, generic space/tab columns; # comments stripped by default
VCD .vcd Value Change Dump — digital simulation waveforms
LitePoint IQ .iqvsa LitePoint IQxstream / IQfact IQ capture data
SigMF .sigmf-meta, .sigmf-data, .sigmf-data.zip, .sigmf SigMF recordings (open either half of the pair, or a .sigmf archive). A zipped dataset (<name>.sigmf-data.zip) is read in place without unpacking. litepoint:scale converts counts to analyser units; litepoint:channel_offset_hz / litepoint:spectrum_inverted put a low-IF capture's FFT on the RF axis. Each recording also gets magnitude views: mag (|iq|) and power_dBm (dBm for LitePoint analyser captures, matching their burst annotations), power_dBFS (ADC counts with a stated full scale) or power_dB. All core:datatypes (cf32_le, ci16_le, cu8, rf64_be, …), multi-channel and per-capture header bytes. Gives a complex iq column plus I/Q, a time axis from core:sample_rate, and the FFT is centred on the first capture's core:frequency
STDF .stdf, .stdf.gz Semiconductor ATE test results (SEMI E10/V4) — parametric (PTR) results per part/site, gzip auto-detected
Raw counter .u32 Bare little-endian uint32 counter records with a .meta.json sidecar giving the tick length and periods per sample; converted to Hz or ns on load, with the dead time between capture chunks preserved
Audio .wav, .flac, .ogg, .opus, .aif/.aiff, .mp3, … Audio recordings. .wav is read natively (PCM 8/16/24/32-bit, 32/64-bit float, WAVE_FORMAT_EXTENSIBLE, RF64); the other formats need pip install cicwave[audio] (soundfile/libsndfile). Samples are in full scale (±1) with a time axis in seconds, one column per channel: audio (mono), left/right (stereo) or ch0, ch1, … The sample rate prefills the FFT and analysis dialogs

Tabular text formats

Format Extension Description
CSV .csv Delimiter auto-detected from `, ; \t
TSV .tsv, .txt Tab separated values
Fixed-width .fwf Fixed-width columnar text (pandas.read_fwf)
HTML .html First <table> in the document
XML .xml pandas.read_xml
JSON .json pandas.read_json records

Spreadsheet formats

Format Extension Description
Excel .xlsx, .xls Microsoft Excel workbooks (sheet selectable)
OpenDocument .ods LibreOffice / OpenOffice spreadsheets (requires odfpy)

Big-data / binary formats

Format Extension Description
Parquet .parquet Columnar storage (requires pip install pyarrow)
Feather .feather Arrow IPC file format (requires pip install pyarrow)
HDF5 .h5, .hdf5 Hierarchical data (requires pip install tables)
Pickle .pkl, .pickle Serialized pandas DataFrame

Statistical packages

Format Extension Description
Stata .dta, .stata Stata data files (pandas.read_stata)
SAS .sas7bdat SAS transport/data files (pandas.read_sas)
SPSS .sav SPSS data files (requires pyreadstat)

Environment Variables

  • CICWAVE_X - Default X-axis column name
  • CICWAVE_PLUGINS=0 - Start without loading any plugins

GUI Features

Waveform Interaction

  • Mouse wheel: Zoom in/out
  • Middle click + drag: Pan
  • Right click: Context menu with analysis tools
  • Ctrl+A: Auto-fit all waveforms
  • Ctrl+Mouse wheel: Zoom X-axis only

Analysis Tools

Right-click a trace in the wave tree for the analysis menu:

  • Cursors: A/B markers measure time / voltage differences
  • FFT / PSD: Hanning-windowed spectrum (peak-normalised dB)
  • ADC PSD (SNDR, SFDR, harmonics)…: ADC characterisation
  • SNR / SNDR / ENOB…: numeric metrics with the same backend
  • Histogram: distribution + Gaussian fit
  • Differentiate (dy/dx): numerical derivative
  • Linear fit…, Difference (this − other)…, X vs Y…
  • 2's complement decode submenu: 8 / 10 / 12 / 16-bit signed
  • Math expressions: create derived signals
  • Digital analysis: bus values and timing
  • Export data: save currently visible waveforms

ADC PSD dialog

Tailored for ADC bench data and behavioural simulations, inspired by oct_dofft.m / dofftsd.m:

Field Meaning
Sample rate F_s Empty → infer from the time axis
Fundamental F₀ Empty / 0 → auto (strongest non-DC bin, with DC and Nyquist guard bands)
Oversampling OSR >1 integrates noise only over the in-band slice (1 … N_fft / OSR), σΔ-style
Max harmonic order Default 5 (H2…H5 typical for ADC reports)
Harmonic lobe ±bins Half-width for the harmonic masks. Hann main lobe is 3 bins; ±3 (7 bins) is a safe default for non-coherent captures
Fundamental lobe ±bins Separate width for the fundamental — use a wider window when jitter or drift smears the tone more than the harmonics
Full-scale amplitude A_FS Peak FS sine amplitude (same units as y). Empty → spectrum is dBc; set → dBFS plot + Signal level = … dBFS line
Exclude harmonics from SNR… Splits SNR vs SNDR (default on); off matches σΔ "in-band noise only"
Logarithmic frequency axis Default on; dialog and markers stay aligned in either mode

Reported metrics (per call, also shown as a banner on the main wave tab):

  • SNR, SNDR, ENOB (dynamic_parameters backend)
  • SFDR — IEEE definition: ratio of fundamental lobe to the largest spur, harmonics included (always in dBc)
  • Hn table — for each harmonic up to Max: integrated lobe power (dBc) and peak bin (dBc)
  • Fundamental + harmonics drawn as vertical markers, with diamond glyphs at the spectrum peak nearest each tone

All dialog fields are persisted between invocations via QSettings (cicwave/cicwave/{snr_dialog,adc_psd_dialog}/…), so running ADC PSD on the next signal reuses the same F_s, A_FS, lobe widths and so on.

Session Management

  • File → Save Session: Save current plot configuration
  • File → Load Session: Restore previous analysis
  • Sessions store: visible signals, zoom levels, cursor positions, analysis setup

Pivot Specifications

For multi-dimensional datasets, use YAML pivot specs to reshape data before visualization:

# analysis.yaml
index: time          # X-axis (rows)
columns: [corner, temperature]  # Create separate traces for each combination  
values: ["v(out)", "v(in)"]     # Y-axis signals to plot
conditions:          # Filter data
  frequency: 1e9
  process: tt
cicwave --pivot analysis.yaml monte_carlo_results.csv

Migrating from cicsim

If you previously used cicsim wave or the standalone cicwave from cicsim:

  1. Install standalone cicwave: pip install cicwave
  2. Update workflows: Replace cicsim wave --backend pg with just cicwave
  3. Session files: Existing .cicwave.yaml files are fully compatible
  4. Tkinter users: cicsim wave --backend tk still works in cicsim for lightweight usage

Development

Running Tests

# Run all unit tests
python -m unittest discover -s tests/unittests/ -p 'test_*.py' -v

# Test specific functionality
python -m unittest tests.unittests.test_wavefiles_lazy -v

Project Structure

cicwave/
├── src/cicwave/
│   ├── cli.py          # Command-line interface
│   ├── wave_pg.py      # Main PyQtGraph viewer
│   ├── wavefiles.py    # File I/O and data loading
│   ├── ngraw.py        # ngspice binary parser  
│   ├── pivot.py        # Data reshaping
│   ├── apisource.py    # Declarative JSON REST API data sources
│   ├── theme.py        # Color themes
│   └── command.py      # Logging utilities
├── tests/unittests/    # Unit test suite
└── scripts/            # Windows shortcut generator

License

MIT License - see LICENSE file for details.

Contributing

Contributions welcome! Please:

  1. Fork the repository
  2. Create a feature branch
  3. Add tests for new functionality
  4. Ensure all tests pass
  5. Submit a pull request
  • cicsim - Simulation orchestration and lightweight tkinter viewer
  • cicpy - Analog IC design transpiler
  • PyQtGraph - High-performance plotting library

Metadata

Release files for cicwave 0.7.4

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for cicwave 0.7.4
File Size Uploaded Provenance Actions
cicwave-0.7.4.tar.gz 143.0 kB Without provenance Details for cicwave-0.7.4.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for cicwave 0.7.4
File Interpreter ABI Platform Actions
cicwave-0.7.4-py3-none-any.whl Python 3 none any Details for cicwave-0.7.4-py3-none-any.whl

Total release size: 285.3 kB

Release files / cicwave-0.7.4.tar.gz

Download URL cicwave-0.7.4.tar.gz
Size 143.0 kB
Tags Source
SHA-256 checksum
How to use checksums
706f61b578e88f71e953ee34cfb3fd787572e10bdb2fd3ffdf13e301abe46e04
BLAKE2b-256 checksum
How to use checksums
d0f0004c09f807c642c736b3cd4484522242b18b6a130e8c5884dde38b8beb18
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.1.0 CPython/3.13.3

Release files / cicwave-0.7.4-py3-none-any.whl

Download URL cicwave-0.7.4-py3-none-any.whl
Size 142.3 kB
Tags Python 3
SHA-256 checksum
How to use checksums
ab78c3e8e66302511908cecc9f7d38741c24f79540a2f7df7113e0312bec0adb
BLAKE2b-256 checksum
How to use checksums
5e14b6cc32f4e62dd27c99b9605039eea2158bbd1dc7b79260d8d165ea91db82
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.1.0 CPython/3.13.3

Security for cicwave 0.7.4

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page