cicwave 0.5.2__tar.gz → 0.6.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (28) hide show
  1. cicwave-0.6.0/PKG-INFO +375 -0
  2. cicwave-0.6.0/README.md +334 -0
  3. {cicwave-0.5.2 → cicwave-0.6.0}/pyproject.toml +4 -2
  4. {cicwave-0.5.2 → cicwave-0.6.0}/src/cicwave/__init__.py +1 -0
  5. cicwave-0.6.0/src/cicwave/analysis.py +871 -0
  6. cicwave-0.6.0/src/cicwave/apisource.py +487 -0
  7. cicwave-0.6.0/src/cicwave/cli.py +365 -0
  8. cicwave-0.6.0/src/cicwave/mcp_server.py +288 -0
  9. {cicwave-0.5.2 → cicwave-0.6.0}/src/cicwave/pivot.py +48 -0
  10. cicwave-0.6.0/src/cicwave/stdf.py +299 -0
  11. {cicwave-0.5.2 → cicwave-0.6.0}/src/cicwave/wave_pg.py +896 -126
  12. cicwave-0.6.0/src/cicwave/wavefiles.py +1773 -0
  13. cicwave-0.6.0/src/cicwave.egg-info/PKG-INFO +375 -0
  14. {cicwave-0.5.2 → cicwave-0.6.0}/src/cicwave.egg-info/SOURCES.txt +4 -0
  15. {cicwave-0.5.2 → cicwave-0.6.0}/src/cicwave.egg-info/entry_points.txt +1 -0
  16. {cicwave-0.5.2 → cicwave-0.6.0}/src/cicwave.egg-info/requires.txt +3 -0
  17. cicwave-0.5.2/PKG-INFO +0 -242
  18. cicwave-0.5.2/README.md +0 -203
  19. cicwave-0.5.2/src/cicwave/cli.py +0 -176
  20. cicwave-0.5.2/src/cicwave/wavefiles.py +0 -935
  21. cicwave-0.5.2/src/cicwave.egg-info/PKG-INFO +0 -242
  22. {cicwave-0.5.2 → cicwave-0.6.0}/LICENSE +0 -0
  23. {cicwave-0.5.2 → cicwave-0.6.0}/setup.cfg +0 -0
  24. {cicwave-0.5.2 → cicwave-0.6.0}/src/cicwave/command.py +0 -0
  25. {cicwave-0.5.2 → cicwave-0.6.0}/src/cicwave/ngraw.py +0 -0
  26. {cicwave-0.5.2 → cicwave-0.6.0}/src/cicwave/theme.py +0 -0
  27. {cicwave-0.5.2 → cicwave-0.6.0}/src/cicwave.egg-info/dependency_links.txt +0 -0
  28. {cicwave-0.5.2 → cicwave-0.6.0}/src/cicwave.egg-info/top_level.txt +0 -0
cicwave-0.6.0/PKG-INFO ADDED
@@ -0,0 +1,375 @@
1
+ Metadata-Version: 2.4
2
+ Name: cicwave
3
+ Version: 0.6.0
4
+ Summary: Advanced waveform viewer with PyQtGraph backend
5
+ Author-email: Carsten Wulff <carsten@wulff.no>
6
+ License: MIT
7
+ Project-URL: Homepage, https://github.com/wulffern/cicwave
8
+ Project-URL: Bug Tracker, https://github.com/wulffern/cicwave/issues
9
+ Classifier: Development Status :: 4 - Beta
10
+ Classifier: Intended Audience :: Developers
11
+ Classifier: Intended Audience :: Science/Research
12
+ Classifier: Natural Language :: English
13
+ Classifier: Operating System :: OS Independent
14
+ Classifier: Programming Language :: Python :: 3
15
+ Classifier: Programming Language :: Python :: 3.8
16
+ Classifier: Programming Language :: Python :: 3.9
17
+ Classifier: Programming Language :: Python :: 3.10
18
+ Classifier: Programming Language :: Python :: 3.11
19
+ Classifier: Topic :: Utilities
20
+ Classifier: Topic :: Scientific/Engineering
21
+ Classifier: Topic :: Scientific/Engineering :: Electronic Design Automation (EDA)
22
+ Classifier: Topic :: Scientific/Engineering :: Visualization
23
+ Requires-Python: >=3.8
24
+ Description-Content-Type: text/markdown
25
+ License-File: LICENSE
26
+ Requires-Dist: numpy
27
+ Requires-Dist: pandas
28
+ Requires-Dist: matplotlib
29
+ Requires-Dist: click
30
+ Requires-Dist: pyyaml
31
+ Requires-Dist: PySide6
32
+ Requires-Dist: pyqtgraph
33
+ Requires-Dist: PyOpenGL
34
+ Provides-Extra: parquet
35
+ Requires-Dist: pyarrow; extra == "parquet"
36
+ Provides-Extra: hdf5
37
+ Requires-Dist: tables; extra == "hdf5"
38
+ Provides-Extra: mcp
39
+ Requires-Dist: mcp[cli]; extra == "mcp"
40
+ Dynamic: license-file
41
+
42
+ # cicwave
43
+
44
+ [![docs](https://github.com/wulffern/cicwave/actions/workflows/docs.yml/badge.svg)](https://github.com/wulffern/cicwave/actions/workflows/docs.yml)
45
+
46
+ Waveform viewer with PyQtGraph backend for high-performance visualization of simulation data.
47
+
48
+ Full documentation: <https://wulffern.github.io/cicwave/>
49
+
50
+ cicwave is a standalone package extracted from
51
+ [cicsim](https://github.com/wulffern/cicsim), focused on providing the
52
+ best possible waveform viewing experience with PyQtGraph and Qt6.
53
+
54
+ ## Background
55
+
56
+ I made my first waveform viewer (<https://github.com/wulffern/NextGenLab.Chart>)
57
+ back in 2001 during a summer internship. NextGenLab.Chart evolved into
58
+ <https://github.com/wulffern/SystemDotNet.Report> during my Ph.D. In I always
59
+ had in my plan to port SdnReport to Mac and Linux, but I never really did (no
60
+ coding time).
61
+
62
+ In December 2023 I needed a waveform viewer for cicsim (read ngspice raw files),
63
+ so I wrote one by hand. It was pretty basic.
64
+
65
+ Enter March 2026, and the advent of agentic coding. It was finally possible to
66
+ revive SdnReport in the form of a Qt port to cicwave. Initially it lived inside
67
+ cicsim, however, in May 2026 it became clear that cicwave deserved it's own
68
+ repo. As such, you're here.
69
+
70
+ ## Features
71
+
72
+ - **High-performance rendering** with PyQtGraph and GPU acceleration
73
+ - **Multiple file format support**:
74
+ - ngspice `.raw` files
75
+ - Xyce `.prn` print waveform files
76
+ - Whitespace-separated text (`.dat`, `.spe`, `.cou`, `.chi`)
77
+ - CSV, TSV, plain `.txt`, Excel, OpenDocument spreadsheets
78
+ - Parquet, HDF5, Feather for big data
79
+ - JSON, HTML, XML, fixed-width tables
80
+ - Pickle (`.pkl`) for cached DataFrames
81
+ - VCD digital waveforms
82
+ - LitePoint `.iqvsa` IQ capture files
83
+ - STDF (`.stdf`, `.stdf.gz`) semiconductor ATE test results
84
+ - Raw `uint32` counter captures (`.u32`) with a JSON sidecar
85
+ - Statistical formats: Stata (`.dta`), SAS (`.sas7bdat`), SPSS (`.sav`)
86
+ - **URL data sources**: load CSV/JSON/Excel/Parquet/... straight from an
87
+ `http(s)://` URL — REST APIs, hosted datasets, anything pandas can read
88
+ - **API data sources**: a pivot spec with a `source:` block fetches its own
89
+ data from a JSON REST API — nested records, one request per row of
90
+ another, no data file — see [docs](https://wulffern.github.io/cicwave/api-sources)
91
+ - **Multi-dimensional data pivoting** with YAML specifications
92
+ - **Digital waveform support** with separate analog/digital panes
93
+ - **Session save/restore** with `.cicwave.yaml` files
94
+ - **Export capabilities** to PDF, PNG, SVG formats, and the underlying
95
+ data itself (CSV/TSV/Parquet/Feather/HDF5) via `--export-data`
96
+ - **Engineering unit formatting** and auto-detection
97
+ - **GPU-accelerated plotting** for smooth interaction with large datasets
98
+ - **MCP server** (`cicwave-mcp`, optional): plot/analyze tools for an
99
+ agent driving tests to call directly — see [docs](https://wulffern.github.io/cicwave/mcp)
100
+
101
+ ## Installation
102
+
103
+ ```bash
104
+ pip install cicwave
105
+ ```
106
+
107
+ For the MCP server (agent-driven plotting/analysis; requires Python 3.10+):
108
+
109
+ ```bash
110
+ pip install "cicwave[mcp]"
111
+ ```
112
+
113
+ For development installation:
114
+
115
+ ```bash
116
+ git clone https://github.com/wulffern/cicwave.git
117
+ cd cicwave
118
+ pip install -e .
119
+ ```
120
+
121
+ ## Usage
122
+
123
+ ### Basic Usage
124
+
125
+ Open waveform files directly:
126
+
127
+ ```bash
128
+ # Single file
129
+ cicwave data.raw
130
+
131
+ # Multiple files
132
+ cicwave sim1.csv sim2.csv results.xlsx
133
+
134
+ # Glob patterns (useful on PowerShell)
135
+ cicwave --glob "results/*.csv" --glob "**/*.raw"
136
+
137
+ # Force a CSV delimiter (disables auto-sniffing for this run)
138
+ cicwave --csv-sep ';' european_data.csv
139
+ cicwave --csv-sep tab measurements.csv
140
+
141
+ # Strip comment lines from text files (CSV/TSV/.dat/.spe/.cou/.chi)
142
+ cicwave --csv-comment '#' results.csv # strip '#' banners
143
+ cicwave --csv-comment '*' spice_log.csv # SPICE-style comments
144
+ cicwave --csv-comment '//' c_style_dump.csv # multi-char marker
145
+ cicwave --csv-comment '' eldo.cou # disable default for .cou
146
+ ```
147
+
148
+ ### Advanced Features
149
+
150
+ **Load data from a URL:**
151
+ ```bash
152
+ cicwave https://raw.githubusercontent.com/owid/co2-data/master/owid-co2-data.csv
153
+
154
+ # Extension-less REST endpoint: force the format
155
+ cicwave https://api.example.com/v1/measurements --format json
156
+ ```
157
+
158
+ **Multi-dimensional data reshaping:**
159
+ ```bash
160
+ cicwave --pivot analysis.yaml dataset.csv
161
+ ```
162
+
163
+ **Fetch from a JSON REST API (spec carries the URL, no data file):**
164
+ ```bash
165
+ cicwave measurements.yaml
166
+ ```
167
+
168
+ **Session management:**
169
+ ```bash
170
+ # Save your current plot configuration in the GUI (File → Save Session)
171
+ cicwave --session my_analysis.cicwave.yaml
172
+
173
+ # Export plots without opening GUI
174
+ cicwave --session config.yaml --export results.pdf
175
+ ```
176
+
177
+ **Data exploration:**
178
+ ```bash
179
+ # Preview pivot dimensions before plotting
180
+ cicwave --pivot spec.yaml --pivot-info data.csv
181
+ ```
182
+
183
+ ## File Format Support
184
+
185
+ cicwave dispatches on file extension. Any extension not listed below falls
186
+ through to the ngspice raw reader, so non-standard suffixes (e.g. `.raw0`,
187
+ `.bin`) on ngspice output usually still work.
188
+
189
+ ### Simulation / measurement formats
190
+
191
+ | Format | Extension | Description |
192
+ |--------|-----------|-------------|
193
+ | ngspice raw | `.raw` (and unknown extensions) | Binary simulation results, parsed by `ngraw.py` |
194
+ | Xyce print | `.prn` | Sandia Xyce print/probe waveform output |
195
+ | Whitespace text | `.dat`, `.spe`, `.cou`, `.chi` | Eldo `.cou`/`.chi`, ngspice `.dat`, generic space/tab columns; `#` comments stripped by default |
196
+ | VCD | `.vcd` | Value Change Dump — digital simulation waveforms |
197
+ | LitePoint IQ | `.iqvsa` | LitePoint IQxstream / IQfact IQ capture data |
198
+ | STDF | `.stdf`, `.stdf.gz` | Semiconductor ATE test results (SEMI E10/V4) — parametric (PTR) results per part/site, gzip auto-detected |
199
+ | 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 |
200
+
201
+ ### Tabular text formats
202
+
203
+ | Format | Extension | Description |
204
+ |--------|-----------|-------------|
205
+ | CSV | `.csv` | Delimiter auto-detected from `, ; \t |` (override with `--csv-sep`; pyarrow when available) |
206
+ | TSV | `.tsv`, `.txt` | Tab separated values |
207
+ | Fixed-width | `.fwf` | Fixed-width columnar text (`pandas.read_fwf`) |
208
+ | HTML | `.html` | First `<table>` in the document |
209
+ | XML | `.xml` | `pandas.read_xml` |
210
+ | JSON | `.json` | `pandas.read_json` records |
211
+
212
+ ### Spreadsheet formats
213
+
214
+ | Format | Extension | Description |
215
+ |--------|-----------|-------------|
216
+ | Excel | `.xlsx`, `.xls` | Microsoft Excel workbooks (sheet selectable) |
217
+ | OpenDocument | `.ods` | LibreOffice / OpenOffice spreadsheets (requires `odfpy`) |
218
+
219
+ ### Big-data / binary formats
220
+
221
+ | Format | Extension | Description |
222
+ |--------|-----------|-------------|
223
+ | Parquet | `.parquet` | Columnar storage (requires `pip install pyarrow`) |
224
+ | Feather | `.feather` | Arrow IPC file format (requires `pip install pyarrow`) |
225
+ | HDF5 | `.h5`, `.hdf5` | Hierarchical data (requires `pip install tables`) |
226
+ | Pickle | `.pkl`, `.pickle` | Serialized pandas DataFrame |
227
+
228
+ ### Statistical packages
229
+
230
+ | Format | Extension | Description |
231
+ |--------|-----------|-------------|
232
+ | Stata | `.dta`, `.stata` | Stata data files (`pandas.read_stata`) |
233
+ | SAS | `.sas7bdat` | SAS transport/data files (`pandas.read_sas`) |
234
+ | SPSS | `.sav` | SPSS data files (requires `pyreadstat`) |
235
+
236
+ ## Environment Variables
237
+
238
+ - `CICWAVE_X` - Default X-axis column name
239
+
240
+ ## GUI Features
241
+
242
+ ### Waveform Interaction
243
+ - **Mouse wheel**: Zoom in/out
244
+ - **Middle click + drag**: Pan
245
+ - **Right click**: Context menu with analysis tools
246
+ - **Ctrl+A**: Auto-fit all waveforms
247
+ - **Ctrl+Mouse wheel**: Zoom X-axis only
248
+
249
+ ### Analysis Tools
250
+
251
+ Right-click a trace in the wave tree for the analysis menu:
252
+
253
+ - **Cursors**: A/B markers measure time / voltage differences
254
+ - **FFT / PSD**: Hanning-windowed spectrum (peak-normalised dB)
255
+ - **ADC PSD (SNDR, SFDR, harmonics)…**: ADC characterisation
256
+ - **SNR / SNDR / ENOB…**: numeric metrics with the same backend
257
+ - **Histogram**: distribution + Gaussian fit
258
+ - **Differentiate (dy/dx)**: numerical derivative
259
+ - **Linear fit…**, **Difference (this − other)…**, **X vs Y…**
260
+ - **2's complement decode** submenu: 8 / 10 / 12 / 16-bit signed
261
+ - **Math expressions**: create derived signals
262
+ - **Digital analysis**: bus values and timing
263
+ - **Export data**: save currently visible waveforms
264
+
265
+ #### ADC PSD dialog
266
+
267
+ Tailored for ADC bench data and behavioural simulations, inspired by
268
+ `oct_dofft.m` / `dofftsd.m`:
269
+
270
+ | Field | Meaning |
271
+ |-------|---------|
272
+ | `Sample rate F_s` | Empty → infer from the time axis |
273
+ | `Fundamental F₀` | Empty / 0 → auto (strongest non-DC bin, with DC and Nyquist guard bands) |
274
+ | `Oversampling OSR` | `>1` integrates noise only over the in-band slice (`1 … N_fft / OSR`), σΔ-style |
275
+ | `Max harmonic order` | Default 5 (H2…H5 typical for ADC reports) |
276
+ | `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 |
277
+ | `Fundamental lobe ±bins` | Separate width for the fundamental — use a wider window when jitter or drift smears the tone more than the harmonics |
278
+ | `Full-scale amplitude A_FS` | Peak FS sine amplitude (same units as `y`). Empty → spectrum is **dBc**; set → **dBFS** plot + `Signal level = … dBFS` line |
279
+ | `Exclude harmonics from SNR…` | Splits SNR vs SNDR (default on); off matches σΔ "in-band noise only" |
280
+ | `Logarithmic frequency axis` | Default on; dialog and markers stay aligned in either mode |
281
+
282
+ **Reported metrics** (per call, also shown as a banner on the main wave tab):
283
+
284
+ - `SNR`, `SNDR`, `ENOB` (`dynamic_parameters` backend)
285
+ - `SFDR` — IEEE definition: ratio of fundamental lobe to the **largest
286
+ spur, harmonics included** (always in dBc)
287
+ - `Hn` table — for each harmonic up to *Max*: integrated `lobe power`
288
+ (dBc) and `peak` bin (dBc)
289
+ - Fundamental + harmonics drawn as vertical markers, with diamond
290
+ glyphs at the spectrum peak nearest each tone
291
+
292
+ All dialog fields are **persisted between invocations** via QSettings
293
+ (`cicwave/cicwave/{snr_dialog,adc_psd_dialog}/…`), so running ADC PSD on
294
+ the next signal reuses the same `F_s`, `A_FS`, lobe widths and so on.
295
+
296
+ ### Session Management
297
+ - **File → Save Session**: Save current plot configuration
298
+ - **File → Load Session**: Restore previous analysis
299
+ - Sessions store: visible signals, zoom levels, cursor positions, analysis setup
300
+
301
+ ## Pivot Specifications
302
+
303
+ For multi-dimensional datasets, use YAML pivot specs to reshape data before visualization:
304
+
305
+ ```yaml
306
+ # analysis.yaml
307
+ index: time # X-axis (rows)
308
+ columns: [corner, temperature] # Create separate traces for each combination
309
+ values: ["v(out)", "v(in)"] # Y-axis signals to plot
310
+ conditions: # Filter data
311
+ frequency: 1e9
312
+ process: tt
313
+ ```
314
+
315
+ ```bash
316
+ cicwave --pivot analysis.yaml monte_carlo_results.csv
317
+ ```
318
+
319
+ ## Migrating from cicsim
320
+
321
+ If you previously used `cicsim wave` or the standalone `cicwave` from cicsim:
322
+
323
+ 1. **Install standalone cicwave**: `pip install cicwave`
324
+ 2. **Update workflows**: Replace `cicsim wave --backend pg` with just `cicwave`
325
+ 3. **Session files**: Existing `.cicwave.yaml` files are fully compatible
326
+ 4. **Tkinter users**: `cicsim wave --backend tk` still works in cicsim for lightweight usage
327
+
328
+ ## Development
329
+
330
+ ### Running Tests
331
+
332
+ ```bash
333
+ # Run all unit tests
334
+ python -m unittest discover -s tests/unittests/ -p 'test_*.py' -v
335
+
336
+ # Test specific functionality
337
+ python -m unittest tests.unittests.test_wavefiles_lazy -v
338
+ ```
339
+
340
+ ### Project Structure
341
+
342
+ ```
343
+ cicwave/
344
+ ├── src/cicwave/
345
+ │ ├── cli.py # Command-line interface
346
+ │ ├── wave_pg.py # Main PyQtGraph viewer
347
+ │ ├── wavefiles.py # File I/O and data loading
348
+ │ ├── ngraw.py # ngspice binary parser
349
+ │ ├── pivot.py # Data reshaping
350
+ │ ├── apisource.py # Declarative JSON REST API data sources
351
+ │ ├── theme.py # Color themes
352
+ │ └── command.py # Logging utilities
353
+ ├── tests/unittests/ # Unit test suite
354
+ └── scripts/ # Windows shortcut generator
355
+ ```
356
+
357
+ ## License
358
+
359
+ MIT License - see LICENSE file for details.
360
+
361
+ ## Contributing
362
+
363
+ Contributions welcome! Please:
364
+
365
+ 1. Fork the repository
366
+ 2. Create a feature branch
367
+ 3. Add tests for new functionality
368
+ 4. Ensure all tests pass
369
+ 5. Submit a pull request
370
+
371
+ ## Related Projects
372
+
373
+ - **[cicsim](https://github.com/wulffern/cicsim)** - Simulation orchestration and lightweight tkinter viewer
374
+ - **[cicpy](https://github.com/wulffern/cicpy)** - Analog IC design transpiler
375
+ - **[PyQtGraph](https://pyqtgraph.readthedocs.io/)** - High-performance plotting library