def calcularWavelet(self, canal): senal = self.__data[canal, :]; #%% analisis usando wavelet continuo import pywt #1.1.1 #%% sampling_period = 1/1000 Frequency_Band = [4, 30] # Banda de frecuencia a analizar # Métodos de obtener las escalas para el Complex Morlet Wavelet # Método 1: # Determinar las frecuencias respectivas para una escalas definidas scales = np.arange(1, 250) frequencies = pywt.scale2frequency('cmor', scales)/sampling_period # Extraer las escalas correspondientes a la banda de frecuencia a analizar scales = scales[(frequencies >= Frequency_Band[0]) & (frequencies <= Frequency_Band[1])] N = senal.shape[0] #%% # Obtener el tiempo correspondiente a una epoca de la señal (en segundos) time_epoch = sampling_period*N # Analizar una epoca de un montaje (con las escalas del método 1) # Obtener el vector de tiempo adecuado para una epoca de un montaje de la señal time = np.arange(0, time_epoch, sampling_period) # Para la primera epoca del segundo montaje calcular la transformada continua de Wavelet, usando Complex Morlet Wavelet [coef, freqs] = pywt.cwt(senal, scales, 'cmor', sampling_period) # Calcular la potencia power = (np.abs(coef)) ** 2 return time, freqs, power
def mirCWt(trackTitle, startSec, lengthSec, sRatio, wtMom, bDebug, bSaveAudio, saveWtSpectra, bCompressWtSpectra): # read audio file audioSig, sampleRate = sf.read('audiosrc/' + trackTitle) # local definitions minFreq = 117 # Hz maxFreq = 500 # Hz scaleFactor = 2 * sRatio dt = sRatio / sampleRate # seconds audioSigLength = int(lengthSec * sampleRate) startPoint = int(startSec * sampleRate) scales = np.arange(sampleRate / (maxFreq * scaleFactor), sampleRate / (minFreq * scaleFactor), int(8 / scaleFactor)) #save audio file if bSaveAudio: saveAudio(trackTitle, startPoint, audioSigLength, sampleRate, audioSig) # cut and/or simplify audioSignal audioSig = audioSig[startPoint:startPoint + audioSigLength:sRatio, 1] # debug if bDebug: print('sample rate = %f\n' % (sampleRate / sRatio)) # 48000 print('audio sample length = %f\n' % len(audioSig)) frequencies = pywt.scale2frequency(wtMom, scales) / dt # frequency print('frequencies:\n') print(frequencies) # wavelet spectra calculation [cfs, wtFreqs] = pywt.cwt(audioSig, scales, wtMom, dt) wtSpectra = (abs(cfs))**2 # save detailed wavelet spectrogram data to file if (saveWtSpectra & 1) == 1: strAdd = '' saveWtSpectraFile(trackTitle[:-4], dt, strAdd, wtFreqs, wtSpectra) # compress spectrogram for CNN if bCompressWtSpectra: fig, axs = plt.subplots(2) fig.suptitle('1d size reduction') axs[0].contourf( np.arange(0, len(wtSpectra[1, :])) * dt, wtFreqs, wtSpectra) wtSpectra = wtSpectra.reshape(-1, 120).mean(axis=1) wtSpectra = np.reshape( a=wtSpectra, newshape=(40, 400)) # matrix with 40 rows and 400 columns dt = dt * 120 axs[1].contourf(np.arange(0, 400) * dt, wtFreqs, wtSpectra) plt.show() # save compressed wavelet spectrogram data to file if (saveWtSpectra & 2) == 2: strAdd = 'Comp' saveWtSpectraFile(trackTitle[:-4], dt, strAdd, wtFreqs, wtSpectra)
def dominant_wavenumber(field, grid, n_scales=120, smoothing=(21, 7)): """Dominant zonal wavenumber at every gridpoint of field. Implements the procedure of Ghinassi et al. (2018) based on a wavelet analysis of the input field. - `n_scales` determines the number of scales used in the continuous wavelet transform. - `smoothing` determines the full width at half maximum of the Hann filter in zonal and meridional direction in degrees longitude/latitude. Returns the gridded dominant zonal wavenumber. Requires `pywt` (version >= 1.1.0) and `scipy`. """ import pywt from scipy import signal # Truncate zonal fourier spectrum of meridional wind after wavenumber 20 x = _restrict_fourier_zonal(field, 0, 20) # Triplicate field to avoid boundary issues (pywt.cwt does not support # periodic mode as of version 1.1) x = np.hstack([x, x, x]) # Use the complex Morlet wavelet morlet = pywt.ContinuousWavelet("cmor1.0-1.0") # ... scales = 3 * 2**np.linspace(0, 6, n_scales) # Apply the continuous wavelet transform coef, freqs = pywt.cwt(x, scales=scales, wavelet=morlet, axis=_ZONAL) # Extract the middle domain, throw away the periodic padding ii = coef.shape[-1] // 3 coef = coef[:, :, ii:-ii] # Obtain the power spectrum power = np.abs(coef)**2 # Determine wavenumbers from scales wavenum = pywt.scale2frequency(morlet, scales) * grid.shape[_ZONAL] # Dominant wavenumber is that of maximum power in the spectrum dom_wavenum = wavenum[np.argmax(power, axis=0)] # Smooth dominant wavenumber with Hann windows. Window width is given as # full width at half maximum, which is half of the full width. Choose the # nearest odd number of gridpoints available to the desired value. smooth_lon, smooth_lat = smoothing hann_lon = signal.windows.hann( int(smooth_lon / 360 * grid.shape[_ZONAL]) * 2 + 1) hann_lon = hann_lon / np.sum(hann_lon) hann_lat = signal.windows.hann( int(smooth_lat / 180 * grid.shape[_MERIDIONAL]) * 2 + 1) hann_lat = hann_lat / np.sum(hann_lat) # Apply zonal filter first with periodic boundary dom_wavenum = signal.convolve2d(dom_wavenum, hann_lon[None, :], mode="same", boundary="wrap") # Then apply meridional filter with symmetrical boundary dom_wavenum = signal.convolve2d(dom_wavenum, hann_lat[:, None], mode="same", boundary="symm") return dom_wavenum
def __call__(self, signal): """Computes the WPS of the signal for the given periods. The following attributes will then be defined: - WPS.signal - WPS.time, WPS.scales - WPS.power, WPS.spectrum - WPS.mask_coi - WPS.masked_spectrum - WPS.sav, WPS.masked_sav - WPS.gwps, WPS.masked_gwps Parameters ---------- signal: `Signal` or array-like Input signal Returns ------- spectrum: ndarray[len(periods), len(signal)] """ if not isinstance(signal, TSeries): signal = TSeries(values=signal) n_times = signal.size n_scales = self.periods.size family = "cmor2.0-1.0" dt = signal.median_dt scales = pywt.scale2frequency(family, 1) * self.periods / dt # Chooses the method with the lowest computational complexity conv_complex = n_scales * n_times fft_complex = (n_scales + n_times - 1) * np.log2(n_scales + n_times - 1) if fft_complex < conv_complex: method = "fft" else: method = "conv" self.coefs, _ = pywt.cwt(signal.values - signal.mean(), scales, family, dt, method=method) # Defines useful attributes power = np.square(np.abs(self.coefs)) unbiased_power = (power.T / scales).T self.signal = signal self.time = signal.time self.scales = scales self.power = TFSeries(time=self.time, frequency=self.frequency, values=power) self.spectrum = TFSeries(time=self.time, frequency=self.frequency, values=unbiased_power) self.masked_spectrum = self.spectrum.copy() self.masked_spectrum.values[~self.mask_coi] = np.nan return self.spectrum
def test_frequency2scale(): """test conversion from scale -> frequency -> scale""" import pywt scale = 5 sr = 44100 wavelet = "morl" f_hz = pywt.scale2frequency(wavelet, scale) * sr assert sig.frequency2scale(f_hz, wavelet, sr) == scale
def wavelet_transform(signal, p): #Assumes that the down-sampled signal at 1kHz is analyzed sampling_period = 1 / 1000 #Use built in pywt function to determine physical frequencies scales = pywt.scale2frequency('morl', np.arange(1, 120)) / sampling_period #Complete wavelet anlaysis coef, freq = pywt.cwt(signal, scales, 'morl', sampling_period) return coef, freq
def cwt(data, fs, f_cutoff): dt = 1 / fs wavelet = 'cmor1.5-1.0' scales = np.arange(1, 255) [cfs, frequencies] = pywt.cwt(data, scales, wavelet, 1 / fs) power = (abs(cfs))**2 * 10 freqs = pywt.scale2frequency(wavelet, scales) / dt mask = frequencies <= f_cutoff index = np.where(mask) time = np.linspace(0, len(data) / fs, num=len(data), endpoint=False) t, f = np.meshgrid(time, frequencies) return t[index], f[index], power[index]
def wavelet(t, x, periods): """Wavelet Power Spectrum using Morlet wavelets. Parameters ---------- t: array-like Time array. x: array-like Signal array. periods: array-like Periods to consider, in the same units as `t`. Returns ------- power: ndarray[len(periods), len(t)] Wavelet Power Spectrum. coi: tuple of ndarray Time and scale samples for plotting the Cone of Influence boundaries. mask_coi: ndarray[len(periods), len(t)] Boolean mask with the same shape as `power`; it is True inside the COI. """ family = 'cmor2.0-1.0' dt = float(np.median(np.diff(t))) scales = pywt.scale2frequency(family, 1) * np.asarray(periods) / dt conv_complex = len(scales) * len(x) fft_complex = (len(scales) + len(x) - 1) * np.log2(len(scales) + len(x) - 1) if fft_complex < conv_complex: method = 'fft' else: method = 'conv' coefs, freqs = pywt.cwt(x - x.mean(), scales, family, dt, method=method) power = np.square(np.abs(coefs)) wps = (power.T / scales).T # Cone of Influence (COI) t_max = np.max(t) t_min = np.min(t) p_max = np.max(periods) p_min = np.min(periods) t_mesh, p_mesh = np.meshgrid(t, periods) mask_coi = (2**.5 * p_mesh < np.minimum(t_mesh - t_min, t_max - t_mesh)) p_samples = np.logspace(np.log10(p_min), np.log10(p_max), 100) p_samples = p_samples[2**.5 * p_samples < (t_max - t_min) / 2] t1 = t_min + 2**.5 * p_samples t2 = t_max - 2**.5 * p_samples t_samples = np.hstack((t1, t2)) p_samples = np.hstack((p_samples, p_samples)) sorted_ids = t_samples.argsort() sorted_t_samples = t_samples[sorted_ids] sorted_p_samples = p_samples[sorted_ids] coi = (sorted_t_samples, sorted_p_samples) return wps, coi, mask_coi
def wavelet_transform(angles, fps=100, chan=25, fmin=1, fmax=50, pca_dim=None, cor=True): ''' Performs complex wavelet transformations for a time-series shape=(frame, angle). Take into account the sampling rate of the data (fps) and some parameters of choice, such as the number of channels, minimum and maximum frequencies, and the use of a correction factor for lower frequencies. ''' nframes = angles.shape[0] nfeats = angles.shape[1] dt = 1 / fps # sampling period pi = math.pi w0 = 2 kk = (w0 + math.sqrt(2 + w0**2)) / (4 * pi * fmax) scales = kk * (2**( (np.linspace(0, chan - 1, chan) / (chan - 1)) * math.log(fmax / fmin, 2))) * (2.824228 * fps) scales = scales[0:chan] fs = pywt.scale2frequency('cmor1-1', scales) / dt print('Range of center frequencies covered for {0}fps:{1}'.format(fps, fs)) # create correction factor array: x = np.arange(nframes) cf = np.zeros(chan) resp = np.zeros(shape=(nframes, chan)) for i in range(chan): resp[:, i] = abs( (pywt.cwt(np.exp((2 * np.pi * fs[i] * (x / fps)) * 1j), scales[i], 'cmor1-1'))[0]) cf[i] = max(resp[:, i]) if cor: print('Correction factor:', cf) # Create matrix for every wavelet transform wav = np.zeros(shape=(nfeats, len(fs), nframes)) for i in range(nfeats): for j in range(len(scales)): # Get correction factor: if cor: ccf = cf[ j] #((pi**-1/4)/(np.sqrt(2*scales[j])))*np.exp(1/(4*(w0-np.sqrt(2+w0**2))**2)); else: ccf = 1 wav[i, j, :] = abs( (pywt.cwt(angles[:, i], scales, 'cmor1-1', sampling_period=dt))[0])[j, :] / ccf wav_c = np.concatenate(wav, axis=0) del wav wav_c = wav_c.transpose() return wav_c
def cwt(epoch, mwt="mexh", density=2, octaves=7): center_wavelet_frequency = pywt.scale2frequency(mwt, [1])[0] const = center_wavelet_frequency * signal_frequency # construct scales scales = const / get_frequencies(density, octaves) # compute coeffs coef, freqs = pywt.cwt(data=epoch, scales=scales, wavelet=mwt, sampling_period=1 / signal_frequency) if "cmor" in mwt: # if complex Morlet, change to real coef = np.abs(coef) return coef
def calcularWavelet(self, senal, fmin, fmax, fs): """ Parameters ---------- senal : datos a los que se le aplicaran el Wavelet continuo. fmin : frecuencia minima de interes. fmax : frecuencia maxima de interes. fs : frecuencia de muestreo de la senal. Returns ------- time : rango de tiempo del espectro. freqs : rengo de frecuencias del espectro. power : rango de potencias del espectro. """ #analisis usando wavelet continuo sampling_period = 1 / fs Frequency_Band = [fmin, fmax] # Banda de frecuencia a analizar # se determinan las frecuencias respectivas para una escala definida scales = np.arange(1, 250) frequencies = pywt.scale2frequency('cmor', scales) / sampling_period # se extraen las escalas correspondientes a la banda de frecuencia a analizar scales = scales[(frequencies >= Frequency_Band[0]) & (frequencies <= Frequency_Band[1])] N = senal.shape[0] # se obtiene el tiempo correspondiente a una epoca de la senal time_epoch = sampling_period * N # se analiza una epoca # se obtiene el vector de tiempo time = np.arange(0, time_epoch, sampling_period) [coef, freqs] = pywt.cwt(senal, scales, 'cmor', sampling_period) # se calcula la potencia power = (np.abs(coef))**2 return time, freqs, power
def calcularwavelet(self, fmin, fmax): # Calculo import pywt period = 1 / self.fs # Se calcula el periodo de la senal band = [fmin, fmax] # Banda de frecuencia que se desea analizar scales = np.arange(1, 250) # numero de escalas frequencies = pywt.scale2frequency('cmor', scales) / period scales = scales[(frequencies >= band[0]) & ( frequencies <= band[1] )] # Se extrae la escalas correspondientes a las frecuencias de interés N = self.senial.shape[0] # numero de datos de la senal time_epoch = period * N # Tiempo correspondiente a una epoca de la señal (en segundos) time = np.arange(0, time_epoch, period) [coef, freqs] = pywt.cwt( self.senial, scales, 'cmor', period ) # Calculo de la transformada continua de Wavelet. Se implementa Complex Morlet Wavelet power = (np.abs(coef))**2 # Calculo de potencia return time, freqs, power
def wavelet_continuo_analisis( self, datos, fs, fmin, fmax, num_muestras ): #algoritmo que realiza los calculos para obtener el analisis por wavelet sampling_period = 1 / fs #periodo de muestreo Frequency_Band = [fmin, fmax] # Banda de frecuencia a analizar scales = np.arange(1, num_muestras) frequencies = pywt.scale2frequency('cmor', scales) / sampling_period # Extraer las escalas correspondientes a la banda de frecuencia a analizar scales = scales[(frequencies >= Frequency_Band[0]) & (frequencies <= Frequency_Band[1])] N = datos.shape[0] # Obtener el tiempo correspondiente a una epoca de la señal (en segundos) time_epoch = sampling_period * N # Analizar una epoca de un montaje (con las escalas del método 1) # Obtener el vector de tiempo adecuado para una epoca de un montaje de la señal time = np.arange(0, time_epoch, sampling_period) # Para la primera epoca del segundo montaje calcular la transformada continua de Wavelet, usando Complex Morlet Wavelet [coef, freqs] = pywt.cwt(datos, scales, 'cmor', sampling_period) # Calcular la potencia power = (np.abs(coef))**2 return time, freqs, power
def Grafica_fvt(self): fs = int(self.FT_fs.text()) fl = int(self.FT_fl.text()) fh = int(self.FT_fh.text()) senal = self.senal - np.mean(self.senal) senal = np.squeeze(senal) N = senal.shape[0] get_ipython().run_line_magic('matplotlib', 'qt') sampling_period = 1 / fs Frequency_Band = [fl, fh] # Banda de frecuencia a analizar # Métodos de obtener las escalas para el Complex Morlet Wavelet # Método 1: # Determinar las frecuencias respectivas para una escalas definidas scales = np.arange(1, N) frequencies = pywt.scale2frequency('cmor', scales) / sampling_period # Extraer las escalas correspondientes a la banda de frecuencia a analizar scales = scales[(frequencies >= Frequency_Band[0]) & (frequencies <= Frequency_Band[1])] time_epoch = sampling_period * N # Analizar una epoca de un montaje (con las escalas del método 1) # Obtener el vector de tiempo adecuado para una epoca de un montaje de la señal time = np.arange(0, time_epoch, sampling_period) scales = np.squeeze(scales) # Para la primera epoca del segundo montaje calcular la transformada continua de Wavelet, usando Complex Morlet Wavelet [coef, freqs] = pywt.cwt(senal, scales, 'cmor', sampling_period) # Calcular la potencia power = np.power(np.abs(coef), 2) # Graficar el escalograma obtenido del análisis tiempo frecuencia f, ax = plt.subplots(figsize=(15, 10)) scalogram = ax.contourf( time, freqs[(freqs >= 4) & (freqs <= 40)], power[(freqs >= 4) & (freqs <= 40), :], 100, # Especificar 20 divisiones en las escalas de color extend='both') ax.set_ylim(4, 40) ax.set_ylabel('Frequencia [Hz]') ax.set_xlabel('Tiempo [s]') cbar = plt.colorbar(scalogram)
def graficacion_wavelet(self): ''' Método que toma realiza el preproceso de los datos ingresador por el usuario para la graficación del Wavelet continuo, envía los parámetros necesarios al método descrito anteriormente como lo son la frecuencia, potencia y tiempo, para la respectiva graficación ''' self.frecuencia_inicial.setEnabled(True) self.frecuencia_final.setEnabled(True) self.radio_wavelet.setEnabled(True) self.escalar_frecuencia.setEnabled(True) # Se toma el índice del canal seleccionado canal_seleccionado = self.comboBox.currentIndex() # Se encuentra el periodo de muestreo por medio del valor puesto en el spinBox sampling_period = 1 / self.fs.value() # Se realiza el procesamiento que requiere la Wavelet continua scales = np.arange(1, self.fs.value()) frequencies = pywt.scale2frequency('cmor', scales) / sampling_period scales = scales[(frequencies >= self.__f_min) & (frequencies <= self.__f_max)] time_epoch = sampling_period * self.__num_datos time = np.arange(0, time_epoch, sampling_period) # Se toman los datos correspondientes al canal seleccionado datos = self.__coordinador.devolverDatosSenal( 0, self.__num_datos)[canal_seleccionado] # Condicional que permite filtrar o no los datos que se van a graficar, esto se hace por #medio de la validación de un cuadro de confirmación, al estar confirmado quiere decir que. #se debe retirar el nivel DC restando la media. if self.check_DC.isChecked() == True: datos = datos - np.mean(datos) # Se toman los coeficientes y la frencuencia entregados por la función [coef, freqs] = pywt.cwt(datos, scales, 'cmor', sampling_period) # Se llama la función graficar espectro definida en línas anteriores. power = (np.abs(coef))**2 self.__sc_2.graficar_espectro(time, freqs, power, self.__f_min, self.__f_max, self.__x_min, self.__x_max) # Se activa un botón tipo radio que permite escalar en tiempo y frecuencia el Wavelet continuo. self.radio_wavelet.setEnabled(True) # Se inicializa una bandera que servirá como verificación self.__ej_wavelet = 1
def calcularWaveletContinuo(self,fs,fcMin,fcMax): if self.senalFiltrada.shape[0] == 0: # Sí ya hay una señal filtrada if self.banderaDimension == 1: # se trabajará con ella, de lo contrario senal = self.senal; # se empleara la señal original elif self.banderaDimension == 2: if self.canalActual == -1: senal = self.senal[0]; else: senal = self.senal[self.canalActual]; else: senal = self.senalFiltrada; senal = senal - np.mean(senal); N = senal.shape[0]; Ts = 1/fs; escalas = np.arange(1, 250); frequencias = pywt.scale2frequency('cmor', escalas)/Ts; # Escalas determinadas por el METODO 1 escalas = escalas[(frequencias >= fcMin) & # Escala de frecuencias correspondiente (frequencias <= fcMax)]; # a la banda a analizar tiempoEpoca = Ts*N; # Tiempo correspondiente a una época de la señal # DUDA: SI COGE 1 EPOCA O TODA LA SEÑAL? # N deberia ser la cantidad de muestras de 1 epoca tiempo = np.arange(0, tiempoEpoca, Ts); # Tiempo correspondiente a 1 epoca [armonicos, f] = pywt.cwt(senal, escalas, 'cmor', Ts); # RECIBE LA SENAL O LOS DATOS DE LA EPOCA? PSD = np.power(np.abs(armonicos),2); # NO HACE FALTA DIVIDIR POR LA CANTIDAD DE DATOS? print('Si'); self.__controlador.graficarWaveletContinuo(tiempo,f,PSD);
def calcularWavelet(self,data,fs): #funcion que realiza todo el proceso de analisis espectral por wavelet senal =self.__data[:] sen= senal - np.mean(senal) import pywt #se importa la libreria sampling_period = 1/fs Frequency_Band = [4, 30] # Banda de frecuencia a analizar # Métodos de obtener las escalas para el Complex Morlet Wavelet # Método 1: # Determinar las frecuencias respectivas para una escalas definidas scales = np.arange(1, 250) frequencies = pywt.scale2frequency('cmor', scales)/sampling_period # Extraer las escalas correspondientes a la banda de frecuencia a analizar scales = scales[(frequencies >= Frequency_Band[0]) & (frequencies <= Frequency_Band[1])] N = sen.shape[0] # Obtener el tiempo correspondiente a una epoca de la señal (en segundos) time_epoch = sampling_period*N # Analizar una epoca de un montaje (con las escalas del método 1) # Obtener el vector de tiempo adecuado para una epoca de un montaje de la señal time = np.arange(0, time_epoch, sampling_period) # Para la primera epoca del segundo montaje calcular la transformada continua de Wavelet, usando Complex Morlet Wavelet [coef, freqs] = pywt.cwt(sen, scales, 'cmor', sampling_period) # Calcular la potencia power = (np.abs(coef)) ** 2 return time, freqs, power
def generate_leak_1bar_in_cwt_xcor_maxpoints_vector_2( self, saved_filename=None, file_to_process=None, denoise=False): ''' version 2: Instead of cwt for all scale in one shot, we do cwt scale by scale this method read all tdms file from a folder, split each of them into certain parts, perform CWT follow by XCOR according to the sensor pair list, then append into a dataset with labels :param saved_filename: filename Label for the dataset generated :param file_to_process: a list of strings, which is full dir and filename of the tdms to be processed. if none, it is taken as all tdms in the 1bar leak :param denoise: True it will denoise the signal bfore CWT and xcor :return: dataset where shape[0] -> no of samples of all classes shape[1] -> no of elements in a vector label where shape[0] -> aligned with the shape[0] of dataset shape[1] -> 1 ''' # CONFIG ------------------------------------------------------------------------------------------------------- # DWT dwt_wavelet = 'db2' dwt_smooth_level = 2 # CWT m_wavelet = 'gaus1' scale = np.linspace(2, 10, 100) fs = 1e6 # segmentation per tdms (sample size by each tdms) no_of_segment = 2 # file dir if file_to_process is None: # list full path of all tdms file in the specified folder folder_path = self.path_leak_1bar_2to12 all_file_path = [(folder_path + f) for f in listdir(folder_path) if f.endswith('.tdms')] else: all_file_path = file_to_process # DATA READING ------------------------------------------------------------------------------------------------- # creating dict to store each class data all_class = {} for i in range(0, 11, 1): all_class['class_[{}]'.format(i)] = [] # for all tdms file in folder (Warning: It takes 24min for 1 tdms file) for tdms_file in all_file_path: # read raw from drive n_channel_data_near_leak = read_single_tdms(tdms_file) n_channel_data_near_leak = np.swapaxes(n_channel_data_near_leak, 0, 1) if denoise: temp = [] for signal in n_channel_data_near_leak: denoised_signal = dwt_smoothing(x=signal, wavelet=dwt_wavelet, level=dwt_smooth_level) temp.append(denoised_signal) n_channel_data_near_leak = np.array(temp) # split on time axis into no_of_segment n_channel_leak = np.split(n_channel_data_near_leak, axis=1, indices_or_sections=no_of_segment) dist_diff = 0 # for all sensor combination for sensor_pair in self.sensor_pair_near: segment_no = 0 pb = ProgressBarForLoop( title='CWT+Xcor using {}'.format(sensor_pair), end=len(n_channel_leak)) # for all segmented signals for segment in n_channel_leak: max_xcor_vector = [] # for all scales for s in scale: pos1_leak_cwt, _ = pywt.cwt(segment[sensor_pair[0]], scales=s, wavelet=m_wavelet) pos2_leak_cwt, _ = pywt.cwt(segment[sensor_pair[1]], scales=s, wavelet=m_wavelet) # xcor for every pair of cwt xcor, _ = one_dim_xcor_1d_input( input_mat=[pos1_leak_cwt, pos2_leak_cwt], pair_list=[(0, 1)]) xcor = xcor[0] # midpoint in xcor mid = xcor.shape[0] // 2 + 1 # 24000 = fs*24ms(max deviation in ToA) upper_xcor_bound = mid + 24000 lower_xcor_bound = mid - 24000 # for every row of xcor, find max point index max_along_x = np.argmax( xcor[lower_xcor_bound:upper_xcor_bound]) max_xcor_vector.append(max_along_x + lower_xcor_bound - mid) # free up memory for unwanted variable pos1_leak_cwt, pos2_leak_cwt, xcor = None, None, None gc.collect() # store all feature vector for same class all_class['class_[{}]'.format(dist_diff)].append( max_xcor_vector) # progress pb.update(now=segment_no) segment_no += 1 pb.destroy() dist_diff += 1 # just to display the dict full dim temp = [] for _, value in all_class.items(): temp.append(value[0]) temp = np.array(temp) print('all_class dim: ', temp.shape) # free up memory for unwanted variable pos1_leak_cwt, pos2_leak_cwt, n_channel_data_near_leak = None, None, None gc.collect() # transfer all data from dict to array dataset = [] label = [] # for all class for i in range(0, 11, 1): # for all samples in a class for sample in all_class['class_[{}]'.format( i)]: # a list of list(max vec) dataset.append(sample) label.append(i) # convert to array dataset = np.array(dataset) label = np.array(label) print('Dataset Dim: ', dataset.shape) print('Label Dim: ', label.shape) # save to csv label = label.reshape((-1, 1)) all_in_one = np.concatenate([dataset, label], axis=1) # column label freq = pywt.scale2frequency(wavelet=m_wavelet, scale=scale) * fs column_label = [ 'Scale_{:.4f}_Freq_{:.4f}Hz'.format(i, j) for i, j in zip(scale, freq) ] + ['label'] df = pd.DataFrame(all_in_one, columns=column_label) filename = direct_to_dir( where='result' ) + 'cwt_xcor_maxpoints_vector_dataset_{}.csv'.format(saved_filename) df.to_csv(filename)
# general method for getting STFT coefficients # win_len = 128 f, t, Zxx = signal.stft(svm_data, Fs, window='bartlett', nperseg=win_len, noverlap=win_len // 2, nfft=win_len, return_onesided=True, boundary='zeros', padded=True, axis=1) Z_stft = np.abs(Zxx) ** 2 # plt.figure(dpi=300) # plt.pcolormesh(t, f, np.abs(Zxx[0, :, :]) ** 2, cmap='viridis', shading='nearest') # used to plot spectrogram Z_stft = np.reshape(Z_stft, (Z_stft.shape[0], Z_stft.shape[1] * Z_stft.shape[2]), order='C') Z_stft = Z_stft / np.max(Z_stft, axis=0) Z_stft = Z_stft - np.mean(Z_stft, axis=0) # some random useful functions for CWT stuff # wvlt = 'cmor1-1.5' center_freq = pywt.scale2frequency(wvlt, 1)/Ts # scales = np.arange(1, 128) scales = center_freq/np.linspace(2000, 1, 50) coeff, freq = pywt.cwt(svm_data, scales=scales, wavelet=wvlt, sampling_period=Ts, method='auto', axis=1) power = np.abs(coeff) ** 2 power = np.reshape(power, (power.shape[0], power.shape[1] * power.shape[2]), order='C') # some random useful functions for DWT stuff # wvlt = 'sym10' wvlt_data = pywt.Wavelet(wvlt) father, mother, coords = wvlt_data.wavefun(level=1) # father=scaling=LPF lpf_coeffs, hpf_coeffs = wvlt_data.filter_bank[0:2] center_freq = pywt.scale2frequency(wvlt, 1)/Ts coeffs = pywt.wavedecn(svm_data, wavelet=wvlt, mode='periodization', level=6, axes=1) coeffs_vec, coeffs_slices = pywt.coeffs_to_array(coeffs, axes=[1])
def gaussian(x, mu, sig): return np.exp(-np.power(x - mu, 2.) / (2 * np.power(sig, 2.))) fs = 1024 window = 4 * fs dt = 1 / fs (f0, f1, f2) = fs / 16, fs / 64, fs / 4 x = np.arange(window) y0 = np.sin(2 * np.pi * x / f0) * gaussian(x, 800, 80) y1 = np.sin(2 * np.pi * x / f1) * gaussian(x, 200, 30) y2 = np.sin(2 * np.pi * x / f2) y = y0 + y1 + y2 scales = np.arange(1, 65) frequencies = pywt.scale2frequency('mexh', scales) / dt coef, freqs = pywt.cwt(y, np.arange(1, fs / 8), 'mexh') plt.close('all') fig, axs = plt.subplots(5, gridspec_kw={'height_ratios': [1, 1, 1, 1, 3]}) axs[0].plot(y0) axs[1].plot(y1) axs[2].plot(y2) axs[3].plot(y) axs[4].matshow( np.flipud(coef), extent=[0, fs, 1, 64], cmap='PRGn', aspect='auto', vmax=abs(coef).max(),
def main(argv): config = read_parser(argv, Inputs, InputsOpt_Defaults) if config['mode'] == 'test': print(pywt.wavelist('morl')) sys.exit() if config['mypath'] == None: print('Select File with signal') root = Tk() root.withdraw() root.update() filepath = filedialog.askopenfilename() root.destroy() else: filepath = [ join(config['mypath'], f) for f in listdir(config['mypath']) if isfile(join(config['mypath'], f)) if f[-4:] == 'tdms' ] x = load_signal(filepath, channel=config['channel']) # sys.exit() x = x[0:int(len(x) / 5)] s_level = 5 coeffs = pywt.wavedec(x, 'db6', level=s_level, mode='periodic') # print(coeffs) # print(len(x)) # print(len(coeffs)) # print(len(coeffs[0])) # print(len(coeffs[1])) # print(len(coeffs[2])) for k in range(s_level + 1): print(len(coeffs[k])) sys.exit() # wsignal = (x)**2.0 # wsignal = (coeffs[5])**2.0 wsignal = (coeffs[5]) wsignal = odd_to_even(wsignal) # wsignal = wsignal / (np.max(wsignal) - np.min(wsignal)) print(type(wsignal)) print(np.ravel(wsignal)) plt.figure(1) plt.plot(wsignal, color='blue') fft, f, df = mag_fft(x=wsignal, fs=config['fs']) plt.figure(2) plt.plot(f, fft, color='red') env = hilbert_demodulation(wsignal) plt.figure(3) plt.plot(env, color='green') fftenv, f, df = mag_fft(x=env, fs=config['fs']) plt.figure(4) plt.plot(f, fftenv, color='black') plt.show() elif config['mode'] == 'work_with_wavelet': root = Tk() root.withdraw() root.update() filepath = filedialog.askopenfilename() root.destroy() print(basename(filepath)) mydict = read_pickle(filepath) x = mydict['x'] fs = mydict['fs'] best_lvl = mydict['best_lvl'] dt = 1. / fs t = dt * np.arange(len(x)) # x = hilbert_demodulation(x) # magX, f, df = mag_fft(x, fs) # plt.plot(f, magX) # plt.show() segments = 20000. window = 'boxcar' mode = 'magnitude' stftX, f_stft, df_stft, t_stft = shortFFT(x, fs, segments, window, mode) fig, ax = plt.subplots() ax.pcolormesh(t_stft, f_stft, stftX) ax.set_xlabel('Dauer [s]', fontsize=13.5) ax.set_ylabel('Frequenz [Hz]', fontsize=13.5) map = [] vmax = max_cspectrum(stftX) map.append( ax.pcolormesh(t_stft, f_stft / 1000., stftX, cmap='plasma', vmax=None)) cbar = fig.colorbar(map[0], ax=ax) # cbar.set_label('log' + ' ' + ylabel_fft, fontsize=13.5) plt.show() elif config['mode'] == 'test_cwt': # import pywt # import numpy as np # import matplotlib.pyplot as plt # x = np.arange(512) # y = np.sin(2*np.pi*x/32) # coef, freqs=pywt.cwt(y,np.arange(1,129),'gaus1') # plt.matshow(coef) # plt.show() # sys.exit() t = np.linspace(-1, 1, 200, endpoint=False) dt = 0.01 t = np.arange(1000) * dt # sig = np.cos(2 * np.pi * 7 * t) + np.real(np.exp(-7*(t-0.4)**2)*np.exp(1j*2*np.pi*2*(t-0.4))) sig = np.exp(-1 * t) * np.cos(2 * np.pi * 5. * t) X, f, df = mag_fft(sig, 1. / dt) plt.plot(f, X, 'r') plt.show() widths = np.arange(1, 31) mother_wv = 'morl' real_freq = pywt.scale2frequency(mother_wv, widths) / dt print(real_freq) # sampling_period_ = dt. # real_f = scale2frequency(widths, wavelet)/sampling_period cwtmatr, freqs = pywt.cwt(data=sig, scales=widths, wavelet=mother_wv, sampling_period=dt) # print(cwtmatr) # print(freqs) # plt.imshow(cwtmatr, extent=[-1, 1, 1, 31], cmap='PRGn', aspect='auto', vmax=abs(cwtmatr).max(), vmin=-abs(cwtmatr).max()) # plt.imshow(cwtmatr, cmap='PRGn', aspect='auto', vmax=abs(cwtmatr).max(), vmin=-abs(cwtmatr).max()) # print(len(cwtmatr)) # print(len(cwtmatr[0])) # x, y = np.meshgrid(real_freq, t) y = real_freq x = t plt.pcolormesh(x, y, cwtmatr) plt.show() sys.exit() print('Select File with signal') root = Tk() root.withdraw() root.update() filepath = filedialog.askopenfilename() root.destroy() sig = load_signal(filepath, channel=config['channel']) sig = sig[:int(len(sig) / 10)] widths = np.arange(1, 100) cwtmatr, freqs = pywt.cwt(sig, widths, 'morl', sampling_period=5) # plt.imshow(cwtmatr, extent=[-1, 1, 1, 31], cmap='PRGn', aspect='auto', vmax=abs(cwtmatr).max(), vmin=-abs(cwtmatr).max()) # plt.imshow(cwtmatr, cmap='PRGn', aspect='auto', vmax=abs(cwtmatr).max(), vmin=-abs(cwtmatr).max()) plt.pcolormesh(cwtmatr) plt.show() elif config['mode'] == 'test_cwt_2': root = Tk() root.withdraw() root.update() filepath = filedialog.askopenfilename() root.destroy() signal = load_signal(filepath, channel=config['channel']) # tb = 6.571951 #86-s1 # tb = 3.013158 #220-s1 # tb = 5.686372 #134-s1 # tb = 5.416039 #227-s1 # tb = 5.667336 #231-s1 # tb = 5.667336 #231-s1 # tb = 10.687999 #106-s1 # tb = 5.949451 #135-s1 # tb = 7.742351 #187-s1 # tb = 4.51823 #486-b3 # tb = 1.59737 #419-b3 # tb = 10.399886 #555-b3 # tb = 2.442161 #592-b3 # wid = 0.002 # tini = tb - wid/2 # tfin = tb + wid signal = signal[int(0 * config['fs']):int(1 * config['fs'])] # signal = signal[int(0*config['fs']) : int(10*config['fs'])]/70.8*140.25 dt = 1. / config['fs'] t = np.arange(len(signal)) * dt # plt.plot(t*1000*1000, signal) # plt.show() max_width = 50 min_width = 1 widths = np.arange(min_width, max_width) mother_wv = 'morl' real_freq = pywt.scale2frequency(mother_wv, widths) / dt print(real_freq) # sys.exit() cwtmatr, freqs = pywt.cwt(data=signal, scales=widths, wavelet=mother_wv, sampling_period=dt) print(cwtmatr) cwtmatr **= 2 print(cwtmatr) sys.exit() # plt.plot(t, signal) # plt.show() # print(len(cwtmatr)) # print(len(cwtmatr[0])) sum = np.zeros(len(cwtmatr)) for i in range(len(cwtmatr)): print(cwtmatr[i]) print((cwtmatr[i])**2.0) sys.exit() sum[i] = np.sum((cwtmatr[i])**2.0) plt.plot(real_freq, sum) plt.show() # sys.exit() print(cwtmatr[2][2]) cwtmatr = cwtmatr**2.0 cwtmatr = np.absolute(cwtmatr) print(cwtmatr[2][2]) cwtmatr = np.log10(cwtmatr) print(cwtmatr[2][2]) y = real_freq x = t # plt.pcolormesh(t, real_freq, cwtmatr) # extent_ = [0, np.max(t), np.max(real_freq), np.min(real_freq)] # extent_ = None extent_ = [-1, 1, min_width, max_width] colormap_ = 'PRGn' # colormap_ = 'plasma' fig, ax = plt.subplots() maxxx = np.max(cwtmatr) minnn = np.min(cwtmatr) print('maxxx = ', maxxx) print('minnn = ', minnn) levels_ = list(np.linspace(minnn, maxxx, num=100)) # ax.contour(t, real_freq, cwtmatr, levels=levels_) ax.contour(t, real_freq, cwtmatr) ax.set_ylim(bottom=0, top=500000) # ax.imshow(cwtmatr, extent=extent_, cmap=colormap_, aspect='auto', vmax=maxxx, vmin=minnn, interpolation='bilinear') # ax.set_xlim(left=-1 , right=1) # ax.set_ylim(bottom=1 , top=max_width) # plt.imshow(cwtmatr, extent=extent_, cmap=colormap_, aspect='auto', vmax=abs(cwtmatr).max(), vmin=-abs(cwtmatr).max(), interpolation='bilinear') plt.show() elif config['mode'] == 'test_cwt_3': root = Tk() root.withdraw() root.update() filepath = filedialog.askopenfilename() root.destroy() signal = load_signal(filepath, channel=config['channel']) # signal = signal[int(0.1*config['fs']) : int(0.101*config['fs'])] signal = signal[int(0 * config['fs']):int(11 * config['fs'])] dt = 1. / config['fs'] t = np.arange(len(signal)) * dt # plt.plot(signal) # plt.show() # nico = pywt.BaseNode(parent='caca', data=signal, node_name='d', wavelet='morl') nico = pywt.WaveletPacket(data=signal, wavelet='db6', maxlevel=3) # perro = nico.decompose() # caca = nico.get_level(level=3, order='freq', decompose=True) # nico.get_level(level=3, order='freq', decompose=True) # print(caca) # print(len(caca)) # print(caca[0].data) # print(type(caca[0].data)) # sys.exit() # print(caca[3]) # print(caca[0]) # print(caca[1]) # print(caca[2]) # print(caca[3]) # print(caca[4]) # print(caca[5]) plt.plot(nico['dd'].data) plt.show() # print(nico['aaa'].data - caca[0].data) # print(caca[8]) sys.exit() fig, ax = plt.subplots(nrows=4, ncols=1) ax[0].plot(signal, 'k') ax[1].plot(caca[0].data, 'g') ax[2].plot(caca[30].data, 'b') ax[3].plot(caca[60].data, 'r') plt.show() # print(len(perro)) # print(perro[0]) # print(perro[1]) # print(perro[2]) sys.exit() max_width = 201 min_width = 1 widths = np.arange(min_width, max_width) mother_wv = 'morl' real_freq = pywt.scale2frequency(mother_wv, widths) / dt print(real_freq) # sys.exit() cwtmatr, freqs = pywt.cwt(data=signal, scales=widths, wavelet=mother_wv, sampling_period=dt) plt.plot(t, signal) plt.show() print(cwtmatr[2][2]) cwtmatr = cwtmatr**2.0 y = real_freq x = t extent_ = [-1, 1, min_width, max_width] colormap_ = 'PRGn' fig, ax = plt.subplots() levels_ = list(np.linspace(np.min(cwtmatr), np.max(cwtmatr), num=100)) ax.contour(t, real_freq, cwtmatr, levels=levels_) ax.set_ylim(bottom=0, top=500000) plt.show() elif config['mode'] == 'test_wv_packet': root = Tk() root.withdraw() root.update() filepath = filedialog.askopenfilename() root.destroy() signal = load_signal(filepath, channel=config['channel']) signal = signal[int(0 * config['fs']):int(10 * config['fs'])] dt = 1. / config['fs'] t = np.arange(len(signal)) * dt max_level = 5 wavelet_mother = 'db6' nico = pywt.WaveletPacket(data=signal, wavelet=wavelet_mother, maxlevel=max_level) signal = signal * 1000. / 70.8 # signal = signal*1000./141.25 RMS = [] MAX = [] KURT = [] SEN = [] CREST = [] mydict = {} mylevels = ['aaa', 'aad', 'ada', 'add', 'daa', 'dad', 'dda', 'ddd'] for level in mylevels: print(level) mywav = nico[level].data n = len(mywav) value_max = np.max(np.absolute(mywav)) value_rms = signal_rms(mywav) px = ((value_rms)**2.0) * n ent = 0. for i in range(n): # if (mywav[i]**2.0)/px > 1.e-15: ent += ((mywav[i]**2.0) / px) * np.log2((mywav[i]**2.0) / px) ent = -ent MAX.append(value_max) RMS.append(value_rms) CREST.append(value_max / value_rms) KURT.append(scipy.stats.kurtosis(mywav, fisher=False)) SEN.append(ent) mydict['MAX'] = MAX mydict['RMS'] = RMS mydict['CREST'] = CREST mydict['KURT'] = KURT mydict['SEN'] = SEN row_names = mylevels DataFr = pd.DataFrame(data=mydict, index=row_names) writer = pd.ExcelWriter('AE_3_B4-5_' + wavelet_mother + '.xlsx') DataFr.to_excel(writer, sheet_name='OV_Features') print('Result in Excel table') sys.exit() elif config['mode'] == 'test_wv_packet_2': root = Tk() root.withdraw() root.update() filepath = filedialog.askopenfilename() root.destroy() signal = load_signal(filepath, channel=config['channel']) name_out = 'Scgr_S1_AE3_B647_db6_lvl5_mv2.pkl' name_out_2 = 'Wfm_S1_AE3_B647_mv.pkl' #bochum b4c+++++ # tb = 3.230392 #221212 + 286 # tb = 2.548122 #221139 + 28 # tb = 2.338875 #221212 + 270 # tb = 6.941142 #221212 + 326 # tb = 0.147558 #221305 + 485 #schottland s1+++++ # tb = 6.960124 #598-s1 193159 tb = 17.278254 #647-s1 193159 # tb = 2.688736 #13-s1 # tb = 7.091994 #78-s1 193023 # tb = 11.446813 #201s1 193023 # tb = 2.062188 #309-s1 193055 # tb = 2.327338 #313-s1 193055 # tb = 11.173631 #347 s1 193055 #new db6 # tb = 7.091994 #178s1 193023 # tb = 13.737517 #214s1 193023 # tb = 13.995451 #215s1 193023 # tb = 0.117088 #1-s1 # tb = 0.624262 #2-s1 # tb = 14.20754 #220 s1 193023 # tb = 27.77809 #288 s1 193023 ** # tb = 22.572601 #528 s1 193127 * # tb = 6.960124 #598 s1 193159 * # tb = 13.644469 #633 s1 193159 # tb = 24.939845 #298 s1 193055 AE1 # tb = 6.232396 #78 s1 193127 AE2 # tb = 4.76218 #13eq-s1pai 192948 # tb = 8.289245 #95-b4 # tb = 4.50221 #173-b4 # tb = 4.717965 # tb = 4.501416 # tb = 1.39132 # tb = 0.089039 # tb = 1.990012 # tb = 1.030173 # tb = 2.734467 # tb = 3.772609 # tb = 3.876989 # tb = 4.629311 # tb = 4.728805 # tb = 0.290801 # tb = 0.324761 # tb = 3.556317 # tb = 2.904387 # tb = 2.45 # tb = 0.73 # tb = 0.7 # tb = 1.19 # tb = 1.681 # tb = 3.81 wid = 0.002 tini = tb - wid / 2 tfin = tb + wid signal = signal[int(tini * config['fs']):int(tfin * config['fs'])] * 1000. / 70.8 # signal = signal[int(tini*config['fs']) : int(tfin*config['fs'])]*1000./141.25 #bochum n = len(signal) # signal = np.hanning(n)*signal # signal = signal[int(0*config['fs']) : int(10*config['fs'])]*1000./70.28 # signal = signal[int(0*config['fs']) : int(10*config['fs'])]/70.8 # signal = signal[int(0*config['fs']) : int(2*config['fs'])]/140.25 dt = 1. / config['fs'] # t = np.arange(1000000)*dt # signal = np.cos(2*3.14*400000*t) t = np.arange(len(signal)) * dt n = len(signal) plt.plot(signal) plt.show() select_level = 5 wavelet_mother = 'db6' nico = pywt.WaveletPacket(data=signal, wavelet=wavelet_mother, maxlevel=select_level) gato = pywt.WaveletPacket(data=None, wavelet=wavelet_mother, maxlevel=5) # mylevels = ['aaa', 'aad', 'ada', 'add', 'daa', 'dad', 'dda', 'ddd'] mylevels = [node.path for node in nico.get_level(select_level, 'freq')] # freq = np.array([0, 62500, 12500, 187500, 250000, 312500, 375000, 437500]) cwtmatr = [] count = 0 for level in mylevels: # print('++count = ', count) print(level) mywav = nico[level].data xold = np.linspace(0., 1., len(mywav)) xnew = np.linspace(0., 1., n) mywav_int = np.interp(x=xnew, xp=xold, fp=mywav) # print('inverse WV!') # gato[level] = nico[level].data # mywav_int = gato.reconstruct(update=False) cwtmatr.append(mywav_int**2) # count += 1 cwtmatr = np.array(cwtmatr) print(cwtmatr) # sum = np.zeros(len(cwtmatr)) # for i in range(len(cwtmatr)): # sum[i] = np.sum((cwtmatr[i])**2.0) # plt.plot(sum) # plt.show() # mydata = cwtmatr[18] # plt.plot(mydata) # plt.show() # mydata = cwtmatr[47] # plt.plot(mydata) # print(len(mydata)) # plt.show() # gato['dddaaa'] = nico['dddaaa'].data # reco = gato.reconstruct(update=False) # reco = reco[0:n] # plt.plot(reco) # print(len(reco)) # plt.show() fig, ax = plt.subplots() maxxx = np.max(cwtmatr) minnn = np.min(cwtmatr) # levels_ = list(np.linspace(minnn, maxxx, num=100)) # ax.contour(t, real_freq, cwtmatr, levels=levels_) # extent_ = [0, np.max(t), 500, 0] extent_ = [0, np.max(t), 0, 500] ax.contourf(cwtmatr, extent=extent_) # ax.set_ylim(bottom=0 , top=500000) plt.show() mydict = {'map': cwtmatr, 'extent': extent_} save_pickle(name_out, mydict) mydict = {'t': t, 'x': signal} save_pickle(name_out_2, mydict) # 'Scgr_S1_AE3_B201_db6_lvl5_mv2.pkl' sys.exit() # max_width = 101 # min_width = 1 # widths = np.arange(min_width, max_width) # mother_wv = 'morl' # real_freq = pywt.scale2frequency(mother_wv, widths)/dt # print(real_freq) # # sys.exit() # cwtmatr, freqs = pywt.cwt(data=signal, scales=widths, wavelet=mother_wv, sampling_period=dt) # plt.plot(t, signal) # plt.show() # print(len(cwtmatr)) # print(len(cwtmatr[0])) sum = np.zeros(len(cwtmatr)) for i in range(len(cwtmatr)): sum[i] = np.sum((cwtmatr[i])) plt.plot(sum, '-o') plt.show() sys.exit() print(cwtmatr[2][2]) cwtmatr = cwtmatr**2.0 cwtmatr = np.absolute(cwtmatr) print(cwtmatr[2][2]) cwtmatr = np.log10(cwtmatr) print(cwtmatr[2][2]) y = real_freq x = t # plt.pcolormesh(t, real_freq, cwtmatr) # extent_ = [0, np.max(t), np.max(real_freq), np.min(real_freq)] # extent_ = None extent_ = [-1, 1, min_width, max_width] colormap_ = 'PRGn' # colormap_ = 'plasma' # ax.imshow(cwtmatr, extent=extent_, cmap=colormap_, aspect='auto', vmax=maxxx, vmin=minnn, interpolation='bilinear') # ax.set_xlim(left=-1 , right=1) # ax.set_ylim(bottom=1 , top=max_width) # plt.imshow(cwtmatr, extent=extent_, cmap=colormap_, aspect='auto', vmax=abs(cwtmatr).max(), vmin=-abs(cwtmatr).max(), interpolation='bilinear') plt.show() elif config['mode'] == 'wv_packet_full': root = Tk() root.withdraw() root.update() filepath = filedialog.askopenfilename() root.destroy() signal = load_signal(filepath, channel=config['channel']) signal = signal[int(0 * config['fs']):int(0.1 * config['fs'])] dt = 1. / config['fs'] t = np.arange(len(signal)) * dt n = len(signal) select_level = 5 wavelet_mother = 'sym6' nico = pywt.WaveletPacket(data=signal, wavelet=wavelet_mother, maxlevel=select_level) gato = pywt.WaveletPacket(data=None, wavelet=wavelet_mother, maxlevel=5) # mylevels = ['aaa', 'aad', 'ada', 'add', 'daa', 'dad', 'dda', 'ddd'] mylevels = [node.path for node in nico.get_level(select_level, 'freq')] # freq = np.array([0, 62500, 12500, 187500, 250000, 312500, 375000, 437500]) cwtmatr = [] count = 0 for level in mylevels: # print('++count = ', count) print(level) mywav = nico[level].data xold = np.linspace(0., 1., len(mywav)) xnew = np.linspace(0., 1., n) mywav_int = np.interp(x=xnew, xp=xold, fp=mywav) # print('inverse WV!') # gato[level] = nico[level].data # mywav_int = gato.reconstruct(update=False) cwtmatr.append(mywav_int**2) # count += 1 cwtmatr = np.array(cwtmatr) print(cwtmatr) fig, ax = plt.subplots() maxxx = np.max(cwtmatr) minnn = np.min(cwtmatr) # levels_ = list(np.linspace(minnn, maxxx, num=100)) # ax.contour(t, real_freq, cwtmatr, levels=levels_) # extent_ = [0, np.max(t), 500, 0] extent_ = [0, np.max(t), 0, 500] ax.contourf(cwtmatr, extent=extent_) # ax.set_ylim(bottom=0 , top=500000) plt.show() mydict = {'map': cwtmatr, 'extent': extent_} save_pickle('Scgr_simulated_AE_mod_fault_frec.pkl', mydict) sys.exit() # max_width = 101 # min_width = 1 # widths = np.arange(min_width, max_width) # mother_wv = 'morl' # real_freq = pywt.scale2frequency(mother_wv, widths)/dt # print(real_freq) # # sys.exit() # cwtmatr, freqs = pywt.cwt(data=signal, scales=widths, wavelet=mother_wv, sampling_period=dt) # plt.plot(t, signal) # plt.show() # print(len(cwtmatr)) # print(len(cwtmatr[0])) sum = np.zeros(len(cwtmatr)) for i in range(len(cwtmatr)): sum[i] = np.sum((cwtmatr[i])) plt.plot(sum, '-o') plt.show() sys.exit() print(cwtmatr[2][2]) cwtmatr = cwtmatr**2.0 cwtmatr = np.absolute(cwtmatr) print(cwtmatr[2][2]) cwtmatr = np.log10(cwtmatr) print(cwtmatr[2][2]) y = real_freq x = t # plt.pcolormesh(t, real_freq, cwtmatr) # extent_ = [0, np.max(t), np.max(real_freq), np.min(real_freq)] # extent_ = None extent_ = [-1, 1, min_width, max_width] colormap_ = 'PRGn' # colormap_ = 'plasma' # ax.imshow(cwtmatr, extent=extent_, cmap=colormap_, aspect='auto', vmax=maxxx, vmin=minnn, interpolation='bilinear') # ax.set_xlim(left=-1 , right=1) # ax.set_ylim(bottom=1 , top=max_width) # plt.imshow(cwtmatr, extent=extent_, cmap=colormap_, aspect='auto', vmax=abs(cwtmatr).max(), vmin=-abs(cwtmatr).max(), interpolation='bilinear') plt.show() elif config['mode'] == 'wv_packet_energy_freq': root = Tk() root.withdraw() root.update() Filepaths = filedialog.askopenfilenames() root.destroy() select_level = 2 wavelet_mother = 'db6' # Channels = ['AE_1', 'AE_2', 'AE_3'] Channels = [config['channel']] Energy = np.zeros(2**select_level) for channel in Channels: for filepath in Filepaths: # signal = load_signal(filepath, channel=config['channel']) signal = load_signal_varb(filepath, channel=channel) # signal = signal*1000./70.8 # signal = signal[int(0*config['fs']) : int(10*config['fs'])]*1000./70.8 # signal = signal[int(0*config['fs']) : int(10*config['fs'])]*1000./281.8 # signal = signal[int(0*config['fs']) : int(10*config['fs'])]*1000./141.25 dt = 1. / config['fs'] t = np.arange(len(signal)) * dt n = len(signal) nico = pywt.WaveletPacket(data=signal, wavelet=wavelet_mother, maxlevel=select_level) # gato = pywt.WaveletPacket(data=None, wavelet=wavelet_mother, maxlevel=5) # mylevels = ['aaa', 'aad', 'ada', 'add', 'daa', 'dad', 'dda', 'ddd'] mylevels = [ node.path for node in nico.get_level(select_level, 'freq') ] # print(mylevels) # sys.exit() # freq = np.array([0, 62500, 12500, 187500, 250000, 312500, 375000, 437500]) cwtmatr = [] count = 0 for level in mylevels: # print('++count = ', count) print(level) mywav = nico[level].data xold = np.linspace(0., 1., len(mywav)) xnew = np.linspace(0., 1., n) mywav_int = np.interp(x=xnew, xp=xold, fp=mywav) # print('inverse WV!') # gato[level] = nico[level].data # mywav_int = gato.reconstruct(update=False) cwtmatr.append(mywav_int**2) # count += 1 cwtmatr = np.array(cwtmatr) # print(cwtmatr) sum = np.zeros(len(cwtmatr)) for i in range(len(cwtmatr)): sum[i] = np.sum((cwtmatr[i])) Energy += sum myfreq = np.arange( len(mylevels)) * config['fs'] / (2**(1 + select_level)) myfreq += config['fs'] / (2**(2 + select_level)) print(myfreq) mypik = {'energy': Energy, 'freq': myfreq} save_pickle('WPD_Parameter_5_c1_db6_lvl5.pkl', mypik) # plt.plot(myfreq, Energy, '-o') # plt.show() elif config['mode'] == 'select_best': if config['mypath'] == None: print('Select File with signal') root = Tk() root.withdraw() root.update() filepath = filedialog.askopenfilename() root.destroy() else: filepath = [ join(config['mypath'], f) for f in listdir(config['mypath']) if isfile(join(config['mypath'], f)) if f[-4:] == 'tdms' ] x = load_signal(filepath, channel=config['channel']) mother_wv = 'db6' fs = config['fs'] # python M_Wavelet.py --mode select_best --channel AE_0 --fs 1.e6 levels = max_wv_level(x, mother_wv) levels = 5 print('max_levels_', levels) int_freqs = [ 4.33, 8.66, 12.99, 17.32, 21.65, 26.0, 30.33, 34.67, 39.00, 43.33 ] int_freqs2 = [312., 624., 936., 1248., 1560.] int_freqs2 += [ 307.67, 316.33, 303.34, 320.66, 294.68, 329.32, 290.35, 333.65 ] + [619.67, 628.33, 615.34, 632.66, 606.68, 641.32, 602.35, 645.65 ] + [ 931.67, 940.33, 927.34, 944.66, 918.68, 953.32, 914.35, 957.65 ] + [ 1243.67, 1252.33, 1239.34, 1256.66, 1230.68, 1265.32, 1226.35, 1269.35 ] + [ 1555.67, 1564.33, 1551.34, 1568.66, 1542.68, 1577.32, 1538.35, 1581.65 ] int_freqs2 += int_freqs freq_values = int_freqs2 freq_range = list(np.array([3., 1600.])) wsignal, best_lvl, new_fs = return_best_wv_level_idx( x, fs, levels, mother_wv, freq_values, freq_range) print('best_lvl_idx_', best_lvl) print( cal_WV_fitness_hilbert_env_Ncomp_mpr(wsignal, freq_values, freq_range, new_fs)) plt.figure(1) plt.plot(wsignal) plt.figure(2) M, f, df = mag_fft(wsignal, new_fs) plt.plot(f, M, 'r') plt.figure(3) env = hilbert_demodulation(wsignal) ME, f, df = mag_fft(env, new_fs) plt.plot(f, ME, 'g') plt.show() else: print('unknown mode') return
def _plot(self): fig, ax = plt.subplots(nrows=2, ncols=2, sharex=True) amplitude = ax[0][0] # phase = ax[0][1] slide = ax[0][1] conj_amplitude=ax[1][0] time_fre = ax[1][1] while not self.end: t = copy.deepcopy(self.t) amp = copy.deepcopy(self.amp) conj_amp=copy.deepcopy(self.conj_amp) pha = copy.deepcopy(self.pha) # if self.count <= TIMEWINDOW + SLIDEWINDOW: flt = copy.deepcopy(self.amp_filter) # if flt and len(flt) == TIMEWINDOW: # flt = Filter(flt).butterWorth() # else: if len(t) == 0: time.sleep(self.interval) continue if len(t) != len(amp) or len(t) != len(pha): continue max_t = t[-1] + 100 min_t = max_t - TIMEWINDOW if max_t - TIMEWINDOW > 0 else 0 amplitude.cla() amplitude.set_title("amplitude") amplitude.set_xlabel("packet / per") amplitude.set_ylim(0, 50) amplitude.set_xlim(min_t, max_t) amplitude.grid() amplitude.plot(t,np.array(amp)) # amplitude.legend(loc='best') # phase.cla() # phase.set_title("phase") # phase.set_xlabel("packet / per") # phase.set_ylim(-2, 2) # phase.set_xlim(min_t, max_t) # phase.grid() # phase.plot(t, np.array(pha)) slide.cla() slide.set_title("slide") slide.set_xlabel("packet / per") slide.set_ylim(0, 50) slide.set_xlim(min_t, max_t) slide.grid() time_fre.set_title("time_fre") time_fre.set_xlabel("time(s)") time_fre.set_ylim(0, 25) if flt and len(flt) == TIMEWINDOW: slide.plot(t,np.array(flt)) sig=[] for i in range(len(flt)): #to 1 dimension sig.append(flt[i][0]) #print sig fs = 50 totalscale = 256 #t = np.arange(0, 1, 1.0 / fs) #sig = np.sin(2 * math.pi * f1 * t) + np.sin(2 * math.pi * f2 * t) wcf = pywt.central_frequency('morl') scale = np.arange(1, totalscale + 1, 1) cparam = 2 * wcf * totalscale scale = cparam / scale frequencies = pywt.scale2frequency('morl', scale) frequencies = frequencies * fs cwtmatr, freqs = pywt.cwt(sig, scale, 'morl') time_fre.pcolormesh(t, frequencies, abs(cwtmatr), vmax=abs(cwtmatr).max(), vmin=-abs(cwtmatr).max()) #time_fre.colorbar() #time_fre.show() conj_amplitude.cla() conj_amplitude.set_title("conj_amplitude") conj_amplitude.set_xlabel("packet / per") #conj_amplitude.set_ylim(0, 100) conj_amplitude.set_xlim(min_t, max_t) conj_amplitude.grid() conj_amplitude.plot(t, np.array(conj_amp)) plt.pause(self.interval)
# choose your wavelet and plot to examine it w1 = pywt.ContinuousWavelet('cmor1.5-1.0') w2 = pywt.ContinuousWavelet('cmor1.5-50.0') wavelet_function, x_values = w1.wavefun() plt.plot(x_values, wavelet_function) # cmorB-C # scale to frequency: f=center_frequency/(scale*sampling_period), Reverse the calculation to get the desired frequency: # Reverse the calculation: scale=center_frequency/(desired_frequency*sampling_period) scales = [1.0 / (f * sampling_period) for f in np.arange(1, 150, 2) ] # np.arange(1,150,2) is your desired frequencies # verification mwavelet = 'cmor1.5-1.0' frequencies = [ scale2frequency(mwavelet, scale) / sampling_period for scale in scales ] [coefficients, frequencies] = pywt.cwt(chirpdata, scales, mwavelet, sampling_period) power = (abs(coefficients))**2 vmin = -4 vmax = 4 fig, ax = plt.subplots() im0 = ax.imshow(power, origin='lower', cmap='RdBu_r', vmin=vmin, vmax=vmax) ax.set_aspect('auto') # frequency precision decrease as frequency increase # increase bandwidth fb to increase frequency precision mwavelet = 'cmor2.5-1.0' scales = [1.0 / (f * sampling_period) for f in np.arange(1, 150, 2) ] # np.arange(1,150,2) is your desired frequencies
def fastcwt(data, scales, wavelet, sampling_period=1.0, method='auto'): """ Compute the continuous wavelet transform (CWT) and has the same signature as ``pywt.cwt()`` but is faster for large signals length and scales. Parameters ---------- signal : array to compute the CWT on scales: dilatation factors for the CWT wavelet: wavelet name or pywt.ContinuousWavelet method=['auto'] | 'conv' | 'fft' for selecting the convolution method the `'auto'` keyword switch automatically to the best complexity at each scales. While the `'fft'` and `'conv'` uses `numpy.fft` and `numpy.conv` respectively. In practice the `'fft'` method is implemented by using the convolution theorem which states:: convolve(wav,sig) == ifft(fft(wav)*fft(sig)) Zero padding is adjusted to keep at bay circular convolution side effects. Example:: %time (coef1, freq1) = fastcwt(np.arange(140000), np.arange(2,200), 'cmorl1-1') => CPU times: user 12.6 s, sys: 2.2 s, total: 14.8 s => Wall time: 14.9 s %time (coef1, freq1) = pywt.cwt(np.arange(140000), np.arange(2,200), 'cmorl1-1') => CPU times: user 1min 50s, sys: 401 ms, total: 1min 51s => Wall time: 1min 51s """ # accept array_like input; make a copy to ensure a contiguous array data = np.array(data) if not isinstance(wavelet, (pywt.ContinuousWavelet, pywt.Wavelet)): wavelet = pywt.DiscreteContinuousWavelet(wavelet) if np.isscalar(scales): scales = np.array([scales]) dt_out = None # currently keep the 1.0.2 behaviour: TODO fix in/out dtype consistency if data.ndim == 1: if wavelet.complex_cwt: dt_out = complex out = np.zeros((np.size(scales), data.size), dtype=dt_out) precision = 10 int_psi, x = pywt.integrate_wavelet(wavelet, precision=precision) if method in ('auto', 'fft'): # - to be as large as the sum of data length and and maximum wavelet # support to avoid circular convolution effects # - additional padding to reach a power of 2 for CPU-optimal FFT size_pad = lambda s: 2**np.int(np.ceil(np.log2(s[0] + s[1]))) size_scale0 = size_pad( (len(data), np.take(scales, 0) * ((x[-1] - x[0]) + 1))) fft_data = None elif not method == 'conv': raise ValueError("method must be in: 'conv', 'fft' or 'auto'") for i in np.arange(np.size(scales)): step = x[1] - x[0] j = np.floor( np.arange(scales[i] * (x[-1] - x[0]) + 1) / (scales[i] * step)) if np.max(j) >= np.size(int_psi): j = np.delete(j, np.where((j >= np.size(int_psi)))[0]) int_psi_scale = int_psi[j.astype(np.int)][::-1] if method == 'conv': conv = np.convolve(data, int_psi_scale) else: size_scale = size_pad((len(data), len(int_psi_scale))) if size_scale != size_scale0: # the fft of data changes when padding size changes thus # it has to be recomputed fft_data = None size_scale0 = size_scale nops_conv = len(data) * len(int_psi_scale) nops_fft = ( 2 + (fft_data is None)) * size_scale * np.log2(size_scale) if (method == 'fft') or ((method == 'auto') and (nops_fft < nops_conv)): if fft_data is None: fft_data = np.fft.fft(data, size_scale) fft_wav = np.fft.fft(int_psi_scale, size_scale) conv = np.fft.ifft(fft_wav * fft_data) conv = conv[0:len(data) + len(int_psi_scale) - 1] else: conv = np.convolve(data, int_psi_scale) coef = -np.sqrt(scales[i]) * np.diff(conv) if not np.iscomplexobj(out): coef = np.real(coef) d = (coef.size - data.size) / 2. if d > 0: out[i, :] = coef[int(np.floor(d)):int(-np.ceil(d))] elif d == 0.: out[i, :] = coef else: raise ValueError("Selected scale of {} too small.".format( scales[i])) frequencies = pywt.scale2frequency(wavelet, scales, precision) if np.isscalar(frequencies): frequencies = np.array([frequencies]) for i in np.arange(len(frequencies)): frequencies[i] /= sampling_period return out, frequencies else: raise ValueError("Only dim == 1 supported")
def reconstruct(coefs, periods, dt, family): scales = pywt.scale2frequency(family, 1) * periods / dt mwf = pywt.ContinuousWavelet("morl").wavefun() y_0 = mwf[0][np.argmin(np.abs(mwf[1]))] r_sum = np.transpose(np.sum(np.transpose(coefs) / scales**0.5, axis=-1)) return r_sum * (1 / y_0)
def calculate_cwt(self, f_center=None, verbose=False, optimize=False, fit=False): ''' Calculate instantaneous frequency using continuous wavelet transfer wavelet specified in self.wavelet. See PyWavelets CWT documentation Parameters ---------- Optimize : bool, optionals Currently placeholder for iteratively determining wavelet scales ''' # wavlist = pywt.wavelist(kind='continuous') # w0, wavelet_increment, cwt_scale = self.__get_cwt__() # determine if scales will capture the relevant frequency if not f_center: f_center = self.drive_freq dt = 1 / self.sampling_rate sc = pywt.scale2frequency(self.wavelet, self.scales) / dt if self.verbose: print('Wavelet scale from', np.min(sc), 'to', np.max(sc)) if f_center < np.min(sc) or f_center > np.max(sc): raise ValueError('Choose a scale that captures frequency of interest') if optimize: print('!') drive_bin = self.scales[np.searchsorted(sc, f_center)] hi = int(1.2 * drive_bin) lo = int(0.8 * drive_bin) self.scales = np.arange(hi, lo, -0.1) spectrogram, freq = pywt.cwt(self.signal, self.scales, self.wavelet, sampling_period=dt) if not fit: inst_freq, amplitude, _ = parab.ridge_finder(np.abs(spectrogram), np.arange(len(freq))) # slow serial curve fitting else: inst_freq = np.zeros(self.n_points) amplitude = np.zeros(self.n_points) for c in range(spectrogram.shape[1]): SIG = spectrogram[:, c] if fit: pk = np.argmax(np.abs(SIG)) popt = np.polyfit(np.arange(20), np.abs(SIG[pk - 10:pk + 10]), 2) inst_freq[c] = -0.5 * popt[1] / popt[0] amplitude[c] = np.abs(SIG)[pk] # rescale to correct frequency inst_freq = pywt.scale2frequency(self.wavelet, inst_freq + self.scales[0]) / dt phase = spg.cumtrapz(inst_freq) phase = np.append(phase, phase[-1]) tidx = int(self.tidx * len(inst_freq) / self.n_points) self.amplitude = amplitude self.inst_freq_raw = inst_freq self.inst_freq = -1 * (inst_freq - inst_freq[tidx]) # -1 due to way scales are ordered self.spectrogram = np.abs(spectrogram) self.wavelet_freq = freq # the wavelet frequencies # subtract the w*t line (drive frequency line) from phase start = int(0.3 * tidx) end = int(0.7 * tidx) xfit = np.polyfit(np.arange(start, end), phase[start:end], 1) phase -= (xfit[0] * np.arange(len(inst_freq))) + xfit[1] self.phase = phase return
plt.subplot(2, 1, 2) plt.plot(f[(f >= 4) & (f <= 40)], Pxx[(f >= 4) & (f <= 40)]) plt.show() #%%analisis usando wavelet continuo import pywt #1.1.1 #%% sampling_period = 1 / fs Frequency_Band = [4, 30] # Banda de frecuencia a analizar # Métodos de obtener las escalas para el Complex Morlet Wavelet # Método 1: # Determinar las frecuencias respectivas para una escalas definidas scales = np.arange(1, 250) frequencies = pywt.scale2frequency('cmor', scales) / sampling_period # Extraer las escalas correspondientes a la banda de frecuencia a analizar scales = scales[(frequencies >= Frequency_Band[0]) & (frequencies <= Frequency_Band[1])] #%% # Obtener el tiempo correspondiente a una epoca de la señal (en segundos) time_epoch = sampling_period * N # Analizar una epoca de un montaje (con las escalas del método 1) # Obtener el vector de tiempo adecuado para una epoca de un montaje de la señal time = np.arange(0, time_epoch, sampling_period) # Para la primera epoca del segundo montaje calcular la transformada continua de Wavelet, usando Complex Morlet Wavelet [coef, freqs] = pywt.cwt(anestesia, scales, 'cmor', sampling_period) # Calcular la potencia power = (np.abs(coef))**2
short_df = df.iloc[:n_days*s_day, :].dropna() print (short_df.shape) # In[6]: sampling_period = 1/60# time difference btw two consecutive samples; inverse of sampling frequency dt = sampling_period# e.g., 100 Hz sampling. 1 sample per second --> 1 Hz wavelet = 'cmor1.5-1.0' scales = range(1,1440)#[60, 120, 360, 720, 1440]# Reasonable choices? Does 1440 correspond to the daily rhythm? signal='temperature' #ok this is the column you are choosing from your data frame # This function converts from scale domain to frequency domain. Higher scale is lower frequency f = pywt.scale2frequency(wavelet, scales)/sampling_period# f is hertz when sampling_period in seconds print ('Frequencies: {}\n'.format(f)) print ('Nyquist limit = {}\n'.format(dt/4))# Per conversation with Adam Rao coeff, freq = pywt.cwt(df[signal], scales, wavelet, dt) #used to say df[signal] print (len(coeff[0]), len(freq)) power = abs(coeff)**2 power[:5] # In[8]: # Using Ahmet's Wavelet Code # http://ataspinar.com/2018/12/21/a-guide-for-using-the-wavelet-transform-in-machine-learning/
def changey(temp, position): sampling_period = 3600 freq = pywt.scale2frequency('morl', temp + 1) / sampling_period freq = freq freq = '%.2e' % freq return freq
def test_scal2frq_scale(): scale = 2 w = pywt.Wavelet('db1') expected = 1. / scale result = pywt.scale2frequency(w, scale, precision=12) assert_almost_equal(result, expected, decimal=3)