diff --git a/setup.py b/setup.py
index 2e93d5cd0b98371b39c8a2c6bd2aa9b0d77fce2b..aa0164766b663db36684ff90b86d6b1849d823d1 100644
--- a/setup.py
+++ b/setup.py
@@ -8,14 +8,27 @@
     http://pyscaffold.readthedocs.org/
 """
 
+import os
 import sys
 from setuptools import setup
 
+from distutils.extension import Extension
+from Cython.Distutils import build_ext
+
 
 def setup_package():
+
+    path = 'wetb/fatigue_tools/rainflowcounting/'
+    module = 'wetb.fatigue_tools.rainflowcounting'
+    names = ['pair_range', 'peak_trough', 'rainflowcount_astm']
+    extlist = [Extension('%s.%s' % (module, n),
+                         [os.path.join(path, n)+'.pyx']) for n in names]
+
     needs_sphinx = {'build_sphinx', 'upload_docs'}.intersection(sys.argv)
     sphinx = ['sphinx'] if needs_sphinx else []
     setup(setup_requires=['six', 'pyscaffold>=2.5a0,<2.6a0'] + sphinx,
+          cmdclass = {'build_ext': build_ext},
+          ext_modules = extlist,
           use_pyscaffold=True)
 
 
diff --git a/wetb/fatigue_tools/rainflowcounting/pair_range.pyx b/wetb/fatigue_tools/rainflowcounting/pair_range.pyx
new file mode 100755
index 0000000000000000000000000000000000000000..5ed95be5b1501d2d938fa3a3e33781d5f5f2969d
--- /dev/null
+++ b/wetb/fatigue_tools/rainflowcounting/pair_range.pyx
@@ -0,0 +1,201 @@
+import cython
+import numpy as np
+cimport numpy as np
+
+import cython
+import numpy as np
+# cimport numpy as np
+
+
+@cython.locals(p=cython.int, q=cython.int, f=cython.int, flow=list, k=cython.int, n=cython.int, ptr=cython.int)
+def pair_range_amplitude(x):  # cpdef pair_range(np.ndarray[long,ndim=1]  x):
+    """
+    Returns a list of half-cycle-amplitudes
+    x: Peak-Trough sequence (integer list of local minima and maxima)
+
+    This routine is implemented according to
+    "Recommended Practices for Wind Turbine Testing - 3. Fatigue Loads", 2. edition 1990, Appendix A
+    except that a list of half-cycle-amplitudes are returned instead of a from_level-to_level-matrix
+    """
+
+    x = x - np.min(x)
+    k = np.max(x)
+    n = x.shape[0]
+    S = np.zeros(n + 1)
+
+    #A = np.zeros(k+1)
+    flow = []
+    S[1] = x[0]
+    ptr = 1
+    p = 1
+    q = 1
+    f = 0
+    # phase 1
+    while True:
+        p += 1
+        q += 1
+
+        # read
+        S[p] = x[ptr]
+        ptr += 1
+
+        if q == n:
+            f = 1
+        while p >= 4:
+            if (S[p - 2] > S[p - 3] and S[p - 1] >= S[p - 3] and S[p] >= S[p - 2]) \
+                or\
+                    (S[p - 2] < S[p - 3] and S[p - 1] <= S[p - 3] and S[p] <= S[p - 2]):
+                ampl = abs(S[p - 2] - S[p - 1])
+                # A[ampl]+=2 #Two half cycles
+                flow.append(ampl)
+                flow.append(ampl)
+                S[p - 2] = S[p]
+
+                p -= 2
+            else:
+                break
+
+        if f == 0:
+            pass
+        else:
+            break
+    # phase 2
+    q = 0
+    while True:
+        q += 1
+        if p == q:
+            break
+        else:
+            ampl = abs(S[q + 1] - S[q])
+            # A[ampl]+=1
+            flow.append(ampl)
+    return flow
+
+
+
+
+
+@cython.locals(p=cython.int, q=cython.int, f=cython.int, flow=list, k=cython.int, n=cython.int, ptr=cython.int)
+def pair_range_from_to(x):  # cpdef pair_range(np.ndarray[long,ndim=1]  x):
+    """
+    Returns a list of half-cycle-amplitudes
+    x: Peak-Trough sequence (integer list of local minima and maxima)
+
+    This routine is implemented according to
+    "Recommended Practices for Wind Turbine Testing - 3. Fatigue Loads", 2. edition 1990, Appendix A
+    except that a list of half-cycle-amplitudes are returned instead of a from_level-to_level-matrix
+    """
+
+    x = x - np.min(x)
+    k = np.max(x)
+    n = x.shape[0]
+    S = np.zeros(n + 1)
+
+    A = np.zeros((k + 1, k + 1))
+    S[1] = x[0]
+    ptr = 1
+    p = 1
+    q = 1
+    f = 0
+    # phase 1
+    while True:
+        p += 1
+        q += 1
+
+        # read
+        S[p] = x[ptr]
+        ptr += 1
+
+        if q == n:
+            f = 1
+        while p >= 4:
+            #print S[p - 3:p + 1]
+            #print S[p - 2], ">", S[p - 3], ", ", S[p - 1], ">=", S[p - 3], ", ", S[p], ">=", S[p - 2], (S[p - 2] > S[p - 3] and S[p - 1] >= S[p - 3] and S[p] >= S[p - 2])
+            #print S[p - 2], "<", S[p - 3], ", ", S[p - 1], "<=", S[p - 3], ", ", S[p], "<=", S[p - 2], (S[p - 2] < S[p - 3] and S[p - 1] <= S[p - 3] and S[p] <= S[p - 2])
+            #print (S[p - 2] > S[p - 3] and S[p - 1] >= S[p - 3] and S[p] >= S[p - 2]) or (S[p - 2] < S[p - 3] and S[p - 1] <= S[p - 3] and S[p] <= S[p - 2])
+            if (S[p - 2] > S[p - 3] and S[p - 1] >= S[p - 3] and S[p] >= S[p - 2]) or \
+               (S[p - 2] < S[p - 3] and S[p - 1] <= S[p - 3] and S[p] <= S[p - 2]):
+                A[S[p - 2], S[p - 1]] += 1
+                A[S[p - 1], S[p - 2]] += 1
+                S[p - 2] = S[p]
+                p -= 2
+            else:
+                break
+
+        if f == 1:
+            break  # q==n
+    # phase 2
+    q = 0
+    while True:
+        q += 1
+        if p == q:
+            break
+        else:
+            #print S[q], "to", S[q + 1]
+            A[S[q], S[q + 1]] += 1
+    return A
+
+@cython.locals(p=cython.int, q=cython.int, f=cython.int, flow=list, k=cython.int, n=cython.int, ptr=cython.int)
+def pair_range_amplitude_mean(x):  # cpdef pair_range(np.ndarray[long,ndim=1]  x):
+    """
+    Returns a list of half-cycle-amplitudes
+    x: Peak-Trough sequence (integer list of local minima and maxima)
+
+    This routine is implemented according to
+    "Recommended Practices for Wind Turbine Testing - 3. Fatigue Loads", 2. edition 1990, Appendix A
+    except that a list of half-cycle-amplitudes are returned instead of a from_level-to_level-matrix
+    """
+
+    x = x - np.min(x)
+    k = np.max(x)
+    n = x.shape[0]
+    S = np.zeros(n + 1)
+    ampl_mean = []
+    A = np.zeros((k + 1, k + 1))
+    S[1] = x[0]
+    ptr = 1
+    p = 1
+    q = 1
+    f = 0
+    # phase 1
+    while True:
+        p += 1
+        q += 1
+
+                # read
+        S[p] = x[ptr]
+        ptr += 1
+
+        if q == n:
+            f = 1
+        while p >= 4:
+            if (S[p - 2] > S[p - 3] and S[p - 1] >= S[p - 3] and S[p] >= S[p - 2]) \
+                or\
+                    (S[p - 2] < S[p - 3] and S[p - 1] <= S[p - 3] and S[p] <= S[p - 2]):
+                # Extract two intermediate half cycles
+                ampl = abs(S[p - 2] - S[p - 1])
+                mean = (S[p - 2] + S[p - 1]) / 2
+                ampl_mean.append((ampl, mean))
+                ampl_mean.append((ampl, mean))
+
+                S[p - 2] = S[p]
+
+                p -= 2
+            else:
+                break
+
+        if f == 0:
+            pass
+        else:
+            break
+    # phase 2
+    q = 0
+    while True:
+        q += 1
+        if p == q:
+            break
+        else:
+            ampl = abs(S[q + 1] - S[q])
+            mean = (S[q + 1] + S[q]) / 2
+            ampl_mean.append((ampl, mean))
+    return ampl_mean
diff --git a/wetb/fatigue_tools/rainflowcounting/peak_trough.pyx b/wetb/fatigue_tools/rainflowcounting/peak_trough.pyx
new file mode 100755
index 0000000000000000000000000000000000000000..f65a24388482a0ca92aa1b94b6957ad17e2af6d4
--- /dev/null
+++ b/wetb/fatigue_tools/rainflowcounting/peak_trough.pyx
@@ -0,0 +1,103 @@
+import cython
+import numpy as np
+cimport numpy as np
+import cython
+import numpy as np
+cimport numpy as np
+
+@cython.locals(BEGIN=cython.int, MINZO=cython.int, MAXZO=cython.int, ENDZO=cython.int, \
+               R=cython.int, L=cython.int, i=cython.int, p=cython.int, f=cython.int)
+cpdef np.ndarray[long,ndim=1] peak_trough(np.ndarray[long,ndim=1] x, int R):
+    """
+    Returns list of local maxima/minima.
+
+    x: 1-dimensional numpy array containing signal
+    R: Thresshold (minimum difference between succeeding min and max
+
+    This routine is implemented directly as described in
+    "Recommended Practices for Wind Turbine Testing - 3. Fatigue Loads", 2. edition 1990, Appendix A
+    """
+
+    BEGIN = 0
+    MINZO = 1
+    MAXZO = 2
+    ENDZO = 3
+    S = np.zeros(x.shape[0] + 1, dtype=np.int)
+
+    L = x.shape[0]
+    goto = BEGIN
+
+    while 1:
+        if goto == BEGIN:
+            trough = x[0]
+            peak = x[0]
+
+            i = 0
+            p = 1
+            f = 0
+            while goto == BEGIN:
+                i += 1
+                if i == L:
+                    goto = ENDZO
+                    continue
+                else:
+                    if x[i] > peak:
+                        peak = x[i]
+                        if peak - trough >= R:
+                            S[p] = trough
+                            goto = MAXZO
+                            continue
+                    elif x[i] < trough:
+                        trough = x[i]
+                        if peak - trough >= R:
+                            S[p] = peak
+                            goto = MINZO
+                            continue
+
+        elif goto == MINZO:
+            f = -1
+
+            while goto == MINZO:
+                i += 1
+                if i == L:
+                    goto = ENDZO
+                    continue
+                else:
+                    if x[i] < trough:
+                        trough = x[i]
+                    else:
+                        if x[i] - trough >= R:
+                            p += 1
+                            S[p] = trough
+                            peak = x[i]
+                            goto = MAXZO
+                            continue
+        elif goto == MAXZO:
+            f = 1
+            while goto == MAXZO:
+                i += 1
+                if i == L:
+                    goto = ENDZO
+                    continue
+                else:
+                    if x[i] > peak:
+                        peak = x[i]
+                    else:
+                        if peak - x[i] >= R:
+                            p += 1
+                            S[p] = peak
+                            trough = x[i]
+                            goto = MINZO
+                            continue
+        elif goto == ENDZO:
+
+            n = p + 1
+            if abs(f) == 1:
+                if f == 1:
+                    S[n] = peak
+                else:
+                    S[n] = trough
+            else:
+                S[n] = (trough + peak) / 2
+            S = S[1:n + 1]
+            return S
diff --git a/wetb/fatigue_tools/rainflowcounting/rainflowcount_astm.pyx b/wetb/fatigue_tools/rainflowcounting/rainflowcount_astm.pyx
new file mode 100755
index 0000000000000000000000000000000000000000..a06f514a61ee13fcbc874b058570cff60b8938e4
--- /dev/null
+++ b/wetb/fatigue_tools/rainflowcounting/rainflowcount_astm.pyx
@@ -0,0 +1,105 @@
+import cython
+import numpy as np
+cimport numpy as np
+'''
+Created on 27/02/2013
+
+@author: mmpe
+
+
+
+How to use:
+
+import_cython("cy_rainflowcount",'cy_rainflowcount.py','')
+from cy_rainflowcount import find_extremes,rainflow
+
+ext = find_extremes(np.array([-2,0,1,0,-3,0,5,0,-1,0,3,0,-4,0,4,0,-2]).astype(np.double))
+print rainflow(ext)
+'''
+
+import numpy as np
+
+
+cpdef find_extremes(np.ndarray[double,ndim=1] signal):
+    """return indexes of local minima and maxima plus first and last element of signal"""
+
+    cdef int pi, i
+    # sign of gradient
+    sign_grad = np.int8(np.sign(np.diff(signal)))
+
+    # remove plateaus(sign_grad==0) by sign_grad[plateau_index]=sign_grad[plateau_index-1]
+    plateau_indexes, = np.where(sign_grad == 0)
+    if len(plateau_indexes) > 0 and plateau_indexes[0] == 0:
+        # first element is a plateau
+        if len(plateau_indexes) == len(sign_grad):
+                # All values are equal to crossing level!
+                return np.array([0])
+
+        # set first element = first element which is not a plateau and delete plateau index
+        i = 0
+        while sign_grad[i] == 0:
+            i += 1
+        sign_grad[0] = sign_grad[i]
+
+        plateau_indexes = np.delete(plateau_indexes, 0)
+
+    for pi in plateau_indexes.tolist():
+        sign_grad[pi] = sign_grad[pi - 1]
+
+    extremes, = np.where(np.r_[1, (sign_grad[1:] * sign_grad[:-1] < 0), 1])
+
+    return signal[extremes]
+
+
+cpdef rainflowcount(np.ndarray[double,ndim=1] sig):
+    """Cython compilable rain ampl_mean count without time analysis
+
+
+    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
+
+    References
+    ----------
+    Adam Nieslony, "Determination of fragments of multiaxial service loading
+    strongly influencing the fatigue of machine components,"
+    Mechanical Systems and Signal Processing 23, no. 8 (2009): 2712-2721.
+
+    and is based on the following standard:
+    ASTM E 1049-85 (Reapproved 1997), Standard practices for cycle counting in
+    fatigue analysis, in: Annual Book of ASTM Standards, vol. 03.01, ASTM,
+    Philadelphia, 1999, pp. 710-718.
+
+    Copyright (c) 1999-2002 by Adam Nieslony
+
+    Ported to Cython compilable Python by Mads M Pedersen
+    In addition peak amplitude is changed to peak to peak amplitude
+
+
+    """
+
+    cdef int sig_ptr, index
+    cdef double ampl
+    a = []
+    sig_ptr = 0
+    ampl_mean = []
+    for _ in range(len(sig)):
+        a.append(sig[sig_ptr])
+        sig_ptr += 1
+        while len(a) > 2 and abs(a[-3] - a[-2]) <= abs(a[-2] - a[-1]):
+            ampl = abs(a[-3] - a[-2])
+            mean = (a[-3] + a[-2]) / 2;
+            if len(a) == 3:
+                del a[0]
+                if ampl > 0:
+                    ampl_mean.append((ampl, mean))
+            elif len(a) > 3:
+                del a[-3:-1]
+                if ampl > 0:
+                    ampl_mean.append((ampl, mean))
+                    ampl_mean.append((ampl, mean))
+    for index in range(len(a) - 1):
+        ampl = abs(a[index] - a[index + 1])
+        mean = (a[index] + a[index + 1]) / 2;
+        if ampl > 0:
+            ampl_mean.append((ampl, mean))
+    return ampl_mean