Skip to main content

optika

tests codecov Black Ruff Documentation Status PyPI version DOI

A Python library for simulating optical systems, similar to Zemax.

optika computes the spectral response and resolution of an arbitrary optical system, and can optimize it using scipy.optimize. Surfaces carry their own sag profile, aperture, material, and rulings, and are placed in global coordinates, so a system is an ordinary Python object that can be built, modified, and swept over programmatically.

Because every parameter can be an array from named-arrays, a whole configuration space of designs propagates through the raytrace at once, and an uncertain parameter carries its uncertainty through to the performance of the system.

More information is available in the documentation.

Installation

Optika can be installed using pip:

pip install optika

Features

  • Sequential raytrace modeling of an optical system
  • Stratified random sampling of input rays for faster convergence
  • Image simulation of a given scene using an optical system
  • A fast linear forward model approximating a raytraced system, for imaging many scenes without raytracing each one
  • Spherical, conical, and toroidal surface sag profiles
  • Circular, rectangular, and polygonal apertures
  • Mirrors and arbitrary multilayer coatings
  • Refractive glass materials with Sellmeier dispersion (e.g. N-BK7, F2)
  • Diffraction gratings, with constant, polynomial, and holographic ruling spacing, and sinusoidal, square, rectangular, sawtooth, and triangular ruling profiles
  • CCD/CMOS sensor simulation, including quantum efficiency, noise, and charge diffusion
  • n-dimensional configurations of the optical system using named-arrays
  • Uncertainty propagation using named-arrays

Key concepts

Surfaces are placed in global coordinates. Unlike Zemax, where each surface is positioned relative to the one before it, an optika surface carries a transformation giving its position and orientation in the coordinate system of the whole instrument. Moving one surface therefore does not move everything downstream of it.

The field of view and entrance pupil are computed, not specified. The apertures of the surfaces determine them, so marking a surface with is_pupil_stop or is_field_stop is enough.

Rulings are a property of a surface. A diffraction grating is an ordinary surface with a rulings field, so switching between ruling designs does not mean switching to a different type of surface.

Any parameter can be an array. Giving a parameter an extra named axis sweeps the system over that axis, and every ray traced through it carries that axis along, which is how optika explores a configuration space without a loop. An UncertainScalarArray parameter propagates its uncertainty through the raytrace by the Monte Carlo method.

Simulate a Newtonian telescope using optika

Newtonian telescope example image simulation

Compute the reflectivity of a multilayer mirror by specifying the materials and thicknesses of the layers.

multilayer example

Model the quantum efficiency of a backilluminated CCD

QE example

Compute the transmissivity of a thin filter, such as the aluminum filters used to reject visible light on solar instruments.

import matplotlib.pyplot as plt
import astropy.units as u
import named_arrays as na
import optika

# Define the wavelengths at which to compute the transmissivity
wavelength = na.geomspace(100, 800, axis="wavelength", num=201) * u.AA

# Compute the efficiency of a 100 nm layer of aluminum
reflectivity, transmissivity = optika.materials.multilayer_efficiency(
    wavelength=wavelength,
    layers=optika.materials.Layer(
        chemical="Al",
        thickness=1000 * u.AA,
    ),
)

# Plot the transmissivity, which drops sharply at the aluminum L edge
fig, ax = plt.subplots(constrained_layout=True)
na.plt.plot(wavelength, transmissivity.average, ax=ax, axis="wavelength");
ax.set_xscale("log");
ax.set_xlabel(f"wavelength ({wavelength.unit:latex_inline})");
ax.set_ylabel("transmissivity");

aluminum filter example

Citation

If you use optika in your research, please cite it. The citation metadata is kept in CITATION.cff, which the "Cite this repository" button on GitHub can export as BibTeX or APA.

Every release of optika is archived on Zenodo with its own DOI. The concept DOI, 10.5281/zenodo.23074621, always resolves to the latest version, and the Zenodo page lists the DOI of every version. Please include the version of optika that you used, which is given by importlib.metadata.version("optika"). The BibTeX entry below uses the concept DOI. To cite a specific version instead, replace doi with the DOI of that version.

@software{optika,
  author = {Smart, Roy T. and Parker, Jacob D. and Kankelborg, Charles C.},
  title = {optika},
  version = {X.Y.Z},
  doi = {10.5281/zenodo.23074621},
  url = {https://github.com/sun-data/optika},
}

Development

Install the package in editable mode along with its test dependencies, and run the test suite using pytest:

pip install -e .[test]
pytest

This project is formatted using black, linted using ruff, and type-checked using mypy, all of which are checked by continuous integration:

black .
ruff check .
mypy optika

To build the documentation locally:

pip install -e .[doc]
sphinx-build docs docs/_build/html

Metadata

Release files for optika 3.7.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for optika 3.7.0
File Size Uploaded Provenance Actions
optika-3.7.0.tar.gz 4.5 MB With provenance Details for optika-3.7.0.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for optika 3.7.0
File Interpreter ABI Platform Actions
optika-3.7.0-py3-none-any.whl Python 3 none any Details for optika-3.7.0-py3-none-any.whl

Total release size: 9.5 MB

Release files / optika-3.7.0.tar.gz

Download URL optika-3.7.0.tar.gz
Size 4.5 MB
Tags Source
SHA-256 checksum
How to use checksums
aac5ec9de02b8f51c22d6a456ffbed86588820d0e266f00fa49c66bde6247e32
BLAKE2b-256 checksum
How to use checksums
af6f823935409f80448e8b1ad680d2382b33b9b7cdc2314c0cfd440dcbd095cd
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 Nov 1, 2026.

Transparency log

Release files / optika-3.7.0-py3-none-any.whl

Download URL optika-3.7.0-py3-none-any.whl
Size 5.0 MB
Tags Python 3
SHA-256 checksum
How to use checksums
d32076db74e9cc5ac7074275e9764cf8c144833ddeede2cd9945584c62de6231
BLAKE2b-256 checksum
How to use checksums
c8f1fc8ce0d6a2d62f7480e777a926fe2436cec0ab0fc885e92f055d798e02db
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 Nov 1, 2026.

Transparency log

Security for optika 3.7.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 2 files in this release have been uploaded with provenance metadata.

Select from 2 files

Attestation for optika-3.7.0.tar.gz

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 Nov 1, 2026.

Transparency log

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.

Release history Release notifications | RSS feed

This release

3.7.0 This release

2 release files Full provenance

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page