def plot_cwt_spectrogram(self, canvas: MatplotlibCanvas): tr = ObspyUtil.get_tracer_from_file(self.file_selector.file_path) ts, te = self.get_time_window() tr.trim(starttime=ts, endtime=te) tr.detrend(type="demean") fs = tr.stats.sampling_rate f_min = 1. / self.spectrum_box.win_bind.value if self.filter.min_freq == 0 else self.filter.min_freq f_max = self.filter.max_freq ObspyUtil.filter_trace(tr, self.filter.filter_value, f_min, f_max) nf = 40 tt = int(self.spectrum_box.win_bind.value * self.tracer_stats.Sampling_rate) wmin = self.spectrum_box.w1_bind.value wmax = self.spectrum_box.w2_bind.value npts = len(tr.data) [ba, nConv, frex, half_wave] = ccwt_ba_fast(npts, self.tracer_stats.Sampling_rate, f_min, f_max, wmin, wmax, tt, nf) cf, sc, scalogram = cwt_fast(tr.data, ba, nConv, frex, half_wave, fs) #scalogram = ccwt(tr.data, self.tracer_stats.Sampling_rate, f_min, f_max, wmin, wmax, tt, nf) scalogram = np.abs(scalogram)**2 t = np.linspace(0, self.tracer_stats.Delta * npts, npts) scalogram2 = 10 * (np.log10(scalogram / np.max(scalogram))) x, y = np.meshgrid(t, np.linspace(f_min, f_max, scalogram2.shape[0])) max_cwt = np.max(scalogram2) min_cwt = np.min(scalogram2) canvas.plot(t[0:len(t) - 1], cf, 0, clear_plot=False, is_twinx=True, color="red", linewidth=0.5) norm = Normalize(vmin=min_cwt, vmax=max_cwt) canvas.plot_contour(x, y, scalogram2, axes_index=1, clabel="Power [dB]", levels=100, cmap=plt.get_cmap("jet"), norm=norm) canvas.set_xlabel(1, "Time (s)")
def plot_mt_spectrogram(self, canvas: MatplotlibCanvas): win = int(self.spectrum_box.win_bind.value * self.tracer_stats.Sampling_rate) tbp = self.spectrum_box.tw_bind.value ntapers = self.spectrum_box.ntapers_bind.value f_min = self.filter.min_freq f_max = self.filter.max_freq ts, te = self.get_time_window() mtspectrogram = MTspectrogram(self.file_selector.file_path, win, tbp, ntapers, f_min, f_max) x, y, log_spectrogram = mtspectrogram.compute_spectrogram( start_time=ts, end_time=te, trace_filter=self.filter.filter_value) canvas.plot_contour(x, y, log_spectrogram, axes_index=1, clabel="Power [dB]", cmap=plt.get_cmap("jet")) canvas.set_xlabel(1, "Time (s)")
class TimeFrequencyFrame(BaseFrame, UiTimeFrequencyFrame): def __init__(self): super(TimeFrequencyFrame, self).__init__() self.setupUi(self) self.__stations_dir = None self.__metadata_manager = None self.inventory = {} self._stations_info = {} self.tr1 = [] self.tr2 = [] self.canvas_plot1 = MatplotlibCanvas(self.widget_plot_up, nrows=2) # self.canvas_plot1.set_xlabel(1, "Time (s)") # self.canvas_plot1.set_ylabel(0, "Amplitude ") # self.canvas_plot1.set_ylabel(1, "Frequency (Hz)") self.canvas_plot2 = MatplotlibCanvas(self.widget_plot_down, nrows=2) # self.canvas_plot2.set_xlabel(1, "Time (s)") # self.canvas_plot2.set_ylabel(0, "Amplitude ") # self.canvas_plot2.set_ylabel(1, "Frequency (Hz)") # Binding self.canvas_plot1.mpl_connect('key_press_event', self.key_pressed) self.canvas_plot2.mpl_connect('key_press_event', self.key_pressed) self.root_path_bind = BindPyqtObject(self.rootPathForm, self.onChange_root_path) self.dataless_path_bind = BindPyqtObject(self.datalessPathForm) self.metadata_path_bind = BindPyqtObject(self.datalessPathForm, self.onChange_metadata_path) # Add file selector to the widget self.file_selector = FilesView( self.root_path_bind.value, parent=self.fileSelectorWidget, on_change_file_callback=lambda file_path: self.onChange_file( file_path)) # Binds self.selectDirBtn.clicked.connect( lambda: self.on_click_select_directory(self.root_path_bind)) self.datalessBtn.clicked.connect( lambda: self.on_click_select_file(self.dataless_path_bind)) # Action Buttons self.actionSettings.triggered.connect( lambda: self.open_parameters_settings()) self.actionOpen_Help.triggered.connect(lambda: self.open_help()) self.actionOpen_Spectral_Analysis.triggered.connect( self.time_frequency_advance) self.plotBtn.clicked.connect(self.plot_seismogram) self.stationsBtn.clicked.connect(self.stations_info) # help Documentation self.help = HelpDoc() # Parameters settings self.parameters = ParametersSettings() # Time Frequency Advance #self.time_frequency_advance = TimeFrequencyAdvance() def filter_error_message(self, msg): md = MessageDialog(self) md.set_info_message(msg) def message_dataless_not_found(self): if len(self.dataless_not_found) > 1: md = MessageDialog(self) md.set_info_message("Metadata not found.") else: for file in self.dataless_not_found: md = MessageDialog(self) md.set_info_message("Metadata for {} not found.".format(file)) self.dataless_not_found.clear() def open_parameters_settings(self): self.parameters.show() def time_frequency_advance(self): self._time_frequency_advance = TimeFrequencyAdvance(self.tr1, self.tr2) self._time_frequency_advance.show() def validate_file(self): if not MseedUtil.is_valid_mseed(self.file_selector.file_path): msg = "The file {} is not a valid mseed. Please, choose a valid format". \ format(self.file_selector.file_name) raise InvalidFile(msg) def onChange_root_path(self, value): """ Fired every time the root_path is changed :param value: The path of the new directory. :return: """ self.file_selector.set_new_rootPath(value) def onChange_file(self, file_path): # Called every time user select a different file pass def on_click_select_directory(self, bind: BindPyqtObject): if "darwin" == platform: dir_path = pw.QFileDialog.getExistingDirectory( self, 'Select Directory', bind.value) else: dir_path = pw.QFileDialog.getExistingDirectory( self, 'Select Directory', bind.value, pw.QFileDialog.DontUseNativeDialog) if dir_path: bind.value = dir_path def on_click_select_file(self, bind: BindPyqtObject): selected = pw.QFileDialog.getOpenFileName(self, "Select metadata file") if isinstance(selected[0], str) and os.path.isfile(selected[0]): bind.value = selected[0] def onChange_metadata_path(self, value): md = MessageDialog(self) try: self.__metadata_manager = MetadataManager(value) self.inventory = self.__metadata_manager.get_inventory() md.set_info_message( "Loaded Metadata, please check your terminal for further details" ) except: md.set_error_message( "Something went wrong. Please check your metada file is a correct one" ) @property def trace(self): return ObspyUtil.get_tracer_from_file(self.file_selector.file_path) def get_data(self): file = self.file_selector.file_path starttime = convert_qdatetime_utcdatetime(self.starttime_date) endtime = convert_qdatetime_utcdatetime(self.endtime_date) diff = endtime - starttime parameters = self.parameters.getParameters() sd = SeismogramDataAdvanced(file) if self.trimCB.isChecked() and diff >= 0: tr = sd.get_waveform_advanced( parameters, self.inventory, filter_error_callback=self.filter_error_message, start_time=starttime, end_time=endtime) else: tr = sd.get_waveform_advanced( parameters, self.inventory, filter_error_callback=self.filter_error_message) t = tr.times() return tr, t def get_time_window(self): t1 = convert_qdatetime_utcdatetime(self.starttime_date) t2 = convert_qdatetime_utcdatetime(self.endtime_date) return t1, t2 def stations_info(self): obsfiles = MseedUtil.get_mseed_files(self.root_path_bind.value) obsfiles.sort() sd = [] for file in obsfiles: st = SeismogramDataAdvanced(file) station = [ st.stats.Network, st.stats.Station, st.stats.Location, st.stats.Channel, st.stats.StartTime, st.stats.EndTime, st.stats.Sampling_rate, st.stats.Npts ] sd.append(station) self._stations_info = StationsInfo(sd, check=False) self._stations_info.show() def plot_seismogram(self): selection = self.selectCB.currentText() if selection == "Seismogram 1": #self.validate_file() [self.tr1, t] = self.get_data() self.canvas_plot1.plot(t, self.tr1.data, 0, clear_plot=True, color="black", linewidth=0.5) self.canvas_plot1.set_xlabel(1, "Time (s)") self.canvas_plot1.set_ylabel(0, "Amplitude ") self.canvas_plot1.set_ylabel(1, "Frequency (Hz)") info = "{}.{}.{}".format(self.tr1.stats.network, self.tr1.stats.station, self.tr1.stats.channel) self.canvas_plot1.set_plot_label(0, info) if self.time_frequencyChB.isChecked(): self.time_frequency(self.tr1, selection) if selection == "Seismogram 2": #self.validate_file() [self.tr2, t] = self.get_data() self.canvas_plot2.plot(t, self.tr2.data, 0, clear_plot=True, color="black", linewidth=0.5) self.canvas_plot2.set_xlabel(1, "Time (s)") self.canvas_plot2.set_ylabel(0, "Amplitude ") self.canvas_plot2.set_ylabel(1, "Frequency (Hz)") info = "{}.{}.{}".format(self.tr2.stats.network, self.tr2.stats.station, self.tr2.stats.channel) self.canvas_plot2.set_plot_label(0, info) if self.time_frequencyChB.isChecked(): self.time_frequency(self.tr2, selection) @AsycTime.run_async() def time_frequency(self, tr, order): selection = self.time_frequencyCB.currentText() ts, te = self.get_time_window() diff = te - ts if selection == "Multitaper Spectrogram": win = int(self.mt_window_lengthDB.value() * tr.stats.sampling_rate) tbp = self.time_bandwidth_DB.value() ntapers = self.number_tapers_mtSB.value() f_min = self.freq_min_mtDB.value() f_max = self.freq_max_mtDB.value() mtspectrogram = MTspectrogram(self.file_selector.file_path, win, tbp, ntapers, f_min, f_max) if self.trimCB.isChecked() and diff >= 0: x, y, log_spectrogram = mtspectrogram.compute_spectrogram( tr, start_time=ts, end_time=te) else: x, y, log_spectrogram = mtspectrogram.compute_spectrogram(tr) log_spectrogram = np.clip(log_spectrogram, a_min=self.minlevelCB.value(), a_max=0) min_log_spectrogram = self.minlevelCB.value() max_log_spectrogram = 0 if order == "Seismogram 1": if self.typeCB.currentText() == 'contourf': self.canvas_plot1.plot_contour(x, y, log_spectrogram, axes_index=1, clabel="Power [dB]", cmap=plt.get_cmap("jet"), vmin=min_log_spectrogram, vmax=max_log_spectrogram) elif self.typeCB.currentText() == 'pcolormesh': print("plotting pcolormesh") self.canvas_plot1.pcolormesh(x, y, log_spectrogram, axes_index=1, clabel="Power [dB]", cmap=plt.get_cmap("jet"), vmin=min_log_spectrogram, vmax=max_log_spectrogram) self.canvas_plot1.set_xlabel(1, "Time (s)") self.canvas_plot1.set_ylabel(0, "Amplitude ") self.canvas_plot1.set_ylabel(1, "Frequency (Hz)") elif order == "Seismogram 2": if self.typeCB.currentText() == 'contourf': self.canvas_plot2.plot_contour(x, y, log_spectrogram, axes_index=1, clear_plot=True, clabel="Power [dB]", cmap=plt.get_cmap("jet"), vmin=min_log_spectrogram, vmax=max_log_spectrogram) elif self.typeCB.currentText() == 'pcolormesh': self.canvas_plot2.pcolormesh(x, y, log_spectrogram, axes_index=1, clear_plot=True, clabel="Power [dB]", cmap=plt.get_cmap("jet"), vmin=min_log_spectrogram, vmax=max_log_spectrogram) self.canvas_plot2.set_xlabel(1, "Time (s)") self.canvas_plot2.set_ylabel(0, "Amplitude ") self.canvas_plot2.set_ylabel(1, "Frequency (Hz)") elif selection == "Wigner Spectrogram": win = int(self.mt_window_lengthDB.value() * tr.stats.sampling_rate) tbp = self.time_bandwidth_DB.value() ntapers = self.number_tapers_mtSB.value() f_min = self.freq_min_mtDB.value() f_max = self.freq_max_mtDB.value() wignerspec = WignerVille(self.file_selector.file_path, win, tbp, ntapers, f_min, f_max) if self.trimCB.isChecked() and diff >= 0: x, y, log_spectrogram = wignerspec.compute_wigner_spectrogram( tr, start_time=ts, end_time=te) else: x, y, log_spectrogram = wignerspec.compute_wigner_spectrogram( tr) if order == "Seismogram 1": if self.typeCB.currentText() == 'contourf': self.canvas_plot1.plot_contour(x, y, log_spectrogram, axes_index=1, clear_plot=True, clabel="Rel Power ", cmap=plt.get_cmap("jet")) elif self.typeCB.currentText() == 'pcolormesh': self.canvas_plot1.pcolormesh(x, y, log_spectrogram, axes_index=1, clear_plot=True, clabel="Rel Power ", cmap=plt.get_cmap("jet")) self.canvas_plot1.set_xlabel(1, "Time (s)") self.canvas_plot1.set_ylabel(0, "Amplitude ") self.canvas_plot1.set_ylabel(1, "Frequency (Hz)") elif order == "Seismogram 2": if self.typeCB.currentText() == 'contourf': self.canvas_plot2.plot_contour(x, y, log_spectrogram, axes_index=1, clear_plot=True, clabel="Power [dB]", cmap=plt.get_cmap("jet")) elif self.typeCB.currentText() == 'pcolormesh': self.canvas_plot2.pcolormesh(x, y, log_spectrogram, axes_index=1, clear_plot=True, clabel="Power [dB]", cmap=plt.get_cmap("jet")) self.canvas_plot2.set_xlabel(1, "Time (s)") self.canvas_plot2.set_ylabel(0, "Amplitude ") self.canvas_plot2.set_ylabel(1, "Frequency (Hz)") elif selection == "Continuous Wavelet Transform": fs = tr.stats.sampling_rate nf = self.atomsSB.value() f_min = self.freq_min_cwtDB.value() f_max = self.freq_max_cwtDB.value() wmin = self.wminSB.value() wmax = self.wminSB.value() #tt = int( self.wavelet_lenghtDB.value()*fs) npts = len(tr.data) t = np.linspace(0, tr.stats.delta * npts, npts) #cw = ConvolveWaveletScipy(self.file_selector.file_path) cw = ConvolveWaveletScipy(tr) wavelet = self.wavelet_typeCB.currentText() m = self.wavelets_param.value() if self.trimCB.isChecked() and diff >= 0: cw.setup_wavelet(ts, te, wmin=wmin, wmax=wmax, tt=int(fs / f_min), fmin=f_min, fmax=f_max, nf=nf, use_wavelet=wavelet, m=m, decimate=False) else: cw.setup_wavelet(wmin=wmin, wmax=wmax, tt=int(fs / f_min), fmin=f_min, fmax=f_max, nf=nf, use_wavelet=wavelet, m=m, decimate=False) scalogram2 = cw.scalogram_in_dbs() scalogram2 = np.clip(scalogram2, a_min=self.minlevelCB.value(), a_max=0) cf = cw.cf_lowpass() freq = np.logspace(np.log10(f_min), np.log10(f_max)) k = wmin / (2 * np.pi * freq) delay = int(fs * np.mean(k)) x, y = np.meshgrid( t, np.logspace(np.log10(f_min), np.log10(f_max), scalogram2.shape[0])) c_f = wmin / 2 * math.pi f = np.linspace((f_min), (f_max), scalogram2.shape[0]) pred = (math.sqrt(2) * c_f / f) - (math.sqrt(2) * c_f / f_max) pred_comp = t[len(t) - 1] - pred min_cwt = self.minlevelCB.value() max_cwt = 0 norm = Normalize(vmin=min_cwt, vmax=max_cwt) tf = t[delay:len(t)] cf = cf[0:len(tf)] if order == "Seismogram 1": #self.canvas_plot1.plot(tf, cf, 0, clear_plot=True, is_twinx=True, color="red", # linewidth=0.5) if self.typeCB.currentText() == 'pcolormesh': self.canvas_plot1.pcolormesh(x, y, scalogram2, axes_index=1, clear_plot=True, clabel="Power [dB]", cmap=plt.get_cmap("jet"), vmin=min_cwt, vmax=max_cwt) elif self.typeCB.currentText() == 'contourf': self.canvas_plot1.plot_contour(x, y, scalogram2, axes_index=1, clear_plot=True, clabel="Power [dB]", cmap=plt.get_cmap("jet"), vmin=min_cwt, vmax=max_cwt) ax_cone = self.canvas_plot1.get_axe(1) ax_cone.fill_between(pred, f, 0, color="black", edgecolor="red", alpha=0.3) ax_cone.fill_between(pred_comp, f, 0, color="black", edgecolor="red", alpha=0.3) self.canvas_plot1.set_xlabel(1, "Time (s)") self.canvas_plot1.set_ylabel(0, "Amplitude ") self.canvas_plot1.set_ylabel(1, "Frequency (Hz)") if order == "Seismogram 2": #self.canvas_plot2.plot(tf, cf, 0, clear_plot=True, is_twinx=True, color="red", # linewidth=0.5) if self.typeCB.currentText() == 'pcolormesh': self.canvas_plot2.pcolormesh(x, y, scalogram2, axes_index=1, clear_plot=True, clabel="Power [dB]", cmap=plt.get_cmap("jet"), vmin=min_cwt, vmax=max_cwt) elif self.typeCB.currentText() == 'contourf': self.canvas_plot2.plot_contour(x, y, scalogram2, axes_index=1, clear_plot=True, clabel="Power [dB]", cmap=plt.get_cmap("jet"), vmin=min_cwt, vmax=max_cwt) ax_cone2 = self.canvas_plot2.get_axe(1) ax_cone2.fill_between(pred, f, 0, color="black", edgecolor="red", alpha=0.3) ax_cone2.fill_between(pred_comp, f, 0, color="black", edgecolor="red", alpha=0.3) self.canvas_plot2.set_xlabel(1, "Time (s)") self.canvas_plot2.set_ylabel(0, "Amplitude ") self.canvas_plot2.set_ylabel(1, "Frequency (Hz)") else: pass def key_pressed(self, event): selection = self.selectCB.currentText() if event.key == 'w': self.plot_seismogram() if event.key == 'q': if selection == "Seismogram 1": [tr, t] = self.get_data() x1, y1 = event.xdata, event.ydata tt = tr.stats.starttime + x1 set_qdatetime(tt, self.starttime_date) self.canvas_plot1.draw_arrow(x1, 0, arrow_label="st", color="purple", linestyles='--', picker=False) elif selection == "Seismogram 2": [tr, t] = self.get_data() x1, y1 = event.xdata, event.ydata tt = tr.stats.starttime + x1 set_qdatetime(tt, self.starttime_date) self.canvas_plot2.draw_arrow(x1, 0, arrow_label="st", color="purple", linestyles='--', picker=False) if event.key == 'e': if selection == "Seismogram 1": [tr, t] = self.get_data() x1, y1 = event.xdata, event.ydata tt = tr.stats.starttime + x1 set_qdatetime(tt, self.endtime_date) self.canvas_plot1.draw_arrow(x1, 0, arrow_label="et", color="purple", linestyles='--', picker=False) elif selection == "Seismogram 2": [tr, t] = self.get_data() x1, y1 = event.xdata, event.ydata tt = tr.stats.starttime + x1 set_qdatetime(tt, self.endtime_date) self.canvas_plot2.draw_arrow(x1, 0, arrow_label="et", color="purple", linestyles='--', picker=False) def open_help(self): self.help.show()
class FrequencyTimeFrame(pw.QWidget, UiFrequencyTime): def __init__(self): super(FrequencyTimeFrame, self).__init__() self.setupUi(self) self.solutions = [] self.periods_now = [] self.colors = ["white", "green", "black"] self._stations_info = {} self.parameters = ParametersSettings() # Binds self.root_path_bind = BindPyqtObject(self.rootPathForm_2, self.onChange_root_path) self.canvas_plot1 = MatplotlibCanvas(self.widget_plot_up, ncols=2, sharey = True) top = 0.900 bottom = 0.180 left = 0.045 right = 0.720 wspace = 0.135 self.canvas_plot1.figure.subplots_adjust(left=left, bottom=bottom, right=right, top=top, wspace=wspace, hspace=0.0) ax = self.canvas_plot1.get_axe(0) left,width = 0.2, 0.55 bottom, height = 0.180, 0.72 spacing = 0.02 coords_ax = [left+width+spacing, bottom, 0.2, height] self.fig = ax.get_figure() #self.ax_seism1 = self.fig.add_axes(coords_ax, sharey = ax) self.ax_seism1 = self.fig.add_axes(coords_ax) self.ax_seism1.yaxis.tick_right() # Add file selector to the widget self.file_selector = FilesView(self.root_path_bind.value, parent=self.fileSelectorWidget_2, on_change_file_callback=lambda file_path: self.onChange_file(file_path)) # Binds self.selectDirBtn_2.clicked.connect(lambda: self.on_click_select_directory(self.root_path_bind)) # action self.plotBtn.clicked.connect(self.plot_seismogram) self.plot2Btn.clicked.connect(self.run_phase_vel) self.stationsBtn.clicked.connect(self.stations_info) self.macroBtn.clicked.connect(lambda: self.open_parameters_settings()) # clicks self.canvas_plot1.on_double_click(self.on_click_matplotlib) self.canvas_plot1.mpl_connect('key_press_event', self.key_pressed) def open_parameters_settings(self): self.parameters.show() def filter_error_message(self, msg): md = MessageDialog(self) md.set_info_message(msg) def onChange_root_path(self, value): """ Fired every time the root_path is changed :param value: The path of the new directory. :return: """ self.file_selector.set_new_rootPath(value) def onChange_file(self, file_path): # Called every time user select a different file pass def on_click_select_directory(self, bind: BindPyqtObject): if "darwin" == platform: dir_path = pw.QFileDialog.getExistingDirectory(self, 'Select Directory', bind.value) else: dir_path = pw.QFileDialog.getExistingDirectory(self, 'Select Directory', bind.value, pw.QFileDialog.DontUseNativeDialog) if dir_path: bind.value = dir_path def on_click_select_file(self, bind: BindPyqtObject): selected = pw.QFileDialog.getOpenFileName(self, "Select metadata file") if isinstance(selected[0], str) and os.path.isfile(selected[0]): bind.value = selected[0] def find_indices(self, lst, condition): return [i for i, elem in enumerate(lst) if condition(elem)] def find_nearest(self, a, a0): "Element in nd array `a` closest to the scalar value `a0`" idx = np.abs(a - a0).argmin() return a.flat[idx], idx def stations_info(self): sd = [] st = read(self.file_selector.file_path) tr = st[0] sd.append([tr.stats.network, tr.stats.station, tr.stats.location, tr.stats.channel, tr.stats.starttime, tr.stats.endtime, tr.stats.sampling_rate, tr.stats.npts]) self._stations_info = StationsInfo(sd, check= False) self._stations_info.show() @property def trace(self): return ObspyUtil.get_tracer_from_file(self.file_selector.file_path) def get_data(self): parameters = self.parameters.getParameters() file = self.file_selector.file_path try: sd = SeismogramDataAdvanced(file_path = file) tr = sd.get_waveform_advanced(parameters, {}, filter_error_callback=self.filter_error_message) #tr = st[0] t = tr.times() return tr, t except: return [] def convert_2_vel(self, tr): geodetic = tr.stats.mseed['geodetic'] dist = geodetic[0] return dist #@AsycTime.run_async() def plot_seismogram(self): [tr1, t] = self.get_data() tr = tr1.copy() fs = tr1.stats.sampling_rate selection = self.time_frequencyCB.currentText() # take into acount causality if self.causalCB.currentText() == "Causal": starttime = tr.stats.starttime endtime = tr.stats.starttime+int(len(tr.data) / (2*fs)) tr.trim(starttime=starttime,endtime=endtime) data = np.flip(tr.data) tr.data = data else: starttime = tr.stats.starttime +int(len(tr.data) / (2*fs)) endtime = tr.stats.endtime tr.trim(starttime=starttime, endtime=endtime) if selection == "Continuous Wavelet Transform": nf = self.atomsSB.value() f_min = 1 / self.period_max_cwtDB.value() f_max = 1/ self.period_min_cwtDB.value() wmin = self.wminSB.value() wmax = self.wminSB.value() npts = len(tr.data) t = np.linspace(0, tr.stats.delta * npts, npts) cw = ConvolveWaveletScipy(tr) wavelet=self.wavelet_typeCB.currentText() m = self.wavelets_param.value() cw.setup_wavelet(wmin=wmin, wmax=wmax, tt=int(fs/f_min), fmin=f_min, fmax=f_max, nf=nf, use_wavelet = wavelet, m = m, decimate=False) scalogram2 = cw.scalogram_in_dbs() phase, inst_freq, ins_freq_hz = cw.phase() # phase in radians inst_freq = ins_freq_hz #delay = cw.get_time_delay() x, y = np.meshgrid(t, np.logspace(np.log10(f_min), np.log10(f_max), scalogram2.shape[0])) #x = x + delay # chop cero division dist = self.convert_2_vel(tr) vel = (dist / (x[:, 1:] * 1000)) min_time_idx = fs * (dist / (self.max_velDB.value() * 1000)) min_time_idx = int(min_time_idx) max_time_idx = fs * (dist / (self.min_velDB.value() * 1000)) max_time_idx = int(max_time_idx) period = 1 / y[:, 1:] scalogram2 = scalogram2[:, 1:] if self.ftCB.isChecked(): min_vel, idx_min_vel = self.find_nearest(vel[0, :], self.min_velDB.value()) max_vel, idx_max_vel = self.find_nearest(vel[0, :], self.max_velDB.value()) self.min_vel = min_vel self.max_vel = max_vel vel = vel[:, idx_max_vel:idx_min_vel] period = period[:, idx_max_vel:idx_min_vel] scalogram2 = scalogram2[:, idx_max_vel:idx_min_vel] phase = phase[:, idx_max_vel:idx_min_vel] inst_freq = inst_freq[:, idx_max_vel:idx_min_vel] scalogram2 = np.clip(scalogram2, a_min=self.minlevelCB.value(), a_max=0) min_cwt= self.minlevelCB.value() max_cwt = 0 #scalogram2 = scalogram2+0.01 # flips scalogram2 = scalogram2.T scalogram2 = np.fliplr(scalogram2) scalogram2 = np.flipud(scalogram2) self.scalogram2 = scalogram2 phase = phase.T phase = np.fliplr(phase) phase = np.flipud(phase) self.phase = phase inst_freq = inst_freq.T inst_freq = np.fliplr(inst_freq) inst_freq = np.flipud(inst_freq) self.inst_freq = inst_freq vel = vel.T vel = np.flipud(vel) self.vel = vel period = period.T period = np.fliplr(period) # extract ridge ridge = np.max(scalogram2, axis = 0) distance = self.dist_ridgDB.value()*vel.shape[0]/(max_vel-min_vel) height = (self.minlevelCB.value(),0) ridges, peaks, group_vel = self.find_ridges(scalogram2, vel, height, distance, self.numridgeSB.value()) #print(ridges) #ridge_vel = [] # for j in range(len(ridge)): # value, idx = self.find_nearest(scalogram2[:,j],ridge[j]) # ridge_vel.append(vel[idx,j]) self.t = dist/(1000*vel) self.dist = dist/1000 # phase_vel = self.phase_vel(scalogram2, ridge, phase, inst_freq, t, dist/1000, n) # phase_vel = np.flipud(phase_vel) # Plot self.ax_seism1.cla() self.ax_seism1.plot(tr.data, tr.times() / tr.stats.sampling_rate, linewidth=0.5) self.ax_seism1.plot(tr.data[min_time_idx:max_time_idx], tr.times()[min_time_idx:max_time_idx] / tr.stats.sampling_rate, color='red', linewidth=0.5) self.ax_seism1.set_xlabel("Amplitude") self.ax_seism1.set_ylabel("Time (s)") self.canvas_plot1.clear() self.canvas_plot1.plot_contour(period, vel, scalogram2, axes_index=1, levels = 100, clabel="Power [dB]", cmap=plt.get_cmap("jet"), vmin=min_cwt, vmax=max_cwt, antialiased=True, xscale = "log") self.canvas_plot1.set_xlabel(1, "Period (s)") self.canvas_plot1.set_ylabel(1, "Group Velocity (km/s)") # Plot ridges for k in range(self.numridgeSB.value()): self.canvas_plot1.plot(period[0,:], group_vel[k], axes_index=1, marker=".", color = self.colors[k], clear_plot=False) self.group_vel = group_vel self.periods = period[0,:] if selection == "Hilbert-Multiband": f_min = 1 / self.period_max_mtDB.value() f_max = 1/ self.period_min_mtDB.value() npts = len(tr.data) t = np.linspace(0, tr.stats.delta * npts, npts) hg = hilbert_gauss(tr, f_min, f_max, self.freq_resDB.value()) scalogram2, phase, inst_freq, inst_freq_hz, f = hg.compute_filter_bank() inst_freq = inst_freq_hz scalogram2 = hg.envelope_db() x, y = np.meshgrid(t, f[0:-1]) # chop cero division dist = self.convert_2_vel(tr) vel = (dist / (x[:, 1:] * 1000)) min_time_idx = fs * (dist / (self.max_velDB.value() * 1000)) min_time_idx = int(min_time_idx) max_time_idx = fs * (dist / (self.min_velDB.value() * 1000)) max_time_idx = int(max_time_idx) period = 1 / y[:, 1:] scalogram2 = scalogram2[:, 1:] if self.ftCB.isChecked(): min_vel, idx_min_vel = self.find_nearest(vel[0, :], self.min_velDB.value()) max_vel, idx_max_vel = self.find_nearest(vel[0, :], self.max_velDB.value()) self.min_vel = min_vel self.max_vel = max_vel vel = vel[:, idx_max_vel:idx_min_vel] period = period[:, idx_max_vel:idx_min_vel] scalogram2 = scalogram2[:, idx_max_vel:idx_min_vel] phase = phase[:, idx_max_vel:idx_min_vel] inst_freq = inst_freq[:, idx_max_vel:idx_min_vel] scalogram2 = np.clip(scalogram2, a_min=self.minlevelCB.value(), a_max=0) min_cwt = self.minlevelCB.value() max_cwt = 0 # flips scalogram2 = scalogram2.T scalogram2 = np.fliplr(scalogram2) scalogram2 = np.flipud(scalogram2) self.scalogram2 = scalogram2 phase = phase.T phase = np.fliplr(phase) phase = np.flipud(phase) self.phase = phase inst_freq = inst_freq.T inst_freq = np.fliplr(inst_freq) inst_freq = np.flipud(inst_freq) self.inst_freq = inst_freq vel = vel.T vel = np.flipud(vel) self.vel = vel period = period.T period = np.fliplr(period) # extract ridge ridge = np.max(scalogram2, axis=0) distance = self.dist_ridgDB.value() * vel.shape[0] / (max_vel - min_vel) height = (self.minlevelCB.value(), 0) ridges, peaks, group_vel = self.find_ridges(scalogram2, vel, height, distance, self.numridgeSB.value()) # print(ridges) # ridge_vel = [] # for j in range(len(ridge)): # value, idx = self.find_nearest(scalogram2[:,j],ridge[j]) # ridge_vel.append(vel[idx,j]) self.t = dist / (1000 * vel) self.dist = dist / 1000 # phase_vel = self.phase_vel(scalogram2, ridge, phase, inst_freq, t, dist/1000, n) # phase_vel = np.flipud(phase_vel) # Plot self.ax_seism1.cla() self.ax_seism1.plot(tr.data, tr.times() / tr.stats.sampling_rate, linewidth=0.5) self.ax_seism1.plot(tr.data[min_time_idx:max_time_idx], tr.times()[min_time_idx:max_time_idx] / tr.stats.sampling_rate, color='red', linewidth=0.5) self.ax_seism1.set_xlabel("Amplitude") self.ax_seism1.set_ylabel("Time (s)") self.canvas_plot1.clear() self.canvas_plot1.plot_contour(period, vel, scalogram2, axes_index=1, levels=100, clabel="Power [dB]", cmap=plt.get_cmap("jet"), vmin=min_cwt, vmax=max_cwt, antialiased=True, xscale="log") self.canvas_plot1.set_xlabel(1, "Period (s)") self.canvas_plot1.set_ylabel(1, "Group Velocity (km/s)") # Plot ridges for k in range(self.numridgeSB.value()): self.canvas_plot1.plot(period[0, :], group_vel[k], axes_index=1, marker=".", color=self.colors[k], clear_plot=False) self.group_vel = group_vel self.periods = period[0, :] def run_phase_vel(self): phase_vel_array = self.phase_vel2() phase_vel__array = np.flipud(phase_vel_array) test = np.arange(-5, 5, 1) # Plot phase vel ax2 = self.canvas_plot1.get_axe(0) ax2.cla() for k in range(len(test)): ax2.semilogx(self.periods_now, phase_vel_array[k,:], linewidth = 0.0, marker=".") #self.canvas_plot1.plot_contour(self.periods_now, phase_vel_array[k,:],np.ones([1, len(self.periods_now)]), # 0, "scatter", show_colorbar=False, marker = '.', xscale="log") #self.canvas_plot1.plot(self.periods_now, phase_vel_array[k,:], axes_index=0, marker=".", clear_plot=False, # xscale="log") if self.ftCB.isChecked(): ax2.set_xlim(self.period_min_cwtDB.value(), self.period_max_cwtDB.value()) ax2.set_ylim(self.min_vel, self.max_vel) # self.canvas_plot1.set_xlabel(0, "Period (s)") self.canvas_plot1.set_ylabel(0, "Phase Velocity (km/s)") def phase_vel2(self): landa = -1*np.pi/4 phase_vel_array = np.zeros([len(np.arange(-5, 5, 1)), len(self.solutions)]) for k in np.arange(-5, 5, 1): for j in range(len(self.solutions)): value_period, idx_period = self.find_nearest(self.periods, self.periods_now[j]) value_group_vel, idx_group_vel = self.find_nearest(self.vel[:,0], self.solutions[j]) to = self.t[idx_group_vel , 0] phase_test = self.phase[idx_group_vel, idx_period] inst_freq_test = self.inst_freq[idx_group_vel, idx_period] phase_vel_num = self.dist * inst_freq_test phase_vel_den = phase_test+inst_freq_test*to-(np.pi/4)-k*2*np.pi+landa phase_vel_array[k, j] = phase_vel_num / phase_vel_den return phase_vel_array def phase_vel(self, scalogram2, ridge, phase, inst_freq, t, dist, n): # extract phase_vel info phase_vel_array = np.zeros([n, len(ridge)]) for k in np.arange(-5, 5, 1): for j in range(len(ridge)): value, idx = self.find_nearest(scalogram2[:, j], ridge[j]) to = t[idx, j] phase_test = phase[idx, j] inst_freq_test = inst_freq[idx, j] phase_vel_num = dist * inst_freq_test phase_vel_den = phase_test+inst_freq_test*to-(np.pi/4)-k*2*np.pi phase_vel_array[k, j] = phase_vel_num / phase_vel_den return phase_vel_array def find_ridges(self, scalogram2, vel, height, distance, num_ridges): distance = int(distance) dim = scalogram2.shape[1] ridges = np.zeros([num_ridges, dim]) peak = np.zeros([num_ridges, dim]) group_vel = np.zeros([num_ridges, dim]) for j in range(dim): peaks, properties = find_peaks(scalogram2[:,j], height = height, threshold=-5, distance = distance) for k in range(num_ridges): try: if len(peaks)>0: ridges[k, j] = peaks[k] peak[k, j] = properties['peak_heights'][k] group_vel[k,j] =vel[int(peaks[k]),0] else: ridges[k, j] = "NaN" peak[k, j] = "NaN" group_vel[k, j] = "NaN" except: ridges[k, j] = "NaN" peak[k, j] = "NaN" group_vel[k, j] = "NaN" return ridges, peak, group_vel def on_click_matplotlib(self, event, canvas): if isinstance(canvas, MatplotlibCanvas): x1_value, y1_value = event.xdata, event.ydata period, pick_vel,_ = self.find_pos(x1_value, y1_value) self.solutions.append(pick_vel) self.periods_now.append(period) self.canvas_plot1.plot(period, pick_vel, color = "purple", axes_index = 1, clear_plot = False, marker = "." ) def find_pos(self, x1, y1): value_period, idx_periods = self.find_nearest(self.periods, x1) dim = self.group_vel.shape[0] rms = [] for k in range(dim): group_vel_test = self.group_vel[k, :][idx_periods] err = abs(group_vel_test - y1) if err>0: rms.append(err) else: err=100 rms.append(err) rms = np.array(rms) idx = np.argmin(rms) return value_period, self.group_vel[idx, idx_periods], idx def key_pressed(self, event): if event.key == 'r': x1_value, y1_value = event.xdata, event.ydata print(x1_value, y1_value) period, pick_vel,idx = self.find_pos(x1_value, y1_value) # check if is in solutions if period in self.periods_now and pick_vel in self.solutions: self.periods_now.remove(period) self.solutions.remove(pick_vel) self.canvas_plot1.plot(period, pick_vel, color=self.colors[idx], axes_index=1, clear_plot=False, marker=".") # if selection == "Multitaper Spectrogram": # # win = int(self.mt_window_lengthDB.value() * tr.stats.sampling_rate) # win_half = int(win / (2 * fs)) # tbp = self.time_bandwidth_DB.value() # ntapers = self.number_tapers_mtSB.value() # f_min = 1 / self.period_max_mtDB.value() # f_max = 1 / self.period_min_mtDB.value() # mtspectrogram = MTspectrogram(self.file_selector.file_path, win, tbp, ntapers, f_min, f_max) # x, y, log_spectrogram = mtspectrogram.compute_spectrogram(tr) # # x in seconds, y in freqs # x = x + win_half # # chop cero division # dist = self.convert_2_vel(tr) # vel = (dist / (x[:, 1:] * 1000)) # min_time_idx = fs * (dist / (self.max_velDB.value() * 1000)) # min_time_idx = int(min_time_idx) # max_time_idx = fs * (dist / (self.min_velDB.value() * 1000)) # max_time_idx = int(max_time_idx) # period = 1 / y[:, 1:] # log_spectrogram = log_spectrogram[:, 1:] # # if self.ftCB.isChecked(): # min_vel, idx_min_vel = self.find_nearest(vel[0, :], self.min_velDB.value()) # max_vel, idx_max_vel = self.find_nearest(vel[0, :], self.max_velDB.value()) # vel = vel[:, idx_max_vel:idx_min_vel] # period = period[:, idx_max_vel:idx_min_vel] # log_spectrogram = log_spectrogram[:, idx_max_vel:idx_min_vel] # # log_spectrogram = np.clip(log_spectrogram, a_min=self.minlevelCB.value(), a_max=0.05) # min_log_spectrogram = self.minlevelCB.value() # max_log_spectrogram = 0.05 # log_spectrogram = log_spectrogram + 0.05 # # # flips # log_spectrogram = log_spectrogram.T # log_spectrogram = np.fliplr(log_spectrogram) # log_spectrogram = np.flipud(log_spectrogram) # # vel = vel.T # vel = np.flipud(vel) # # period = period.T # period = np.fliplr(period) # # # Plot # self.ax_seism1.cla() # self.ax_seism1.plot(tr.data, tr.times() / tr.stats.sampling_rate, linewidth=0.5) # self.ax_seism1.plot(tr.data[min_time_idx:max_time_idx], # tr.times()[min_time_idx:max_time_idx] / tr.stats.sampling_rate, # color='red', linewidth=0.5) # # self.ax_seism1.set_xlabel("Amplitude") # self.ax_seism1.set_ylabel("Time (s)") # self.canvas_plot1.clear() # self.canvas_plot1.plot_contour(period, vel, log_spectrogram, axes_index=0, clabel="Power [dB]", # cmap=plt.get_cmap("jet"), vmin=min_log_spectrogram, vmax=max_log_spectrogram, # antialiased=True, xscale="log") # # # ax = self.canvas_plot1.get_axe(0) # # ax.clabel(cs, levels = levels, fmt = '%2.1', colors = 'k', fontsize = 12) # self.canvas_plot1.set_xlabel(0, "Period (s)") # self.canvas_plot1.set_ylabel(0, "Group Velocity (m/s)")
class ArrayAnalysisFrame(BaseFrame, UiArrayAnalysisFrame): def __init__(self): super(ArrayAnalysisFrame, self).__init__() self.setupUi(self) self.__stations_dir = None self.stream_frame = None self.__metadata_manager = None self.inventory = {} self._stations_info = {} self._stations_coords = {} self.stack = None self.canvas = MatplotlibCanvas(self.responseMatWidget) self.canvas_fk = MatplotlibCanvas(self.widget_fk, nrows=4) self.canvas_slow_map = MatplotlibCanvas(self.widget_slow_map) self.canvas_fk.on_double_click(self.on_click_matplotlib) self.canvas_stack = MatplotlibCanvas(self.widget_stack) self.cartopy_canvas = CartopyCanvas(self.widget_map) self.canvas.set_new_subplot(1, ncols=1) #Binding self.root_pathFK_bind = BindPyqtObject(self.rootPathFormFK) self.root_pathBP_bind = BindPyqtObject(self.rootPathFormBP) self.metadata_path_bind = BindPyqtObject(self.datalessPathForm, self.onChange_metadata_path) self.metadata_path_bindBP = BindPyqtObject(self.datalessPathFormBP, self.onChange_metadata_path) self.output_path_bindBP = BindPyqtObject(self.outputPathFormBP, self.onChange_metadata_path) self.fmin_bind = BindPyqtObject(self.fminSB) self.fmax_bind = BindPyqtObject(self.fmaxSB) self.grid_bind = BindPyqtObject(self.gridSB) self.smax_bind = BindPyqtObject(self.smaxSB) # On select self.canvas_fk.register_on_select(self.on_select, rectprops=dict(alpha=0.2, facecolor='red')) self.fminFK_bind = BindPyqtObject(self.fminFKSB) self.fmaxFK_bind = BindPyqtObject(self.fmaxFKSB) self.overlap_bind = BindPyqtObject(self.overlapSB) self.timewindow_bind = BindPyqtObject(self.timewindowSB) self.smaxFK_bind = BindPyqtObject(self.slowFKSB) self.slow_grid_bind = BindPyqtObject(self.gridFKSB) # Bind buttons self.selectDirBtnFK.clicked.connect( lambda: self.on_click_select_directory(self.root_pathFK_bind)) self.datalessBtn.clicked.connect( lambda: self.on_click_select_metadata_file(self.metadata_path_bind )) # Bind buttons BackProjection self.selectDirBtnBP.clicked.connect( lambda: self.on_click_select_directory(self.root_pathBP_bind)) self.datalessBtnBP.clicked.connect( lambda: self.on_click_select_metadata_file(self. metadata_path_bindBP)) self.outputBtn.clicked.connect( lambda: self.on_click_select_directory(self.output_path_bindBP)) #Action Buttons self.arfBtn.clicked.connect(lambda: self.arf()) self.runFKBtn.clicked.connect(lambda: self.FK_plot()) self.plotBtn.clicked.connect(lambda: self.plot_seismograms()) self.plotBtnBP.clicked.connect(lambda: self.plot_seismograms(FK=False)) self.actionSettings.triggered.connect( lambda: self.open_parameters_settings()) self.actionProcessed_Seimograms.triggered.connect(self.write) self.actionStacked_Seismograms.triggered.connect(self.write_stack) self.stationsBtn.clicked.connect(lambda: self.stationsInfo()) self.stationsBtnBP.clicked.connect(lambda: self.stationsInfo(FK=False)) self.mapBtn.clicked.connect(self.stations_map) self.actionCreate_Stations_File.triggered.connect( self.stations_coordinates) self.actionLoad_Stations_File.triggered.connect(self.load_path) self.actionRunVespagram.triggered.connect(self.open_vespagram) self.shortcut_open = pw.QShortcut(pqg.QKeySequence('Ctrl+O'), self) self.shortcut_open.activated.connect(self.open_solutions) self.create_gridBtn.clicked.connect(self.create_grid) self.actionOpen_Help.triggered.connect(lambda: self.open_help()) self.load_videoBtn.clicked.connect(self.loadvideoBP) # help Documentation self.help = HelpDoc() # Parameters settings self.__parameters = ParametersSettings() # Stations Coordinates self.__stations_coords = StationsCoords() # picks self.picks = { 'Time': [], 'Phase': [], 'BackAzimuth': [], 'Slowness': [], 'Power': [] } # video self.player = QMediaPlayer(None, QMediaPlayer.VideoSurface) self.player.setVideoOutput(self.backprojection_widget) self.player.stateChanged.connect(self.mediaStateChanged) self.player.positionChanged.connect(self.positionChanged) self.player.durationChanged.connect(self.durationChanged) self.playButton.setIcon(self.style().standardIcon(QStyle.SP_MediaPlay)) self.playButton.clicked.connect(self.play_bp) self.positionSlider.sliderMoved.connect(self.setPosition) def mediaStateChanged(self): if self.player.state() == QMediaPlayer.PlayingState: self.playButton.setIcon(self.style().standardIcon( QStyle.SP_MediaPause)) else: self.playButton.setIcon(self.style().standardIcon( QStyle.SP_MediaPlay)) def positionChanged(self, position): self.positionSlider.setValue(position) def durationChanged(self, duration): self.positionSlider.setRange(0, duration) def setPosition(self, position): self.player.setPosition(position) def open_parameters_settings(self): self.__parameters.show() def stations_coordinates(self): self.__stations_coords.show() def open_vespagram(self): if self.st and self.inventory and self.t1 and self.t2: self.__vespagram = Vespagram(self.st, self.inventory, self.t1, self.t2) self.__vespagram.show() def on_click_select_directory(self, bind: BindPyqtObject): if "darwin" == platform: dir_path = pw.QFileDialog.getExistingDirectory( self, 'Select Directory', bind.value) else: dir_path = pw.QFileDialog.getExistingDirectory( self, 'Select Directory', bind.value, pw.QFileDialog.DontUseNativeDialog) if dir_path: bind.value = dir_path def onChange_metadata_path(self, value): md = MessageDialog(self) try: self.__metadata_manager = MetadataManager(value) self.inventory = self.__metadata_manager.get_inventory() print(self.inventory) md.set_info_message( "Loaded Metadata, please check your terminal for further details" ) except: md.set_error_message( "Something went wrong. Please check your metada file is a correct one" ) def on_click_select_metadata_file(self, bind: BindPyqtObject): selected = pw.QFileDialog.getOpenFileName(self, "Select metadata file") if isinstance(selected[0], str) and os.path.isfile(selected[0]): bind.value = selected[0] def load_path(self): selected_file = pw.QFileDialog.getOpenFileName( self, "Select Stations Coordinates file") self.path_file = selected_file[0] df = pd.read_csv(self.path_file, delim_whitespace=True) n = len(df) self.coords = np.zeros([n, 3]) for i in range(n): #coords[i]=data[i] self.coords[i] = np.array( [df['Lon'][i], df['Lat'][i], df['Depth'][i]]) def arf(self): try: if self.coords.all(): wavenumber = array_analysis.array() arf = wavenumber.arf(self.coords, self.fmin_bind.value, self.fmax_bind.value, self.smax_bind.value, self.grid_bind.value) slim = self.smax_bind.value x = y = np.linspace(-1 * slim, slim, len(arf)) self.canvas.plot_contour(x, y, arf, axes_index=0, clabel="Power [dB]", cmap=plt.get_cmap("jet")) self.canvas.set_xlabel(0, "Sx (s/km)") self.canvas.set_ylabel(0, "Sy (s/km)") except: md = MessageDialog(self) md.set_error_message( "Couldn't compute ARF, please check if you have loaded stations coords" ) def stations_map(self): coords = {} if self.path_file: df = pd.read_csv(self.path_file, delim_whitespace=True) n = len(df) self.coords = np.zeros([n, 3]) for i in range(n): coords[df['Name'][i]] = [ df['Lat'][i], df['Lon'][i], ] #try: self.cartopy_canvas.plot_map(df['Lat'][0], df['Lon'][0], 0, 0, 0, 0, resolution="low", stations=coords) #except: # pass def FK_plot(self): self.canvas_stack.set_new_subplot(nrows=1, ncols=1) starttime = convert_qdatetime_utcdatetime(self.starttime_date) endtime = convert_qdatetime_utcdatetime(self.endtime_date) selection = self.inventory.select(station=self.stationLE.text(), channel=self.channelLE.text()) if self.trimCB.isChecked(): wavenumber = array_analysis.array() relpower, abspower, AZ, Slowness, T = wavenumber.FK( self.st, selection, starttime, endtime, self.fminFK_bind.value, self.fmaxFK_bind.value, self.smaxFK_bind.value, self.slow_grid_bind.value, self.timewindow_bind.value, self.overlap_bind.value) self.canvas_fk.scatter3d(T, relpower, relpower, axes_index=0, clabel="Power [dB]") self.canvas_fk.scatter3d(T, abspower, relpower, axes_index=1, clabel="Power [dB]") self.canvas_fk.scatter3d(T, AZ, relpower, axes_index=2, clabel="Power [dB]") self.canvas_fk.scatter3d(T, Slowness, relpower, axes_index=3, clabel="Power [dB]") self.canvas_fk.set_ylabel(0, " Rel Power ") self.canvas_fk.set_ylabel(1, " Absolute Power ") self.canvas_fk.set_ylabel(2, " Back Azimuth ") self.canvas_fk.set_ylabel(3, " Slowness [s/km] ") self.canvas_fk.set_xlabel(3, " Time [s] ") ax = self.canvas_fk.get_axe(3) formatter = mdt.DateFormatter('%H:%M:%S') ax.xaxis.set_major_formatter(formatter) ax.xaxis.set_tick_params(rotation=30) else: md = MessageDialog(self) md.set_info_message("Please select dates and then check Trim box") def on_click_matplotlib(self, event, canvas): output_path = os.path.join(ROOT_DIR, 'arrayanalysis', 'dataframe.csv') if isinstance(canvas, MatplotlibCanvas): st = self.st.copy() wavenumber = array_analysis.array() selection = self.inventory.select(station=self.stationLE.text(), channel=self.channelLE.text()) x1, y1 = event.xdata, event.ydata DT = x1 Z, Sxpow, Sypow, coord = wavenumber.FKCoherence( st, selection, DT, self.fminFK_bind.value, self.fmaxFK_bind.value, self.smaxFK_bind.value, self.timewindow_bind.value, self.slow_grid_bind.value, self.methodSB.currentText()) backacimuth = wavenumber.azimuth2mathangle( np.arctan2(Sypow, Sxpow) * 180 / np.pi) slowness = np.abs(Sxpow, Sypow) if self.methodSB.currentText() == "FK": clabel = "Power" elif self.methodSB.currentText() == "MTP.COHERENCE": clabel = "Magnitude Coherence" Sx = np.arange(-1 * self.smaxFK_bind.value, self.smaxFK_bind.value, self.slow_grid_bind.value)[np.newaxis] nx = len(Sx[0]) x = y = np.linspace(-1 * self.smaxFK_bind.value, self.smaxFK_bind.value, nx) X, Y = np.meshgrid(x, y) self.canvas_slow_map.plot_contour(X, Y, Z, axes_index=0, clabel=clabel, cmap=plt.get_cmap("jet")) self.canvas_slow_map.set_xlabel(0, "Sx [s/km]") self.canvas_slow_map.set_ylabel(0, "Sy [s/km]") # Save in a dataframe the pick value x1 = wavenumber.gregorian2date(x1) self.picks['Time'].append(x1.isoformat()) self.picks['Phase'].append(self.phaseCB.currentText()) self.picks['BackAzimuth'].append(backacimuth[0]) self.picks['Slowness'].append(slowness[0]) self.picks['Power'].append(np.max(Z)) df = pd.DataFrame(self.picks) df.to_csv(output_path, index=False, header=True) # Call Stack and Plot### #stream_stack, time = wavenumber.stack_stream(self.root_pathFK_bind.value, Sxpow, Sypow, coord) if st: st2 = self.st.copy() # Align for the maximum power and give the data of the traces stream_stack, self.time, self.stats = wavenumber.stack_stream( st2, Sxpow, Sypow, coord) # stack the traces self.stack = wavenumber.stack( stream_stack, stack_type=self.stackCB.currentText()) self.canvas_stack.plot(self.time, self.stack, axes_index=0, linewidth=0.75) self.canvas_stack.set_xlabel(0, " Time [s] ") self.canvas_stack.set_ylabel(0, "Stack Amplitude") def filter_error_message(self, msg): md = MessageDialog(self) md.set_info_message(msg) def plot_seismograms(self, FK=True): if FK: starttime = convert_qdatetime_utcdatetime(self.starttime_date) endtime = convert_qdatetime_utcdatetime(self.endtime_date) else: starttime = convert_qdatetime_utcdatetime(self.starttime_date_BP) endtime = convert_qdatetime_utcdatetime(self.endtime_date_BP) diff = endtime - starttime if FK: file_path = self.root_pathFK_bind.value else: file_path = self.root_pathBP_bind.value obsfiles = [] for dirpath, _, filenames in os.walk(file_path): for f in filenames: if f != ".DS_Store": obsfiles.append(os.path.abspath(os.path.join(dirpath, f))) obsfiles.sort() parameters = self.__parameters.getParameters() all_traces = [] trace_number = 0 for file in obsfiles: sd = SeismogramDataAdvanced(file) if FK: if self.trimCB.isChecked() and diff >= 0: tr = sd.get_waveform_advanced( parameters, self.inventory, filter_error_callback=self.filter_error_message, start_time=starttime, end_time=endtime, trace_number=trace_number) else: tr = sd.get_waveform_advanced( parameters, self.inventory, filter_error_callback=self.filter_error_message, trace_number=trace_number) else: if self.trimCB_BP.isChecked() and diff >= 0: tr = sd.get_waveform_advanced( parameters, self.inventory, filter_error_callback=self.filter_error_message, start_time=starttime, end_time=endtime, trace_number=trace_number) else: tr = sd.get_waveform_advanced( parameters, self.inventory, filter_error_callback=self.filter_error_message, trace_number=trace_number) all_traces.append(tr) trace_number = trace_number + 1 self.st = Stream(traces=all_traces) if FK: if self.selectCB.isChecked(): self.st = self.st.select(station=self.stationLE.text(), channel=self.channelLE.text()) else: if self.selectCB_BP.isChecked(): self.st = self.st.select(network=self.stationLE_BP.text(), station=self.stationLE_BP.text(), channel=self.channelLE_BP.text()) self.stream_frame = MatplotlibFrame(self.st, type='normal') self.stream_frame.show() def stationsInfo(self, FK=True): if FK: obsfiles = MseedUtil.get_mseed_files(self.root_pathFK_bind.value) else: obsfiles = MseedUtil.get_mseed_files(self.root_pathBP_bind.value) obsfiles.sort() sd = [] for file in obsfiles: st = SeismogramDataAdvanced(file) station = [ st.stats.Network, st.stats.Station, st.stats.Location, st.stats.Channel, st.stats.StartTime, st.stats.EndTime, st.stats.Sampling_rate, st.stats.Npts ] sd.append(station) self._stations_info = StationsInfo(sd, check=True) self._stations_info.show() def write(self): root_path = os.path.dirname(os.path.abspath(__file__)) if "darwin" == platform: dir_path = pw.QFileDialog.getExistingDirectory( self, 'Select Directory', root_path) else: dir_path = pw.QFileDialog.getExistingDirectory( self, 'Select Directory', root_path, pw.QFileDialog.DontUseNativeDialog) if dir_path: n = len(self.st) try: if len(n) > 0: for j in range(n): tr = self.st[j] t1 = tr.stats.starttime id = tr.id + "." + "D" + "." + str( t1.year) + "." + str(t1.julday) print(tr.id, "Writing data processed") path_output = os.path.join(dir_path, id) tr.write(path_output, format="MSEED") else: md = MessageDialog(self) md.set_info_message("Nothing to write") except: pass def write_stack(self): if self.stack is not None and len(self.stack) > 0: root_path = os.path.dirname(os.path.abspath(__file__)) if "darwin" == platform: dir_path = pw.QFileDialog.getExistingDirectory( self, 'Select Directory', root_path) else: dir_path = pw.QFileDialog.getExistingDirectory( self, 'Select Directory', root_path, pw.QFileDialog.DontUseNativeDialog) if dir_path: tr = Trace(data=self.stack, header=self.stats) file = os.path.join(dir_path, tr.id) tr.write(file, format="MSEED") else: md = MessageDialog(self) md.set_info_message("Nothing to write") def __to_UTC(self, DT): # Convert start from Greogorian to actual date Time = DT Time = Time - int(Time) d = date.fromordinal(int(DT)) date1 = d.isoformat() H = (Time * 24) H1 = int(H) # Horas minutes = (H - int(H)) * 60 minutes1 = int(minutes) seconds = (minutes - int(minutes)) * 60 H1 = str(H1).zfill(2) minutes1 = str(minutes1).zfill(2) seconds = "%.2f" % seconds seconds = str(seconds).zfill(2) DATE = date1 + "T" + str(H1) + minutes1 + seconds t1 = UTCDateTime(DATE) return t1 def on_select(self, ax_index, xmin, xmax): self.t1 = self.__to_UTC(xmin) self.t2 = self.__to_UTC(xmax) def open_solutions(self): output_path = os.path.join(ROOT_DIR, 'arrayanalysis', 'dataframe.csv') try: command = "{} {}".format('open', output_path) exc_cmd(command, cwd=ROOT_DIR) except: md = MessageDialog(self) md.set_error_message("Coundn't open solutions file") ### New part back-projection def create_grid(self): area_coords = [ self.minLonBP, self.maxLonBP, self.minLatBP, self.maxLatBP ] bp = back_proj_organize(self, self.rootPathFormBP, self.datalessPathFormBP, area_coords, self.sxSB.value, self.sxSB.value, self.depthSB.value) mapping = bp.create_dict() try: self.path_file = os.path.join(self.output_path_bindBP.value, "mapping.pkl") file_to_store = open(self.path_file, "wb") pickle.dump(mapping, file_to_store) md = MessageDialog(self) md.set_info_message("BackProjection grid created succesfully!!!") except: md = MessageDialog(self) md.set_error_message("Coundn't create a BackProjection grid") def run_bp(self): try: if os.path.exists(self.path_file): with open(self.path_file, 'rb') as handle: mapping = pickle.load(handle) except: md = MessageDialog(self) md.set_error_message( "Please you need try to previously create a BackProjection grid" ) power = backproj.run_back(self.st, mapping, self.time_winBP.value, self.stepBP.value, window=self.slide_winBP.value, multichannel=self.mcccCB.isChecked(), stack_process=self.methodBP.currentText()) #plot_cum(power, mapping['area_coords'], self.cum_sumBP.value, self.st) plot_bp(power, mapping['area_coords'], self.cum_sumBP.value, self.st, output=self.output_path_bindBP.value) fname = os.path.join(self.output_path_bindBP.value, "power.pkl") file_to_store = open(fname, "wb") pickle.dump(power, file_to_store) def loadvideoBP(self): self.path_video, _ = pw.QFileDialog.getOpenFileName( self, "Choose your BackProjection", ".", "Video Files (*.mp4 *.flv *.ts *.mts *.avi)") if self.path_video != '': self.player.setVideoOutput(self.backprojection_widget) self.player.setMedia( QMediaContent(pyc.QUrl.fromLocalFile(self.path_video))) md = MessageDialog(self) md.set_info_message( "Video containing BackProjection succesfully loaded") else: md = MessageDialog(self) md.set_error_message( "Video containing BackProjection couldn't be loaded") def play_bp(self): if self.player.state() == QMediaPlayer.PlayingState: self.player.pause() else: self.player.play() def open_help(self): self.help.show()
class TimeFrequencyAdvance(pw.QFrame, UiTimeFrequencyWidget): def __init__(self, tr1, tr2): super(TimeFrequencyAdvance, self).__init__() self.setupUi(self) self.spectrum_Widget_Canvas = MatplotlibCanvas(self.spectrumWidget, nrows=2, ncols=2, sharex=False, constrained_layout=True) self.spectrum_Widget_Canvas2 = MatplotlibCanvas(self.spectrumWidget2, nrows=1, ncols=1, sharex=False, constrained_layout=True) self.coherence_Widget_Canvas = MatplotlibCanvas(self.coherenceWidget, nrows=2, ncols=1, sharex=False, constrained_layout=True) self.cross_correlation_Widget_Canvas = MatplotlibCanvas(self.cross_correlationWidget, nrows = 3, ncols = 1) self.cross_spectrumWidget_Widget_Canvas = MatplotlibCanvas(self.cross_spectrumWidget,nrows = 2, ncols = 1, sharex=True, constrained_layout=True) self.plot_spectrumBtn.clicked.connect(self.plot_spectrum) self.coherenceBtn.clicked.connect(self.coherence) self.cross_correlationsBtn.clicked.connect(self.plot_correlation) #self.Cross_spectrumBtn.clicked.connect(self.plot_cross_spectrogram) self.Cross_scalogramBtn.clicked.connect(self.plot_cross_scalogram) self.tr1 = tr1 self.tr2 = tr2 def plot_spectrum(self): if len(self.tr1) >0: [spec1, freq1, jackknife_errors] = spectrumelement(self.tr1.data, self.tr1.stats.delta, self.tr1.id) self.spectrum_Widget_Canvas.plot(freq1, spec1, 0) ax1 = self.spectrum_Widget_Canvas.get_axe(0) ax1.cla() ax1.loglog(freq1, spec1, '0.1', linewidth=0.5, color='steelblue', label=self.tr1.id) ax1.fill_between(freq1, jackknife_errors[:, 0], jackknife_errors[:, 1], facecolor="0.75", alpha=0.5, edgecolor="0.5") ax1.set_ylim(spec1.min() / 10.0, spec1.max() * 100.0) ax1.set_xlim(freq1[1], freq1[len(freq1)-1]) ax1.set_ylabel('Amplitude') ax1.set_xlabel('Frequency [Hz]') ax1.grid(True, which="both", ls="-", color='grey') ax1.legend() #plot the phase N = len(self.tr1.data) D = 2 ** math.ceil(math.log2(N)) z = np.zeros(D - N) data = np.concatenate((self.tr1.data, z), axis=0) spectrum = np.fft.rfft(data, D) phase = np.angle(spectrum) ax3 = self.spectrum_Widget_Canvas.get_axe(2) ax3.semilogx(freq1, phase*180/math.pi, color = 'orangered', linewidth=0.5) ax3.set_xlim(freq1[1], freq1[len(freq1) - 1]) ax3.grid(True, which="both", ls="-", color='grey') ax3.set_ylabel('Phase') ax3.set_xlabel('Frequency [Hz]') else: pass if len(self.tr2) > 0: [spec2, freq2, jackknife_errors] = spectrumelement(self.tr2.data, self.tr2.stats.delta, self.tr2.id) self.spectrum_Widget_Canvas.plot(freq2, spec2, 1) ax2 = self.spectrum_Widget_Canvas.get_axe(1) ax2.cla() ax2.loglog(freq2, spec2, '0.1', linewidth=0.5, color='steelblue', label=self.tr2.id) ax2.fill_between(freq2, jackknife_errors[:, 0], jackknife_errors[:, 1], facecolor="0.75", alpha=0.5, edgecolor="0.5") ax2.set_ylim(spec2.min() / 10.0, spec2.max() * 100.0) ax2.set_xlim(freq2[1], freq2[len(freq2) - 1]) ax2.set_ylabel('Amplitude') ax2.set_xlabel('Frequency [Hz]') ax2.grid(True, which="both", ls="-", color='grey') ax2.legend() # plot the phase N = len(self.tr2.data) D = 2 ** math.ceil(math.log2(N)) z = np.zeros(D - N) data = np.concatenate((self.tr2.data, z), axis=0) spectrum = np.fft.rfft(data, D) phase = np.angle(spectrum) ax4 = self.spectrum_Widget_Canvas.get_axe(3) ax4.semilogx(freq2, phase * 180 / math.pi, color = 'orangered', linewidth=0.5) ax4.set_xlim(freq2[1], freq2[len(freq2) - 1]) ax4.grid(True, which="both", ls="-", color='grey') ax4.set_ylabel('Phase') ax4.set_xlabel('Frequency [Hz]') else: pass # Power try: self.spectrum_Widget_Canvas2.plot(freq1, spec1, 0) ax5 = self.spectrum_Widget_Canvas2.get_axe(0) ax5.cla() spec1=spec1**2 spec2=spec2**2 ax5.loglog(freq1, spec1, '0.1', linewidth=0.5, color='steelblue', label=self.tr1.id) ax5.loglog(freq2, spec2, '0.1', linewidth=0.5, color='orangered', label=self.tr2.id) ax5.set_ylabel('Amplitude') ax5.set_xlabel('Frequency [Hz]') ax5.grid(True, which="both", ls="-", color='grey') ax5.legend() except: raise("Some data is missing") def coherence(self): if len(self.tr1) > 0 and len(self.tr2) > 0: sampling_rates = [] fs1=self.tr1.stats.sampling_rate fs2=self.tr2.stats.sampling_rate sampling_rates.append(fs1) sampling_rates.append(fs2) max_sampling_rates = np.max(sampling_rates) overlap = self.cohe_overlapSB.value() time_window = self.time_window_coheSB.value() nfft = time_window*max_sampling_rates if fs1 != fs2: self.tr1.resample(max_sampling_rates) self.tr1.resample(max_sampling_rates) # Plot Amplitude [A,f, phase] = cohe(self.tr1.data, self.tr2.data, max_sampling_rates, nfft, overlap) self.coherence_Widget_Canvas.plot(f, A, 0) ax1 = self.coherence_Widget_Canvas.get_axe(0) ax1.cla() ax1.loglog(f, A, '0.1', linewidth=0.5, color='steelblue', label="Amplitude Coherence "+ self.tr1.id+" "+ self.tr2.id) ax1.set_ylim(A.min() / 10.0, A.max() * 100.0) ax1.set_xlim(f[1], f[len(f) - 1]) ax1.set_ylabel('Magnitude Coherence') ax1.set_xlabel('Frequency [Hz]') ax1.grid(True, which="both", ls="-", color='grey') ax1.legend() # Plot Phase ax2 = self.coherence_Widget_Canvas.get_axe(1) ax2.cla() ax2.semilogx(f, phase * 180 / math.pi, color='orangered', linewidth=0.5, label="Phase Coherence "+ self.tr1.id+" "+ self.tr2.id) ax2.set_xlim(f[1], f[len(f) - 1]) ax2.set_ylabel('Phase') ax2.set_xlabel('Frequency [Hz]') ax2.grid(True, which="both", ls="-", color='grey') ax2.legend() def plot_correlation(self): if len(self.tr1) > 0 and len(self.tr2) > 0: sampling_rates = [] fs1=self.tr1.stats.sampling_rate fs2=self.tr2.stats.sampling_rate sampling_rates.append(fs1) sampling_rates.append(fs2) max_sampling_rates = np.max(sampling_rates) if fs1 != fs2: self.tr1.resample(max_sampling_rates) self.tr2.resample(max_sampling_rates) cc1 = correlate_maxlag(self.tr1.data, self.tr1.data, maxlag = max([len(self.tr1.data),len(self.tr2.data)])) cc2 = correlate_maxlag(self.tr2.data, self.tr2.data, maxlag = max([len(self.tr1.data),len(self.tr2.data)])) cc3 = correlate_maxlag(self.tr1.data, self.tr2.data, maxlag = max([len(self.tr1.data),len(self.tr2.data)])) N1 = len(cc1) N2 = len(cc2) N3 = len(cc3) self.cross_correlation_Widget_Canvas.plot(get_lags(cc1)/max_sampling_rates, cc1, 0, clear_plot=True, linewidth=0.5,color='black') self.cross_correlation_Widget_Canvas.plot(get_lags(cc2)/max_sampling_rates, cc2, 1, clear_plot=True, linewidth=0.5, color = 'black') self.cross_correlation_Widget_Canvas.plot(get_lags(cc3)/max_sampling_rates, cc3, 2, clear_plot=True, linewidth=0.5, color = 'red') def plot_cross_spectrogram(self): if len(self.tr1) > 0 and len(self.tr2) > 0: csp = cross_spectrogram(self.tr1, self.tr2, win=self.time_windowSB.value(), tbp=self.time_bandwidthSB.value(), ntapers = self.num_tapersSB.value()) [coherence_cross, freq, t] = csp.compute_coherence_crosspectrogram() f_min = 0 f_max = 0.5*(1/max(freq)) f_max=50 x, y = np.meshgrid(t, np.linspace(f_min, f_max, coherence_cross.shape[0])) self.cross_spectrumWidget_Widget_Canvas.plot_contour(x, y, coherence_cross, axes_index=0, clabel="Coherence", cmap=plt.get_cmap("jet"), vmin=0,vmax=1) self.cross_spectrumWidget_Widget_Canvas.set_xlabel(0, "Time (s)") self.cross_spectrumWidget_Widget_Canvas.set_ylabel(0, "Frequency (Hz)") def plot_cross_scalogram(self): base_line = self.base_lineDB.value() colour = self.colourCB.currentText() if len(self.tr1) > 0 and len(self.tr2) > 0: # fs1 = self.tr1.stats.sampling_rate fs2 = self.tr2.stats.sampling_rate fs = max(fs1, fs2) if fs1 < fs: self.tr1.resample(fs) elif fs2 < fs: self.tr2.resample(fs) all_traces = [self.tr1, self.tr2] st = Stream(traces=all_traces) maxstart = np.max([tr.stats.starttime for tr in st]) minend = np.min([tr.stats.endtime for tr in st]) st.trim(maxstart, minend) tr1 = st[0] tr2 = st[1] tr1.detrend(type='demean') tr1.taper(max_percentage=0.05) tr2.detrend(type='demean') tr2.taper(max_percentage=0.05) npts =len(tr1.data) t = np.linspace(0, npts/fs, npts) f_max = fs/2 nf = 40 wmin=wmax=self.num_cyclesSB.value() f_min = self.freq_min_waveletSB.value() tt = int(fs / f_min) [ba, nConv, frex, half_wave] = ccwt_ba_fast(npts, fs, f_min, f_max, wmin, wmax, tt, nf) cf, sc, scalogram1 = cwt_fast(tr1.data, ba, nConv, frex, half_wave, fs) cf, sc, scalogram2 = cwt_fast(tr2.data, ba, nConv, frex, half_wave, fs) crossCFS = scalogram1 * np.conj(scalogram2) cross_scalogram = np.abs(crossCFS)**2 cross_scalogram = 10*np.log(cross_scalogram/np.max(cross_scalogram)) cross_scalogram = np.clip(cross_scalogram, a_min=base_line, a_max=0) min_cwt = base_line max_cwt = 0 x, y = np.meshgrid(t, np.logspace(np.log10(f_min), np.log10(f_max), cross_scalogram.shape[0])) c_f = wmin / 2 * math.pi f = np.linspace((f_min), (f_max), cross_scalogram.shape[0]) pred = (math.sqrt(2) * c_f / f) - (math.sqrt(2) * c_f / f_max) pred_comp = t[len(t) - 1] - pred #Plot Seismograms self.cross_spectrumWidget_Widget_Canvas.plot(tr1.times(), self.tr1.data, 0, color="black", linewidth=0.5,alpha = 0.75) self.cross_spectrumWidget_Widget_Canvas.plot(tr2.times(), tr2.data, 0, clear_plot=False, is_twinx=True, color="orangered", linewidth=0.5, alpha=0.75) info = tr1.id + " " + tr2.id self.cross_spectrumWidget_Widget_Canvas.set_plot_label(0, info) self.cross_spectrumWidget_Widget_Canvas.set_ylabel(0, "Amplitude") #info = "{}.{}.{}".format(tr1.stats.network, tr1.stats.station, tr1.stats.channel) #self.cross_spectrumWidget_Widget_Canvas.set_plot_label(0, info) #info = "{}.{}.{}".format(tr2.stats.network, tr2.stats.station, tr1.stats.channel) #self.cross_spectrumWidget_Widget_Canvas.set_plot_label(0, info) # Plot Cross Scalogram self.cross_spectrumWidget_Widget_Canvas.plot_contour(x, y, cross_scalogram, axes_index=1, clabel="Cross Power [dB]", cmap=plt.get_cmap(colour)) # Plot Cone ax_cone = self.cross_spectrumWidget_Widget_Canvas.get_axe(1) ax_cone.fill_between(pred, f, 0, color="black", edgecolor="red", alpha=0.3) ax_cone.fill_between(pred_comp, f, 0, color="black", edgecolor="red", alpha=0.3) self.cross_spectrumWidget_Widget_Canvas.set_xlabel(1, "Time (s)") self.cross_spectrumWidget_Widget_Canvas.set_ylabel(1, "Frequency (Hz)")
class Vespagram(pw.QFrame, UiVespagram): def __init__(self, st, inv, t1, t2): super(Vespagram, self).__init__() self.setupUi(self) """ Vespagram, computed a fixed slowness or backazimuth :param params required to initialize the class: """ self.st = st self.inv = inv self.t1 = t1 self.t2 = t2 self.canvas_vespagram = MatplotlibCanvas(self.widget_vespagram, nrows=2) self.run_vespaBtn.clicked.connect(self.run_vespa) self.plotBtn.clicked.connect(self.plot_vespa) def closeEvent(self, ce): self.save_values() def __load__(self): self.load_values() #@AsycTime.run_async() def run_vespa(self): vespa = vespagram_util(self.st, self.freq_min_DB.value(), self.freq_max_DB.value(), self.win_len_DB.value(), self.slownessDB.value(), self.backazimuthCB.value(), self.inv, self.t1, self.t2, self.overlapSB.value(), selection=self.selectionCB.currentText(), method="FK") self.x, self.y, self.log_vespa_spectrogram = vespa.vespa_deg() md = MessageDialog(self) md.set_info_message("Vespagram Estimated !!!") def plot_vespa(self): if self.selectionCB.currentText() == "Slowness": self.__plot_vespa_slow() else: self.__plot_vespa_az() def __plot_vespa_slow(self): base_line = self.base_lineDB.value() colour = self.colourCB.currentText() #vespagram = np.clip(self.log_vespa_spectrogram, a_min=base_line, a_max=0) vespagram = np.clip(self.log_vespa_spectrogram, a_min=0, a_max=1) self.canvas_vespagram.plot_contour(self.x, self.y, vespagram, axes_index=0, clabel="Rel. Power", cmap=plt.get_cmap(colour)) self.canvas_vespagram.set_xlabel(0, "Time (s)") self.canvas_vespagram.set_ylabel(0, "Azimuth") def __plot_vespa_az(self): base_line = self.base_lineDB.value() colour = self.colourCB.currentText() #vespagram = np.clip(self.log_vespa_spectrogram, a_min=base_line, a_max=0) vespagram = np.clip(self.log_vespa_spectrogram, a_min=0, a_max=1) self.canvas_vespagram.plot_contour(self.x, self.y, vespagram, axes_index=1, clabel="Rel Power", cmap=plt.get_cmap(colour)) self.canvas_vespagram.set_xlabel(1, "Time (s)") self.canvas_vespagram.set_ylabel(1, "Slowness (s/km)")