Diff of /ppfunctions_1.py [000000] .. [a007e7]

Switch to side-by-side view

--- a
+++ b/ppfunctions_1.py
@@ -0,0 +1,339 @@
+# -*- coding: utf-8 -*-
+"""
+Personal Processing Functions 1 (ppfunctions_1)
+Created on Mon Apr  9 11:48:37 2018
+@author: Kevin MAchado
+
+Module file containing Python definitions and statements
+"""
+
+# Libraries
+import numpy as np
+from scipy.signal import kaiserord, lfilter, firwin
+from scipy.fftpack import fft
+#import peakutils                                # Librery to help in peak detection
+
+# Functions 
+# Normal energy = np.sum(pcgFFT1**2)
+# Normalized average Shannon Energy = sum((l**2)*np.log(l**2))/l.shape[0]
+# Third Order Shannon Energy = sum((l**3)*np.log(l**3))/l.shape[0]
+
+def vec_nor(x):
+    """
+    Normalize the amplitude of a vector from -1 to 1
+    """
+    lenght=np.size(x)				# Get the length of the vector	
+    xMax=max(x);					   # Get the maximun value of the vector
+    nVec=np.zeros(lenght);		   # Initializate derivate vector
+    nVec = np.divide(x, xMax)
+    nVec=nVec-np.mean(nVec);
+    nVec=np.divide(nVec,np.max(nVec));
+        
+    return nVec
+
+def derivate (x):
+    """
+    Derivate of an input signal as y[n]= x[n+1]- x[n-1] 
+    """
+    lenght=x.shape[0]				# Get the length of the vector
+    y=np.zeros(lenght);				# Initializate derivate vector
+    for i in range(lenght-1):
+        y[i]=x[i-1]-x[i];		
+    return y
+# -----------------------------------------------------------------------------
+# Energy
+# -----------------------------------------------------------------------------
+def Energy_value (x):
+    """
+    Energy of an input signal  
+    """
+    y = np.sum(x**2)
+    return y
+
+def E_VS (pcgFFT1, vTfft1, on):
+    """
+    Energy of PCG Vibratory Spectrum
+    (frequency components, frequency value vector, on = on percentage or not)
+    According with [1] The total vibratory spectrum can be divided into 7 bands:
+    1. 0-5Hz, 2. 5-25Hz; 3. 25-120Hz; 4. 120-240Hz; 5. 240-500Hz; 6. 500-1000Hz; 7. 1000-2000Hz
+
+The PCG signal producess vibrations in the spectrum between 0-2k Hz. 
+[1] Abbas, Abbas K. (Abbas Khudair), Bassam, Rasha and Morgan & Claypool Publishers Phonocardiography signal processing. Morgan & Claypool Publishers, San Rafael, Calif, 2009.
+    """
+    c1 = (np.abs(vTfft1-5)).argmin()
+    c2 = (np.abs(vTfft1-25)).argmin()
+    c3 = (np.abs(vTfft1-120)).argmin()
+    c4 = (np.abs(vTfft1-240)).argmin()
+    c5 = (np.abs(vTfft1-500)).argmin()
+    c6 = (np.abs(vTfft1-1000)).argmin()
+    c7 = (np.abs(vTfft1-2000)).argmin()
+    
+    # All vector energy
+    xAll = Energy_value(pcgFFT1)
+
+    # Procesando de 0.01-5 Hz
+    pcgFFT_F1 = pcgFFT1[0:c1]
+    x1 = Energy_value(pcgFFT_F1)
+    
+    # Procesando de 5-25 Hz
+    pcgFFT_F2 = pcgFFT1[c1:c2]
+    x2 = Energy_value(pcgFFT_F2)
+    
+    # Procesando de 25-120 Hz
+    pcgFFT_F3 = pcgFFT1[c2:c3]
+    x3 = Energy_value(pcgFFT_F3)
+    
+    # Procesando de 120-240 Hz
+    pcgFFT_F4 = pcgFFT1[c3:c4]
+    x4 = Energy_value(pcgFFT_F4)
+    
+    # Procesando de 240-500 Hz
+    pcgFFT_F5 = pcgFFT1[c4:c5]
+    x5 = Energy_value(pcgFFT_F5)
+    
+    # Procesando de 500-1000 Hz
+    pcgFFT_F6 = pcgFFT1[c5:c6]
+    x6 = Energy_value(pcgFFT_F6)
+    
+    # Procesando de 1000-2000 Hz
+    pcgFFT_F7 = pcgFFT1[c6:c7]
+    x7 = Energy_value(pcgFFT_F7)
+    
+    x = np.array([xAll, x1, x2, x3, x4, x5, x6, x7])
+    
+    if (on == 'percentage'):
+        x = 100*(x/x[0])
+
+    return x 
+
+def shannonE_value (x):
+    """
+    Shannon energy of an input signal  
+    """
+    y = sum((x**2)*np.log(x**2))/x.shape[0]
+    return y
+
+def shannonE_vector (x):
+    """
+    Shannon energy of an input signal  
+    """
+    mu = -(x**2)*np.log(x**2)/x.shape[0]
+    y = -(((x**2)*np.log(x**2)) - mu)/np.std(x)
+    return y
+
+# -----------------------------------------------------------------------------
+# Filter Processes
+# -----------------------------------------------------------------------------
+def Fpass(X,lp):
+    """
+    Fpass is the function to pass the coefficients of a filter trough a signal'
+    """
+    llp=np.size(lp)	  	        # Get the length of the lowpass vector		
+
+    x=np.convolve(X,lp);		        # Disrete convolution 
+    x=x[int(llp/2):-int(llp/2)];
+    x=x-(np.mean(x));
+    x=x/np.max(x);
+    
+    y=vec_nor(x);				# Vector Normalizing
+        
+    return y
+
+def FpassBand(X,hp,lp):
+    """
+    FpassBand is the function that develop a pass band filter of the signal 'x' through the
+    discrete convolution of this 'x' first with the coeficients of a High Pass Filter 'hp' and then
+    with the discrete convolution of this result with a Low Pass Filter 'lp'
+    """
+    llp=np.shape(lp)	  	        # Get the length of the lowpass vector		
+    llp=llp[0];				       # Get the value of the length
+    lhp=np.shape(hp)			    # Get the length of the highpass vector		
+    lhp=lhp[0];				       # Get the value of the length	
+
+    x=np.convolve(X,lp);		        # Disrete convolution 
+    x=x[int(llp/2):-int(llp/2)];
+    x=x-(np.mean(x));
+    x=x/np.max(x);
+	
+    y=np.convolve(x,hp);			# Disrete onvolution
+    y=y[int(lhp/2):-int(lhp/2)];
+    y=y-np.mean(y);
+    y=y/np.max(y);
+
+    x=np.convolve(y,lp);		        # Disrete convolution 
+    x=x[int(llp/2):-int(llp/2)];
+    x=x-(np.mean(x));
+    x=x/np.max(x);
+	
+    y=np.convolve(x,hp);			# Disrete onvolution
+    y=y[int(lhp/2):-int(lhp/2)];
+    y=y-np.mean(y);
+    y=y/np.max(y);
+        
+    y=vec_nor(y);				# Vector Normalizing
+        
+    return y
+
+def FpassBand_1(X,Fs,H_cutoff_hz, L_cutoff_hz):
+    """
+    Ref: http://scipy-cookbook.readthedocs.io/items/FIRFilter.html
+    http://lagrange.univ-lyon1.fr/docs/scipy/0.17.1/generated/scipy.signal.firwin.html
+    FpassBand_1 is a function to develop a passband filter using 'firwin'
+    and 'lfilter' functions from the "Scipy" library
+    """
+
+    # The Nyquist rate of the signal.
+    nyq_rate = Fs / 2.0
+    # The desired width of the transition from pass to stop,
+    # relative to the Nyquist rate.  We'll design the filter
+    # with a 5 Hz transition width.
+    width = 5.0/nyq_rate
+    # The desired attenuation in the stop band, in dB.
+    ripple_db = 60.0
+    # Compute the order and Kaiser parameter for the FIR filter.
+    N, beta = kaiserord(ripple_db, width)
+    # Use firwin with a Kaiser window to create a lowpass FIR filter.
+    taps = firwin(N, L_cutoff_hz/nyq_rate, window=('kaiser', beta))
+    taps_2 = firwin(N, H_cutoff_hz/nyq_rate, pass_zero=False)
+    # Use lfilter to filter x with the FIR filter.
+    X_l= lfilter(taps, 1.0, X)
+    X_pb= lfilter(taps_2, 1.0, X_l)
+    
+    return X_pb[N-1:]
+
+def FhighPass(X, Fs, H_cutoff_hz):
+    """
+    Ref: http://scipy-cookbook.readthedocs.io/items/FIRFilter.html
+    http://lagrange.univ-lyon1.fr/docs/scipy/0.17.1/generated/scipy.signal.firwin.html
+    FhighPass is a function to develop a highpass filter using 'firwin'
+    and 'lfilter' functions from the "Scipy" library
+    """
+    # The Nyquist rate of the signal.
+    nyq_rate = Fs / 2.0
+    # The desired width of the transition from pass to stop,
+    # relative to the Nyquist rate.  We'll design the filter
+    # with a 5 Hz transition width.
+    width = 5.0/nyq_rate
+    # The desired attenuation in the stop band, in dB.
+    ripple_db = 60.0
+    # Compute the order and Kaiser parameter for the FIR filter.
+    N, beta = kaiserord(ripple_db, width)
+    # Use firwin with a Kaiser window to create a lowpass FIR filter.
+    taps_2 = firwin(N, H_cutoff_hz/nyq_rate, pass_zero=False)
+    # Use lfilter to filter x with the FIR filter.
+    X_h= lfilter(taps_2, 1.0, X)
+    
+    return X_h[N-1:]
+    
+def FlowPass(X, Fs, L_cutoff_hz):
+    """
+    Ref: http://scipy-cookbook.readthedocs.io/items/FIRFilter.html
+    http://lagrange.univ-lyon1.fr/docs/scipy/0.17.1/generated/scipy.signal.firwin.html
+    FlowPass is a function to develop a lowpass filter using 'firwin'
+    and 'lfilter' functions from the "Scipy" library
+    """
+    # The Nyquist rate of the signal.
+    nyq_rate = Fs / 2.0
+    # The desired width of the transition from pass to stop,
+    # relative to the Nyquist rate.  We'll design the filter
+    # with a 5 Hz transition width.
+    width = 5.0/nyq_rate
+    # The desired attenuation in the stop band, in dB.
+    ripple_db = 60.0
+    # Compute the order and Kaiser parameter for the FIR filter.
+    N, beta = kaiserord(ripple_db, width)
+    # Use firwin with a Kaiser window to create a lowpass FIR filter.
+    taps = firwin(N, L_cutoff_hz/nyq_rate, window=('kaiser', beta))
+    # Use lfilter to filter x with the FIR filter.
+    X_l= lfilter(taps, 1.0, X)
+    
+    return X_l[N-1:]
+# -----------------------------------------------------------------------------
+# Peak Detection
+# -----------------------------------------------------------------------------
+def PDP(Xf, samplerate):
+    """
+    Peak Detection Process
+    """
+    timeCut = samplerate*0.25                       # time to count another pulse
+    vCorte = 0.6
+    
+    Xf = vec_nor(Xf)
+    dX=derivate(Xf);				                      # Derivate of the signal
+    dX=vec_nor(dX);			                         # Vector Normalizing
+    
+    size=np.shape(Xf)				                  # Rank or dimension of the array
+    fil=size[0];					                     # Number of rows
+ 
+    positive=np.zeros((1,fil+1));                   # Initializating Vector 
+    positive=positive[0];                           # Getting the Vector
+
+    points=np.zeros((1,fil));                       # Initializating the Peak Points Vector
+    points=points[0];                               # Getting the point vector
+
+    points1=np.zeros((1,fil));                      # Initializating the Peak Points Vector
+    points1=points1[0];                             # Getting the point vector
+    
+    vCorte = 0.6
+       
+    '''
+    FIRST! having the positives values of the slope as 1
+    And the negative values of the slope as 0
+    '''
+    for i in range(0,fil):
+        if dX[i]>0:
+            positive[i]=1;
+        else:
+            positive[i]=0;
+    '''
+    SECOND! a peak will be found when the ith value is equal to 1 &&
+    the ith+1 is equal to 0
+    '''
+    for i in range(0,fil):
+        if (positive[i]==1 and positive[i+1]==0):
+            points[i]=Xf[i];
+        else:
+            points[i]=0;
+    '''
+    THIRD! Define a minimun Peak Height
+    '''
+    p=0;
+    for i in range(0,fil):
+        if (points[i] > vCorte and p==0):
+            p=i
+            points1[i]=Xf[i]
+            
+        else:
+            points1[i]=0;
+            if (p+timeCut < i):
+                p=0
+                    
+    return points1
+# -----------------------------------------------------------------------------
+# Fast Fourier Transform
+# -----------------------------------------------------------------------------
+def fft_k(data, samplerate, showFrequency):
+    '''
+    Fast Fourier Transform
+    Ref: https://docs.scipy.org/doc/scipy/reference/tutorial/fftpack.html
+    '''
+    pcgFFT = fft(data)                                                    # FFT Full Vector
+    short_pcgFFT = 2.0/np.size(data) * np.abs(pcgFFT[0:np.size(data)//2]) # FFT positives values
+    vTfft = np.linspace(0.0, 1.0/(2.0*(1/samplerate)), np.size(data)//2)  # Vector of frequencies (X-axes)
+       
+    idx = (np.abs(vTfft-showFrequency)).argmin()             # find the value closest to a value
+    
+    return short_pcgFFT[0:idx], vTfft[0:idx]
+
+def fft_k_N(data, samplerate, showFrequency):
+    '''
+    Normalized Fast Fourier Transform
+    Ref: https://docs.scipy.org/doc/scipy/reference/tutorial/fftpack.html
+    '''
+    pcgFFT = fft(data)                                                    # FFT Full Vector
+    short_pcgFFT = 2.0/np.size(data) * np.abs(pcgFFT[0:np.size(data)//2]) # FFT positives values
+    vTfft = np.linspace(0.0, 1.0/(2.0*(1/samplerate)), np.size(data)//2)  # Vector of frequencies (X-axes)
+       
+    idx = (np.abs(vTfft-showFrequency)).argmin()             # find the value closest to a value
+    
+    return vec_nor(short_pcgFFT[0:idx]), vTfft[0:idx]
\ No newline at end of file