Wafer-level Zernike polynomial decomposition and fitting
Project description
wlzpoly — Wafer-Level Zernike Polynomials
Decompose 13-point wafer thickness measurements into 9 Zernike coefficients (LSQ / Ridge), with a reproducible demo workflow that generates synthetic data, fits it, and verifies the recovered coefficients against ground truth.
Install
pip install wlzpoly
Requires Python 3.9+. Dependencies: numpy >= 1.22, pandas >= 1.5, matplotlib >= 3.5, tqdm >= 4.60.
Quick start
import numpy as np
from wlzpoly import ZernikePolynomials, WaferLevelZernikePolynomials
# 1) Build a wavefront from known coefficients (Noll j -> a_j)
z = ZernikePolynomials(coeffs={1: 500.0, 4: -12.0, 6: 0.5}, n_terms=9)
field = z.evaluate(rho=np.array([0.0, 0.5, 1.0]),
theta=np.array([0.0, 0.0, 0.0]))
# 2) Fit Zernike coefficients from measurements at known coordinates
# coords_df : DataFrame indexed by point_id, columns ['x','y'] (mm),
# attrs['wafer_radius_mm']
# df_measured : DataFrame indexed by MultiIndex(wafer_id, point_id),
# column ['T']
wlz = WaferLevelZernikePolynomials(
coords_df=coords_df, coordinate="cartesian", n_terms=9,
)
fit_results = wlz.fit_coefficients(mesured_df=df_measured, solver="lsq")
# fit_results : list of {"id": <wafer_id>, "coeffs": np.ndarray}
# 3) Render a fitted wafer field
fig = wlz.draw_field(coeffs=fit_results[0]["coeffs"])
fig.savefig("W_01_fit.png", dpi=130, bbox_inches="tight")
ZernikePolynomials follows the Noll convention and supports any radial order — the j -> (n, m) mapping is computed dynamically.
Public API
from wlzpoly import (
ZernikePolynomials, # pure-math + per-wavefront instance
WaferLevelZernikePolynomials, # wafer-aware (coords + measurements -> fit)
fit_lsq, fit_ridge, # general-purpose linear solvers
)
| Function / class | Purpose |
|---|---|
ZernikePolynomials.basis(j, rho, theta) |
Single Zernike basis Z_j(rho, theta) |
ZernikePolynomials.basis_matrix(rho, theta, n_terms=...) |
Design matrix A for fitting |
ZernikePolynomials.pyramid_image(n_max=..., names=..., return_type=...) |
Zernike pyramid PNG / Figure |
ZernikePolynomials(coeffs=...).evaluate(rho, theta) |
Evaluate a specific wavefront |
WaferLevelZernikePolynomials(coords_df, coordinate, n_terms) |
Pre-compute A from measurement layout |
wlz.fit_coefficients(mesured_df, solver, lam) |
Per-wafer LSQ / Ridge fit |
wlz.draw_field(coeffs) |
Heatmap with measurement-point overlay |
fit_lsq(A, T) |
a_hat = (A^T A)^-1 A^T T |
fit_ridge(A, T, lam) |
a_hat = (A^T A + lam I)^-1 A^T T |
loocv_lambda(A, T, lambdas) |
LOOCV-driven lambda selection |
Three-stage demo (after development install)
git clone https://github.com/ykim2718/WaferLevelZernikePolynomials.git
cd WaferLevelZernikePolynomials
pip install -e .
cd examples
python generate_samples.py # Stage 1: synthesize wafers
python -m wlzpoly.decompose --solver lsq # Stage 2: fit coefficients
python -m wlzpoly.verify --solver lsq ridge # Stage 3: compare vs truth
Demo outputs land in examples/{samples,decomposition,verification}/. Pre-generated copies are visible on the GitHub repo.
Documentation
Full documentation — folder layout, CLI options, configuration files, output schemas, scenario reference, recipes, algorithm summary — lives on the GitHub README:
https://github.com/ykim2718/WaferLevelZernikePolynomials
Links
- Source / docs: https://github.com/ykim2718/WaferLevelZernikePolynomials
- Issues: https://github.com/ykim2718/WaferLevelZernikePolynomials/issues
- License: MIT
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file wlzpoly-0.0.0.tar.gz.
File metadata
- Download URL: wlzpoly-0.0.0.tar.gz
- Upload date:
- Size: 25.1 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.10.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
03ef53279d04e933e07f3236cfd03f1682708f6fa86a3b6a72acee73d5a33d1f
|
|
| MD5 |
3f5dd8e947503e8e78c5d62279b85d91
|
|
| BLAKE2b-256 |
654808c02ab6ea5b19cad31ec459094e50a5f25c3046923a7b3e390fc52efbab
|
File details
Details for the file wlzpoly-0.0.0-py3-none-any.whl.
File metadata
- Download URL: wlzpoly-0.0.0-py3-none-any.whl
- Upload date:
- Size: 22.2 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.10.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
9da4a7706da5caa37b767dc3b6cba5668a15a4f7cdc0b9385d929dbb9f24d330
|
|
| MD5 |
60a0b91e3ce6a399f0f0294ad65cddb1
|
|
| BLAKE2b-256 |
c18b1107db28da0fcddc94a80d40882e39c0f117b6068ade1905edffa892fc0f
|