Source code for dispel.signal.sensor
"""Sensor functionality for signal processing tasks."""
import pandas as pd
from scipy import stats
#: A dictionary for sensor units.
SENSOR_UNIT = {"acc": "G", "gyr": "rad/s", "diss": "pixel"}
[docs]
def detrend_signal(signal: pd.Series) -> pd.Series:
"""Detrend signal and remove offset component.
The final signal will end up centered on zero and stationary. This function is based
on :func:`scipy.stats.linregress`.
Parameters
----------
signal: pandas.Series
The raw signal.
Returns
-------
pandas.Series
The detrended signal.
"""
original_x = signal.index.to_numpy(float)
signal_without_na = signal.dropna()
y = signal_without_na.to_numpy(float)
x = signal_without_na.index.to_numpy(float)
(
slope,
intercept,
*_,
) = stats.linregress(x, y)
y_estimate = slope * original_x + intercept
return signal - y_estimate
[docs]
def check_amplitude(
data: pd.DataFrame, min_amplitude: float, max_amplitude: float
) -> bool:
"""Check if the signal amplitudes belong to a reasonable range.
The function will return true only if all the values of each column are between the
min and max amplitude bounds.
Parameters
----------
data
A data frame containing one column or more. The data contains in columns must
all have the same nature as the bounds are applied on the entire data frame.
min_amplitude
The expected min amplitude.
max_amplitude
The expected max amplitude.
Returns
-------
bool
``True`` if all the values are in the range. ``False`` otherwise.
"""
amplitude = data.max() - data.min()
return amplitude.between(left=min_amplitude, right=max_amplitude).all()
[docs]
def find_zero_crossings(data: pd.DataFrame, col: str) -> pd.DataFrame:
"""Find zero crossing in the signal."""
zero_crossings = data.index[(data[col] > 0).diff().fillna(False)]
return data.loc[zero_crossings, col]