The FourPointDetector class

class pylife.stress.rainflow.FourPointDetector(recorder)[source]

Implements four point rainflow counting algorithm.

from pylife.stress.timesignal import TimeSignalGenerator
import pylife.stress.rainflow as RF

ts = TimeSignalGenerator(10, {
    'number': 50,
    'amplitude_median': 1.0, 'amplitude_std_dev': 0.5,
    'frequency_median': 4, 'frequency_std_dev': 3,
    'offset_median': 0, 'offset_std_dev': 0.4}, None, None).query(10000)

rfc = RF.FourPointDetector(recorder=RF.LoopValueRecorder())
rfc.process(ts)

rfc.recorder.collective
from to
0 2.220151 2.420256
1 1.117788 0.091969
2 -3.033760 1.126358
3 -7.161082 2.568089
4 -9.636807 -9.738175
... ... ...
1262 -7.324690 8.685267
1263 -9.834257 10.311611
1264 5.326117 2.667811
1265 10.919571 -12.857578
1266 5.997012 0.797330

1267 rows × 2 columns

Alternatively you can ask the recorder for a histogram matrix:

rfc.recorder.histogram(bins=16)
from                                        to                                        
(-19.306479614234092, -17.017811906236947]  (-18.336203955069866, -16.10029158092544]     0.0
                                            (-16.10029158092544, -13.864379206781013]     0.0
                                            (-13.864379206781013, -11.628466832636585]    0.0
                                            (-11.628466832636585, -9.392554458492159]     0.0
                                            (-9.392554458492159, -7.156642084347732]      0.0
                                                                                         ... 
(15.023536005723088, 17.31220371372024]     (6.258832160518828, 8.494744534663258]        0.0
                                            (8.494744534663258, 10.730656908807685]       0.0
                                            (10.730656908807685, 12.966569282952111]      0.0
                                            (12.966569282952111, 15.202481657096538]      0.0
                                            (15.202481657096538, 17.438394031240964]      0.0
Length: 256, dtype: float64

We take four turning points into account to detect closed hysteresis loops.

Consider four consecutive peak/valley points say, A, B, C, and D If B and C are contained within A and B, then a cycle is counted from B to C; otherwise no cycle is counted.

i.e, If X Y AND Z Y then a cycle exist FROM = B and TO = C where, ranges X = |D–C|, Y = |C–B|, and Z = |B–A|

Load -----------------------------
|        x B               F x
--------/-\-----------------/-----
|      /   \   x D         /
------/-----\-/-\---------/-------
|    /     C x   \       /
--\-/-------------\-----/---------
|  x A             \   /
--------------------\-/-----------
|                    x E
----------------------------------
|              Time

So, if a cycle exsist from B to C then delete these peaks from the turns array and perform next iteration by joining A&D else if no cylce exsists, then B would be the next strarting point.

__init__(recorder)[source]

Instantiate a FourPointDetector.

Parameters:

recorder (subclass of AbstractRecorder) – The recorder that the detector will report to.

process(samples, flush=False)[source]

Process a sample chunk.

Parameters:
  • samples (array_like, shape (N, )) – The samples to be processed

  • flush (bool) –

    Whether to flush the cached values at the end.

    If flush=False, the last value of a load sequence is cached for a subsequent call to process, because it may or may not be a turning point of the sequence, which is only decided when the next data point arrives.

    Setting flush=True forces processing of the last value. When process is called again afterwards with new data, two increasing or decreasing values in a row might have been processed, as opposed to only turning points of the sequence.

    Example: a)

    process([1, 2], flush=False) # processes 1 process([3, 1], flush=True) # processes 3, 1 -> processed sequence is [1,3,1], only turning points

    1. process([1, 2], flush=True) # processes 1, 2 process([3, 1], flush=True) # processes 3, 1 -> processed sequence is [1,2,3,1], “,” is not a turning point

    2. process([1, 2]) # processes 1 process([3, 1]) # processes 3 -> processed sequence is [1,3], end (“1”) is missing

    3. process([1, 2]) # processes 1 process([3, 1]) # processes 3 flush() # process 1 -> processed sequence is [1,3,1]

Returns:

self – The self object so that processing can be chained

Return type:

FourPointDetector