Metadata-Version: 2.4
Name: sedes
Version: 0.1.8
Classifier: Development Status :: 3 - Alpha
Classifier: Operating System :: POSIX :: Linux
Classifier: Operating System :: MacOS
Classifier: Operating System :: Microsoft :: Windows
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: Scientific/Engineering
Classifier: Topic :: Scientific/Engineering :: Electronic Design Automation (EDA)
Requires-Dist: numpy
Summary: Parallel ngspice SPICE simulation from Python — LTspice-friendly, with built-in MOSFET LUT and gm/Id sizing
Keywords: spice,ngspice,circuit,simulation,ltspice,analog,mosfet,gm-id
License: MIT
Requires-Python: >=3.10
Description-Content-Type: text/markdown; charset=UTF-8; variant=GFM
Project-URL: Documentation, https://github.com/timvandenakker/sedes/blob/main/sedes/README.md
Project-URL: Homepage, https://github.com/timvandenakker/sedes
Project-URL: Issues, https://github.com/timvandenakker/sedes/issues

# sedes

Parallel ngspice SPICE simulation from Python.  LTspice-friendly, with built-in
MOSFET LUT generation and gm/Id sizing.

- **Cross-platform**: prebuilt wheels for Linux, macOS, and Windows (x86_64,
  plus arm64 on macOS).  Python 3.10+.
- **No system ngspice required**: libngspice is bundled inside the wheel.
- **No GIL bottleneck**: simulations run in parallel ngspice worker
  subprocesses, dispatched by an internal tokio runtime.
- **Typed surface**: ships `py.typed` and a hand-written `.pyi` so Pyright,
  Pylance, and mypy give you full autocomplete out of the box.

## Install

```bash
pip install sedes
```

That's it — no Rust toolchain, no SPICE install, no DLL hunt.

## Quickstart — run a netlist, sweep a value

```python
import numpy as np
import sedes

# Build a circuit programmatically …
ckt = (sedes.Circuit("RC filter")
    .V("v1", "in", "0", "ac 1")
    .R("r1", "in", "out", "1k")
    .C("c1", "out", "0", "100n")
    .ac("dec", 100, 1, 1e6))

# … or load one exported from LTspice (View → SPICE Netlist):
# ckt = sedes.Circuit.from_file("filter.cir")

pool = sedes.SimulationPool(workers=8)

# One run
result = ckt.run(pool)
print(result.frequency.shape, result.vector("v(out)").shape)

# Multi-value sweep — Cartesian product, run in parallel.
results = sedes.sweep(ckt, pool, {"r1": ["1k", "2.2k", "10k"]})
for R, r in zip(["1k", "2.2k", "10k"], results):
    mag = r.mag("v(out)")
    f_3db = r.frequency[np.argmin(np.abs(mag - 1/np.sqrt(2)))]
    print(f"R={R:>4}  →  f_-3dB ≈ {f_3db:.0f} Hz")
```

A runnable version of this lives at [`examples/rc_sweep.py`](examples/rc_sweep.py).

## What's in the package

| Import | Role |
|---|---|
| `sedes.Circuit` | Programmatic SPICE netlist builder. Load with `Circuit.from_file(...)`, mutate with `.set_value()`, `.replace()`, `.remove()`, attach analyses with `.op()` / `.tran()` / `.dc()` / `.ac()` / `.noise()`. |
| `sedes.parse_file`, `parse_string` | Standalone netlist parsers. |
| `sedes.SimulationPool` | Worker-pool dispatcher. `pool.run_simulation(netlist, ["run"])`, `pool.run_simulations_batch(jobs)`, `pool.generate_lut(cfg)`. |
| `sedes.sweep` | Cartesian-product parameter sweep over component values, returns typed result list. |
| `sedes.LutConfig` / `sedes.Lut` | MOSFET characterisation (Id, gm, gds, capacitances, ft) and gm/Id transistor sizing. |
| `sedes.OpResult` / `TranResult` / `DCResult` / `ACResult` / `NoiseResult` / … | Typed result wrappers with `.plot()` helpers. |
| `sedes.PsfFile` / `sedes.NgpsfFile` | Cadence PSF / PSFXL waveform readers (pure Rust, no `libpsf`). |

## Coming from LTspice?

Read **[`docs/ltspice_migration.md`](docs/ltspice_migration.md)** for the
export workflow and the syntax differences that matter (the big one: in
ngspice, `M` is **mega**, `m` is **milli** — LTspice is more forgiving).

For sweep recipes (1-axis, 2-axis corner grids, MOSFET parameter sweeps) see
**[`docs/sweeps.md`](docs/sweeps.md)**.

## Supported platforms

| OS | Architecture | Python |
|---|---|---|
| Linux  | x86_64 (manylinux_2_28) | 3.10–3.13 |
| macOS  | x86_64, aarch64         | 3.10–3.13 |
| Windows | x86_64                  | 3.10–3.13 |

## Development

```bash
# Build once, populate the bundled libngspice into python/sedes/_libs:
bash ../.github/scripts/fetch_ngspice.sh macos python/sedes/_libs

# Build the extension and install it editable into a venv:
uv venv && uv pip install maturin numpy
uv run maturin develop --release
uv run python examples/rc_sweep.py
```

When you change the `#[pyclass]` / `#[pyfunction]` surface under `src/python/`
or `src/psf/python.rs`, also update `python/sedes/sedes.pyi` so IDE
autocomplete remains accurate.

## License

MIT — see [`LICENSE`](../LICENSE).

