The timesignal module#

Handle sampled time signals for pyLife stress workflows.

Provide helpers for generating, resampling, filtering, spectral analysis, and cleaning load-time histories before rainflow counting or other fatigue post-processing.

Warning

This module is not considered finalized even though it is part of pylife-2.0. Breaking changes might occur in upcoming minor releases.

class pylife.stress.timesignal.TimeSignalGenerator(sample_rate, sine_set, gauss_set=None, log_gauss_set=None)[source]#

Generate mixed sinusoidal load-time signals.

Create synthetic load signals, e.g. stress in MPa, for examples and tests in the time series handling workflow. The generated signal is a sum of sinusoidal components with normally distributed amplitudes, frequencies, offsets, and uniformly distributed phases.

Parameters:
  • sample_rate (float) – Sampling rate in Hz used when query advances the generated signal.

  • sine_set (dict) – Definition of the sinusoidal components. Mandatory keys are "number", "amplitude_median", "amplitude_std_dev", "frequency_median", "frequency_std_dev", "offset_median", and "offset_std_dev".

  • gauss_set (dict) – Reserved for Gaussian random components. The current implementation accepts the argument for compatibility but does not use it.

  • log_gauss_set (dict) – Reserved for lognormal random components. The current implementation accepts the argument for compatibility but does not use it.

Notes

Each component is evaluated as

\[s_i(t) = A_i \sin(\omega_i t + \phi_i) + c_i,\]

where \(A_i\), \(\omega_i\), and \(c_i\) are drawn from the normal distributions described by sine_set and \(\phi_i\) is drawn uniformly from [0, 2\pi). The returned signal is

\[S(t) = \sum_i s_i(t).\]
query(sample_num)[source]#

Return the next contiguous chunk of the generated time signal.

Use repeated calls to build a longer synthetic load-time history. The first returned sample follows the internal time cursor, and subsequent calls continue without a time gap.

Parameters:

sample_num (int) – Number of samples requested.

Returns:

Requested samples of the generated load signal.

Return type:

numpy.ndarray

reset()[source]#

Reset the generator to the start of the time signal.

After resetting, the next query call returns the same time positions as a newly created generator with the same random component parameters.

pylife.stress.timesignal.butter_bandpass(df, lowcut, highcut, order=5)[source]#

Apply a zero-phase Butterworth band-pass filter to a time signal.

Filter each column of a load-time history before fatigue evaluation. This is a thin wrapper around scipy.signal.butter() and scipy.signal.filtfilt().

Parameters:
  • df (pandas.DataFrame) – Time series with a numeric time index in s and load columns, e.g. stress in MPa.

  • lowcut (float) – Lower cut-off frequency in Hz.

  • highcut (float) – Upper cut-off frequency in Hz.

  • order (int, optional) – Butterworth filter order. Default is 5.

Returns:

Filtered time series with the same time index and columns as df.

Return type:

pandas.DataFrame

Notes

The filter is an order-th order digital Butterworth band-pass filter applied forward and backward with scipy.signal.filtfilt(), resulting in zero phase shift.

pylife.stress.timesignal.clean_timeseries(df, comparison_column, window_size=1000, overlap=800, feature='abs_energy', method='keep', n_gridpoints=3, percentage_max=0.05, order=3)[source]#

Clean a time series by removing low-feature windows.

Use this helper to reduce a load-time history before rainflow counting. The function rolls the signal into windows, extracts one tsfresh feature, removes or keeps windows based on a threshold, and fills short gaps by polynomial interpolation.

Parameters:
  • df (pandas.DataFrame) – Input time series with a numeric time index in s and load columns, e.g. stress in MPa.

  • comparison_column (str) – Column used for feature comparison with percentage_max.

  • window_size (int, optional) – Window size of the rolled segments in samples. Default is 1000.

  • overlap (int, optional) – Overlap between adjacent windows in samples. Default is 800.

  • feature (str, optional) – Feature calculator name from tsfresh. Only calculators without extra parameters are supported. Default is "abs_energy".

  • method ({'keep', 'remove'}, optional) – Return convention. "keep" keeps windows above the feature threshold, while "remove" keeps windows at or below it. Default is "keep".

  • n_gridpoints (int, optional) – Number of grid points used to bridge removed windows. Default is 3.

  • percentage_max (float, optional) – Minimum fraction of the maximum feature value for a window to remain in "keep" mode. Default is 0.05.

  • order (int, optional) – Polynomial interpolation order. Default is 3.

Returns:

Cleaned time series with the helper id column removed.

Return type:

pandas.DataFrame

Raises:

ImportError – Raised if tsfresh is not installed.

Notes

A window is classified as low-feature if

\[x_i \leq p \max_j x_j,\]

where \(x_i\) is the selected feature value and \(p\) is percentage_max.

pylife.stress.timesignal.fs_calc(df)[source]#

Calculate the sampling rate of a time-indexed signal.

Use this helper before filtering or spectral estimation when the sampling rate is encoded by an equidistant numeric time index.

Parameters:

df (pandas.DataFrame) – Time series with a numeric time index in s.

Returns:

Sampling rate in Hz, rounded to the nearest integer value.

Return type:

float

Examples

>>> from pylife.stress.timesignal import fs_calc
>>> df = pd.DataFrame({"stress": [0.0, 1.0, 0.0]},
...                   index=[0.0, 0.5, 1.0])
>>> float(fs_calc(df))
2.0
pylife.stress.timesignal.psd_df(df_ts, nfft=512, nperseg=256)[source]#

Estimate power spectral density columns with Welch’s method.

Convert a time-domain load signal into a frequency-indexed PSD for spectral comparison or frequency-domain fatigue workflows. This is a thin wrapper around scipy.signal.welch().

Parameters:
  • df_ts (pandas.DataFrame) – Time series with a numeric time index in s and load columns, e.g. stress in MPa.

  • nfft (int, optional) – Length of the FFT used by Welch’s method. Default is 512.

  • nperseg (int, optional) – Segment length used by Welch’s method. Values larger than nfft are clipped to nfft. Default is 256.

Returns:

Power spectral density with frequency index in Hz and one PSD column per input column.

Return type:

pandas.DataFrame

Notes

The PSD scaling is the scipy.signal.welch() default scaling="density". For a load signal in MPa, the resulting PSD has units MPa²/Hz and integrates to the mean square value of the signal.

pylife.stress.timesignal.resample_acc(df, fs=1)[source]#

Resample a pandas time series to an equidistant time index.

Interpolate each column of a load-time history onto a new time index. This prepares measured signals for filters, PSD estimation, or rainflow counting algorithms that expect a constant sampling rate.

Parameters:
  • df (pandas.DataFrame) – Time series with a numeric time index in s and load columns, e.g. stress in MPa.

  • fs (float, optional) – Sampling rate in Hz of the resampled time series. Default is 1.

Returns:

Resampled time series with an equidistant time index in s.

Return type:

pandas.DataFrame