Design and global optimization of dielectric coatings
Description
Thin film coating design, optimization, and analysis tools based on G. Venugopalan et. al.
Install
From within your favorite python environment (e.g. conda) run:
python -m pip install OptimalBragg
Examples
Quarter-wave high-reflectivity (HR) coating
import numpy as np
import matplotlib.pyplot as plt
from physunits import um, nm, ppm
from OptimalBragg.materials import *
from OptimalBragg import qw_stack, Material
from OptimalBragg.layers import *
from OptimalBragg.plot import plot_layers, plot_spectral
lam_ref = 1064 * nm
silica = Material(SiO2)
tantala = Material(Ta2O5)
Nlayers = 11
# Makes arbitrary quarter-wave stack
stack = qw_stack(
lam_ref,
substrate=silica,
superstrate=Material(air),
thin_films={"A": silica, "B": tantala},
pattern="BA" * Nlayers,
)
# Results
T_ref = trans(lam_ref, stack)
print(Rf"T = {T_ref/ppm:.1f} ppm at {lam_ref/um:.2f} um.")
# Show layer structure and spectral refl/trans
plot_layers(stack)
rel_lambdas = np.linspace(0.75 * lam_ref, 1.25 * lam_ref, 2**10)
# Let's pretend I have custom dispersion data for these thin films
lam_disp = np.array([0.532, 0.633, 0.780, 0.852, 1.064, 1.083, 1.550]) * um
nSiO2 = np.interp(
rel_lambdas,
lam_disp,
[1.4607, 1.4570, 1.4537, 1.4525, 1.4496, 1.4494, 1.444],
)
nTa2O5 = np.interp(
rel_lambdas,
lam_disp,
[2.24, 2.1979, 2.1628, 2.1515, 2.1297, 2.1282, 2.1046],
)
plot_spectral(rel_lambdas, stack)
plot_spectral(rel_lambdas, stack, dispersion={"A": nSiO2, "B": nTa2O5})
plt.show()
Optimize an existing anti-reflective (AR) coating
import time
import h5py
import numpy as np
import matplotlib.pyplot as plt
from physunits import um, nm, ppm, Hz
from OptimalBragg.materials import *
from OptimalBragg import qw_stack, h5write, Material
from OptimalBragg.layers import *
from OptimalBragg.plot import plot_layers, plot_spectral
from OptimalBragg.optimizer import diff_evo
lam_ref = 1550 * nm
# Initialize QW stack but override with user defined pre-designed stack
stack = qw_stack(
lam_ref=lam_ref,
substrate=Material(SiO2),
superstrate=Material(air),
thin_films={"L": Material(SiO2), "H": Material(Ta2O5)},
pattern="LH" * 4,
hwcap="H",
)
# stack["ns"] = np.array([1.0, 2.1, 1.45, 2.1, 1.45, 2.1, 1.45])
# stack["Ls"] = np.array([0.8548, 268.4, 204.2, 90.18, 61.42]) * nm
T_ref = trans(lam_ref, stack)
stack["T_ref"] = T_ref
print(Rf"R < {(1 - T_ref)*100:.8f} % at {lam_ref/um:.2f} um.")
# Optimization over multiple wavelength AR and absorption
lam_m = 1545 * nm
lam_p = 1564 * nm
T_p = trans(lam_p, stack)
T_m = trans(lam_m, stack)
# Reference (initial) stack
stack["init"] = {"ns": stack["ns"], "Ls": stack["Ls"], "T_ref": T_ref}
multi_target = {
"R": {
"target": {
lam_ref: 10 * ppm,
lam_p: 10 * ppm,
lam_m: 10 * ppm,
},
"weight": {lam_ref: 1, lam_p: 1, lam_m: 1},
},
"abs": {"target": 25 * ppm, "weight": 1e-2},
}
optimization_result = diff_evo(stack, multi_target)
stack["optimized"] = True
# Update thicknesses and other optimized attributes
stack["Ls"] = optimization_result["Ls"]
T_ref = trans(lam_ref, stack)
_, Enorm = field_zmag(
stack["ns"], stack["Ls"], n_pts=2**8, lam=stack["lam_ref"]
)
intAbs = calc_abs(Enorm, stack["Ls"], stack["alphas"])
stack["Absorption"] = intAbs
stack["T_ref"] = T_ref
# Results
plot_layers(stack)
plt.show()
wavelengths = np.linspace(0.95 * lam_m, 1.05 * lam_p, 2**12)
plot_spectral(wavelengths, stack, markers={"R": [lam_p, lam_m, lam_ref]})
plt.show()
# Save to hdf5
time_tag = time.strftime("%Y%m%d-%H%M%S")
h5write(
Rf"./AR1550_R_{(1-T_ref)/ppm:.0f}_A_{intAbs/ppm:.0f}_ppm_{time_tag}.h5",
stack,
)
Metadata
Release files for OptimalBragg 1.0.2
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | Actions |
|---|---|---|---|---|
| optimalbragg-1.0.2.tar.gz | 27.8 kB | Without provenance | Details for optimalbragg-1.0.2.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| OptimalBragg-1.0.2-py3-none-any.whl | Python 3 | none | any | Details for OptimalBragg-1.0.2-py3-none-any.whl |
Total release size: 58.1 kB
Release files / optimalbragg-1.0.2.tar.gz
| Download URL | optimalbragg-1.0.2.tar.gz |
|---|---|
| Size | 27.8 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
2af107ca39d94e318494c12d3eb09575831a3e60b2c3bae2ce4144127f74dbfd
|
|
BLAKE2b-256 checksum How to use checksums |
ea259a227082875f583d3116c8d812b2887dbc6893b5b76ff0f1ecb45393f1cc
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/5.0.0 CPython/3.11.8
|
Release files / OptimalBragg-1.0.2-py3-none-any.whl
| Download URL | OptimalBragg-1.0.2-py3-none-any.whl |
|---|---|
| Size | 30.4 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
305856cf28a63825236789becf97af0fcc6d88f3e6a42af0cf25db97fc3853bf
|
|
BLAKE2b-256 checksum How to use checksums |
975506d6ae6b786645fd433bc8c834e521aa2cded066a4351a50a408ef2a8e98
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/5.0.0 CPython/3.11.8
|
Security for OptimalBragg 1.0.2
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.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A 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.