Source code for nnsa.feature_extraction.time_domain

"""
Functions for time-domain feature computation.
"""
import warnings

import numpy as np
import scipy.integrate

__all__ = [
    'auc',
    'compute_flatness',
]


[docs]def auc(y, x=None, dx=1.0, zero_level=0, normalize=False, axis=-1, method='trapz', **kwargs): """ Compute the area under the curve (AUC). Excludes nans. Args: y (np.ndarray): input array to integrate. x (np.ndarray, optional): the sample points corresponding to the `y` values. If `x` is None, the sample points are assumed to be evenly spaced `dx` apart. The default is None. dx (float, optional): the spacing between sample points when `x` is None. The default is 1. zero_level (float, optional): y translation. `y` will be translated by y = y-zero_level before AUC computation. Defaults to 0. normalize (bool, optional): if True, normalizes the auc by the number of points. axis (int, optional): the axis along which to integrate. Defaults to -1. method (str, optional): the method to use for integration. Choose from 'trapz', 'simps' to use the trapezoidal or Simpson's rule, respectively. **kwargs (optional): optional keyword arguments for the function that is called, depedning on `method`. Returns: auc (float): area between `y` and `zero_level`. y values above `zero_level` have a positive contribution, while values below `zero_level` have a negative contribution. """ # Translate to the requested zero-level. y = y - zero_level # Set nans to zero. nanmask = np.isnan(y) y[nanmask] = 0 # Evoke the requested method. method = method.lower() if method == 'trapz': auc = np.trapz(y, x=x, dx=dx, axis=axis, **kwargs) elif method == 'simps': auc = scipy.integrate.simps(y, x=x, dx=dx, axis=axis, **kwargs) else: raise ValueError(f'Invalid choice method="{method}". Choose "trapz" or "simps".') if normalize: auc /= np.sum(~nanmask) return auc
[docs]def compute_flatness(x, q=95): """ Compute the flatness of x, which is defined as the minimal range in which q% of the values in x lie. Args: x (np.ndarray): 1D array. q (float, optional): percentage of data that must lie in the flatness range. Defaults to 95. Returns: flatness (float): minimal range in which q% of the values in x lie. """ x = np.asarray(x).squeeze() if x.ndim != 1: raise ValueError('Expected input to be 1-dimensional. Got shape = {}.' .format(x.shape)) # Remove nans. x = x[~np.isnan(x)] if len(x) < 20: msg = 'Signal too short (len(x) = {}).'.format(x) warnings.warn(msg) return np.nan # Number of samples to discard. num_discard = int((1 - q/100)*len(x)) # Sort the values. x_sort = np.sort(x) # Height of all possible partitions. possibilities = x_sort[-(num_discard+1):] - x_sort[:num_discard+1] # Flatness is the partition with the lowest height. flatness = np.min(possibilities) return flatness