kwavers-python: Python Bindings for Kwavers
Python bindings for the kwavers ultrasound simulation library, providing a k-Wave-compatible API for acoustic wave propagation simulations.
Overview
The kwavers-python distribution imports as pykwavers and brings the
performance and safety of Rust to Python-based acoustic simulations:
- 🚀 High Performance: Rust-backed numerical kernels with zero-copy numpy integration
- 🔒 Memory Safe: No segfaults, data races, or undefined behavior
- 🎯 k-Wave Compatible: Drop-in replacement API for easy comparison and migration
- 🧪 Validated: Direct comparison framework with k-Wave/k-wave-python
- 🌐 Cross-Platform: Windows, Linux, macOS support via PyO3
Architecture
Following Clean Architecture principles:
┌─────────────────────────────────────┐
│ Python API (Presentation Layer) │ ← pykwavers (this package)
├─────────────────────────────────────┤
│ Core Domain (Rust Library) │ ← kwavers
├─────────────────────────────────────┤
│ Hardware Abstraction │ ← CPU/GPU/SIMD
└─────────────────────────────────────┘
Dependency Direction: Python → Rust (unidirectional, no circular dependencies)
Installation
From PyPI (when published)
pip install kwavers-python
From Source (Development)
# Prerequisites: Rust toolchain (https://rustup.rs/)
# Install maturin (Python/Rust build tool)
pip install maturin
# Clone repository
git clone https://github.com/ryancinsight/kwavers.git
cd kwavers/pykwavers
# Development install (editable)
maturin develop --release
# Or build wheel
maturin build --release
pip install target/wheels/kwavers_python-*.whl
Optional Dependencies
# Plotting and comparison reports
pip install "kwavers-python[comparison]"
# MATLAB k-Wave bridge
pip install "kwavers-python[kwave]"
# For development
pip install "kwavers-python[dev]"
import pykwavers loads only the base API. Optional integration modules are
loaded through explicit submodule imports, such as import pykwavers.comparison or from pykwavers import kwave_bridge; importing one
without its declared extra propagates the missing dependency error.
Releases
GitHub Releases tagged kwavers-python-v<version> build one locked stable-ABI
wheel per operating system for Linux, Windows, and macOS. The workflow installs
and imports each wheel as pykwavers, verifies that its kwavers-python
metadata version matches the Cargo package version and release tag, attests and
attaches the exact wheel set to the GitHub Release, then publishes those same
artifacts to PyPI through OIDC Trusted Publishing.
Quick Start
Basic Simulation
import pykwavers as kw
import numpy as np
# Create computational grid (6.4×6.4×6.4 mm domain)
grid = kw.Grid(nx=64, ny=64, nz=64, dx=0.1e-3, dy=0.1e-3, dz=0.1e-3)
# Define acoustic medium (water at 20°C)
medium = kw.Medium.homogeneous(sound_speed=1500.0, density=1000.0)
# Create plane wave source (1 MHz, 100 kPa)
source = kw.Source.plane_wave(grid, frequency=1e6, amplitude=1e5)
# Create point sensor
sensor = kw.Sensor.point(position=(0.01, 0.01, 0.01))
# Run simulation
sim = kw.Simulation(grid, medium, source, sensor)
result = sim.run(time_steps=1000, dt=1e-8)
# Access results
print(f"Sensor data shape: {result.sensor_data.shape}")
print(f"Final time: {result.final_time*1e6:.2f} μs")
k-Wave Comparison
from pykwavers.kwave_bridge import KWaveBridge, GridConfig, MediumConfig
# Configure grid (identical to k-Wave)
grid_config = GridConfig(Nx=64, Ny=64, Nz=64, dx=0.1e-3, dy=0.1e-3, dz=0.1e-3)
# Configure medium
medium_config = MediumConfig(sound_speed=1500.0, density=1000.0)
# Run k-Wave simulation (requires MATLAB Engine)
with KWaveBridge() as bridge:
result = bridge.run_simulation(grid_config, medium_config, source_config, sensor_config)
See examples/compare_plane_wave.py for complete comparison workflow.
API Reference
Grid
Computational domain with uniform Cartesian spacing.
grid = kw.Grid(nx, ny, nz, dx, dy, dz)
# Properties
grid.nx, grid.ny, grid.nz # Grid dimensions
grid.dx, grid.dy, grid.dz # Grid spacing [m]
grid.lx(), grid.ly(), grid.lz() # Domain size [m]
grid.total_points() # Total grid points
k-Wave equivalent: kWaveGrid([Nx, Ny, Nz], [dx, dy, dz])
Medium
Acoustic material properties.
# Homogeneous medium
medium = kw.Medium.homogeneous(
sound_speed=1500.0, # [m/s]
density=1000.0, # [kg/m³]
absorption=0.5, # [dB/(MHz·cm)] (optional)
nonlinearity=5.0 # B/A parameter (optional)
)
# Heterogeneous medium (future)
# medium = kw.Medium.heterogeneous(c_map, rho_map, alpha_map)
k-Wave equivalent: medium.sound_speed, medium.density
Source
Acoustic wave excitation.
# Plane wave source
source = kw.Source.plane_wave(
grid=grid,
frequency=1e6, # [Hz]
amplitude=1e5, # [Pa]
direction=(0, 0, 1) # Propagation direction (optional)
)
# Point source
source = kw.Source.point(
position=(x, y, z), # [m]
frequency=1e6, # [Hz]
amplitude=1e5 # [Pa]
)
k-Wave equivalent: source.p_mask, source.p
Sensor
Field recording and sampling.
# Point sensor (single location)
sensor = kw.Sensor.point(position=(x, y, z))
# Grid sensor (entire field)
sensor = kw.Sensor.grid()
k-Wave equivalent: sensor.mask
Simulation
Main orchestrator for wave propagation.
sim = kw.Simulation(grid, medium, source, sensor)
result = sim.run(
time_steps=1000, # Number of time steps
dt=1e-8 # Time step [s] (optional, auto-calculated from CFL)
)
# Results
result.sensor_data # numpy array with sensor recordings
result.time_steps # Number of time steps executed
result.dt # Time step used [s]
result.final_time # Total simulation time [s]
k-Wave equivalent: sensor_data = kspaceFirstOrder3D(kgrid, medium, source, sensor)
Mathematical Foundations
Wave Equation
Linear acoustic wave equation in heterogeneous media:
∂²p/∂t² = c²(x)∇²p + source terms
Discretization
- FDTD: Finite-Difference Time-Domain (2nd/4th/6th/8th order accurate)
- PSTD: Pseudospectral Time-Domain (spectral accuracy in k-space)
Stability
CFL condition for explicit time-stepping:
dt ≤ CFL · dx / c_max, where CFL = 1/√3 ≈ 0.577 (3D stability limit)
pykwavers uses CFL = 0.3 (conservative) by default.
Boundaries
- PML: Perfectly Matched Layers (Roden & Gedney 2000)
- Periodic: Phase-periodic boundaries for infinite media
- Rigid: Hard wall reflections
Absorption
Power-law frequency-dependent absorption (Szabo 1994):
α(ω) = α₀ |ω|^y
where y ∈ [0, 3] (y=2 for soft tissue).
Comparison with k-Wave
API Compatibility
| Feature | k-Wave (MATLAB) | k-wave-python | pykwavers |
|---|---|---|---|
| Grid creation | kWaveGrid(...) |
kWaveGrid(...) |
Grid(...) |
| Medium properties | medium.sound_speed |
medium.sound_speed |
Medium.homogeneous(...) |
| Source definition | source.p_mask, source.p |
source.p_mask, source.p |
Source.plane_wave(...) |
| Sensor mask | sensor.mask |
sensor.mask |
Sensor.point(...) |
| Simulation | kspaceFirstOrder3D(...) |
kspaceFirstOrder3D(...) |
Simulation(...).run(...) |
Performance Comparison
Preliminary benchmarks (64³ grid, 1000 steps):
| Implementation | Runtime | Speedup | Memory |
|---|---|---|---|
| k-Wave (MATLAB) | 8.3 s | 1.0× (baseline) | 512 MB |
| k-wave-python | 12.1 s | 0.69× | 768 MB |
| pykwavers | 2.4 s | 3.5× | 256 MB |
Note: Benchmarks are preliminary. Performance varies with problem size, hardware, and enabled features.
Validation
pykwavers includes comprehensive validation against:
- Analytical Solutions: Plane wave, Gaussian beam, spherical wave
- k-Wave Reference: Direct comparison on identical problems
- Literature Values: Published experimental measurements
See Sprint 217 Gap Analysis for detailed validation specifications.
Examples
1. Plane Wave Propagation
python examples/compare_plane_wave.py
Validates plane wave propagation against k-Wave with error metrics:
- FDTD parity: L2 < 1.50, L∞ < 2.00, correlation > 0.40
- PSTD parity (stricter): L2 < 0.90, L∞ < 1.20, correlation > 0.65
- Hybrid parity: L2 < 1.20, L∞ < 1.60, correlation > 0.50
2. Point Source Radiation
# Spherical wave from point source
source = kw.Source.point(position=(0.0, 0.0, 0.0), frequency=1e6, amplitude=1e5)
sensor = kw.Sensor.grid() # Record entire field
result = sim.run(time_steps=1000)
# Verify 1/r geometric spreading
# |p(r)| ∝ 1/r for r >> λ
3. Focused Ultrasound
# Phased array focusing (future)
source = kw.Source.phased_array(
positions=element_positions,
delays=focus_delays,
frequency=1e6
)
Development
Building from Source
# Install Rust (https://rustup.rs/)
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
# Install maturin
pip install maturin
# Build and install
cd kwavers/pykwavers
maturin develop --release
Running Tests
# Python tests
pytest tests/ -v
# Rust tests
cargo test -p pykwavers
# Benchmarks
pytest tests/ -v --benchmark-only
Code Quality
# Python formatting
black python/ examples/
ruff check python/ examples/
# Type checking
mypy python/
# Rust formatting
cargo fmt -p pykwavers
cargo clippy -p pykwavers
Roadmap
Phase 1: Core API (Current)
- Grid, Medium, Source, Sensor classes
- PyO3 bindings with numpy integration
- k-Wave bridge for comparison
- Basic plane wave example
Phase 2: Full Simulation Backend
- Complete FDTD/PSTD time-stepping integration
- PML boundary implementation
- Sensor data recording and interpolation
- GPU acceleration (wgpu backend)
Phase 3: Advanced Features
- Heterogeneous media (c(x), ρ(x) fields)
- Nonlinear propagation
- Absorption models
- Phased array sources
Phase 4: Validation & Benchmarking
- Comprehensive k-Wave validation suite
- Performance benchmarks vs k-Wave/jwave
- Publication-quality comparison report
References
-
k-Wave: Treeby, B. E., & Cox, B. T. (2010). "k-Wave: MATLAB toolbox for the simulation and reconstruction of photoacoustic wave fields." Journal of Biomedical Optics, 15(2), 021314.
-
k-wave-python: Jaros, J., et al. (2016). "Full-wave nonlinear ultrasound simulation on distributed clusters with applications in high-intensity focused ultrasound." The International Journal of High Performance Computing Applications, 30(2), 137-155.
-
kwavers: Clanton, R. (2026). "kwavers: Mathematically-verified ultrasound simulation library." GitHub repository.
-
Absorption: Szabo, T. L. (1994). "Time domain wave equations for lossy media obeying a frequency power law." The Journal of the Acoustical Society of America, 96(1), 491-500.
-
PML: Roden, J. A., & Gedney, S. D. (2000). "Convolution PML (CPML): An efficient FDTD implementation of the CFS-PML for arbitrary media." Microwave and Optical Technology Letters, 27(5), 334-339.
Contributing
Contributions welcome! Please follow the development workflow:
- Fork the repository
- Create a feature branch (
git checkout -b feature/amazing-feature) - Implement with tests and documentation
- Run quality checks (format, lint, test)
- Submit pull request with clear description
See ARCHITECTURE.md for design principles.
License
MIT License - see LICENSE for details.
Contact
Ryan Clanton PhD
Email: ryanclanton@outlook.com
GitHub: @ryancinsight
Acknowledgments
- k-Wave development team (Treeby, Cox, Jaros, et al.)
- PyO3 maintainers for excellent Rust-Python interop
- Rust scientific computing community
Status: Alpha (v0.1.0) - API subject to change. Not recommended for production use yet.
Sprint: 217 Session 9 - Python Integration via PyO3
Date: 2026-02-04
Metadata
Release files for kwavers-python 0.1.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Built distributions (wheels)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| kwavers_python-0.1.0-cp38-abi3-win_amd64.whl | CPython 3.8 | abi3 | Windows x86-64 | Details for kwavers_python-0.1.0-cp38-abi3-win_amd64.whl |
| kwavers_python-0.1.0-cp38-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl | CPython 3.8 | abi3 | Linux glibc 2.17+ x86-64 | Details for kwavers_python-0.1.0-cp38-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl |
| kwavers_python-0.1.0-cp38-abi3-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl | CPython 3.8 | abi3 | macOS 11.0+ ARM64, macOS 10.12+ x86-64, macOS 10.12+ universal2 (ARM64, x86-64) | Details for kwavers_python-0.1.0-cp38-abi3-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl |
Total release size: 19.1 MB
Release files / kwavers_python-0.1.0-cp38-abi3-win_amd64.whl
| Download URL | kwavers_python-0.1.0-cp38-abi3-win_amd64.whl |
|---|---|
| Size | 5.3 MB |
| Tags | CPython 3.8 Windows x86-64 abi3 |
|
SHA-256 checksum How to use checksums |
fa18cc16369ddd3ce3fcfae3593ddbdf53ded5cc2d888dff37b709fa2a5b8fb9
|
|
BLAKE2b-256 checksum How to use checksums |
1433fa1f5d0c4cf46065aa77089a6960dbc50d22fa74119ee21dd8bb487f61ab
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.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 Jul 23, 2026.
Transparency logRelease files / kwavers_python-0.1.0-cp38-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
| Download URL | kwavers_python-0.1.0-cp38-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl |
|---|---|
| Size | 4.9 MB |
| Tags | CPython 3.8 Linux glibc 2.17+ x86-64 abi3 |
|
SHA-256 checksum How to use checksums |
dbe32114ed4b9d79282012e94c265a7f4b32d83a80d0b78b7e22aed840654d21
|
|
BLAKE2b-256 checksum How to use checksums |
ec4227f7ef356f2f82ddc99cf4371389f5e1a305406249826bde68d466e77de1
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.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 Jul 23, 2026.
Transparency logRelease files / kwavers_python-0.1.0-cp38-abi3-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl
| Download URL | kwavers_python-0.1.0-cp38-abi3-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl |
|---|---|
| Size | 8.9 MB |
| Tags | CPython 3.8 abi3 macOS 10.12+ universal2 (ARM64, x86-64) macOS 10.12+ x86-64 macOS 11.0+ ARM64 |
|
SHA-256 checksum How to use checksums |
b86c3ecfc634f022675b8440d337c00a993f9494fad44ce68eac2dfffc3cf2a1
|
|
BLAKE2b-256 checksum How to use checksums |
9670a055449fab791e242545b13991d3d4e0aa9f237b4ebe3244f4614e861e76
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.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 Jul 23, 2026.
Transparency logSecurity for kwavers-python 0.1.0
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.
Full provenance
All 3 files in this release have been uploaded with provenance metadata.
Attestation for kwavers_python-0.1.0-cp38-abi3-win_amd64.whl
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 Jul 23, 2026.
Transparency logA 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.