Forked from
toolbox / WindEnergyToolbox
805 commits behind the upstream repository.
-
Mads M. Pedersen authoredMads M. Pedersen authored
rainflowcount.py 4.35 KiB
from __future__ import division
from __future__ import unicode_literals
from __future__ import print_function
from __future__ import absolute_import
from builtins import str
from future import standard_library
standard_library.install_aliases()
import numpy as np
from wetb.fatigue_tools.rainflowcounting import peak_trough
from wetb.fatigue_tools.rainflowcounting import pair_range
def check_signal(signal):
# check input data validity
if not type(signal).__name__ == 'ndarray':
raise TypeError('signal must be ndarray, not: ' + type(signal).__name__)
elif len(signal.shape) not in (1, 2):
raise TypeError('signal must be 1D or 2D, not: ' + str(len(signal.shape)))
if len(signal.shape) == 2:
if signal.shape[1] > 1:
raise TypeError('signal must have one column only, not: ' + str(signal.shape[1]))
if np.min(signal) == np.max(signal):
raise TypeError("Signal contains no variation")
def rainflow_windap(signal, levels=255., thresshold=(255 / 50)):
"""Windap equivalent rainflow counting
Calculate the amplitude and mean values of half cycles in signal
This algorithms used by this routine is implemented directly as described in
"Recommended Practices for Wind Turbine Testing - 3. Fatigue Loads", 2. edition 1990, Appendix A
Parameters
----------
Signal : array-like
The raw signal
levels : int, optional
The signal is discretize into this number of levels.
255 is equivalent to the implementation in Windap
thresshold : int, optional
Cycles smaller than this thresshold are ignored
255/50 is equivalent to the implementation in Windap
Returns
-------
ampl : array-like
Peak to peak amplitudes of the half cycles
mean : array-like
Mean values of the half cycles
Examples
--------
>>> signal = np.array([-2.0, 0.0, 1.0, 0.0, -3.0, 0.0, 5.0, 0.0, -1.0, 0.0, 3.0, 0.0, -4.0, 0.0, 4.0, 0.0, -2.0])
>>> ampl, mean = rainflow_windap(signal)
"""
check_signal(signal)
#type <double> is required by <find_extreme> and <rainflow>
signal = signal.astype(np.double)
offset = np.nanmin(signal)
signal -= offset
if np.nanmax(signal) > 0:
gain = np.nanmax(signal) / levels
signal = signal / gain
signal = np.round(signal).astype(np.int)
# If possible the module is compiled using cython otherwise the python implementation is used
#Convert to list of local minima/maxima where difference > thresshold
sig_ext = peak_trough.peak_trough(signal, thresshold)
#rainflow count
ampl_mean = pair_range.pair_range_amplitude_mean(sig_ext)
ampl_mean = np.array(ampl_mean)
ampl_mean = np.round(ampl_mean / thresshold) * gain * thresshold
ampl_mean[:, 1] += offset
return ampl_mean.T
def rainflow_astm(signal):
"""Matlab equivalent rainflow counting
Calculate the amplitude and mean values of half cycles in signal
This implemementation is based on the c-implementation by Adam Nieslony found at
the MATLAB Central File Exchange http://www.mathworks.com/matlabcentral/fileexchange/3026
Parameters
----------
Signal : array-like
The raw signal
Returns
-------
ampl : array-like
peak to peak amplitudes of the half cycles (note that the matlab implementation
uses peak amplitude instead of peak to peak)
mean : array-like
Mean values of the half cycles
Examples
--------
>>> signal = np.array([-2.0, 0.0, 1.0, 0.0, -3.0, 0.0, 5.0, 0.0, -1.0, 0.0, 3.0, 0.0, -4.0, 0.0, 4.0, 0.0, -2.0])
>>> ampl, mean = rainflow_astm(signal)
"""
check_signal(signal)
# type <double> is reuqired by <find_extreme> and <rainflow>
signal = signal.astype(np.double)
# Import find extremes and rainflow.
# If possible the module is compiled using cython otherwise the python implementation is used
from wetb.fatigue_tools.rainflowcounting.rainflowcount_astm import find_extremes, rainflowcount
# Remove points which is not local minimum/maximum
sig_ext = find_extremes(signal)
# rainflow count
ampl_mean = np.array(rainflowcount(sig_ext))
return np.array(ampl_mean).T