def Wavelet_Spectrum_WS(data,sampling_time,year,wavelet='cmor0.7-1.5'): dt = 1/sampling_time time = np.arange(len(data))*dt data.fillna(method='ffill',inplace=True) signal = data['WS95'].copy() - data['WS95'].mean() scales = np.logspace(0, 5, num=350, dtype=np.int32) fig, (ax) = plt.subplots(1, 1,figsize=(18,8)) scg.cws(time,signal, scales,clim=(0,50), cbar= 'horizontal',cmap='inferno',cbarlabel='Amplitude (absCWT)', cbarkw={'aspect':45, 'pad':0.15,'shrink':0.5, 'fraction':0.05,'ticks':[0,10,20,30,40,50]}, ylabel="Period [hour]", xlabel='minute',yscale='log',ax=ax) y_tic = [1,2,4,8,12,16,24,32,64,128] ax.set_yticks(y_tic) ax.set_yticklabels(y_tic) m_day = [0,31,28,31,30,31,30,31,31,30,31,30] x_tic = np.array(m_day)*24 x_tic2 = x_tic.copy() for i in range(len(x_tic)): x_tic2[i] = int(x_tic[i] + x_tic[:i].sum()) base = data['DateTime'].iloc[0] mon = ['01','02','03','04','05','06','07','08','09','10','11','12'] arr=np.array(["{}-{}".format(base.year,mon[i]) for i in range(len(mon))]) ax.set_xticks(x_tic2) ax.set_xticklabels(arr) ax.set_ylim(1,y_tic[-1]) ax.tick_params(axis="x", labelsize=18) ax.tick_params(axis="y", labelsize=18) ax.set_ylabel("Period [hour]",size=20) ax.set_xlabel("Time [month]",size=18) ax.set_title("Contunuous Wavelet Transform of Wind Speed ({})".format(year),size=20) plt.show()
def generate_spectral_analysis(ecg_data: list, start: int, end: int, classif: str = 'NA', spectrum_max_hz: int = 40, fs: int = 1_000): fig, (ax0, ax1, ax2) = plt.subplots(3, 1, figsize=(8, 4), sharex=True) fig.subplots_adjust(hspace=.01) # ax0 ax0.plot(np.arange(0, len(ecg_data)), ecg_data, linewidth=1) ax0.axis('off') # ax2 f, t, Sxx = signal.spectrogram( ecg_data, fs, # window=('tukey', 0.1), # nperseg=150) window=('tukey', 0.1), nperseg=int(round(fs / 4, 0))) ax1.pcolormesh(t * fs, -f, Sxx, shading='flat') ax1.set_ylim(-spectrum_max_hz) ax1.set_ylabel('Hz (inv)') # ax1 scg.set_default_wavelet('morl') signal_length = spectrum_max_hz # range of scales to perform the transform scales = scg.periods2scales(np.arange(1, signal_length + 1)) # the scaleogram # sampling_ratio = 4 # sample_ecg = [] # for element in range(int(round(len(ecg_data)/sampling_ratio, 0))): # sample_ecg.append(np.mean(ecg_data[sampling_ratio * element: # sampling_ratio * element + # sampling_ratio])) scg.cws(ecg_data, scales=scales, figsize=(10, 2.0), coi=False, ylabel="Hz", xlabel='Frame', ax=ax2, cbar=None, title='') fig.suptitle( 'spectrum frequency from frame {} to {} - classif : {}'.format( start, end, classif), fontsize=10) st.pyplot(fig)
def plot_sensors_cwt(data_seg, n_periods, wavelet, figsize=(12, 32)): f, axs = plt.subplots(10, 2, figsize=figsize, constrained_layout=True, sharex=True) periods = np.arange(1, n_periods) scales = scaleogram.periods2scales(periods) time = data_seg.reset_index()['index'].values for ax, case in zip(axs, data_seg.columns): sensor_number = case.split("_")[-1] ax[0].set_title(f'Time series: sensor:{sensor_number}') ax[0].plot(data_seg[case].values, marker='o', ls='-', ms=0.05, alpha=0.5) ax[1] = scaleogram.cws(time=time, wavelet=wavelet, scales=scales, signal=data_seg[case].values, coikw={"alpha": 0.9}, ax=ax[1]) ax[1].set_title(f'CWT: sensor:{sensor_number}: wavelet: {wavelet}') plt.show()
def wavelets(time, flux): """Using morlet wavelet from scaleogram package to determine period. Values are plotted on a 2-D contour map, and then transformed into a 1-D plot. Args: time (List): Time values from processed data file. flux (List): Flux values from processed data file. """ flux = flux / np.median(flux) - 1 flux = flux / np.std(np.diff(flux)) # Convert time to np array for scaleogram. time = np.asarray(time) # Spacing in time values for computing transform dt = time[1] - time[0] scales = scg.periods2scales(np.arange(1, len(time))) scg.set_default_wavelet('cmor2-2.0') wavelet = scg.get_default_wavelet ax2 = scg.cws(time, flux, scales=scales, coikw={ 'alpha': 0.5, 'hatch': '/' }) plt.show() # Same code in scaleogram package, used to visualize 1-D version of the data. coeff, scales_freq = scg.fastcwt(flux, scales, 'cmor2-2.0', dt) # Sum all of the x values pertaining to each period value. period_sum = [] for idx, arr in enumerate(coeff): period_sum.append(np.sum(np.abs(arr))) # Period values from the fastcwt function. transformed_time = 1. / scales_freq output.plot_graph(transformed_time, period_sum, "Period", "Sum per Period", "Wavelet Transformation - 1-D")
yticks = 2**np.arange(np.ceil(np.log2(period.min())), np.ceil(np.log2(period.max()))) ax.set_yticks(np.log2(yticks)) ax.set_yticklabels(yticks) ax.invert_yaxis() ylim = ax.get_ylim() ax.set_ylim(ylim[0], -1) cbar_ax = fig.add_axes([0.95, 0.5, 0.03, 0.25]) fig.colorbar(im, cax=cbar_ax, orientation="vertical") plt.show() #PLOT SPECTROGRAM fig, ax = plt.subplots(figsize=(10, 10)) plot_spectrogram(ax=ax, time=time, signal=elnino) plt.show() #PLOT HIGHER RESOLUTION SCALEOGRAM USING SCALEOGRAM PACKAGE scales = np.logspace(1, 2.4, num=200, dtype=np.int32) #scales = np.arange(4,400,8) #For a coarser decomp (adjust last param to change resolution) ax = scg.cws(time, elnino, scales, figsize=(14, 7), ylabel="Period [Years]", xlabel='Year', yscale='log') ticks = ax.set_yticks([2, 4, 8, 16, 32]) ticks = ax.set_yticklabels([2, 4, 8, 16, 32])
fs = 1024 window = 2 * fs (f0, f1, f2) = fs / 16, fs / 64, fs / 4 p1, p2 = 1 / f1, 1 / f2 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 x = np.arange(window) wavelet = 'cmor0.5-1' plt.close('all') fig, axs = plt.subplots(2, gridspec_kw={'height_ratios': [1, 3]}) axs[0].plot(y) scg.cws(x, y, scales=np.arange(1, 150), wavelet=wavelet, ax=axs[1]) fig.tight_layout() txt = ax2.annotate("p1=%ds" % p1, xy=(n / 2, p1), xytext=(n / 2 - 10, p1), bbox=dict(boxstyle="round4", fc="w")) txt = ax2.annotate("p2=%ds" % p2, xy=(n / 2, p2), xytext=(n / 2 - 10, p2), bbox=dict(boxstyle="round4", fc="w")) #%% from scipy import signal plt.close('all') fs = 1024 f0 = fs / 16
def pre_process_cwt(onsets_images_dir, non_onsets_images_dir, audio_files, ann_files): # onsets_images_dir = join('dataset_transformed', 'train')# , 'onsets') # non_onsets_images_dir = join('dataset_transformed', 'train')# , 'non-onsets') onsets_images_dir = 'dataset_transformed' non_onsets_images_dir = 'dataset_transformed' dataset_dir = 'dataset' audio_files = list_audio_files(dataset_dir) ann_files = list_annotation_files(dataset_dir) frame_size = 1024 sample_rate = 44100 t = frame_size / sample_rate # t = 0.09287981859410431 # seconds for frame_size = 4096 time = np.arange(frame_size, dtype=np.float16) scales = np.arange(1,81) # scaleogram with 80 rows print(f'There are {str(len(audio_files))} audio files and {str(len(ann_files))} annotation files') i = 0 for audio_file in audio_files: file_name = basename(audio_file) print(f'Pre-processing file {str(i+1)}/{str(len(audio_files))}: {file_name}') # Read audio file sig = Signal(audio_file, sample_rate, num_channels = 1) # Split audio signal into frames of same size frames = FramedSignal(sig, frame_size, hop_size = frame_size) print(f'There are {str(len(frames))} frames') # Read onset annotations for current audio file onset_file = ann_files[i] onsets = np.loadtxt(onset_file) print(f'Onsets read from {onset_file}') number_of_onsets = len(onsets) print(f'There are {str(number_of_onsets)} onsets') # Check if we already generated the correct amount of frames for that file before matching_files = glob.glob('dataset_transformed/' + '*'+ file_name + '*') if len(matching_files) > 0: if len(frames) == len(matching_files): print(f'Skipping file {str(i)}/{str(len(audio_files))}: {file_name}') i += 1 continue start = 0 end = t f = 0 onsets_found_this_file = 0 for frame in frames: # Plot frame # plt.plot(frame) # plt.show() # Check if contains onset start = f * t end = start + t f += 1 hasOnset = False for onset in onsets: if start <= onset and end >= onset: hasOnset = True onsets_found_this_file += 1 if hasOnset: print(f'There is an onset within the range: {str(start)} to {str(end)} ms') else: print(f'There are no onsets within the range: {str(start)} to {str(end)} ms') # Apply CWT cwt = scg.CWT(time, frame, scales, wavelet='cmor1.5-1.0') # print(cwt.coefs.shape) # Get scaleogram ax = scg.cws(cwt, yaxis = 'frequency', wavelet = 'cmor1.5-1.0', cbar = None, coi = False) # ['cgau1 :\tComplex Gaussian wavelets', 'cgau2 :\tComplex Gaussian wavelets', # 'cgau3 :\tComplex Gaussian wavelets', 'cgau4 :\tComplex Gaussian wavelets', # 'cgau5 :\tComplex Gaussian wavelets', 'cgau6 :\tComplex Gaussian wavelets', # 'cgau7 :\tComplex Gaussian wavelets', 'cgau8 :\tComplex Gaussian wavelets', # 'cmor1.5-1.0 :\tComplex Morlet wavelets', 'fbsp1-1.5-1.0 :\tFrequency B-Spline wavelets', # 'gaus1 :\tGaussian', 'gaus2 :\tGaussian', 'gaus3 :\tGaussian', 'gaus4 :\tGaussian', # 'gaus5 :\tGaussian', 'gaus6 :\tGaussian', 'gaus7 :\tGaussian', 'gaus8 :\tGaussian', # 'mexh :\tMexican hat wavelet', 'morl :\tMorlet wavelet', 'shan1.5-1.0 :\tShannon wavelets'] # Remove axis from image plt.subplots_adjust(bottom = 0, top = 1, left = 0, right = 1) # plt.show() # Get image from matplot and process it fig = plt.gcf() plot_img_np = get_img_from_fig(fig) image = Image.fromarray(plot_img_np).convert('RGB').resize((15,80)) # TODO try PIL.Image.LANCZOS # Save image label = '1' if hasOnset == True else '0' image.save(join(onsets_images_dir, f'{label}-{file_name}-F{str(f)}.png')) plt.close() if number_of_onsets != onsets_found_this_file: print(f'It was supposed to have {str(number_of_onsets)} onsets. Found {str(onsets_found_this_file)} instead. Exiting...') exit() i += 1
# Wavelet attempt wl_rise_data = rolling_rise_mean.dropna() wl_rise_time = rise_panda.time[wl_rise_data.index].to_numpy() wl_rise_data = wl_rise_data.to_numpy() wl_rise_data_norm = wl_rise_data-wl_rise_data.mean() # choose default wavelet function for the entire notebook scg.set_default_wavelet('cmor1.5-1.0') if testing == True: fig1, axs = plt.subplots(2, figsize=(20,12)); lines = axs[0].plot(wl_rise_time, wl_rise_data); axs[0].set(xlabel='time', ylabel='detrended and norm width of jet [km]') scales = scg.periods2scales(np.arange(1, 120)) scg.cws(wl_rise_time, wl_rise_data_norm, scales=scales, ax=axs[1]) scg.cws(wl_rise_time, wl_rise_data_norm, ax=axs[1], yscale='linear', cbar='horizontal'); plt.tight_layout() plt.show() wl_fall_data = rolling_fall_mean.dropna() wl_fall_time = fall_panda.time[wl_fall_data.index].to_numpy() wl_fall_time = wl_fall_time-wl_fall_time[0] wl_fall_data = wl_fall_data.to_numpy() wl_fall_data_norm = wl_fall_data-wl_fall_data.mean() # choose default wavelet function forlen() the entire notebook if testing == True: fig1, axs = plt.subplots(2, figsize=(20,12)); lines = axs[0].plot(wl_fall_time, wl_fall_data);
if st.checkbox('Show raw data'): st.subheader('Raw data') st.write(data) st.subheader(f"ECG record : {chosen_record}") st.line_chart(data) if samptovalue - sampfromvalue > 2000: st.text('No scaleogram range to long') else: # choose default wavelet function scg.set_default_wavelet('morl') signal_length = samptovalue - sampfromvalue # range of scales to perform the transform scales = scg.periods2scales(np.arange(1, signal_length + 1)) x_values_wvt_arr = range(0, len(data), 1) # the scaleogram fig = scg.cws(data, scales=scales, figsize=(10, 4.0), coi=False, ylabel="Period", xlabel="Time") #st.plotly_chart(scal) #coeff, freq = pywt.cwt(data, 500 , 'morl', 1) st.pyplot(fig.figure)