Metadata-Version: 2.4
Name: ppops
Version: 0.0.0
Summary: Performance Prediction for Optical Particle Spectrometer
Author-email: Corey Pedersen <coreyped@gmail.com>
License-Expression: MIT
Project-URL: Homepage, https://github.com/c-pedersen/PPOPS
Project-URL: Repository, https://github.com/c-pedersen/PPOPS
Project-URL: Documentation, https://github.com/c-pedersen/PPOPS#readme
Project-URL: Bug Tracker, https://github.com/c-pedersen/PPOPS/issues
Keywords: OPS,OPC,POPS,Optical Particle Spectrometer
Classifier: Development Status :: 3 - Alpha
Classifier: Intended Audience :: Science/Research
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Programming Language :: Python :: 3.14
Classifier: Topic :: Scientific/Engineering :: Physics
Requires-Python: >=3.9
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: numpy>=2.0.0
Requires-Dist: pandas>=2.0.0
Requires-Dist: scipy>=1.0.0
Requires-Dist: miepython>=3.0.0
Provides-Extra: test
Requires-Dist: pytest>=8.0.0; extra == "test"
Requires-Dist: pytest-cov>=6.0.0; extra == "test"
Provides-Extra: docs
Requires-Dist: sphinx>=8.0.0; extra == "docs"
Requires-Dist: sphinx-mdinclude; extra == "docs"
Requires-Dist: sphinx-autodoc-typehints>=3.2.0; extra == "docs"
Requires-Dist: sphinx-autoapi>=3.0.0; extra == "docs"
Requires-Dist: nbsphinx>=0.9.0; extra == "docs"
Requires-Dist: pandoc>=2.0.0; extra == "docs"
Requires-Dist: ipykernel>=7.0.0; extra == "docs"
Requires-Dist: sphinx_rtd_theme>=3.1.0; extra == "docs"
Provides-Extra: dev
Requires-Dist: twine>=6.0.0; extra == "dev"
Requires-Dist: ruff; extra == "dev"
Requires-Dist: mypy; extra == "dev"
Requires-Dist: ipykernel>=6.0.0; extra == "dev"
Requires-Dist: build; extra == "dev"
Provides-Extra: validation
Requires-Dist: matplotlib>=3.0.0; extra == "validation"
Provides-Extra: profiling
Requires-Dist: snakeviz>2.0.0; extra == "profiling"
Dynamic: license-file

# PPOPS

Performance Prediction for Optical Particle Spectrometer

[![codecov](https://codecov.io/gh/c-pedersen/ppops/branch/main/graph/badge.svg?ts=20251106)](https://codecov.io/gh/c-pedersen/ppops)
[![CI](https://github.com/c-pedersen/PPOPS/actions/workflows/ci.yml/badge.svg)](https://github.com/c-pedersen/PPOPS/actions/workflows/ci.yml)

Documentation: <https://rtd-ppops.readthedocs.io/>

## Overview

This repository simulates the performance of a simple Optical Particle
Spectrometer (OPS) using a physics-based model. The default optical
system is based on Gao et al., Aerosol Sci. Technol., 2016, which is
also what the POPS instrument sold by Handix Scientific is based on. The
PPOPS model is semi-validated in that PPOPS modeled signal was within
50% of the actual signal of a POPS unit from Handix Scientific (see
validation section of PPOPS website for more information).

The PPOPS model calculates the amount and direction of scattered light
by aerosols according to Mie theory. The scattered light is integrated
over the solid-angle acceptance of the collection mirror to calculate a
truncated scattering cross section (the effective scattering cross
section). This truncated scattering cross section is then used to
calculate the instrument signal and noise current.

To summarize, the PPOPS workflow includes,

1. Use miepython to calculate the scattering amplitudes (`S₁`, `S₂`)
according to Mie theory.
   1. Compute Mie coefficients (`a_n`, `b_n`) for electric and magnetic
scattering modes.
   1. Generate angular functions (`π_n`, `τ_n`) that describe
angle-dependent intensity.
1. Integrating over the OPS collection mirror’s polar and azimuthal
acceptance to compute the truncated scattering cross section.
1. Convert the truncated scattering cross section to signal and noise
current based on detector specifications.
1. Optionally, convert signal current to digitizer bins for direct
comparison with POPS data.

## Assumptions

This package makes several assumptions:

1. Particles are perfectly spherical.
2. Scattering is elastic.
3. All scattered light incident on the collection mirror is detected.
4. The only noise sources are signal noise, dark noise, and preamp noise
(i.e., we neglect stray scattering).
5. The detector is shot noise limited.

## Installation

PPOPS is available via PyPI

```Python
pip install ppops
```

## Usage

See PPOPS website for more information.

```Python
import ppops

ops = ppops.OpticalParticleSpectrometer()

ops.estimate_signal_noise(diameters = [0.1, 0.5, 1.0], ior = 1.5+0.001j)
```

## References

Gao, R.S., Telg, H., McLaughlin, R.J., Ciciora, S.J., Watts, L.A., Richardson, M.S., Schwarz, J.P., Perring, A.E., Thornberry, T.D., Rollins, A.W., Markovic, M.Z., Bates, T.S., Johnson, J.E., Fahey, D.W., 2016. A light-weight, high-sensitivity particle spectrometer for PM2.5 aerosol measurements. Aerosol Science and Technology 50, 88–99. <https://doi.org/10.1080/02786826.2015.1131809>

miepython: 10.5281/zenodo.7949263

## Author Notes

This repository is intended as a transparent, well-documented
implementation of Mie scattering and optical geometry for POPS
performance prediction and analysis.

## License

`PPOPS` is released under the MIT license.
