Metadata-Version: 2.4
Name: muellerkit
Version: 0.1.1
Summary: Mueller-matrix decomposition and polarimetry tools
License-Expression: MIT
Project-URL: Homepage, https://github.com/adamt222/muellerkit
Project-URL: Repository, https://github.com/adamt222/muellerkit
Project-URL: Issues, https://github.com/adamt222/muellerkit/issues
Classifier: Development Status :: 3 - Alpha
Classifier: Intended Audience :: Science/Research
Classifier: Programming Language :: Python :: 3
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: Topic :: Scientific/Engineering :: Physics
Requires-Python: >=3.10
Description-Content-Type: text/markdown
License-File: LICENSE
License-File: NOTICE
Requires-Dist: numpy>=1.23
Provides-Extra: test
Requires-Dist: pytest>=8; extra == "test"
Dynamic: license-file

# MuellerKit

`muellerkit` provides vectorized Lu-Chipman polar decomposition for individual
Mueller matrices and batches such as Mueller-matrix images. The decomposition
uses the convention

```text
M = M_delta @ M_R @ M_D
```

where `M_delta` is the depolarizer, `M_R` is the retarder, and `M_D` is the
diattenuator.

The implementation follows S.-Y. Lu and R. A. Chipman, “Interpretation of
Mueller matrices based on polar decomposition,” *J. Opt. Soc. Am. A* 13,
1106–1113 (1996), [doi:10.1364/JOSAA.13.001106](https://doi.org/10.1364/JOSAA.13.001106).

## Installation

Install the project from a checkout with:

```bash
python -m pip install .
```

For development and testing:

```bash
python -m pip install -e '.[test]'
python -m pytest
```

## Usage

```python
import numpy as np
import muellerkit

M = np.eye(4)
M_delta, M_R, M_D = (
    muellerkit.decompose_depolarizer_retarder_diattenuator(M)
)

parameters = muellerkit.extract_parameters(M_delta, M_R, M_D)
print(parameters.total_retardance)
print(parameters.diattenuation)

np.testing.assert_allclose(M_delta @ M_R @ M_D, M)
```

Inputs may have shape `(4, 4)` or `(..., 4, 4)`. Outputs preserve all leading
batch dimensions. All angular parameters are returned in radians.

Ensemble physical realizability can be checked before decomposition:

```python
physicality = muellerkit.physical_realizability(M)
print(physicality.is_realizable)
print(physicality.minimum_eigenvalue)

M_delta, M_R, M_D = (
    muellerkit.decompose_depolarizer_retarder_diattenuator(
        M,
        valid_mask=physicality.is_realizable,
    )
)

parameters = muellerkit.extract_parameters(
    M_delta,
    M_R,
    M_D,
    valid_mask=physicality.is_realizable,
)
```

This constructs the Hermitian coherency matrix and tests whether its
eigenvalues are non-negative within an absolute and relative numerical
tolerance. For an image, nonfinite pixels are marked unrealizable and assigned
`NaN` eigenvalues without preventing the remaining pixels from being tested.
Passing the resulting Boolean mask to the decomposition restricts all input
validation and numerical work to selected matrices. Each returned factor is
filled with `NaN` at masked pixels. Passing the same mask to parameter
extraction produces parameter maps with `NaN` at those pixels without
processing their factors.
The criterion follows J. J. Gil, “Characteristic properties of Mueller
matrices,” *J. Opt. Soc. Am. A* 17, 328–334 (2000),
[doi:10.1364/JOSAA.17.000328](https://doi.org/10.1364/JOSAA.17.000328).

`extract_parameters` returns a frozen `PolarizationParameters` object with the
following fields:

| Field | Symbol | Meaning |
| --- | --- | --- |
| `diattenuation` | `D` | Diattenuation magnitude |
| `total_depolarization` | `Delta` | Total depolarization power |
| `total_retardance` | `R` | Total retardance |
| `linear_retardance` | `delta` | Linear retardance from Ghosh et al. |
| `optical_rotation` | `psi` | Optical rotation from Ghosh et al. |
| `linear_retardance_axis_orientation` | `theta` | Orientation of the linear-retardance axis |
| `linear_phase_retardance` | `d_L` | Linear phase retardance from Qi and Elson |
| `circular_phase_retardance` | `d_C` | Circular phase retardance from Qi and Elson |

The Ghosh and Qi-Elson quantities intentionally remain separate. Under the
Qi-Elson retarder-matrix convention used here, `circular_phase_retardance` is
the full rotation in the `S1-S2` plane and equals `-2 * optical_rotation`.

Parameter equations follow N. Ghosh, M. F. G. Wood, and I. A. Vitkin,
“Mueller matrix decomposition for extraction of individual polarization
parameters from complex turbid media exhibiting multiple scattering, optical
activity, and linear birefringence,” *J. Biomed. Opt.* 13, 044036 (2008),
[doi:10.1117/1.2960934](https://doi.org/10.1117/1.2960934), and J. Qi and
D. S. Elson, “Mueller polarimetric imaging for surgical and diagnostic
applications: a review,” *J. Biophotonics* 10, 950–982 (2017),
[doi:10.1002/jbio.201600152](https://doi.org/10.1002/jbio.201600152).

## Input assumptions and edge cases

- Decomposition inputs must be finite, real arrays with trailing shape
  `(4, 4)` and non-negative `M[0, 0]`.
- A matrix with `M[0, 0] == 0` is accepted only when the complete matrix is
  zero. It is represented by identity depolarizer and retarder factors and a
  zero diattenuator factor.
- Diattenuation magnitudes greater than one, beyond numerical tolerance, are
  rejected.
- Decomposition does not automatically call `physical_realizability`; measured
  matrices should be checked explicitly when this validation is required.
- `physical_realizability` checks ensemble realizability but not passivity.
  Passivity additionally depends on absolute intensity transmission and cannot
  be inferred after normalizing every matrix by `M[0, 0]`.
- Singular decompositions are not unique. The implementation selects the
  canonical proper rotations described by the Lu-Chipman Appendix B branches.

## Development status

This is research software and the first public API release. Numerical results
should be validated for the conventions and measurement regime of the
application. Tests include nonsingular Eq. (52), singular Appendix B cases,
batched inputs, unit diattenuation, the Ghosh and Qi-Elson parameter equations,
coherency-matrix physical realizability, and invalid inputs.

## Attribution and license

The project is distributed under the MIT License. Portions are modified,
vectorized Python derivatives of public-domain NIST SCATMECH/pySCATMECH code;
see [`NOTICE`](NOTICE) for attribution and the upstream disclaimer.
