refactor: reorganize backend modules into sub-packages for models, data, visualization, wafer, and controllers
This commit is contained in:
@@ -0,0 +1,61 @@
|
||||
"""RBF (thin-plate spline) heatmap field.
|
||||
|
||||
Uses CuPy for GPU acceleration when available, falls back to NumPy + SciPy.
|
||||
"""
|
||||
from __future__ import annotations
|
||||
|
||||
import numpy as np
|
||||
from scipy.interpolate import RBFInterpolator
|
||||
|
||||
try:
|
||||
import cupy as _cupy # type: ignore
|
||||
BACKEND = "cupy"
|
||||
except Exception:
|
||||
_cupy = None
|
||||
BACKEND = "numpy"
|
||||
|
||||
_KERNEL = "thin_plate_spline"
|
||||
_SMOOTHING = 0.0
|
||||
|
||||
|
||||
def interpolate_field(
|
||||
xs: np.ndarray,
|
||||
ys: np.ndarray,
|
||||
vs: np.ndarray,
|
||||
*,
|
||||
width: int,
|
||||
height: int,
|
||||
extent: tuple[float, float, float, float], # (xmin, xmax, ymin, ymax) in mm
|
||||
round_clip: bool = False,
|
||||
) -> np.ndarray:
|
||||
"""Return a (height, width) float64 array of interpolated values.
|
||||
|
||||
Args:
|
||||
xs, ys: sensor positions in mm (1-D arrays, length N)
|
||||
vs: sensor values (length N)
|
||||
width/height: output grid dimensions in pixels
|
||||
extent: (xmin, xmax, ymin, ymax) in the same mm space as xs/ys
|
||||
round_clip: if True, pixels outside the inscribed ellipse become NaN
|
||||
"""
|
||||
coords = np.column_stack([xs, ys])
|
||||
rbf = RBFInterpolator(coords, vs, kernel=_KERNEL, smoothing=_SMOOTHING)
|
||||
|
||||
xmin, xmax, ymin, ymax = extent
|
||||
gx = np.linspace(xmin, xmax, width)
|
||||
gy = np.linspace(ymin, ymax, height)
|
||||
grid_x, grid_y = np.meshgrid(gx, gy)
|
||||
flat = np.column_stack([grid_x.ravel(), grid_y.ravel()])
|
||||
|
||||
# RBFInterpolator always runs on CPU; CuPy only accelerates other ops if added later
|
||||
field = rbf(flat).reshape(height, width)
|
||||
|
||||
if round_clip:
|
||||
cx = (xmin + xmax) / 2
|
||||
cy = (ymin + ymax) / 2
|
||||
rx = (xmax - xmin) / 2
|
||||
ry = (ymax - ymin) / 2
|
||||
dist = ((grid_x - cx) / rx) ** 2 + ((grid_y - cy) / ry) ** 2
|
||||
field = np.where(dist <= 1.0, field, np.nan)
|
||||
|
||||
return field.astype(np.float64)
|
||||
|
||||
Reference in New Issue
Block a user