miepython 3.0.0__tar.gz → 3.0.2__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.
- {miepython-3.0.0 → miepython-3.0.2}/CHANGELOG.rst +12 -0
- {miepython-3.0.0 → miepython-3.0.2}/CITATION.cff +2 -2
- miepython-3.0.2/PKG-INFO +330 -0
- miepython-3.0.2/README.rst +299 -0
- {miepython-3.0.0 → miepython-3.0.2}/miepython/__init__.py +24 -9
- {miepython-3.0.0 → miepython-3.0.2}/miepython/core.py +58 -273
- {miepython-3.0.0 → miepython-3.0.2}/miepython/field.py +1 -1
- {miepython-3.0.0 → miepython-3.0.2}/miepython/mie_jit.py +187 -19
- {miepython-3.0.0 → miepython-3.0.2}/miepython/mie_nojit.py +174 -18
- {miepython-3.0.0 → miepython-3.0.2}/miepython/util.py +1 -1
- {miepython-3.0.0 → miepython-3.0.2}/miepython/vsh.py +2 -2
- miepython-3.0.2/miepython.egg-info/PKG-INFO +330 -0
- {miepython-3.0.0 → miepython-3.0.2}/miepython.egg-info/SOURCES.txt +2 -0
- {miepython-3.0.0 → miepython-3.0.2}/pyproject.toml +1 -1
- {miepython-3.0.0 → miepython-3.0.2}/tests/test_jit.py +3 -0
- {miepython-3.0.0 → miepython-3.0.2}/tests/test_jit_D.py +13 -11
- {miepython-3.0.0 → miepython-3.0.2}/tests/test_jit_abcd.py +11 -5
- miepython-3.0.2/tests/test_jit_speed.py +45 -0
- {miepython-3.0.0 → miepython-3.0.2}/tests/test_nojit_D.py +13 -11
- {miepython-3.0.0 → miepython-3.0.2}/tests/test_nojit_abcd.py +17 -14
- miepython-3.0.2/tests/test_nojit_speed.py +45 -0
- miepython-3.0.0/PKG-INFO +0 -179
- miepython-3.0.0/README.rst +0 -149
- miepython-3.0.0/miepython.egg-info/PKG-INFO +0 -179
- {miepython-3.0.0 → miepython-3.0.2}/LICENSE.txt +0 -0
- {miepython-3.0.0 → miepython-3.0.2}/MANIFEST.in +0 -0
- {miepython-3.0.0 → miepython-3.0.2}/miepython/bessel.py +0 -0
- {miepython-3.0.0 → miepython-3.0.2}/miepython/data/Johnson.txt +0 -0
- {miepython-3.0.0 → miepython-3.0.2}/miepython/data/ag-Johnson.txt +0 -0
- {miepython-3.0.0 → miepython-3.0.2}/miepython/data/segelstein81_index.txt +0 -0
- {miepython-3.0.0 → miepython-3.0.2}/miepython/examples/01_dielectric.py +0 -0
- {miepython-3.0.0 → miepython-3.0.2}/miepython/examples/02_glass.py +0 -0
- {miepython-3.0.0 → miepython-3.0.2}/miepython/examples/03_droplets.py +0 -0
- {miepython-3.0.0 → miepython-3.0.2}/miepython/examples/04_gold.py +0 -0
- {miepython-3.0.0 → miepython-3.0.2}/miepython/monte_carlo.py +0 -0
- {miepython-3.0.0 → miepython-3.0.2}/miepython/rayleigh.py +0 -0
- {miepython-3.0.0 → miepython-3.0.2}/miepython.egg-info/dependency_links.txt +0 -0
- {miepython-3.0.0 → miepython-3.0.2}/miepython.egg-info/requires.txt +0 -0
- {miepython-3.0.0 → miepython-3.0.2}/miepython.egg-info/top_level.txt +0 -0
- {miepython-3.0.0 → miepython-3.0.2}/requirements-dev.txt +0 -0
- {miepython-3.0.0 → miepython-3.0.2}/requirements.txt +0 -0
- {miepython-3.0.0 → miepython-3.0.2}/setup.cfg +0 -0
- {miepython-3.0.0 → miepython-3.0.2}/setup.py +0 -0
- {miepython-3.0.0 → miepython-3.0.2}/tests/test_bessel.py +0 -0
- {miepython-3.0.0 → miepython-3.0.2}/tests/test_field.py +0 -0
- {miepython-3.0.0 → miepython-3.0.2}/tests/test_nojit.py +0 -0
- {miepython-3.0.0 → miepython-3.0.2}/tests/test_rayleigh.py +0 -0
- {miepython-3.0.0 → miepython-3.0.2}/tests/test_vsh.py +0 -0
|
@@ -1,6 +1,18 @@
|
|
|
1
1
|
Changelog
|
|
2
2
|
=========
|
|
3
3
|
|
|
4
|
+
3.0.1 (5/25/2025)
|
|
5
|
+
-------------------
|
|
6
|
+
* fix JIT regression (thanks @avgeiss)
|
|
7
|
+
* clarify polarization in docstrings
|
|
8
|
+
* improve README.rst
|
|
9
|
+
* fix git branches
|
|
10
|
+
* rename mie.mie_scalar to mie.single_sphere
|
|
11
|
+
* rename small_mie_sphere to small_sphere
|
|
12
|
+
* rename small_conducting_mie to small_conducting_sphere
|
|
13
|
+
* rationalize importing of jit and non-jit code
|
|
14
|
+
* add test_jit_speed.py and test_nojit_speed.py
|
|
15
|
+
|
|
4
16
|
3.0.0 (3/16/2025)
|
|
5
17
|
-------------------
|
|
6
18
|
* breaking api changes
|
|
@@ -3,9 +3,9 @@ authors:
|
|
|
3
3
|
given-names: Scott
|
|
4
4
|
orcid: https://orcid.org/0000-0003-1468-6851
|
|
5
5
|
cff-version: 1.2.0
|
|
6
|
-
date-released: '
|
|
6
|
+
date-released: '2025-05-25'
|
|
7
7
|
doi: 10.5281/zenodo.7949264
|
|
8
8
|
message: If you use this software, please cite it as below.
|
|
9
9
|
title: 'miepython: Pure python calculation of Mie scattering'
|
|
10
10
|
url: https://doi.org/10.5281/zenodo.7949403
|
|
11
|
-
version:
|
|
11
|
+
version: 3.0.2
|
miepython-3.0.2/PKG-INFO
ADDED
|
@@ -0,0 +1,330 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: miepython
|
|
3
|
+
Version: 3.0.2
|
|
4
|
+
Summary: Mie scattering of a plane wave by a sphere
|
|
5
|
+
Home-page: https://github.com/scottprahl/miepython.git
|
|
6
|
+
Author: Scott Prahl
|
|
7
|
+
Author-email: scott.prahl@oit.edu
|
|
8
|
+
License: MIT License
|
|
9
|
+
Keywords: mie,scattering,rainbow,droplet,backscatter,sphere,nanoparticle,cloud,phase function,efficiency,rayleigh,backscattering
|
|
10
|
+
Classifier: Development Status :: 5 - Production/Stable
|
|
11
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
12
|
+
Classifier: Intended Audience :: Science/Research
|
|
13
|
+
Classifier: Programming Language :: Python
|
|
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: Programming Language :: Python :: 3.12
|
|
20
|
+
Requires-Python: >=3.8
|
|
21
|
+
Description-Content-Type: text/x-rst
|
|
22
|
+
License-File: LICENSE.txt
|
|
23
|
+
Requires-Dist: numpy
|
|
24
|
+
Requires-Dist: matplotlib
|
|
25
|
+
Requires-Dist: numba
|
|
26
|
+
Requires-Dist: scipy
|
|
27
|
+
Dynamic: author
|
|
28
|
+
Dynamic: author-email
|
|
29
|
+
Dynamic: home-page
|
|
30
|
+
Dynamic: license-file
|
|
31
|
+
|
|
32
|
+
.. |pypi| image:: https://img.shields.io/pypi/v/miepython?color=68CA66
|
|
33
|
+
:target: https://pypi.org/project/miepython/
|
|
34
|
+
:alt: PyPI
|
|
35
|
+
|
|
36
|
+
.. |github| image:: https://img.shields.io/github/v/tag/scottprahl/miepython?label=github&color=68CA66
|
|
37
|
+
:target: https://github.com/scottprahl/miepython
|
|
38
|
+
:alt: GitHub
|
|
39
|
+
|
|
40
|
+
.. |conda| image:: https://img.shields.io/conda/vn/conda-forge/miepython?label=conda&color=68CA66
|
|
41
|
+
:target: https://github.com/conda-forge/miepython-feedstock
|
|
42
|
+
:alt: Conda
|
|
43
|
+
|
|
44
|
+
.. |doi| image:: https://zenodo.org/badge/99259684.svg
|
|
45
|
+
:target: https://zenodo.org/badge/latestdoi/99259684
|
|
46
|
+
:alt: DOI
|
|
47
|
+
|
|
48
|
+
.. |license| image:: https://img.shields.io/github/license/scottprahl/miepython?color=68CA66
|
|
49
|
+
:target: https://github.com/scottprahl/miepython/blob/master/LICENSE.txt
|
|
50
|
+
:alt: License
|
|
51
|
+
|
|
52
|
+
.. |test| image:: https://github.com/scottprahl/miepython/actions/workflows/test.yml/badge.svg
|
|
53
|
+
:target: https://github.com/scottprahl/miepython/actions/workflows/test.yml
|
|
54
|
+
:alt: Testing
|
|
55
|
+
|
|
56
|
+
.. |docs| image:: https://readthedocs.org/projects/miepython/badge?color=68CA66
|
|
57
|
+
:target: https://miepython.readthedocs.io
|
|
58
|
+
:alt: Docs
|
|
59
|
+
|
|
60
|
+
.. |downloads| image:: https://img.shields.io/pypi/dm/miepython?color=68CA66
|
|
61
|
+
:target: https://pypi.org/project/miepython/
|
|
62
|
+
:alt: Downloads
|
|
63
|
+
|
|
64
|
+
.. |black| image:: https://img.shields.io/badge/code%20style-black-000000.svg
|
|
65
|
+
:target: https://github.com/psf/black
|
|
66
|
+
:alt: code style: black
|
|
67
|
+
|
|
68
|
+
miepython
|
|
69
|
+
=========
|
|
70
|
+
|
|
71
|
+
|pypi| |github| |conda| |doi|
|
|
72
|
+
|
|
73
|
+
|license| |test| |docs| |downloads| |black|
|
|
74
|
+
|
|
75
|
+
``miepython`` is a pure‑Python implementation of Mie theory for spherical
|
|
76
|
+
scatterers, validated against Wiscombe's reference results. The library is
|
|
77
|
+
lightweight, extensively tested, and—thanks to an *optional* Numba backend—can
|
|
78
|
+
process nearly a million particles per second.
|
|
79
|
+
|
|
80
|
+
Overview
|
|
81
|
+
--------
|
|
82
|
+
|
|
83
|
+
- **Non-absorbing spheres** (dielectric particles)
|
|
84
|
+
- **Partially-absorbing spheres** (lossy dielectrics)
|
|
85
|
+
- **Perfectly-conducting spheres** (metallic particles)
|
|
86
|
+
|
|
87
|
+
Key Features
|
|
88
|
+
~~~~~~~~~~~~
|
|
89
|
+
|
|
90
|
+
- ✅ **Pure Python** - No external dependencies beyond NumPy
|
|
91
|
+
- ✅ **Validated algorithms** - Follows Wiscombe's trusted implementation
|
|
92
|
+
- ✅ **Comprehensive outputs** - Extinction, scattering, backscattering, asymmetry
|
|
93
|
+
- ✅ **Angular distributions** - Full scattering phase functions
|
|
94
|
+
- ✅ **Flexible normalization** - Multiple conventions supported
|
|
95
|
+
- ✅ **Code Jitting** - the python Numba package enables 10-50X speedup
|
|
96
|
+
- ✅ **Field calculations** - Internal field coefficients coming!
|
|
97
|
+
|
|
98
|
+
|
|
99
|
+
Documentation
|
|
100
|
+
-------------
|
|
101
|
+
|
|
102
|
+
- **Full Documentation**: `miepython.readthedocs.io <https://miepython.readthedocs.io>`_
|
|
103
|
+
- **API Reference**: `miepython api <https://miepython.readthedocs.io/en/latest/#api-reference>`_
|
|
104
|
+
- **Jupyter Notebooks**: `Interactive Jupyter notebooks <https://github.com/scottprahl/miepython/tree/main/docs>`_
|
|
105
|
+
- **Theory Background**: `Mathematical foundations and validation <https://miepython.readthedocs.io/en/latest/07_algorithm.html>`_
|
|
106
|
+
|
|
107
|
+
Version 3.0 Breaking Changes
|
|
108
|
+
----------------------------
|
|
109
|
+
|
|
110
|
+
Version 3.0 introduced significant API changes and new functionality:
|
|
111
|
+
|
|
112
|
+
- **Internal field calculations** - Compute electromagnetic fields inside spheres
|
|
113
|
+
- **Enhanced coefficient access** - Direct access to Mie expansion coefficients
|
|
114
|
+
- **Future-ready architecture** - Foundation for full field calculations
|
|
115
|
+
|
|
116
|
+
If you need the old API, pin to version 2.5.5::
|
|
117
|
+
|
|
118
|
+
pip install miepython==2.5.5
|
|
119
|
+
|
|
120
|
+
Installation
|
|
121
|
+
~~~~~~~~~~~~
|
|
122
|
+
|
|
123
|
+
Using pip::
|
|
124
|
+
|
|
125
|
+
pip install miepython
|
|
126
|
+
|
|
127
|
+
Using conda::
|
|
128
|
+
|
|
129
|
+
conda install -c conda-forge miepython
|
|
130
|
+
|
|
131
|
+
Basic Example
|
|
132
|
+
~~~~~~~~~~~~~
|
|
133
|
+
|
|
134
|
+
.. code-block:: python
|
|
135
|
+
|
|
136
|
+
import miepython as mie
|
|
137
|
+
|
|
138
|
+
# Define sphere properties
|
|
139
|
+
m = 1.5 - 1j # Complex refractive index
|
|
140
|
+
d = 100 # Diameter (nm)
|
|
141
|
+
lambda0 = 314.15 # Wavelength in vacuum (nm)
|
|
142
|
+
|
|
143
|
+
# Calculate efficiencies
|
|
144
|
+
qext, qsca, qback, g = mie.efficiencies(m, d, lambda0)
|
|
145
|
+
|
|
146
|
+
print(f"Extinction efficiency: {qext:.3f}")
|
|
147
|
+
print(f"Scattering efficiency: {qsca:.3f}")
|
|
148
|
+
print(f"Backscatter efficiency: {qback:.3f}")
|
|
149
|
+
print(f"Scattering anisotropy: {g:.3f}")
|
|
150
|
+
|
|
151
|
+
**Output:**
|
|
152
|
+
|
|
153
|
+
.. code-block:: text
|
|
154
|
+
|
|
155
|
+
Extinction efficiency: 2.336
|
|
156
|
+
Scattering efficiency: 0.663
|
|
157
|
+
Backscatter efficiency: 0.573
|
|
158
|
+
Scattering anisotropy: 0.192
|
|
159
|
+
|
|
160
|
+
|
|
161
|
+
API Reference
|
|
162
|
+
-------------
|
|
163
|
+
|
|
164
|
+
Basic Functions
|
|
165
|
+
~~~~~~~~~~~~~~~
|
|
166
|
+
|
|
167
|
+
============================================ ===========================================================
|
|
168
|
+
Function Purpose
|
|
169
|
+
============================================ ===========================================================
|
|
170
|
+
``efficiencies(m, d, lambda0, n_env=1)`` Calculate extinction, scattering, backscattering, asymmetry
|
|
171
|
+
``intensities(m, d, lambda0, mu, n_env=1)`` Angular scattering intensities for parallel/perpendicular polarization
|
|
172
|
+
``S1_S2(m, x, mu)`` Complex scattering amplitudes
|
|
173
|
+
``coefficients(m, x)`` Mie coefficients for field calculations
|
|
174
|
+
``phase_matrix(m, x, mu)`` Mueller matrix for sphere
|
|
175
|
+
============================================ ===========================================================
|
|
176
|
+
|
|
177
|
+
Parameters
|
|
178
|
+
~~~~~~~~~~
|
|
179
|
+
|
|
180
|
+
- **m** (complex): Complex refractive index of sphere
|
|
181
|
+
- **n_env** (complex): Real refractive index of medium
|
|
182
|
+
- **d** (float): Sphere diameter [same units as wavelength]
|
|
183
|
+
- **lambda0** (float): Wavelength in vacuum [same units as diameter]
|
|
184
|
+
- **x** (float): Size parameter (π×diameter/wavelength)
|
|
185
|
+
- **mu** (array): Cosine of scattering angles
|
|
186
|
+
|
|
187
|
+
|
|
188
|
+
Important Conventions
|
|
189
|
+
---------------------
|
|
190
|
+
|
|
191
|
+
1. **Negative imaginary refractive index**: For absorbing materials, use ``m = n - ik`` where k > 0
|
|
192
|
+
2. **Albedo normalization**: Scattering phase functions integrate to the single scattering albedo over 4π steradians (customizable)
|
|
193
|
+
|
|
194
|
+
These latter may be mitigated using custom normalization
|
|
195
|
+
|
|
196
|
+
.. code-block:: python
|
|
197
|
+
|
|
198
|
+
# Different scattering function normalizations
|
|
199
|
+
I_albedo = mie.i_unpolarized(m, x, mu, norm='albedo') # Default
|
|
200
|
+
I_unity = mie.i_unpolarized(m, x, mu, norm='one') # Normalized to 1
|
|
201
|
+
I_4pi = mie.i_unpolarized(m, x, mu, norm='4pi') # 4π normalization
|
|
202
|
+
|
|
203
|
+
|
|
204
|
+
|
|
205
|
+
Performance & JIT Compilation
|
|
206
|
+
-----------------------------
|
|
207
|
+
|
|
208
|
+
``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.
|
|
209
|
+
|
|
210
|
+
Enabling JIT
|
|
211
|
+
~~~~~~~~~~~~
|
|
212
|
+
|
|
213
|
+
.. code-block:: python
|
|
214
|
+
|
|
215
|
+
import os
|
|
216
|
+
os.environ["MIEPYTHON_USE_JIT"] = "1" # Must be set before importing
|
|
217
|
+
import miepython as mie
|
|
218
|
+
|
|
219
|
+
Performance Comparison
|
|
220
|
+
~~~~~~~~~~~~~~~~~~~~~~
|
|
221
|
+
|
|
222
|
+
JIT compilation provides substantial speedups for large-scale calculations:
|
|
223
|
+
|
|
224
|
+
=========== ============== ================== ==========
|
|
225
|
+
Version JIT Status Time (N=100,000) Speedup
|
|
226
|
+
=========== ============== ================== ==========
|
|
227
|
+
v3.0.1 Disabled 4.00 seconds 1×
|
|
228
|
+
v3.0.1 **Enabled** **0.15 seconds** **27×**
|
|
229
|
+
=========== ============== ================== ==========
|
|
230
|
+
|
|
231
|
+
Benchmark Example
|
|
232
|
+
~~~~~~~~~~~~~~~~~
|
|
233
|
+
|
|
234
|
+
.. code-block:: python
|
|
235
|
+
|
|
236
|
+
import os
|
|
237
|
+
import numpy as np
|
|
238
|
+
from time import time
|
|
239
|
+
|
|
240
|
+
os.environ["MIEPYTHON_USE_JIT"] = "1" # must be before import miepython
|
|
241
|
+
import miepython as mie
|
|
242
|
+
|
|
243
|
+
# Generate random particle ensemble
|
|
244
|
+
N = 100_000
|
|
245
|
+
refr = np.random.uniform(1.0, 2.0, N)
|
|
246
|
+
refi = np.exp(np.random.uniform(np.log(1e-4), np.log(1.0), N))
|
|
247
|
+
x = np.exp(np.random.uniform(np.log(0.01), np.log(100), N))
|
|
248
|
+
m = refr - 1j * refi
|
|
249
|
+
|
|
250
|
+
# Benchmark calculation
|
|
251
|
+
t0 = time()
|
|
252
|
+
qext, qsca, qback, g = mie.efficiencies_mx(m, x)
|
|
253
|
+
elapsed = time() - t0
|
|
254
|
+
|
|
255
|
+
print(f"JIT enabled: {os.environ.get('MIEPYTHON_USE_JIT') == '1'}")
|
|
256
|
+
print(f"Calculated {N:,} particles in {elapsed:.3f} seconds")
|
|
257
|
+
print(f"Rate: {N/elapsed:,.0f} particles/second")
|
|
258
|
+
|
|
259
|
+
.. note::
|
|
260
|
+
The first JIT-compiled call includes compilation overhead (~1-2 seconds). Subsequent calls achieve full performance.
|
|
261
|
+
|
|
262
|
+
Examples Gallery
|
|
263
|
+
----------------
|
|
264
|
+
|
|
265
|
+
The repository includes several `example scripts <https://github.com/scottprahl/miepython/tree/master/miepython/examples>`_ demonstrating different applications:
|
|
266
|
+
|
|
267
|
+
Dielectric vs. Absorbing Spheres
|
|
268
|
+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
269
|
+
|
|
270
|
+
.. image:: https://raw.githubusercontent.com/scottprahl/miepython/main/docs/01.svg
|
|
271
|
+
:alt: Dielectric vs Absorbing
|
|
272
|
+
|
|
273
|
+
Glass Microspheres with Resonances
|
|
274
|
+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
275
|
+
|
|
276
|
+
.. image:: https://raw.githubusercontent.com/scottprahl/miepython/main/docs/02.svg
|
|
277
|
+
:alt: Glass Spheres
|
|
278
|
+
|
|
279
|
+
Water Droplets
|
|
280
|
+
~~~~~~~~~~~~~~
|
|
281
|
+
|
|
282
|
+
.. image:: https://raw.githubusercontent.com/scottprahl/miepython/main/docs/03.svg
|
|
283
|
+
:alt: Water Droplets
|
|
284
|
+
|
|
285
|
+
Gold Nanoparticles
|
|
286
|
+
~~~~~~~~~~~~~~~~~~
|
|
287
|
+
|
|
288
|
+
.. image:: https://raw.githubusercontent.com/scottprahl/miepython/main/docs/04.svg
|
|
289
|
+
:alt: Gold Nanoparticles
|
|
290
|
+
|
|
291
|
+
|
|
292
|
+
|
|
293
|
+
|
|
294
|
+
Citing `miepython`
|
|
295
|
+
--------------------
|
|
296
|
+
|
|
297
|
+
If this library contributes to your research, please cite the `relevant doi release
|
|
298
|
+
on zenodo <https://zenodo.org/badge/latestdoi/99259684>`_
|
|
299
|
+
|
|
300
|
+
* **Generic DOI (always the newest release)** — `10.5281/zenodo.7949263`. The
|
|
301
|
+
badge at the top of this file resolves to that record.
|
|
302
|
+
* **Version‑specific DOIs** — click the Zenodo badge |doi| and choose the DOI that
|
|
303
|
+
corresponds to the exact version you want to cite (e.g.
|
|
304
|
+
`10.5281/zenodo.14257432 for v2.5.5`).
|
|
305
|
+
|
|
306
|
+
For example::
|
|
307
|
+
|
|
308
|
+
S. Prahl, *miepython — Pure‑Python Mie scattering calculations*, Zenodo,
|
|
309
|
+
16 March 2025. doi:10.5281/zenodo.7949263
|
|
310
|
+
|
|
311
|
+
.. code-block:: bibtex
|
|
312
|
+
|
|
313
|
+
@software{prahl_miepython_2025,
|
|
314
|
+
author = {Prahl, Scott},
|
|
315
|
+
title = {{miepython}: A Python library for Mie scattering calculations},
|
|
316
|
+
url = {https://github.com/scottprahl/miepython},
|
|
317
|
+
doi = {10.5281/zenodo.7949263},
|
|
318
|
+
year = {2025},
|
|
319
|
+
version = {latest}
|
|
320
|
+
}
|
|
321
|
+
|
|
322
|
+
|
|
323
|
+
License
|
|
324
|
+
-------
|
|
325
|
+
|
|
326
|
+
``miepython`` is licensed under the `MIT License <LICENSE.txt>`_.
|
|
327
|
+
|
|
328
|
+
--------
|
|
329
|
+
|
|
330
|
+
**Maintained by** `Scott Prahl <https://github.com/scottprahl>`_
|
|
@@ -0,0 +1,299 @@
|
|
|
1
|
+
.. |pypi| image:: https://img.shields.io/pypi/v/miepython?color=68CA66
|
|
2
|
+
:target: https://pypi.org/project/miepython/
|
|
3
|
+
:alt: PyPI
|
|
4
|
+
|
|
5
|
+
.. |github| image:: https://img.shields.io/github/v/tag/scottprahl/miepython?label=github&color=68CA66
|
|
6
|
+
:target: https://github.com/scottprahl/miepython
|
|
7
|
+
:alt: GitHub
|
|
8
|
+
|
|
9
|
+
.. |conda| image:: https://img.shields.io/conda/vn/conda-forge/miepython?label=conda&color=68CA66
|
|
10
|
+
:target: https://github.com/conda-forge/miepython-feedstock
|
|
11
|
+
:alt: Conda
|
|
12
|
+
|
|
13
|
+
.. |doi| image:: https://zenodo.org/badge/99259684.svg
|
|
14
|
+
:target: https://zenodo.org/badge/latestdoi/99259684
|
|
15
|
+
:alt: DOI
|
|
16
|
+
|
|
17
|
+
.. |license| image:: https://img.shields.io/github/license/scottprahl/miepython?color=68CA66
|
|
18
|
+
:target: https://github.com/scottprahl/miepython/blob/master/LICENSE.txt
|
|
19
|
+
:alt: License
|
|
20
|
+
|
|
21
|
+
.. |test| image:: https://github.com/scottprahl/miepython/actions/workflows/test.yml/badge.svg
|
|
22
|
+
:target: https://github.com/scottprahl/miepython/actions/workflows/test.yml
|
|
23
|
+
:alt: Testing
|
|
24
|
+
|
|
25
|
+
.. |docs| image:: https://readthedocs.org/projects/miepython/badge?color=68CA66
|
|
26
|
+
:target: https://miepython.readthedocs.io
|
|
27
|
+
:alt: Docs
|
|
28
|
+
|
|
29
|
+
.. |downloads| image:: https://img.shields.io/pypi/dm/miepython?color=68CA66
|
|
30
|
+
:target: https://pypi.org/project/miepython/
|
|
31
|
+
:alt: Downloads
|
|
32
|
+
|
|
33
|
+
.. |black| image:: https://img.shields.io/badge/code%20style-black-000000.svg
|
|
34
|
+
:target: https://github.com/psf/black
|
|
35
|
+
:alt: code style: black
|
|
36
|
+
|
|
37
|
+
miepython
|
|
38
|
+
=========
|
|
39
|
+
|
|
40
|
+
|pypi| |github| |conda| |doi|
|
|
41
|
+
|
|
42
|
+
|license| |test| |docs| |downloads| |black|
|
|
43
|
+
|
|
44
|
+
``miepython`` is a pure‑Python implementation of Mie theory for spherical
|
|
45
|
+
scatterers, validated against Wiscombe's reference results. The library is
|
|
46
|
+
lightweight, extensively tested, and—thanks to an *optional* Numba backend—can
|
|
47
|
+
process nearly a million particles per second.
|
|
48
|
+
|
|
49
|
+
Overview
|
|
50
|
+
--------
|
|
51
|
+
|
|
52
|
+
- **Non-absorbing spheres** (dielectric particles)
|
|
53
|
+
- **Partially-absorbing spheres** (lossy dielectrics)
|
|
54
|
+
- **Perfectly-conducting spheres** (metallic particles)
|
|
55
|
+
|
|
56
|
+
Key Features
|
|
57
|
+
~~~~~~~~~~~~
|
|
58
|
+
|
|
59
|
+
- ✅ **Pure Python** - No external dependencies beyond NumPy
|
|
60
|
+
- ✅ **Validated algorithms** - Follows Wiscombe's trusted implementation
|
|
61
|
+
- ✅ **Comprehensive outputs** - Extinction, scattering, backscattering, asymmetry
|
|
62
|
+
- ✅ **Angular distributions** - Full scattering phase functions
|
|
63
|
+
- ✅ **Flexible normalization** - Multiple conventions supported
|
|
64
|
+
- ✅ **Code Jitting** - the python Numba package enables 10-50X speedup
|
|
65
|
+
- ✅ **Field calculations** - Internal field coefficients coming!
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
Documentation
|
|
69
|
+
-------------
|
|
70
|
+
|
|
71
|
+
- **Full Documentation**: `miepython.readthedocs.io <https://miepython.readthedocs.io>`_
|
|
72
|
+
- **API Reference**: `miepython api <https://miepython.readthedocs.io/en/latest/#api-reference>`_
|
|
73
|
+
- **Jupyter Notebooks**: `Interactive Jupyter notebooks <https://github.com/scottprahl/miepython/tree/main/docs>`_
|
|
74
|
+
- **Theory Background**: `Mathematical foundations and validation <https://miepython.readthedocs.io/en/latest/07_algorithm.html>`_
|
|
75
|
+
|
|
76
|
+
Version 3.0 Breaking Changes
|
|
77
|
+
----------------------------
|
|
78
|
+
|
|
79
|
+
Version 3.0 introduced significant API changes and new functionality:
|
|
80
|
+
|
|
81
|
+
- **Internal field calculations** - Compute electromagnetic fields inside spheres
|
|
82
|
+
- **Enhanced coefficient access** - Direct access to Mie expansion coefficients
|
|
83
|
+
- **Future-ready architecture** - Foundation for full field calculations
|
|
84
|
+
|
|
85
|
+
If you need the old API, pin to version 2.5.5::
|
|
86
|
+
|
|
87
|
+
pip install miepython==2.5.5
|
|
88
|
+
|
|
89
|
+
Installation
|
|
90
|
+
~~~~~~~~~~~~
|
|
91
|
+
|
|
92
|
+
Using pip::
|
|
93
|
+
|
|
94
|
+
pip install miepython
|
|
95
|
+
|
|
96
|
+
Using conda::
|
|
97
|
+
|
|
98
|
+
conda install -c conda-forge miepython
|
|
99
|
+
|
|
100
|
+
Basic Example
|
|
101
|
+
~~~~~~~~~~~~~
|
|
102
|
+
|
|
103
|
+
.. code-block:: python
|
|
104
|
+
|
|
105
|
+
import miepython as mie
|
|
106
|
+
|
|
107
|
+
# Define sphere properties
|
|
108
|
+
m = 1.5 - 1j # Complex refractive index
|
|
109
|
+
d = 100 # Diameter (nm)
|
|
110
|
+
lambda0 = 314.15 # Wavelength in vacuum (nm)
|
|
111
|
+
|
|
112
|
+
# Calculate efficiencies
|
|
113
|
+
qext, qsca, qback, g = mie.efficiencies(m, d, lambda0)
|
|
114
|
+
|
|
115
|
+
print(f"Extinction efficiency: {qext:.3f}")
|
|
116
|
+
print(f"Scattering efficiency: {qsca:.3f}")
|
|
117
|
+
print(f"Backscatter efficiency: {qback:.3f}")
|
|
118
|
+
print(f"Scattering anisotropy: {g:.3f}")
|
|
119
|
+
|
|
120
|
+
**Output:**
|
|
121
|
+
|
|
122
|
+
.. code-block:: text
|
|
123
|
+
|
|
124
|
+
Extinction efficiency: 2.336
|
|
125
|
+
Scattering efficiency: 0.663
|
|
126
|
+
Backscatter efficiency: 0.573
|
|
127
|
+
Scattering anisotropy: 0.192
|
|
128
|
+
|
|
129
|
+
|
|
130
|
+
API Reference
|
|
131
|
+
-------------
|
|
132
|
+
|
|
133
|
+
Basic Functions
|
|
134
|
+
~~~~~~~~~~~~~~~
|
|
135
|
+
|
|
136
|
+
============================================ ===========================================================
|
|
137
|
+
Function Purpose
|
|
138
|
+
============================================ ===========================================================
|
|
139
|
+
``efficiencies(m, d, lambda0, n_env=1)`` Calculate extinction, scattering, backscattering, asymmetry
|
|
140
|
+
``intensities(m, d, lambda0, mu, n_env=1)`` Angular scattering intensities for parallel/perpendicular polarization
|
|
141
|
+
``S1_S2(m, x, mu)`` Complex scattering amplitudes
|
|
142
|
+
``coefficients(m, x)`` Mie coefficients for field calculations
|
|
143
|
+
``phase_matrix(m, x, mu)`` Mueller matrix for sphere
|
|
144
|
+
============================================ ===========================================================
|
|
145
|
+
|
|
146
|
+
Parameters
|
|
147
|
+
~~~~~~~~~~
|
|
148
|
+
|
|
149
|
+
- **m** (complex): Complex refractive index of sphere
|
|
150
|
+
- **n_env** (complex): Real refractive index of medium
|
|
151
|
+
- **d** (float): Sphere diameter [same units as wavelength]
|
|
152
|
+
- **lambda0** (float): Wavelength in vacuum [same units as diameter]
|
|
153
|
+
- **x** (float): Size parameter (π×diameter/wavelength)
|
|
154
|
+
- **mu** (array): Cosine of scattering angles
|
|
155
|
+
|
|
156
|
+
|
|
157
|
+
Important Conventions
|
|
158
|
+
---------------------
|
|
159
|
+
|
|
160
|
+
1. **Negative imaginary refractive index**: For absorbing materials, use ``m = n - ik`` where k > 0
|
|
161
|
+
2. **Albedo normalization**: Scattering phase functions integrate to the single scattering albedo over 4π steradians (customizable)
|
|
162
|
+
|
|
163
|
+
These latter may be mitigated using custom normalization
|
|
164
|
+
|
|
165
|
+
.. code-block:: python
|
|
166
|
+
|
|
167
|
+
# Different scattering function normalizations
|
|
168
|
+
I_albedo = mie.i_unpolarized(m, x, mu, norm='albedo') # Default
|
|
169
|
+
I_unity = mie.i_unpolarized(m, x, mu, norm='one') # Normalized to 1
|
|
170
|
+
I_4pi = mie.i_unpolarized(m, x, mu, norm='4pi') # 4π normalization
|
|
171
|
+
|
|
172
|
+
|
|
173
|
+
|
|
174
|
+
Performance & JIT Compilation
|
|
175
|
+
-----------------------------
|
|
176
|
+
|
|
177
|
+
``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.
|
|
178
|
+
|
|
179
|
+
Enabling JIT
|
|
180
|
+
~~~~~~~~~~~~
|
|
181
|
+
|
|
182
|
+
.. code-block:: python
|
|
183
|
+
|
|
184
|
+
import os
|
|
185
|
+
os.environ["MIEPYTHON_USE_JIT"] = "1" # Must be set before importing
|
|
186
|
+
import miepython as mie
|
|
187
|
+
|
|
188
|
+
Performance Comparison
|
|
189
|
+
~~~~~~~~~~~~~~~~~~~~~~
|
|
190
|
+
|
|
191
|
+
JIT compilation provides substantial speedups for large-scale calculations:
|
|
192
|
+
|
|
193
|
+
=========== ============== ================== ==========
|
|
194
|
+
Version JIT Status Time (N=100,000) Speedup
|
|
195
|
+
=========== ============== ================== ==========
|
|
196
|
+
v3.0.1 Disabled 4.00 seconds 1×
|
|
197
|
+
v3.0.1 **Enabled** **0.15 seconds** **27×**
|
|
198
|
+
=========== ============== ================== ==========
|
|
199
|
+
|
|
200
|
+
Benchmark Example
|
|
201
|
+
~~~~~~~~~~~~~~~~~
|
|
202
|
+
|
|
203
|
+
.. code-block:: python
|
|
204
|
+
|
|
205
|
+
import os
|
|
206
|
+
import numpy as np
|
|
207
|
+
from time import time
|
|
208
|
+
|
|
209
|
+
os.environ["MIEPYTHON_USE_JIT"] = "1" # must be before import miepython
|
|
210
|
+
import miepython as mie
|
|
211
|
+
|
|
212
|
+
# Generate random particle ensemble
|
|
213
|
+
N = 100_000
|
|
214
|
+
refr = np.random.uniform(1.0, 2.0, N)
|
|
215
|
+
refi = np.exp(np.random.uniform(np.log(1e-4), np.log(1.0), N))
|
|
216
|
+
x = np.exp(np.random.uniform(np.log(0.01), np.log(100), N))
|
|
217
|
+
m = refr - 1j * refi
|
|
218
|
+
|
|
219
|
+
# Benchmark calculation
|
|
220
|
+
t0 = time()
|
|
221
|
+
qext, qsca, qback, g = mie.efficiencies_mx(m, x)
|
|
222
|
+
elapsed = time() - t0
|
|
223
|
+
|
|
224
|
+
print(f"JIT enabled: {os.environ.get('MIEPYTHON_USE_JIT') == '1'}")
|
|
225
|
+
print(f"Calculated {N:,} particles in {elapsed:.3f} seconds")
|
|
226
|
+
print(f"Rate: {N/elapsed:,.0f} particles/second")
|
|
227
|
+
|
|
228
|
+
.. note::
|
|
229
|
+
The first JIT-compiled call includes compilation overhead (~1-2 seconds). Subsequent calls achieve full performance.
|
|
230
|
+
|
|
231
|
+
Examples Gallery
|
|
232
|
+
----------------
|
|
233
|
+
|
|
234
|
+
The repository includes several `example scripts <https://github.com/scottprahl/miepython/tree/master/miepython/examples>`_ demonstrating different applications:
|
|
235
|
+
|
|
236
|
+
Dielectric vs. Absorbing Spheres
|
|
237
|
+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
238
|
+
|
|
239
|
+
.. image:: https://raw.githubusercontent.com/scottprahl/miepython/main/docs/01.svg
|
|
240
|
+
:alt: Dielectric vs Absorbing
|
|
241
|
+
|
|
242
|
+
Glass Microspheres with Resonances
|
|
243
|
+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
244
|
+
|
|
245
|
+
.. image:: https://raw.githubusercontent.com/scottprahl/miepython/main/docs/02.svg
|
|
246
|
+
:alt: Glass Spheres
|
|
247
|
+
|
|
248
|
+
Water Droplets
|
|
249
|
+
~~~~~~~~~~~~~~
|
|
250
|
+
|
|
251
|
+
.. image:: https://raw.githubusercontent.com/scottprahl/miepython/main/docs/03.svg
|
|
252
|
+
:alt: Water Droplets
|
|
253
|
+
|
|
254
|
+
Gold Nanoparticles
|
|
255
|
+
~~~~~~~~~~~~~~~~~~
|
|
256
|
+
|
|
257
|
+
.. image:: https://raw.githubusercontent.com/scottprahl/miepython/main/docs/04.svg
|
|
258
|
+
:alt: Gold Nanoparticles
|
|
259
|
+
|
|
260
|
+
|
|
261
|
+
|
|
262
|
+
|
|
263
|
+
Citing `miepython`
|
|
264
|
+
--------------------
|
|
265
|
+
|
|
266
|
+
If this library contributes to your research, please cite the `relevant doi release
|
|
267
|
+
on zenodo <https://zenodo.org/badge/latestdoi/99259684>`_
|
|
268
|
+
|
|
269
|
+
* **Generic DOI (always the newest release)** — `10.5281/zenodo.7949263`. The
|
|
270
|
+
badge at the top of this file resolves to that record.
|
|
271
|
+
* **Version‑specific DOIs** — click the Zenodo badge |doi| and choose the DOI that
|
|
272
|
+
corresponds to the exact version you want to cite (e.g.
|
|
273
|
+
`10.5281/zenodo.14257432 for v2.5.5`).
|
|
274
|
+
|
|
275
|
+
For example::
|
|
276
|
+
|
|
277
|
+
S. Prahl, *miepython — Pure‑Python Mie scattering calculations*, Zenodo,
|
|
278
|
+
16 March 2025. doi:10.5281/zenodo.7949263
|
|
279
|
+
|
|
280
|
+
.. code-block:: bibtex
|
|
281
|
+
|
|
282
|
+
@software{prahl_miepython_2025,
|
|
283
|
+
author = {Prahl, Scott},
|
|
284
|
+
title = {{miepython}: A Python library for Mie scattering calculations},
|
|
285
|
+
url = {https://github.com/scottprahl/miepython},
|
|
286
|
+
doi = {10.5281/zenodo.7949263},
|
|
287
|
+
year = {2025},
|
|
288
|
+
version = {latest}
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
|
|
292
|
+
License
|
|
293
|
+
-------
|
|
294
|
+
|
|
295
|
+
``miepython`` is licensed under the `MIT License <LICENSE.txt>`_.
|
|
296
|
+
|
|
297
|
+
--------
|
|
298
|
+
|
|
299
|
+
**Maintained by** `Scott Prahl <https://github.com/scottprahl>`_
|