tmmcore
Transfer-matrix method for multilayer thin-film optics, with exact analytic derivatives.
Documentation · Python · Source
Takes a stack of layers and returns reflectance, transmittance and absorptance for absorbing and dispersive materials, at any angle of incidence, in s and p polarization. Alongside them it returns the exact thickness Jacobian and Hessian, and phase, group delay, GDD and third-order dispersion with their thickness derivatives, all computed analytically rather than by finite differences.
This is the Python package of tmmcore. The wheel carries the same C kernel as the npm package, compiled for your platform and called through ctypes. It needs numpy and nothing else.
Install
pip install tmmcore
Wheels are built for Windows (x86-64), macOS (Intel and Apple silicon) and Linux (x86-64 and ARM64, glibc), for Python 3.9 and later.
Use
import tmmcore
# A quarter-wave MgF2 layer on glass, at 550 nm, normal incidence.
stack = {"incident": 1.0, "substrate": 1.52,
"layers": [{"n": 1.38, "d": 550 / (4 * 1.38)}]} # d in nm
print(tmmcore.rta(stack, 550)["R"]) # 0.012600790214630274
Layers run from the incident medium toward the substrate. In rta_spectrum any n or k can be one value per wavelength. A quarter-half-quarter antireflection coating on BK7-like glass (Macleod, Thin-Film Optical Filters 5th ed., ch. 4), with Cauchy indices:
import numpy as np
import tmmcore
def cauchy(a, b):
return lambda lam: a + b / lam**2
low, high, mid, glass = cauchy(1.377, 2000), cauchy(2.170, 8000), cauchy(1.680, 5000), cauchy(1.504, 4200)
lam = np.arange(400.0, 701.0, 2.0) # nm
# Quarter, half and quarter wave at 510 nm, the layer facing air first.
layers = [{"n": m(lam), "d": waves * 510 / m(510)} for m, waves in ((low, 0.25), (high, 0.5), (mid, 0.25))]
coated = tmmcore.rta_spectrum({"incident": 1.0, "substrate": {"n": glass(lam)}, "layers": layers}, lam)
print(f"{coated['R'].mean():.2%}") # 0.25%, against 4.25% for bare glass
Calls
| Call | Returns |
|---|---|
rta, rta_spectrum |
R, T and A |
jacobian, jacobian_spectrum |
R, T and A, and their derivatives in each layer's thickness |
hessian, hessian_spectrum |
the same, and the second derivatives |
needle_scan, needle_scan_spectrum |
the derivatives of R, T and A for inserting a thin layer anywhere in the stack |
phase, phase_spectrum |
phase, GD, GDD and TOD of r and t |
phase_jacobian, phase_jacobian_spectrum |
the same, and their thickness derivatives |
monitor_curve, deposition_spectra, growing_stack |
R and T in s and p while the layers are deposited |
jet_*, wavelength_omega_jet, omega_from_lambda_nm |
Taylor-jet arithmetic, which builds the dispersive indices the phase calls take |
Each call takes the stack, then one wavelength or, in a _spectrum call, deposition_spectra and growing_stack, an array of them. angle and pol are keyword arguments. angle is the angle of incidence, 0 when left out, and over an array of wavelengths may be one angle per wavelength. pol is "s", "p" or "avg" (the default, the mean of the two) in the R/T, derivative and needle calls, and "s" or "p" in the phase calls, which may leave it out at normal incidence, where the two are the same. In place of angle the phase calls take sine, the sine of the angle of incidence as a jet, one per wavelength in a _spectrum call, for an angle fixed outside a dispersive incident medium. The needle calls take candidates, the materials they try inserting, each an index given as a medium is, and fractions, where inside each layer they also try them. The monitoring calls take angle and no pol, and return s and p together with the reflectance seen from the substrate side; monitor_curve also takes top, the growing layer's index, and thicknesses, the thicknesses of it to sample. Results are dicts. At one wavelength the values are numbers, each first derivative an array with one value per layer and each second derivative an (N, N) array; a needle call's gaps and intra are dicts of dR, dT and dA, arrays of shape (N + 1, nCand) and (N, nFrac, nCand). Over a grid each gains a leading wavelength axis. The phase calls return one dict for r and one for t, and at one wavelength None for a coefficient that is exactly zero. monitor_curve returns one value per thickness, deposition_spectra arrays of shape (N, nLam), row k after k + 1 layers, and each sample of growing_stack one value per wavelength.
Conventions
| Refractive index | ñ = n + ik, with k ≥ 0 for absorbing media; n may instead be complex, n + ik |
| Time factor | exp(−iωt), so a wave exp(i(kz − ωt)) decays for k > 0 |
| p-polarized amplitudes | from the tilted admittance n/cos θ, so r_p = r_s at normal incidence |
| Wavelength, thickness | nanometres |
| Angle of incidence | degrees from normal |
| Phase | radians, in Macleod's sign convention; GD, GDD and TOD in fs, fs² and fs³ |
| Layer order | incident medium first, substrate last |
Agreement with the npm package
The package's tests run every call on the cases of the npm package's equivalence suite and compare each value with its WebAssembly build: R, T and A to within 1e-9, everything else to within 1e-7 of its size or 1e-12, whichever is larger. Both run the same C, so they differ only in the last digits, where the platform's math library rounds differently from the one compiled into the WebAssembly.
They also run the comparison with Essential Macleod on its committed results, to the same tolerances as the npm package.
Licence
MIT © Andrey Achapovsky
Metadata
Release files for tmmcore 0.5.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Built distributions (wheels)
| File | Actions Reset | |||
|---|---|---|---|---|
| tmmcore-0.5.0-py3-none-win_amd64.whl | Python 3 | none | Windows x86-64 | Details for tmmcore-0.5.0-py3-none-win_amd64.whl |
| tmmcore-0.5.0-py3-none-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl | Python 3 | none | Linux glibc 2.17+ ARM64, Linux glibc 2.28+ ARM64 | Details for tmmcore-0.5.0-py3-none-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl |
| tmmcore-0.5.0-py3-none-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl | Python 3 | none | Linux glibc 2.5+ x86-64, Linux glibc 2.28+ x86-64 | Details for tmmcore-0.5.0-py3-none-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl |
| tmmcore-0.5.0-py3-none-macosx_11_0_arm64.whl | Python 3 | none | macOS 11.0+ ARM64 | Details for tmmcore-0.5.0-py3-none-macosx_11_0_arm64.whl |
| tmmcore-0.5.0-py3-none-macosx_10_9_x86_64.whl | Python 3 | none | macOS 10.9+ x86-64 | Details for tmmcore-0.5.0-py3-none-macosx_10_9_x86_64.whl |
Total release size: 719.3 kB
Release files / tmmcore-0.5.0-py3-none-win_amd64.whl
| Download URL | tmmcore-0.5.0-py3-none-win_amd64.whl |
|---|---|
| Size | 77.9 kB |
| Tags | Python 3 Windows x86-64 |
|
SHA-256 checksum How to use checksums |
6f38391987ee8ab849fe52b6827eea8b9a35675b7783f5f74e3905910f2e6f4e
|
|
BLAKE2b-256 checksum How to use checksums |
8ca74aa76cddb8fc33ac0edc50426a6bc8cccec2f0021567f3f2625749e2ae59
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.16
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 31, 2026.
Transparency logRelease files / tmmcore-0.5.0-py3-none-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl
| Download URL | tmmcore-0.5.0-py3-none-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl |
|---|---|
| Size | 226.8 kB |
| Tags | Linux glibc 2.17+ ARM64 Linux glibc 2.28+ ARM64 Python 3 |
|
SHA-256 checksum How to use checksums |
a2ae5f7047bc6fbb1abfd6ffb528eade508fbeca8f93aeb5b7c310f4c1b57882
|
|
BLAKE2b-256 checksum How to use checksums |
7881117b7766ea07d7a271ae76137845889a107069dea412281a77f655db864d
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.16
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 31, 2026.
Transparency logRelease files / tmmcore-0.5.0-py3-none-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl
| Download URL | tmmcore-0.5.0-py3-none-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl |
|---|---|
| Size | 246.9 kB |
| Tags | Linux glibc 2.28+ x86-64 Linux glibc 2.5+ x86-64 Python 3 |
|
SHA-256 checksum How to use checksums |
a0b8cdee504ad6b17459ff67236f98d3fed847d85bb4b107e495b6e31616282c
|
|
BLAKE2b-256 checksum How to use checksums |
b4e214a64ac6c0ad6033fd785d8695d1b8b21bf72e0c9a6012c8dc46a01b3399
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.16
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 31, 2026.
Transparency logRelease files / tmmcore-0.5.0-py3-none-macosx_11_0_arm64.whl
| Download URL | tmmcore-0.5.0-py3-none-macosx_11_0_arm64.whl |
|---|---|
| Size | 79.0 kB |
| Tags | Python 3 macOS 11.0+ ARM64 |
|
SHA-256 checksum How to use checksums |
55565c1275051dc84b8e665e2ffb0d7ca21bf197a03c0d7d4426b939f1a98260
|
|
BLAKE2b-256 checksum How to use checksums |
d249584d65fd90c44c886c00fbd63c29e6f91502d58b34670ef8914a2ade65c6
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.16
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 31, 2026.
Transparency logRelease files / tmmcore-0.5.0-py3-none-macosx_10_9_x86_64.whl
| Download URL | tmmcore-0.5.0-py3-none-macosx_10_9_x86_64.whl |
|---|---|
| Size | 88.7 kB |
| Tags | Python 3 macOS 10.9+ x86-64 |
|
SHA-256 checksum How to use checksums |
dc6ebb17a18418c8949bd1512aa375d2cfd70dece53ba22ec2d71dca6cfe99a3
|
|
BLAKE2b-256 checksum How to use checksums |
0bad544f20662c4a7ccc16237456dab3c92505936d0524bd7933172b9a13d0ca
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.16
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 31, 2026.
Transparency logSecurity for tmmcore 0.5.0
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
Full provenance
All 5 files in this release have been uploaded with provenance metadata.
Attestation for tmmcore-0.5.0-py3-none-win_amd64.whl
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 31, 2026.
Transparency logA note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.