Source code for daxs.interpolators
"""The module provides interpolators."""
from __future__ import annotations
import logging
from typing import Any
import numpy as np
import numpy.typing as npt
from scipy.interpolate import (
CloughTocher2DInterpolator,
LinearNDInterpolator,
NearestNDInterpolator,
)
logger = logging.getLogger(__name__)
[docs]
class Interpolator2D:
"""Two-dimensional interpolator."""
[docs]
def __init__(
self,
x: npt.NDArray[np.float64],
y: npt.NDArray[np.float64],
z: npt.NDArray[np.float64],
kind: str = "linear",
fill_value: float = np.nan,
):
"""Initialize the 2D interpolator.
Args:
x: X-axis values (1-D array)
y: Y-axis values (1-D array)
z: Data values (1-D array)
kind: The kind of interpolation to use. Options are "nearest" or "linear".
fill_value: Value used to fill in for requested points outside of the convex
hull of the input points.
"""
if not (x.ndim == y.ndim == z.ndim == 1):
raise ValueError("x, y, z must be 1D arrays.")
if not (len(x) == len(y) == len(z)):
raise ValueError("x, y, z must have the same length.")
self.x = x
self.y = y
self.z = z
self.kind = kind
self.fill_value = fill_value
self._interpolator = None
@property
def interpolator(self):
"""The actual interpolator."""
if self._interpolator is None:
if self.kind == "nearest":
interp = NearestNDInterpolator((self.x, self.y), self.z)
elif self.kind == "linear":
interp = LinearNDInterpolator((self.x, self.y), self.z, self.fill_value)
elif self.kind == "cubic":
interp = CloughTocher2DInterpolator(
(self.x, self.y), self.z, fill_value=self.fill_value
)
else:
raise ValueError(f"Unknown interpolation method: {self.kind}")
self._interpolator = interp
return self._interpolator
[docs]
def update(self, parameters: dict[str, Any]):
"""Update the interpolator parameters."""
for key, value in parameters.items():
setattr(self, key, value)
logger.info("The interpolator parameters have been updated.")
self._interpolator = None
def __call__(self, points: npt.NDArray[np.float64]) -> npt.NDArray[np.float64]:
"""Evaluate interpolator."""
return self.interpolator.__call__(points)