cicwave
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
.rawfiles - Xyce
.prnprint 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
.iqvsaIQ capture files - STDF (
.stdf,.stdf.gz) semiconductor ATE test results - Raw
uint32counter captures (.u32) with a JSON sidecar - Statistical formats: Stata (
.dta), SAS (.sas7bdat), SPSS (.sav)
- ngspice
- 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.yamlfiles - 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
Installation
pip install cicwave
For the MCP server (agent-driven plotting/analysis; requires Python 3.10+):
pip install "cicwave[mcp]"
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 |
| 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 |
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
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_parametersbackend)SFDR— IEEE definition: ratio of fundamental lobe to the largest spur, harmonics included (always in dBc)Hntable — for each harmonic up to Max: integratedlobe power(dBc) andpeakbin (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:
- Install standalone cicwave:
pip install cicwave - Update workflows: Replace
cicsim wave --backend pgwith justcicwave - Session files: Existing
.cicwave.yamlfiles are fully compatible - Tkinter users:
cicsim wave --backend tkstill 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:
- Fork the repository
- Create a feature branch
- Add tests for new functionality
- Ensure all tests pass
- Submit a pull request
Related Projects
Release files for cicwave 0.7.2
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| cicwave-0.7.2.tar.gz | 123.1 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| cicwave-0.7.2-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 246.0 kB
Release files / cicwave-0.7.2.tar.gz
| Download URL | cicwave-0.7.2.tar.gz |
|---|---|
| Size | 123.1 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
973abf9204727a89f14c0212d4f362e9128512f8b85d60649f0e15f29e3b1e36
|
|
BLAKE2b-256 checksum How to use checksums |
7a93461115b8cf1420b48aab0e10b2d70cbf3aee10e624060cecd1e18b979c2f
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
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.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Aug 28, 2026.
Transparency logRelease files / cicwave-0.7.2-py3-none-any.whl
| Download URL | cicwave-0.7.2-py3-none-any.whl |
|---|---|
| Size | 122.9 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
2239237f37dd12bc017bf5e885300d7589472d470b6fca1379dc66718bb04994
|
|
BLAKE2b-256 checksum How to use checksums |
0ad1446ff01e9b93ff33e1f7ada26a31022a2332e0f17af7b1cbf1bc81d54f96
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
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.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Aug 28, 2026.
Transparency log