miepython
is a pure‑Python implementation of Mie theory for spherical
scatterers, validated against Wiscombe's reference results. The library is
lightweight, extensively tested, and—thanks to an optional Numba backend—can
process nearly a million particles per second.
- Non-absorbing spheres (dielectric particles)
- Partially-absorbing spheres (lossy dielectrics)
- Perfectly-conducting spheres (metallic particles)
- ✅ Pure Python - No external dependencies beyond NumPy
- ✅ Validated algorithms - Follows Wiscombe's trusted implementation
- ✅ Comprehensive outputs - Extinction, scattering, backscattering, asymmetry
- ✅ Angular distributions - Full scattering phase functions
- ✅ Flexible normalization - Multiple conventions supported
- ✅ Code Jitting - the python Numba package enables 10-50X speedup
- ✅ Field calculations - Internal field coefficients coming!
- Full Documentation: miepython.readthedocs.io
- API Reference: miepython api
- Jupyter Notebooks: Interactive Jupyter notebooks
- Theory Background: Mathematical foundations and validation
Version 3.0 introduced significant API changes to rationalize the API as well as new functionality:
- Enhanced coefficient access - Direct access to Mie expansion coefficients
- Future-ready architecture - Foundation for full field calculations
If you need the old API, pin to version 2.5.5:
pip install miepython==2.5.5
Using pip:
pip install miepython
Using conda:
conda install -c conda-forge miepython
import miepython as mie
# Define sphere properties
m = 1.5 - 1j # Complex refractive index
d = 100 # Diameter (nm)
lambda0 = 314.15 # Wavelength in vacuum (nm)
# Calculate efficiencies
qext, qsca, qback, g = mie.efficiencies(m, d, lambda0)
print(f"Extinction efficiency: {qext:.3f}")
print(f"Scattering efficiency: {qsca:.3f}")
print(f"Backscatter efficiency: {qback:.3f}")
print(f"Scattering anisotropy: {g:.3f}")
Output:
Extinction efficiency: 2.336
Scattering efficiency: 0.663
Backscatter efficiency: 0.573
Scattering anisotropy: 0.192
Function | Purpose |
---|---|
efficiencies(m, d, lambda0, n_env=1) |
Calculate extinction, scattering, backscattering, asymmetry |
intensities(m, d, lambda0, mu, n_env=1) |
Angular scattering intensities for parallel/perpendicular polarization |
S1_S2(m, x, mu) |
Complex scattering amplitudes |
coefficients(m, x) |
Mie coefficients for field calculations |
phase_matrix(m, x, mu) |
Mueller matrix for sphere |
- m (complex): Complex refractive index of sphere
- n_env (complex): Real refractive index of medium
- d (float): Sphere diameter [same units as wavelength]
- lambda0 (float): Wavelength in vacuum [same units as diameter]
- x (float): Size parameter (π×diameter/wavelength)
- mu (array): Cosine of scattering angles
- Negative imaginary refractive index: For absorbing materials, use
m = n - ik
where k > 0- Albedo normalization: Scattering phase functions integrate to the single scattering albedo over 4π steradians (customizable)
These latter may be mitigated using custom normalization
# Different scattering function normalizations
I_albedo = mie.i_unpolarized(m, x, mu, norm='albedo') # Default
I_unity = mie.i_unpolarized(m, x, mu, norm='one') # Normalized to 1
I_4pi = mie.i_unpolarized(m, x, mu, norm='4pi') # 4π normalization
miepython
supports Just-In-Time (JIT) compilation via Numba for dramatic performance improvements on large datasets. This is especially beneficial for batch calculations with thousands of particles.
import os
os.environ["MIEPYTHON_USE_JIT"] = "1" # Must be set before importing
import miepython as mie
JIT compilation provides substantial speedups for large-scale calculations:
Version | JIT Status | Time (N=100,000) | Speedup |
---|---|---|---|
v3.0.1 | Disabled | 4.00 seconds | 1× |
v3.0.1 | Enabled | 0.15 seconds | 27× |
import os
import numpy as np
from time import time
os.environ["MIEPYTHON_USE_JIT"] = "1" # must be before import miepython
import miepython as mie
# Generate random particle ensemble
N = 100_000
refr = np.random.uniform(1.0, 2.0, N)
refi = np.exp(np.random.uniform(np.log(1e-4), np.log(1.0), N))
x = np.exp(np.random.uniform(np.log(0.01), np.log(100), N))
m = refr - 1j * refi
# Benchmark calculation
t0 = time()
qext, qsca, qback, g = mie.efficiencies_mx(m, x)
elapsed = time() - t0
print(f"JIT enabled: {os.environ.get('MIEPYTHON_USE_JIT') == '1'}")
print(f"Calculated {N:,} particles in {elapsed:.3f} seconds")
print(f"Rate: {N/elapsed:,.0f} particles/second")
Note
The first JIT-compiled call includes compilation overhead (~1-2 seconds). Subsequent calls achieve full performance.
The repository includes several example scripts demonstrating different applications:
If this library contributes to your research, please cite the relevant doi release on zenodo
- Generic DOI (always the newest release) — 10.5281/zenodo.7949263. The badge at the top of this file resolves to that record.
- Version‑specific DOIs — click the Zenodo badge
and choose the DOI that corresponds to the exact version you want to cite (e.g. 10.5281/zenodo.14257432 for v2.5.5).
For example:
S. Prahl, *miepython — Pure‑Python Mie scattering calculations*, Zenodo, 16 March 2025. doi:10.5281/zenodo.7949263
@software{prahl_miepython_2025,
author = {Prahl, Scott},
title = {{miepython}: A Python library for Mie scattering calculations},
url = {https://github.com/scottprahl/miepython},
doi = {10.5281/zenodo.7949263},
year = {2025},
version = {latest}
}
miepython
is licensed under the MIT License.
Maintained by Scott Prahl