Source code for suboptimumg.log_analysis.utils

import numpy as np
from numpy.typing import NDArray


[docs] def estimate_fs(t_s: NDArray[np.float64]) -> float: """Median-step sample-rate estimate (Hz) from a seconds time vector.""" if len(t_s) < 2: return 0.0 dt = float(np.median(np.diff(t_s))) return 1.0 / dt if dt > 0 else 0.0
[docs] def safe_gradient(signal: NDArray[np.float64], dt: NDArray[np.float64]) -> 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 : NDArray[np.float64] The signal to differentiate. dt : NDArray[np.float64] Time step array. Must be the same length as ``signal``. Returns ------- 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