miepython 3.0.5__py3-none-any.whl → 3.2.0__py3-none-any.whl
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/__init__.py +79 -33
- miepython/_backend.py +49 -0
- miepython/core.py +3 -4
- miepython/field.py +676 -143
- miepython/mie_jit.py +55 -22
- miepython/mie_nojit.py +73 -34
- miepython/vsh.py +3 -1
- {miepython-3.0.5.dist-info → miepython-3.2.0.dist-info}/METADATA +43 -35
- miepython-3.2.0.dist-info/RECORD +18 -0
- {miepython-3.0.5.dist-info → miepython-3.2.0.dist-info}/WHEEL +1 -1
- miepython-3.0.5.dist-info/RECORD +0 -17
- {miepython-3.0.5.dist-info → miepython-3.2.0.dist-info}/licenses/LICENSE.txt +0 -0
- {miepython-3.0.5.dist-info → miepython-3.2.0.dist-info}/top_level.txt +0 -0
miepython/mie_jit.py
CHANGED
|
@@ -321,8 +321,8 @@ def _S1_S2_nb(m, x, mu, n_pole):
|
|
|
321
321
|
N = len(a)
|
|
322
322
|
pi = np.zeros(N)
|
|
323
323
|
tau = np.zeros(N)
|
|
324
|
-
n = np.arange(1, N + 1)
|
|
325
|
-
scale = (2 * n + 1) / ((n + 1) * n)
|
|
324
|
+
n = np.arange(1, N + 1, dtype=np.float64)
|
|
325
|
+
scale = (2.0 * n + 1.0) / ((n + 1.0) * n)
|
|
326
326
|
|
|
327
327
|
nangles = len(mu)
|
|
328
328
|
S1 = np.zeros(nangles, dtype=np.complex128)
|
|
@@ -331,8 +331,14 @@ def _S1_S2_nb(m, x, mu, n_pole):
|
|
|
331
331
|
for k in range(nangles):
|
|
332
332
|
_pi_tau_nb(mu[k], pi, tau)
|
|
333
333
|
if n_pole == 0:
|
|
334
|
-
|
|
335
|
-
|
|
334
|
+
s1 = 0.0 + 0.0j
|
|
335
|
+
s2 = 0.0 + 0.0j
|
|
336
|
+
for i in range(N):
|
|
337
|
+
si = scale[i]
|
|
338
|
+
s1 += si * (pi[i] * a[i] + tau[i] * b[i])
|
|
339
|
+
s2 += si * (tau[i] * a[i] + pi[i] * b[i])
|
|
340
|
+
S1[k] = s1
|
|
341
|
+
S2[k] = s2
|
|
336
342
|
else:
|
|
337
343
|
S1[k] = scale[n_pole] * (pi[n_pole] * a[n_pole] + tau[n_pole] * b[n_pole])
|
|
338
344
|
S2[k] = scale[n_pole] * (tau[n_pole] * a[n_pole] + pi[n_pole] * b[n_pole])
|
|
@@ -443,7 +449,7 @@ def _single_sphere_nb(m, x, n_pole, e_field):
|
|
|
443
449
|
qback: the backscatter efficiency
|
|
444
450
|
g: the average cosine of the scattering phase function
|
|
445
451
|
"""
|
|
446
|
-
|
|
452
|
+
_ = e_field # unused
|
|
447
453
|
|
|
448
454
|
# case when sphere matches its environment
|
|
449
455
|
if abs(m.real - 1) <= 1e-8 and abs(m.imag) < 1e-8:
|
|
@@ -461,33 +467,60 @@ def _single_sphere_nb(m, x, n_pole, e_field):
|
|
|
461
467
|
m = 1 - 10000j
|
|
462
468
|
|
|
463
469
|
a, b = _an_bn_nb(m, x, n_pole)
|
|
470
|
+
x2 = x * x
|
|
464
471
|
|
|
465
472
|
if n_pole == 0:
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
473
|
+
n_terms = len(a)
|
|
474
|
+
qext_acc = 0.0
|
|
475
|
+
qsca_acc = 0.0
|
|
476
|
+
qback_acc = 0.0 + 0.0j
|
|
477
|
+
g_acc = 0.0
|
|
478
|
+
|
|
479
|
+
for i in range(n_terms):
|
|
480
|
+
ni = i + 1
|
|
481
|
+
cn = 2.0 * ni + 1.0
|
|
482
|
+
|
|
483
|
+
ai = a[i]
|
|
484
|
+
bi = b[i]
|
|
485
|
+
ai_re = ai.real
|
|
486
|
+
ai_im = ai.imag
|
|
487
|
+
bi_re = bi.real
|
|
488
|
+
bi_im = bi.imag
|
|
489
|
+
|
|
490
|
+
qext_acc += cn * (ai_re + bi_re)
|
|
491
|
+
|
|
492
|
+
if m.imag != 0.0:
|
|
493
|
+
qsca_acc += cn * (ai_re * ai_re + ai_im * ai_im + bi_re * bi_re + bi_im * bi_im)
|
|
494
|
+
|
|
495
|
+
# (-1)^n with n starting from 1.
|
|
496
|
+
sign = -1.0 if (ni % 2) == 1 else 1.0
|
|
497
|
+
qback_acc += sign * cn * (ai - bi)
|
|
498
|
+
|
|
499
|
+
if i < n_terms - 1:
|
|
500
|
+
aip1 = a[i + 1]
|
|
501
|
+
bip1 = b[i + 1]
|
|
502
|
+
c1n = ni * (ni + 2.0) / (ni + 1.0)
|
|
503
|
+
c2n = cn / ni / (ni + 1.0)
|
|
504
|
+
g_acc += c1n * (ai * np.conjugate(aip1) + bi * np.conjugate(bip1)).real
|
|
505
|
+
g_acc += c2n * (ai * np.conjugate(bi)).real
|
|
506
|
+
|
|
507
|
+
qext = 2.0 * qext_acc / x2
|
|
508
|
+
|
|
509
|
+
if m.imag == 0.0:
|
|
472
510
|
qsca = qext
|
|
473
511
|
else:
|
|
474
|
-
qsca = 2
|
|
475
|
-
|
|
476
|
-
qback = np.abs(np.sum((-1) ** n * cn * (a - b))) ** 2 / x**2
|
|
512
|
+
qsca = 2.0 * qsca_acc / x2
|
|
477
513
|
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
asy1 = c1n[:-1] * (a[:-1] * a[1:].conjugate() + b[:-1] * b[1:].conjugate()).real
|
|
481
|
-
asy2 = c2n[:-1] * (a[:-1] * b[:-1].conjugate()).real
|
|
482
|
-
g = 4 * np.sum(asy1 + asy2) / qsca / x**2
|
|
514
|
+
qback = np.abs(qback_acc) ** 2 / x2
|
|
515
|
+
g = 4.0 * g_acc / qsca / x2
|
|
483
516
|
|
|
484
517
|
else:
|
|
485
518
|
cn = 2.0 * n_pole + 1
|
|
486
|
-
qext = 2 * cn * (a[-1].real + b[-1].real) /
|
|
487
|
-
qback = np.abs((-1) ** n_pole * cn * (a[-1] - b[-1])) ** 2 /
|
|
519
|
+
qext = 2.0 * cn * (a[-1].real + b[-1].real) / x2
|
|
520
|
+
qback = np.abs((-1) ** n_pole * cn * (a[-1] - b[-1])) ** 2 / x2
|
|
488
521
|
qsca = qext
|
|
489
522
|
if m.imag < 0:
|
|
490
|
-
qsca = 2 * cn * (np.abs(a[-1]) ** 2 + np.abs(b[-1]) ** 2) /
|
|
523
|
+
qsca = 2.0 * cn * (np.abs(a[-1]) ** 2 + np.abs(b[-1]) ** 2) / x2
|
|
491
524
|
g = 0
|
|
492
525
|
|
|
493
526
|
return qext, qsca, qback, g
|
miepython/mie_nojit.py
CHANGED
|
@@ -2,6 +2,8 @@
|
|
|
2
2
|
Low-level Mie calculations that do not use numba.
|
|
3
3
|
"""
|
|
4
4
|
|
|
5
|
+
from functools import lru_cache
|
|
6
|
+
|
|
5
7
|
import numpy as np
|
|
6
8
|
|
|
7
9
|
__all__ = (
|
|
@@ -16,6 +18,31 @@ __all__ = (
|
|
|
16
18
|
)
|
|
17
19
|
|
|
18
20
|
|
|
21
|
+
@lru_cache(maxsize=128)
|
|
22
|
+
def _series_scale_factors(n_terms):
|
|
23
|
+
"""Return cached per-order scale factors for Mie series summations."""
|
|
24
|
+
n = np.arange(1, n_terms + 1, dtype=np.float64)
|
|
25
|
+
scale = (2.0 * n + 1.0) / ((n + 1.0) * n)
|
|
26
|
+
scale.setflags(write=False)
|
|
27
|
+
return scale
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
@lru_cache(maxsize=128)
|
|
31
|
+
def _single_sphere_factors(n_terms):
|
|
32
|
+
"""Return cached per-order factors used by ``_single_sphere_py``."""
|
|
33
|
+
n_int = np.arange(1, n_terms + 1, dtype=np.int64)
|
|
34
|
+
n = n_int.astype(np.float64)
|
|
35
|
+
cn = 2.0 * n + 1.0
|
|
36
|
+
alt = np.where((n_int % 2) == 0, 1.0, -1.0) # (-1)^n with n starting at 1
|
|
37
|
+
c1n = n * (n + 2.0) / (n + 1.0)
|
|
38
|
+
c2n = cn / n / (n + 1.0)
|
|
39
|
+
cn.setflags(write=False)
|
|
40
|
+
alt.setflags(write=False)
|
|
41
|
+
c1n.setflags(write=False)
|
|
42
|
+
c2n.setflags(write=False)
|
|
43
|
+
return cn, alt, c1n, c2n
|
|
44
|
+
|
|
45
|
+
|
|
19
46
|
def _Lentz_Dn(z, N):
|
|
20
47
|
"""
|
|
21
48
|
Compute the logarithmic derivative of the Ricatti-Bessel function.
|
|
@@ -139,7 +166,7 @@ def _an_bn_py(m, x, n_pole=0):
|
|
|
139
166
|
Returns:
|
|
140
167
|
a, b: arrays of Mie coefficents An and Bn
|
|
141
168
|
"""
|
|
142
|
-
if
|
|
169
|
+
if m.imag > 0: # ensure imaginary part of refractive index is negative
|
|
143
170
|
m = np.conj(m)
|
|
144
171
|
|
|
145
172
|
if n_pole == 0:
|
|
@@ -152,21 +179,24 @@ def _an_bn_py(m, x, n_pole=0):
|
|
|
152
179
|
if x <= 0:
|
|
153
180
|
return a, b
|
|
154
181
|
|
|
182
|
+
inv_x = 1.0 / x
|
|
155
183
|
psi_nm1 = np.sin(x) # nm1 = n-1 = 0
|
|
156
|
-
psi_n = psi_nm1
|
|
184
|
+
psi_n = psi_nm1 * inv_x - np.cos(x)
|
|
157
185
|
xi_nm1 = np.complex128(psi_nm1 + 1j * np.cos(x))
|
|
158
|
-
xi_n = np.complex128(psi_n + 1j * (np.cos(x)
|
|
186
|
+
xi_n = np.complex128(psi_n + 1j * (np.cos(x) * inv_x + np.sin(x)))
|
|
159
187
|
|
|
160
188
|
if m.real > 0.0:
|
|
161
189
|
D = _D_calc_py(m, x, nstop + 1)
|
|
162
190
|
|
|
163
191
|
for n in range(1, nstop):
|
|
164
|
-
|
|
192
|
+
n_over_x = n * inv_x
|
|
193
|
+
temp = D[n - 1] / m + n_over_x
|
|
165
194
|
a[n - 1] = (temp * psi_n - psi_nm1) / (temp * xi_n - xi_nm1)
|
|
166
|
-
temp = D[n - 1] * m +
|
|
195
|
+
temp = D[n - 1] * m + n_over_x
|
|
167
196
|
b[n - 1] = (temp * psi_n - psi_nm1) / (temp * xi_n - xi_nm1)
|
|
168
|
-
|
|
169
|
-
|
|
197
|
+
two_np1_over_x = (2 * n + 1) * inv_x
|
|
198
|
+
psi = two_np1_over_x * psi_n - psi_nm1
|
|
199
|
+
xi = two_np1_over_x * xi_n - xi_nm1
|
|
170
200
|
xi_nm1 = xi_n
|
|
171
201
|
xi_n = xi
|
|
172
202
|
psi_nm1 = psi_n
|
|
@@ -174,9 +204,10 @@ def _an_bn_py(m, x, n_pole=0):
|
|
|
174
204
|
|
|
175
205
|
else:
|
|
176
206
|
for n in range(1, nstop):
|
|
177
|
-
|
|
207
|
+
n_over_x = n * inv_x
|
|
208
|
+
a[n - 1] = (n_over_x * psi_n - psi_nm1) / (n_over_x * xi_n - xi_nm1)
|
|
178
209
|
b[n - 1] = psi_n / xi_n
|
|
179
|
-
xi = (2 * n + 1) *
|
|
210
|
+
xi = (2 * n + 1) * inv_x * xi_n - xi_nm1
|
|
180
211
|
xi_nm1 = xi_n
|
|
181
212
|
xi_n = xi
|
|
182
213
|
psi_nm1 = psi_n
|
|
@@ -216,35 +247,39 @@ def _cn_dn_py(m, x, n_pole):
|
|
|
216
247
|
if x <= 0:
|
|
217
248
|
return c, d
|
|
218
249
|
|
|
250
|
+
inv_x = 1.0 / x
|
|
219
251
|
# no need to calculate anything when sphere is perfectly conducting
|
|
220
252
|
if m.real > 0.0 and not np.isinf(m.real) or not np.isinf(m.imag):
|
|
221
253
|
psi_nm1 = np.sin(x) # nm1 = n-1 = 0
|
|
222
|
-
psi_n = psi_nm1
|
|
254
|
+
psi_n = psi_nm1 * inv_x - np.cos(x)
|
|
223
255
|
|
|
256
|
+
inv_mx = 1.0 / mx
|
|
224
257
|
psi_nm1_mx = np.sin(mx) # nm1 = n-1 = 0
|
|
225
|
-
psi_n_mx = psi_nm1_mx
|
|
258
|
+
psi_n_mx = psi_nm1_mx * inv_mx - np.cos(mx)
|
|
226
259
|
|
|
227
260
|
xi_nm1 = np.complex128(psi_nm1 + 1j * np.cos(x))
|
|
228
|
-
xi_n = np.complex128(psi_n + 1j * (np.cos(x)
|
|
261
|
+
xi_n = np.complex128(psi_n + 1j * (np.cos(x) * inv_x + np.sin(x)))
|
|
229
262
|
|
|
230
263
|
Dmx = _D_calc_py(np.complex128(m), x, nstop + 1)
|
|
231
264
|
Dx = _D_calc_py(np.complex128(1), x, nstop + 1)
|
|
232
265
|
|
|
233
266
|
for n in range(1, nstop + 1):
|
|
234
|
-
|
|
267
|
+
n_over_x = n * inv_x
|
|
268
|
+
common = (psi_n / psi_n_mx) * ((Dx[n - 1] + n_over_x) * xi_n - xi_nm1)
|
|
235
269
|
|
|
236
|
-
c[n - 1] = m * common / ((m * Dmx[n - 1] +
|
|
237
|
-
d[n - 1] = common / ((Dmx[n - 1] / m +
|
|
270
|
+
c[n - 1] = m * common / ((m * Dmx[n - 1] + n_over_x) * xi_n - xi_nm1)
|
|
271
|
+
d[n - 1] = common / ((Dmx[n - 1] / m + n_over_x) * xi_n - xi_nm1)
|
|
238
272
|
|
|
239
|
-
|
|
273
|
+
two_np1 = 2 * n + 1
|
|
274
|
+
psi = two_np1 * inv_x * psi_n - psi_nm1
|
|
240
275
|
psi_nm1 = psi_n
|
|
241
276
|
psi_n = psi
|
|
242
277
|
|
|
243
|
-
psi_mx =
|
|
278
|
+
psi_mx = two_np1 * inv_mx * psi_n_mx - psi_nm1_mx
|
|
244
279
|
psi_nm1_mx = psi_n_mx
|
|
245
280
|
psi_n_mx = psi_mx
|
|
246
281
|
|
|
247
|
-
xi =
|
|
282
|
+
xi = two_np1 * inv_x * xi_n - xi_nm1
|
|
248
283
|
xi_nm1 = xi_n
|
|
249
284
|
xi_n = xi
|
|
250
285
|
|
|
@@ -310,8 +345,9 @@ def _S1_S2_py(m, x, mu, n_pole):
|
|
|
310
345
|
N = len(a)
|
|
311
346
|
pi = np.zeros(N)
|
|
312
347
|
tau = np.zeros(N)
|
|
313
|
-
|
|
314
|
-
|
|
348
|
+
scale = _series_scale_factors(N)
|
|
349
|
+
scale_a = scale * a
|
|
350
|
+
scale_b = scale * b
|
|
315
351
|
|
|
316
352
|
nangles = len(mu)
|
|
317
353
|
S1 = np.zeros(nangles, dtype=np.complex128)
|
|
@@ -320,8 +356,8 @@ def _S1_S2_py(m, x, mu, n_pole):
|
|
|
320
356
|
for k in range(nangles):
|
|
321
357
|
_pi_tau_py(mu[k], pi, tau)
|
|
322
358
|
if n_pole == 0:
|
|
323
|
-
S1[k] = np.
|
|
324
|
-
S2[k] = np.
|
|
359
|
+
S1[k] = np.dot(pi, scale_a) + np.dot(tau, scale_b)
|
|
360
|
+
S2[k] = np.dot(tau, scale_a) + np.dot(pi, scale_b)
|
|
325
361
|
else:
|
|
326
362
|
S1[k] = scale[n_pole] * (pi[n_pole] * a[n_pole] + tau[n_pole] * b[n_pole])
|
|
327
363
|
S2[k] = scale[n_pole] * (tau[n_pole] * a[n_pole] + pi[n_pole] * b[n_pole])
|
|
@@ -429,7 +465,7 @@ def _single_sphere_py(m, x, n_pole, e_field):
|
|
|
429
465
|
qback: the backscatter efficiency
|
|
430
466
|
g: the average cosine of the scattering phase function
|
|
431
467
|
"""
|
|
432
|
-
|
|
468
|
+
_ = e_field # currently unused in scalar aggregate efficiencies
|
|
433
469
|
|
|
434
470
|
# case when sphere matches its environment
|
|
435
471
|
if abs(m.real - 1) <= 1e-8 and abs(m.imag) < 1e-8:
|
|
@@ -447,33 +483,36 @@ def _single_sphere_py(m, x, n_pole, e_field):
|
|
|
447
483
|
m = 1 - 10000j
|
|
448
484
|
|
|
449
485
|
a, b = _an_bn_py(m, x, n_pole)
|
|
486
|
+
x2 = x * x
|
|
450
487
|
|
|
451
488
|
if n_pole == 0:
|
|
452
|
-
|
|
453
|
-
cn
|
|
489
|
+
n_terms = len(a)
|
|
490
|
+
cn, alt, c1n, c2n = _single_sphere_factors(n_terms)
|
|
491
|
+
a_re = a.real
|
|
492
|
+
b_re = b.real
|
|
493
|
+
a_abs2 = a_re * a_re + a.imag * a.imag
|
|
494
|
+
b_abs2 = b_re * b_re + b.imag * b.imag
|
|
454
495
|
|
|
455
|
-
qext = 2 * np.
|
|
496
|
+
qext = 2.0 * np.dot(cn, a_re + b_re) / x2
|
|
456
497
|
|
|
457
498
|
if m.imag == 0:
|
|
458
499
|
qsca = qext
|
|
459
500
|
else:
|
|
460
|
-
qsca = 2 * np.
|
|
501
|
+
qsca = 2.0 * np.dot(cn, a_abs2 + b_abs2) / x2
|
|
461
502
|
|
|
462
|
-
qback = np.abs(np.
|
|
503
|
+
qback = np.abs(np.dot(alt * cn, a - b)) ** 2 / x2
|
|
463
504
|
|
|
464
|
-
c1n = n * (n + 2) / (n + 1)
|
|
465
|
-
c2n = cn / n / (n + 1)
|
|
466
505
|
asy1 = c1n[:-1] * (a[:-1] * a[1:].conjugate() + b[:-1] * b[1:].conjugate()).real
|
|
467
506
|
asy2 = c2n[:-1] * (a[:-1] * b[:-1].conjugate()).real
|
|
468
|
-
g = 4 * np.sum(asy1 + asy2) / qsca /
|
|
507
|
+
g = 4.0 * np.sum(asy1 + asy2) / qsca / x2
|
|
469
508
|
|
|
470
509
|
else:
|
|
471
510
|
cn = 2.0 * n_pole + 1
|
|
472
|
-
qback = np.abs((-1) ** n_pole * cn * (a[-1] - b[-1])) ** 2 /
|
|
473
|
-
qext = 2 * cn * (a[-1].real + b[-1].real) /
|
|
511
|
+
qback = np.abs((-1) ** n_pole * cn * (a[-1] - b[-1])) ** 2 / x2
|
|
512
|
+
qext = 2.0 * cn * (a[-1].real + b[-1].real) / x2
|
|
474
513
|
qsca = qext
|
|
475
514
|
if m.imag < 0:
|
|
476
|
-
qsca = 2 * cn * (np.abs(a[-1]) ** 2 + np.abs(b[-1]) ** 2) /
|
|
515
|
+
qsca = 2.0 * cn * (np.abs(a[-1]) ** 2 + np.abs(b[-1]) ** 2) / x2
|
|
477
516
|
g = None
|
|
478
517
|
|
|
479
518
|
return qext, qsca, qback, g
|
miepython/vsh.py
CHANGED
|
@@ -311,7 +311,9 @@ def N_base(n, m_index, kr, theta, inside):
|
|
|
311
311
|
factor1 = rho ** (n - 1) / factorial2(2 * n + 1)
|
|
312
312
|
else:
|
|
313
313
|
factor1 = spherical_jn(n, rho)
|
|
314
|
-
|
|
314
|
+
# D_calc returns D_1..D_N; request one extra term and take D_n.
|
|
315
|
+
Dn = mie.D_calc(m_index, kr, n + 1)[n - 1]
|
|
316
|
+
factor2 = factor1 * Dn
|
|
315
317
|
factor1 /= rho
|
|
316
318
|
else:
|
|
317
319
|
factor1 = spherical_h1(n, rho) / rho
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: miepython
|
|
3
|
-
Version: 3.0
|
|
3
|
+
Version: 3.2.0
|
|
4
4
|
Summary: Mie scattering of a plane wave by a sphere
|
|
5
5
|
Author-email: Scott Prahl <scott.prahl@oit.edu>
|
|
6
6
|
License-Expression: MIT
|
|
@@ -14,17 +14,45 @@ Classifier: Development Status :: 5 - Production/Stable
|
|
|
14
14
|
Classifier: Intended Audience :: Science/Research
|
|
15
15
|
Classifier: Programming Language :: Python
|
|
16
16
|
Classifier: Programming Language :: Python :: 3
|
|
17
|
-
Classifier: Programming Language :: Python :: 3.9
|
|
18
17
|
Classifier: Programming Language :: Python :: 3.10
|
|
19
18
|
Classifier: Programming Language :: Python :: 3.11
|
|
20
19
|
Classifier: Programming Language :: Python :: 3.12
|
|
21
|
-
|
|
20
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
21
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
22
|
+
Requires-Python: >=3.10
|
|
22
23
|
Description-Content-Type: text/x-rst
|
|
23
24
|
License-File: LICENSE.txt
|
|
24
25
|
Requires-Dist: numpy
|
|
25
26
|
Requires-Dist: matplotlib
|
|
26
|
-
Requires-Dist: numba
|
|
27
27
|
Requires-Dist: scipy
|
|
28
|
+
Requires-Dist: numba; sys_platform != "emscripten"
|
|
29
|
+
Provides-Extra: docs
|
|
30
|
+
Requires-Dist: Sphinx>=8.1.3; extra == "docs"
|
|
31
|
+
Requires-Dist: nbsphinx>=0.9.7; extra == "docs"
|
|
32
|
+
Requires-Dist: ipython; extra == "docs"
|
|
33
|
+
Requires-Dist: sphinx_automodapi; extra == "docs"
|
|
34
|
+
Requires-Dist: sphinx_rtd_theme; extra == "docs"
|
|
35
|
+
Provides-Extra: dev
|
|
36
|
+
Requires-Dist: pytest; extra == "dev"
|
|
37
|
+
Requires-Dist: imageio; extra == "dev"
|
|
38
|
+
Requires-Dist: requests; extra == "dev"
|
|
39
|
+
Requires-Dist: ruff; extra == "dev"
|
|
40
|
+
Requires-Dist: yamllint; extra == "dev"
|
|
41
|
+
Requires-Dist: rstcheck[sphinx,toml]; extra == "dev"
|
|
42
|
+
Requires-Dist: pylint; extra == "dev"
|
|
43
|
+
Requires-Dist: pyroma; extra == "dev"
|
|
44
|
+
Requires-Dist: black[jupyter]; extra == "dev"
|
|
45
|
+
Requires-Dist: build; extra == "dev"
|
|
46
|
+
Requires-Dist: check-manifest; extra == "dev"
|
|
47
|
+
Requires-Dist: libarchive-c; extra == "dev"
|
|
48
|
+
Requires-Dist: pyyaml; extra == "dev"
|
|
49
|
+
Requires-Dist: setuptools; extra == "dev"
|
|
50
|
+
Requires-Dist: jupyterlab; extra == "dev"
|
|
51
|
+
Requires-Dist: nbconvert; extra == "dev"
|
|
52
|
+
Requires-Dist: nbformat; extra == "dev"
|
|
53
|
+
Provides-Extra: lite
|
|
54
|
+
Requires-Dist: jupyterlite-core<0.8,>=0.7; extra == "lite"
|
|
55
|
+
Requires-Dist: jupyterlite-pyodide-kernel<0.8,>=0.7; extra == "lite"
|
|
28
56
|
Dynamic: license-file
|
|
29
57
|
|
|
30
58
|
.. |pypi| image:: https://img.shields.io/pypi/v/miepython?color=68CA66
|
|
@@ -47,8 +75,8 @@ Dynamic: license-file
|
|
|
47
75
|
:target: https://github.com/scottprahl/miepython/blob/master/LICENSE.txt
|
|
48
76
|
:alt: License
|
|
49
77
|
|
|
50
|
-
.. |test| image:: https://github.com/scottprahl/miepython/actions/workflows/test.
|
|
51
|
-
:target: https://github.com/scottprahl/miepython/actions/workflows/test.
|
|
78
|
+
.. |test| image:: https://github.com/scottprahl/miepython/actions/workflows/test.yaml/badge.svg
|
|
79
|
+
:target: https://github.com/scottprahl/miepython/actions/workflows/test.yaml
|
|
52
80
|
:alt: Testing
|
|
53
81
|
|
|
54
82
|
.. |docs| image:: https://readthedocs.org/projects/miepython/badge?color=68CA66
|
|
@@ -86,11 +114,13 @@ The library implements the full Mie solution, including:
|
|
|
86
114
|
- angle-resolved scattering intensities
|
|
87
115
|
- Mie expansion coefficients
|
|
88
116
|
- complex amplitude functions and Mueller matrices
|
|
117
|
+
- E-field and H-field calculations in the near-field around a sphere
|
|
89
118
|
|
|
90
119
|
The implementation is numerically stable for a wide range of size parameters and refractive indices, including lossy materials and high-index contrasts.
|
|
91
120
|
|
|
92
|
-
|
|
93
|
-
|
|
121
|
+
|
|
122
|
+
JupyterLite Implementation
|
|
123
|
+
--------------------------
|
|
94
124
|
|
|
95
125
|
The entire package can be used **immediately** in a browser — without installation — using the JupyterLite interface:
|
|
96
126
|
|
|
@@ -138,33 +168,10 @@ A typical calculation is straightforward:
|
|
|
138
168
|
Documentation and Examples
|
|
139
169
|
--------------------------
|
|
140
170
|
|
|
141
|
-
The full documentation is available
|
|
171
|
+
The full documentation is available on ReadTheDocs:
|
|
142
172
|
|
|
143
|
-
Interactive documentation (JupyterLite):
|
|
144
|
-
|lite|
|
|
145
|
-
|
|
146
|
-
Static Jupyter notebooks on ReadTheDocs:
|
|
147
173
|
|docs|
|
|
148
174
|
|
|
149
|
-
Among other things the documentation discusses:
|
|
150
|
-
|
|
151
|
-
- **Mathematical formulation of Mie theory**
|
|
152
|
-
https://miepython.readthedocs.io/en/latest/01_theory.html
|
|
153
|
-
|
|
154
|
-
- **Normalization conventions and units**
|
|
155
|
-
https://miepython.readthedocs.io/en/latest/02_normalization.html
|
|
156
|
-
|
|
157
|
-
- **Numerical stability considerations**
|
|
158
|
-
https://miepython.readthedocs.io/en/latest/03_stability.html
|
|
159
|
-
|
|
160
|
-
- **Validation against MIEV0 and other reference implementations**
|
|
161
|
-
https://miepython.readthedocs.io/en/latest/04_validation.html
|
|
162
|
-
|
|
163
|
-
- **Guidelines for parameter choices and truncation order**
|
|
164
|
-
https://miepython.readthedocs.io/en/latest/05_truncation.html
|
|
165
|
-
|
|
166
|
-
- **Physical interpretation, resonances, and comparison plots**
|
|
167
|
-
https://miepython.readthedocs.io/en/latest/06_examples.html
|
|
168
175
|
|
|
169
176
|
Representative results simple examples:
|
|
170
177
|
|
|
@@ -174,6 +181,7 @@ Representative results simple examples:
|
|
|
174
181
|
.. image:: https://raw.githubusercontent.com/scottprahl/miepython/main/docs/images/02.svg
|
|
175
182
|
.. image:: https://raw.githubusercontent.com/scottprahl/miepython/main/docs/images/03.svg
|
|
176
183
|
.. image:: https://raw.githubusercontent.com/scottprahl/miepython/main/docs/images/04.svg
|
|
184
|
+
.. image:: https://raw.githubusercontent.com/scottprahl/miepython/main/docs/images/05.svg
|
|
177
185
|
|
|
178
186
|
Performance and Acceleration
|
|
179
187
|
----------------------------
|
|
@@ -202,19 +210,19 @@ Citation
|
|
|
202
210
|
|
|
203
211
|
If you use ``laserbeamsize`` in academic, instructional, or applied technical work, please cite:
|
|
204
212
|
|
|
205
|
-
Prahl, S. (2026). *miepython: Pure python calculation of Mie scattering* (Version 3.0
|
|
213
|
+
Prahl, S. (2026). *miepython: Pure python calculation of Mie scattering* (Version 3.1.0) [Computer software]. Zenodo. https://doi.org/10.5281/zenodo.7949263
|
|
206
214
|
|
|
207
215
|
BibTeX:
|
|
208
216
|
|
|
209
217
|
.. code-block:: bibtex
|
|
210
218
|
|
|
211
|
-
@software{
|
|
219
|
+
@software{prahl_miepython_2026,
|
|
212
220
|
author = {Scott Prahl},
|
|
213
221
|
title = {{miepython}: A Python library for Mie scattering calculations},
|
|
214
222
|
url = {https://github.com/scottprahl/miepython},
|
|
215
223
|
doi = {10.5281/zenodo.7949263},
|
|
216
224
|
year = {2026},
|
|
217
|
-
version = {3.0
|
|
225
|
+
version = {3.1.0},
|
|
218
226
|
publisher = {Zenodo}
|
|
219
227
|
}
|
|
220
228
|
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
miepython/__init__.py,sha256=Hs1MtLbYN1trH8aAIT4uiZASWTtCTu3gki5MNq3HdXs,4516
|
|
2
|
+
miepython/_backend.py,sha256=l_faAa6zanygRZKA9vMVcfcutHPFFkpqZzHqwjU8QcE,1619
|
|
3
|
+
miepython/bessel.py,sha256=U094wY_5RFqrVjXZgMbacmt_yqpP8GBtRZ24-MNzBsU,3647
|
|
4
|
+
miepython/core.py,sha256=_6bceok2AZ5-rxgLw8AZ0qR-x0dPfgjoaY7EUE12FaE,19404
|
|
5
|
+
miepython/field.py,sha256=_kD5lAFJPGhBEjx33wBzqaxho2YBLBImKz5IRmlk8lY,26979
|
|
6
|
+
miepython/mie_jit.py,sha256=wSxuo3Dhhm08tTcWRJeuNxwziM6mnlPwnQHZkaDFILs,16282
|
|
7
|
+
miepython/mie_nojit.py,sha256=Vu5jQLr-wNWjAbNSdNfJynyizn_mWL8kX-KtowYGywU,16216
|
|
8
|
+
miepython/monte_carlo.py,sha256=gemJ2vhUyiTg-hAneGRW3typd3SFM2LL4R2o1UAzLeA,3818
|
|
9
|
+
miepython/rayleigh.py,sha256=P-rpa9SKVH3RaxuUUiZzQYYk6c3cFF6vDAAgo9xChz8,9401
|
|
10
|
+
miepython/util.py,sha256=LQEDkJqz6GHVHYog2JzTE12Ibv2ncLeMI20S8IjZzAc,2908
|
|
11
|
+
miepython/vsh.py,sha256=7uHo2o_cFJ2NzB7QfTI3ABJGEZSaO7ndUdxlY5BG3bo,17532
|
|
12
|
+
miepython/data/Johnson.txt,sha256=PcdEhJ3ZKUnt--86ukEvUt-w-814uOyWXtE-G3qWTNE,1337
|
|
13
|
+
miepython/data/segelstein81_index.txt,sha256=aJLqcPIkw-0WDY37GRcTefLV0WGhyMt6IbOKY8JxGww,36719
|
|
14
|
+
miepython-3.2.0.dist-info/licenses/LICENSE.txt,sha256=g9-BWWRLvMDMQ1Zflxliku7Sleom1_SbXHQHOLGgqqk,1055
|
|
15
|
+
miepython-3.2.0.dist-info/METADATA,sha256=LNH39wbRza2D0DymlOpJ2FBAPsy9k08zwfsxIpYTjKE,7795
|
|
16
|
+
miepython-3.2.0.dist-info/WHEEL,sha256=YCfwYGOYMi5Jhw2fU4yNgwErybb2IX5PEwBKV4ZbdBo,91
|
|
17
|
+
miepython-3.2.0.dist-info/top_level.txt,sha256=bfkk6YwrKm_aIzInR5y03YbywpwCzUjJEHaFkEiSKxI,10
|
|
18
|
+
miepython-3.2.0.dist-info/RECORD,,
|
miepython-3.0.5.dist-info/RECORD
DELETED
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
miepython/__init__.py,sha256=D6Uc5ZJzlTLwziyzYaE7KCzBwH9N9cStRh2_zlYgiaE,3244
|
|
2
|
-
miepython/bessel.py,sha256=U094wY_5RFqrVjXZgMbacmt_yqpP8GBtRZ24-MNzBsU,3647
|
|
3
|
-
miepython/core.py,sha256=wMFAqHL252RLXhsh84JNoLmBpvXNKdZl29aSAMGRjNQ,19389
|
|
4
|
-
miepython/field.py,sha256=Ts1QZCHsTLkIu6gzCwyuPtHyC_SWW2gggPv2-9RHkmk,6499
|
|
5
|
-
miepython/mie_jit.py,sha256=Dr2cbv1Scotp3fxkHsFEg5gSLPVlzF1u_xjySF2F_88,15441
|
|
6
|
-
miepython/mie_nojit.py,sha256=yt3iWmjQY5bp1qHPVUCGGhms-qkKnLQufyjI_u8FB8Y,14942
|
|
7
|
-
miepython/monte_carlo.py,sha256=gemJ2vhUyiTg-hAneGRW3typd3SFM2LL4R2o1UAzLeA,3818
|
|
8
|
-
miepython/rayleigh.py,sha256=P-rpa9SKVH3RaxuUUiZzQYYk6c3cFF6vDAAgo9xChz8,9401
|
|
9
|
-
miepython/util.py,sha256=LQEDkJqz6GHVHYog2JzTE12Ibv2ncLeMI20S8IjZzAc,2908
|
|
10
|
-
miepython/vsh.py,sha256=f7WBSoZou_w0FtpYitl6cTmjrFpi0hwSOjJ9X8tNFEk,17430
|
|
11
|
-
miepython/data/Johnson.txt,sha256=PcdEhJ3ZKUnt--86ukEvUt-w-814uOyWXtE-G3qWTNE,1337
|
|
12
|
-
miepython/data/segelstein81_index.txt,sha256=aJLqcPIkw-0WDY37GRcTefLV0WGhyMt6IbOKY8JxGww,36719
|
|
13
|
-
miepython-3.0.5.dist-info/licenses/LICENSE.txt,sha256=g9-BWWRLvMDMQ1Zflxliku7Sleom1_SbXHQHOLGgqqk,1055
|
|
14
|
-
miepython-3.0.5.dist-info/METADATA,sha256=JtouOwg6loYnfq0Cf77RR4G9de8gCXWHGKzpEcLkiSI,7280
|
|
15
|
-
miepython-3.0.5.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
16
|
-
miepython-3.0.5.dist-info/top_level.txt,sha256=bfkk6YwrKm_aIzInR5y03YbywpwCzUjJEHaFkEiSKxI,10
|
|
17
|
-
miepython-3.0.5.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|