cicwave 0.5.2__tar.gz → 0.7.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.7.0/PKG-INFO +378 -0
  2. cicwave-0.7.0/README.md +337 -0
  3. {cicwave-0.5.2 → cicwave-0.7.0}/pyproject.toml +4 -2
  4. {cicwave-0.5.2 → cicwave-0.7.0}/src/cicwave/__init__.py +1 -0
  5. cicwave-0.7.0/src/cicwave/analysis.py +871 -0
  6. cicwave-0.7.0/src/cicwave/apisource.py +802 -0
  7. cicwave-0.7.0/src/cicwave/cli.py +431 -0
  8. cicwave-0.7.0/src/cicwave/mcp_server.py +288 -0
  9. {cicwave-0.5.2 → cicwave-0.7.0}/src/cicwave/pivot.py +170 -8
  10. cicwave-0.7.0/src/cicwave/stdf.py +299 -0
  11. {cicwave-0.5.2 → cicwave-0.7.0}/src/cicwave/wave_pg.py +1055 -130
  12. cicwave-0.7.0/src/cicwave/wavefiles.py +1866 -0
  13. cicwave-0.7.0/src/cicwave.egg-info/PKG-INFO +378 -0
  14. {cicwave-0.5.2 → cicwave-0.7.0}/src/cicwave.egg-info/SOURCES.txt +4 -0
  15. {cicwave-0.5.2 → cicwave-0.7.0}/src/cicwave.egg-info/entry_points.txt +1 -0
  16. {cicwave-0.5.2 → cicwave-0.7.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.7.0}/LICENSE +0 -0
  23. {cicwave-0.5.2 → cicwave-0.7.0}/setup.cfg +0 -0
  24. {cicwave-0.5.2 → cicwave-0.7.0}/src/cicwave/command.py +0 -0
  25. {cicwave-0.5.2 → cicwave-0.7.0}/src/cicwave/ngraw.py +0 -0
  26. {cicwave-0.5.2 → cicwave-0.7.0}/src/cicwave/theme.py +0 -0
  27. {cicwave-0.5.2 → cicwave-0.7.0}/src/cicwave.egg-info/dependency_links.txt +0 -0
  28. {cicwave-0.5.2 → cicwave-0.7.0}/src/cicwave.egg-info/top_level.txt +0 -0
cicwave-0.7.0/PKG-INFO ADDED
@@ -0,0 +1,378 @@
1
+ Metadata-Version: 2.4
2
+ Name: cicwave
3
+ Version: 0.7.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
+ - **Fetch on demand**: a `catalog:` block builds the wave tree from a cheap
92
+ listing and downloads a series only when you plot it, so a database of
93
+ thousands of sweeps opens instantly
94
+ - **Multi-dimensional data pivoting** with YAML specifications
95
+ - **Digital waveform support** with separate analog/digital panes
96
+ - **Session save/restore** with `.cicwave.yaml` files
97
+ - **Export capabilities** to PDF, PNG, SVG formats, and the underlying
98
+ data itself (CSV/TSV/Parquet/Feather/HDF5) via `--export-data`
99
+ - **Engineering unit formatting** and auto-detection
100
+ - **GPU-accelerated plotting** for smooth interaction with large datasets
101
+ - **MCP server** (`cicwave-mcp`, optional): plot/analyze tools for an
102
+ agent driving tests to call directly — see [docs](https://wulffern.github.io/cicwave/mcp)
103
+
104
+ ## Installation
105
+
106
+ ```bash
107
+ pip install cicwave
108
+ ```
109
+
110
+ For the MCP server (agent-driven plotting/analysis; requires Python 3.10+):
111
+
112
+ ```bash
113
+ pip install "cicwave[mcp]"
114
+ ```
115
+
116
+ For development installation:
117
+
118
+ ```bash
119
+ git clone https://github.com/wulffern/cicwave.git
120
+ cd cicwave
121
+ pip install -e .
122
+ ```
123
+
124
+ ## Usage
125
+
126
+ ### Basic Usage
127
+
128
+ Open waveform files directly:
129
+
130
+ ```bash
131
+ # Single file
132
+ cicwave data.raw
133
+
134
+ # Multiple files
135
+ cicwave sim1.csv sim2.csv results.xlsx
136
+
137
+ # Glob patterns (useful on PowerShell)
138
+ cicwave --glob "results/*.csv" --glob "**/*.raw"
139
+
140
+ # Force a CSV delimiter (disables auto-sniffing for this run)
141
+ cicwave --csv-sep ';' european_data.csv
142
+ cicwave --csv-sep tab measurements.csv
143
+
144
+ # Strip comment lines from text files (CSV/TSV/.dat/.spe/.cou/.chi)
145
+ cicwave --csv-comment '#' results.csv # strip '#' banners
146
+ cicwave --csv-comment '*' spice_log.csv # SPICE-style comments
147
+ cicwave --csv-comment '//' c_style_dump.csv # multi-char marker
148
+ cicwave --csv-comment '' eldo.cou # disable default for .cou
149
+ ```
150
+
151
+ ### Advanced Features
152
+
153
+ **Load data from a URL:**
154
+ ```bash
155
+ cicwave https://raw.githubusercontent.com/owid/co2-data/master/owid-co2-data.csv
156
+
157
+ # Extension-less REST endpoint: force the format
158
+ cicwave https://api.example.com/v1/measurements --format json
159
+ ```
160
+
161
+ **Multi-dimensional data reshaping:**
162
+ ```bash
163
+ cicwave --pivot analysis.yaml dataset.csv
164
+ ```
165
+
166
+ **Fetch from a JSON REST API (spec carries the URL, no data file):**
167
+ ```bash
168
+ cicwave measurements.yaml
169
+ ```
170
+
171
+ **Session management:**
172
+ ```bash
173
+ # Save your current plot configuration in the GUI (File → Save Session)
174
+ cicwave --session my_analysis.cicwave.yaml
175
+
176
+ # Export plots without opening GUI
177
+ cicwave --session config.yaml --export results.pdf
178
+ ```
179
+
180
+ **Data exploration:**
181
+ ```bash
182
+ # Preview pivot dimensions before plotting
183
+ cicwave --pivot spec.yaml --pivot-info data.csv
184
+ ```
185
+
186
+ ## File Format Support
187
+
188
+ cicwave dispatches on file extension. Any extension not listed below falls
189
+ through to the ngspice raw reader, so non-standard suffixes (e.g. `.raw0`,
190
+ `.bin`) on ngspice output usually still work.
191
+
192
+ ### Simulation / measurement formats
193
+
194
+ | Format | Extension | Description |
195
+ |--------|-----------|-------------|
196
+ | ngspice raw | `.raw` (and unknown extensions) | Binary simulation results, parsed by `ngraw.py` |
197
+ | Xyce print | `.prn` | Sandia Xyce print/probe waveform output |
198
+ | Whitespace text | `.dat`, `.spe`, `.cou`, `.chi` | Eldo `.cou`/`.chi`, ngspice `.dat`, generic space/tab columns; `#` comments stripped by default |
199
+ | VCD | `.vcd` | Value Change Dump — digital simulation waveforms |
200
+ | LitePoint IQ | `.iqvsa` | LitePoint IQxstream / IQfact IQ capture data |
201
+ | STDF | `.stdf`, `.stdf.gz` | Semiconductor ATE test results (SEMI E10/V4) — parametric (PTR) results per part/site, gzip auto-detected |
202
+ | 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 |
203
+
204
+ ### Tabular text formats
205
+
206
+ | Format | Extension | Description |
207
+ |--------|-----------|-------------|
208
+ | CSV | `.csv` | Delimiter auto-detected from `, ; \t |` (override with `--csv-sep`; pyarrow when available) |
209
+ | TSV | `.tsv`, `.txt` | Tab separated values |
210
+ | Fixed-width | `.fwf` | Fixed-width columnar text (`pandas.read_fwf`) |
211
+ | HTML | `.html` | First `<table>` in the document |
212
+ | XML | `.xml` | `pandas.read_xml` |
213
+ | JSON | `.json` | `pandas.read_json` records |
214
+
215
+ ### Spreadsheet formats
216
+
217
+ | Format | Extension | Description |
218
+ |--------|-----------|-------------|
219
+ | Excel | `.xlsx`, `.xls` | Microsoft Excel workbooks (sheet selectable) |
220
+ | OpenDocument | `.ods` | LibreOffice / OpenOffice spreadsheets (requires `odfpy`) |
221
+
222
+ ### Big-data / binary formats
223
+
224
+ | Format | Extension | Description |
225
+ |--------|-----------|-------------|
226
+ | Parquet | `.parquet` | Columnar storage (requires `pip install pyarrow`) |
227
+ | Feather | `.feather` | Arrow IPC file format (requires `pip install pyarrow`) |
228
+ | HDF5 | `.h5`, `.hdf5` | Hierarchical data (requires `pip install tables`) |
229
+ | Pickle | `.pkl`, `.pickle` | Serialized pandas DataFrame |
230
+
231
+ ### Statistical packages
232
+
233
+ | Format | Extension | Description |
234
+ |--------|-----------|-------------|
235
+ | Stata | `.dta`, `.stata` | Stata data files (`pandas.read_stata`) |
236
+ | SAS | `.sas7bdat` | SAS transport/data files (`pandas.read_sas`) |
237
+ | SPSS | `.sav` | SPSS data files (requires `pyreadstat`) |
238
+
239
+ ## Environment Variables
240
+
241
+ - `CICWAVE_X` - Default X-axis column name
242
+
243
+ ## GUI Features
244
+
245
+ ### Waveform Interaction
246
+ - **Mouse wheel**: Zoom in/out
247
+ - **Middle click + drag**: Pan
248
+ - **Right click**: Context menu with analysis tools
249
+ - **Ctrl+A**: Auto-fit all waveforms
250
+ - **Ctrl+Mouse wheel**: Zoom X-axis only
251
+
252
+ ### Analysis Tools
253
+
254
+ Right-click a trace in the wave tree for the analysis menu:
255
+
256
+ - **Cursors**: A/B markers measure time / voltage differences
257
+ - **FFT / PSD**: Hanning-windowed spectrum (peak-normalised dB)
258
+ - **ADC PSD (SNDR, SFDR, harmonics)…**: ADC characterisation
259
+ - **SNR / SNDR / ENOB…**: numeric metrics with the same backend
260
+ - **Histogram**: distribution + Gaussian fit
261
+ - **Differentiate (dy/dx)**: numerical derivative
262
+ - **Linear fit…**, **Difference (this − other)…**, **X vs Y…**
263
+ - **2's complement decode** submenu: 8 / 10 / 12 / 16-bit signed
264
+ - **Math expressions**: create derived signals
265
+ - **Digital analysis**: bus values and timing
266
+ - **Export data**: save currently visible waveforms
267
+
268
+ #### ADC PSD dialog
269
+
270
+ Tailored for ADC bench data and behavioural simulations, inspired by
271
+ `oct_dofft.m` / `dofftsd.m`:
272
+
273
+ | Field | Meaning |
274
+ |-------|---------|
275
+ | `Sample rate F_s` | Empty → infer from the time axis |
276
+ | `Fundamental F₀` | Empty / 0 → auto (strongest non-DC bin, with DC and Nyquist guard bands) |
277
+ | `Oversampling OSR` | `>1` integrates noise only over the in-band slice (`1 … N_fft / OSR`), σΔ-style |
278
+ | `Max harmonic order` | Default 5 (H2…H5 typical for ADC reports) |
279
+ | `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 |
280
+ | `Fundamental lobe ±bins` | Separate width for the fundamental — use a wider window when jitter or drift smears the tone more than the harmonics |
281
+ | `Full-scale amplitude A_FS` | Peak FS sine amplitude (same units as `y`). Empty → spectrum is **dBc**; set → **dBFS** plot + `Signal level = … dBFS` line |
282
+ | `Exclude harmonics from SNR…` | Splits SNR vs SNDR (default on); off matches σΔ "in-band noise only" |
283
+ | `Logarithmic frequency axis` | Default on; dialog and markers stay aligned in either mode |
284
+
285
+ **Reported metrics** (per call, also shown as a banner on the main wave tab):
286
+
287
+ - `SNR`, `SNDR`, `ENOB` (`dynamic_parameters` backend)
288
+ - `SFDR` — IEEE definition: ratio of fundamental lobe to the **largest
289
+ spur, harmonics included** (always in dBc)
290
+ - `Hn` table — for each harmonic up to *Max*: integrated `lobe power`
291
+ (dBc) and `peak` bin (dBc)
292
+ - Fundamental + harmonics drawn as vertical markers, with diamond
293
+ glyphs at the spectrum peak nearest each tone
294
+
295
+ All dialog fields are **persisted between invocations** via QSettings
296
+ (`cicwave/cicwave/{snr_dialog,adc_psd_dialog}/…`), so running ADC PSD on
297
+ the next signal reuses the same `F_s`, `A_FS`, lobe widths and so on.
298
+
299
+ ### Session Management
300
+ - **File → Save Session**: Save current plot configuration
301
+ - **File → Load Session**: Restore previous analysis
302
+ - Sessions store: visible signals, zoom levels, cursor positions, analysis setup
303
+
304
+ ## Pivot Specifications
305
+
306
+ For multi-dimensional datasets, use YAML pivot specs to reshape data before visualization:
307
+
308
+ ```yaml
309
+ # analysis.yaml
310
+ index: time # X-axis (rows)
311
+ columns: [corner, temperature] # Create separate traces for each combination
312
+ values: ["v(out)", "v(in)"] # Y-axis signals to plot
313
+ conditions: # Filter data
314
+ frequency: 1e9
315
+ process: tt
316
+ ```
317
+
318
+ ```bash
319
+ cicwave --pivot analysis.yaml monte_carlo_results.csv
320
+ ```
321
+
322
+ ## Migrating from cicsim
323
+
324
+ If you previously used `cicsim wave` or the standalone `cicwave` from cicsim:
325
+
326
+ 1. **Install standalone cicwave**: `pip install cicwave`
327
+ 2. **Update workflows**: Replace `cicsim wave --backend pg` with just `cicwave`
328
+ 3. **Session files**: Existing `.cicwave.yaml` files are fully compatible
329
+ 4. **Tkinter users**: `cicsim wave --backend tk` still works in cicsim for lightweight usage
330
+
331
+ ## Development
332
+
333
+ ### Running Tests
334
+
335
+ ```bash
336
+ # Run all unit tests
337
+ python -m unittest discover -s tests/unittests/ -p 'test_*.py' -v
338
+
339
+ # Test specific functionality
340
+ python -m unittest tests.unittests.test_wavefiles_lazy -v
341
+ ```
342
+
343
+ ### Project Structure
344
+
345
+ ```
346
+ cicwave/
347
+ ├── src/cicwave/
348
+ │ ├── cli.py # Command-line interface
349
+ │ ├── wave_pg.py # Main PyQtGraph viewer
350
+ │ ├── wavefiles.py # File I/O and data loading
351
+ │ ├── ngraw.py # ngspice binary parser
352
+ │ ├── pivot.py # Data reshaping
353
+ │ ├── apisource.py # Declarative JSON REST API data sources
354
+ │ ├── theme.py # Color themes
355
+ │ └── command.py # Logging utilities
356
+ ├── tests/unittests/ # Unit test suite
357
+ └── scripts/ # Windows shortcut generator
358
+ ```
359
+
360
+ ## License
361
+
362
+ MIT License - see LICENSE file for details.
363
+
364
+ ## Contributing
365
+
366
+ Contributions welcome! Please:
367
+
368
+ 1. Fork the repository
369
+ 2. Create a feature branch
370
+ 3. Add tests for new functionality
371
+ 4. Ensure all tests pass
372
+ 5. Submit a pull request
373
+
374
+ ## Related Projects
375
+
376
+ - **[cicsim](https://github.com/wulffern/cicsim)** - Simulation orchestration and lightweight tkinter viewer
377
+ - **[cicpy](https://github.com/wulffern/cicpy)** - Analog IC design transpiler
378
+ - **[PyQtGraph](https://pyqtgraph.readthedocs.io/)** - High-performance plotting library