Source code for suboptimumg.log_analysis.utils

import numpy as np
import numpy.typing as npt


[docs] def safe_gradient( signal: npt.NDArray[np.float64], dt: npt.NDArray[np.float64] ) -> npt.NDArray[np.float64]: """Compute a time derivative that is robust to zero-width time steps, so that duplicate timestamps do not produce inf or NaN values. Parameters ---------- signal : npt.NDArray[np.float64] The signal to differentiate. dt : npt.NDArray[np.float64] Time step array. Must be the same length as ``signal``. Returns ------- npt.NDArray[np.float64] ``d(signal)/dt`` with NaNs from zero-width steps filled by linear interpolation between the nearest valid neighbours. """ # Compute the raw gradient, masking out any points where dt == 0 # to avoid division-by-zero producing inf or incorrect values. result = np.full_like(signal, np.nan) mask = dt != 0 result[mask] = np.gradient(signal[mask]) / dt[mask] nans = np.isnan(result) if nans.any(): # Fill masked positions by linearly interpolating from valid neighbours. idx = np.arange(len(result)) result[nans] = np.interp(idx[nans], idx[~nans], result[~nans]) return result