📖 Beginner Friendly
Start from zero — learn image sensor optics fundamentals before diving into simulation
Simulate CMOS image sensor pixels with multiple EM solvers from a single YAML config
COMPASS bridges the gap between electromagnetic theory and practical CMOS image sensor design. Define your pixel stack once, run it through any solver, and compare results -- all from Python.
Run the same pixel structure through RCWA (torcwa, grcwa, meent, fmmax) and FDTD (flaport, Meep, fdtdz) solvers from a single YAML config. Compare results head-to-head.
Leverage PyTorch and JAX GPU backends for massively parallel wavelength sweeps. Achieve 10-100x speedup over CPU-only solvers on large parameter spaces.
Automatic differentiation through the solver enables gradient-based inverse design. Optimize microlens profiles, BARL stacks, and color filter thicknesses directly.
Built-in solver comparison framework ensures physics accuracy. Compare energy balance (R+T+A=1), QE spectra, and field distributions across solver backends.
Compute QE per pixel per wavelength, crosstalk matrices, energy balance, and field distributions. Plot results with built-in matplotlib and 3D PyVista viewers.
MIT licensed. Fully documented with theory guides, cookbooks, and API references. Built on established open-source EM solver ecosystems.
A clean five-stage pipeline takes you from YAML configuration to publication-ready results. Click any stage to learn more.
COMPASS provides a unified interface to 8 solver backends across three electromagnetic methods. Click any solver to see details.
Define your simulation in a single YAML config and run it with three lines of Python:
# config.yaml
pixel:
pitch: 1.0 # um
unit_cell: [2, 2] # 2x2 Bayer pattern
solver:
name: torcwa
type: rcwa
fourier_order: 9
source:
wavelength:
mode: sweep
sweep: { start: 0.4, stop: 0.7, step: 0.01 }
polarization: unpolarizedfrom compass.runners.single_run import SingleRunner
result = SingleRunner.run("config.yaml")
for pixel, qe in result.qe_per_pixel.items():
print(f"{pixel}: peak QE = {qe.max():.2%}")