Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
48 commits
Select commit Hold shift + click to select a range
de1b0ab
changed parsing of m to allow multilayer and (soon) multiwavelength
vnmanoharan Mar 8, 2025
0170160
removed legacy import try..except block in multilayer_sphere_lib
vnmanoharan Mar 8, 2025
1669c75
initial tests to check whether vectorized Mie solutions work
vnmanoharan Mar 8, 2025
d32bbc3
moved multilayer code to mie.py. multilayer_sphere_lib marked for del…
vnmanoharan Mar 8, 2025
ddd4554
use vectorized spherical_jn instead of riccati_jn in riccati_psi_xi
vnmanoharan Mar 8, 2025
2edbd2b
initial vectorization of scattering coefficients (and test)
vnmanoharan Mar 9, 2025
37987b2
made vectorized _scatcoeffs() more succinct
vnmanoharan Mar 9, 2025
39e104c
vectorized _asymmetry_parameter() and added test
vnmanoharan Mar 9, 2025
0c1c477
vectorized _cross_sections() and added test
vnmanoharan Mar 9, 2025
ef3559d
changed output of size_parameter to allow vectorization; updated code
vnmanoharan Mar 10, 2025
c96274a
vectorized _internal_coeffs() and added test
vnmanoharan Mar 10, 2025
2678aa5
corrected size_parameter output and fixed some docstrings
vnmanoharan Mar 12, 2025
f76f369
vectorized scattering matrix for both Mie and Rayleigh_Gans; added tests
vnmanoharan Mar 13, 2025
0abe265
test_vectorized_cross_sections now tests mie.calc_cross_sections()
vnmanoharan Mar 13, 2025
58e162f
improved speed of dn_1_down by 1.5x
vnmanoharan Mar 13, 2025
79818af
fixed bug in calc_g (had assumed vector x is layers); test vectorization
vnmanoharan Mar 13, 2025
624bb86
fixed bug in vectorized lentz_dn_1 and added test (xfail for now)
vnmanoharan Mar 14, 2025
fa9b311
vectorized up-recursion in Qratio (large speedup) and added test
vnmanoharan Mar 14, 2025
8355bde
vectorized lentz_dn1, speeding up _scatcoeffs_multi a lot; added tests
vnmanoharan Mar 15, 2025
6a2a048
added test for lentz_dn1 based on value in Lentz 1976
vnmanoharan Mar 15, 2025
7f39fe8
vectorized up-recursion in R_psi, removing loop
vnmanoharan Mar 15, 2025
1cac9ba
vectorized calc_efficiencies and added tests
vnmanoharan Mar 16, 2025
14ef21e
parametrized tests in TestVectorizedSpecialFuncs
vnmanoharan Mar 18, 2025
0aa3e13
parametrized and organized tests of internal functions (start with _)
vnmanoharan Mar 19, 2025
aeab042
parametrized some tests of user functions, and cleaned up parametriza…
vnmanoharan Mar 19, 2025
e479900
fixed bug in calc_efficiencies; now scales by outermost x
vnmanoharan Mar 19, 2025
dd16e30
parameterized tests of calc_efficiencies and removed redundant tests
vnmanoharan Mar 19, 2025
4c84693
parameterized test_vectorized_calc_ang_dist()
vnmanoharan Mar 19, 2025
2c4fd93
added comments on which functions have yet to be tested for vectoriza…
vnmanoharan Mar 19, 2025
e4b8eea
test that calc_efficiencies returns correct efficiencies for multilayer
vnmanoharan Mar 19, 2025
45e63ad
corrected ValueError testing and cleaned up a few lines in tests
vnmanoharan Mar 19, 2025
58ead6f
updated calc_integrated_cross_section and tested vectorization
vnmanoharan Mar 20, 2025
8a5c5a0
fixed unit-related bug in calc_reflectance and added vectorization test
vnmanoharan Mar 20, 2025
f05fe86
added vectorization test for amplitude_scattering_matrix()
vnmanoharan Mar 20, 2025
5310cf8
tested vectorization by coordinate system in amplitude_scattering_mat…
vnmanoharan Mar 20, 2025
a650eaa
added test for vectorization of vector_scattering_amplitude()
vnmanoharan Mar 20, 2025
085ae44
tested vectorized diff_scat_intensity_complex_medium()
vnmanoharan Mar 21, 2025
c8d2a09
fixed vectorization issues in absorbing medium angular functions
vnmanoharan Mar 21, 2025
f762d76
vectorized integrate_intensity_complex_medium and added test
vnmanoharan Jun 6, 2025
2a5e969
vectorized calc_reflectance and fixed test
vnmanoharan Jun 14, 2025
eebbe21
vectorized _cross_sections_complex_medium_fu() and added test
vnmanoharan Jun 16, 2025
372230f
vectorized _cross_sections_complex_medium_sudiarta and updated test
vnmanoharan Jun 17, 2025
8d9afc5
updated docstring in test_mie_vectorized.py
vnmanoharan Jun 17, 2025
4aa9c99
fixed bug in Sudiarta fn giving negative Cabs; added test
vnmanoharan Jun 17, 2025
dbf1cbc
added GitHub Actions lint_and_test.yml for continuous integration
vnmanoharan Jun 18, 2025
f8a5d2f
removed defaults channel (now commercial); use only conda-forge
vnmanoharan Jun 18, 2025
6174928
removed setup.py and configured pyproject.toml for setuptools install
vnmanoharan Jun 18, 2025
fb70840
updated README.md with installation instructions
vnmanoharan Jun 18, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
55 changes: 55 additions & 0 deletions .github/workflows/lint_and_test.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
name: Lint, then test on all platforms

on:
# empty "push:" will trigger CI on push to any branch
push:
pull_request:
branches: [ "develop", "master" ]

jobs:
lint:
# only need to run on one platform since we're just looking at the code
runs-on: ubuntu-latest
defaults:
run:
shell: bash -el {0}
steps:
- uses: actions/checkout@v4
- uses: astral-sh/ruff-action@v3
with:
# check based on rulesets defined in pyproject.toml and fail if errors
args: "check"
# do another run to produce a linting report for pull requests. exit-zero
# treats all errors as warnings. This will flag codestyle problems in the
# PR
- run: ruff check --exit-zero --output-format=github

test:
# linting must succeed for testing to run; this helps us rapidly flag code
# errors before going to testing
needs: lint
runs-on: ${{ matrix.os }}
# conda enviroment activation requires bash
defaults:
run:
shell: bash -el {0}
strategy:
fail-fast: false
matrix:
os: [ubuntu-latest, macos-latest, windows-latest]
python-version: ["3.13"] # , "3.10", "3.11", "3.12"]
max-parallel: 5

steps:
- uses: actions/checkout@v4
- name: Set up miniforge with pymie environment
uses: conda-incubator/setup-miniconda@v3
with:
environment-file: environment.yml
miniforge-version: latest
conda-remove-defaults: "true"
- name: Install plugin to annotate test results
run: pip install pytest-github-actions-annotate-failures
- name: Test with pytest
run: |
pytest
30 changes: 26 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,31 @@ Pure Python package for Mie scattering calculations. This package is used by,
for example, the [structural-color python
package](https://github.com/manoharan-lab/structural-color).

To install:

```shell
git clone https://github.com/manoharan-lab/python-mie.git
python -m pip install ./python-mie
```

To remove:

```shell
python -m pip uninstall pymie
```

You can then run the tests to make sure the package works properly:
```shell
cd python-mie
pytest -v
```

The original code was developed by Jerome Fung in the [Manoharan Lab at Harvard
University](http://manoharan.seas.harvard.edu). This research was supported by
the National Science Foundation under grant numbers CBET-0747625, DMR-0820484,
DMR-1306410, and DMR-1420570. The code has since been updated. It now works in
Python 3, and it can handle quantities with dimensions (using
University](http://manoharan.seas.harvard.edu). The code has since been updated
by Victoria Hwang, Anna B. Stephenson, and Vinothan N. Manoharan. It works
in Python 3, and it can handle quantities with dimensions (using
[pint](https://github.com/hgrecco/pint)).

The development of this code was made possible with support from the National
Science Foundation under award numbers CBET-0747625, DMR-0820484, DMR-1306410,
DMR-1420570, and DMR-2011754.
5 changes: 2 additions & 3 deletions environment.yml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# dependencies for structural color package
# dependencies for pymie package
#
# To use:
# conda env create -f .\environment.yml
# conda env create -f environment.yml
# and then
# conda activate pymie
#
Expand All @@ -12,7 +12,6 @@
name: pymie
channels:
- conda-forge
- defaults
dependencies:
- python>=3.11
- numpy
Expand Down
46 changes: 32 additions & 14 deletions pymie/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,8 @@
Github: https://github.com/hgrecco/pint
Docs: https://pint.readthedocs.io/en/latest/

.. moduleauthor :: Vinothan N. Manoharan <vnm@seas.harvard.edu>
.. moduleauthor :: Sofia Magkiriadou <sofia@physics.harvard.edu>.
.. moduleauthor:: Vinothan N. Manoharan <vnm@seas.harvard.edu>
.. moduleauthor:: Sofia Magkiriadou <sofia@physics.harvard.edu>.
"""

import numpy as np
Expand Down Expand Up @@ -68,20 +68,22 @@ def index_ratio(n_particle, n_matrix):

Parameters
----------
n_particle: structcol.Quantity [dimensionless]
refractive index of particle at a particular wavelength
n_particle: structcol.Quantity [dimensionless] or ndarray thereof
refractive index of particle at particular wavelength(s)
can be complex
n_matrix: structcol.Quantity [dimensionless]
refractive index of matrix at a particular wavelength

Notes
-----
Returns a scalar rather than a Quantity because scipy special functions
don't seem to be able to handle pint Quantities
Nondimensionalizes from input arguments and strips units, returning a pure
ndarray (not a Quantity object)

Returns
-------
float
ndarray or scalar (complex or float):
Return type depends on type of n_particle and n_matrix, and return
shape should be the same as n_particle
"""
return (n_particle/n_matrix).magnitude

Expand All @@ -92,26 +94,42 @@ def size_parameter(wavelen, n_matrix, radius):

Parameters
----------
wavelen: structcol.Quantity [length]
wavelen: structcol.Quantity [length], array-like
wavelength in vacuum
n_matrix: structcol.Quantity [dimensionless]
n_matrix: structcol.Quantity [dimensionless], array-like
refractive index of matrix at wavelength=wavelen
radius: structcol.Quantity [length]
radius: structcol.Quantity [length], array-like
radius of particle

Notes
-----
Returns a scalar rather than a Quantity because scipy special functions
don't seem to be able to handle pint Quantities
Nondimensionalizes from input arguments and strips units, returning a pure
ndarray (not a Quantity object)

Returns
-------
complex or float
ndarray or scalar (complex or float):
returns scalar if both wavelen and radius are scalars. If wavelen is an
array, returns shape [len(wavelen), 1]. If radius is an array, returns
shape [1, len(radius)]. If both are arrays, returns shape
[len(wavelen), len(radius)]

"""
# ensure size parameter calculation broadcasts correctly when both
# wavelength and radius are arrays
radius = np.broadcast_to(radius, (np.size(wavelen), np.size(radius)))
wavelen = np.reshape(wavelen, (np.size(wavelen), 1))
# matrix index may be specifed as an array to account for dispersion
if isinstance(n_matrix, np.ndarray):
n_matrix = np.reshape(n_matrix, (np.size(wavelen), 1))
sp = (2 * np.pi * n_matrix / wavelen * radius)

# must use to('dimensionless') in case the wavelength and radius are
# specified in different units; pint doesn't automatically make
# ratios such as 'nm'/'um' dimensionless
sp = (2 * np.pi * n_matrix / wavelen * radius)
if isinstance(sp, Quantity):
sp = sp.to('dimensionless').magnitude
if np.size(sp) == 1:
sp = sp.item()

return sp
Loading
Loading