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 EarthquakeLocationFrame(pw.QFrame, UiEarthquakeLocationFrame): def __init__(self, parent: pw.QWidget): super(EarthquakeLocationFrame, self).__init__(parent) self.setupUi(self) ParentWidget.set_parent(parent, self) self.__pick_output_path = PickerManager.get_default_output_path() self.__dataless_dir = None self.__nll_manager = None self.__first_polarity = None # Map self.cartopy_canvas = CartopyCanvas(self.widget_map) # Canvas for Earthquake Location Results self.residuals_canvas = MatplotlibCanvas(self.plotMatWidget_residuals) #self.residuals_canvas.figure.subplots_adjust(left = 0.03, bottom = 0.36, right=0.97, top=0.95, wspace=0.2, # hspace=0.0) # Canvas for FOCMEC Results self.focmec_canvas = FocCanvas(self.widget_focmec) self.grid_latitude_bind = BindPyqtObject(self.gridlatSB) self.grid_longitude_bind = BindPyqtObject(self.gridlonSB) self.grid_depth_bind = BindPyqtObject(self.griddepthSB) self.grid_xnode_bind = BindPyqtObject(self.xnodeSB) self.grid_ynode_bind = BindPyqtObject(self.ynodeSB) self.grid_znode_bind = BindPyqtObject(self.znodeSB) self.grid_dxsize_bind = BindPyqtObject(self.dxsizeSB) self.grid_dysize_bind = BindPyqtObject(self.dysizeSB) self.grid_dzsize_bind = BindPyqtObject(self.dzsizeSB) self.genvelBtn.clicked.connect(lambda: self.on_click_run_vel_to_grid()) self.grdtimeBtn.clicked.connect( lambda: self.on_click_run_grid_to_time()) self.runlocBtn.clicked.connect(lambda: self.on_click_run_loc()) self.plotmapBtn.clicked.connect(lambda: self.on_click_plot_map()) self.stationsBtn.clicked.connect( lambda: self.on_click_select_metadata_file()) self.firstpolarityBtn.clicked.connect(self.first_polarity) self.plotpdfBtn.clicked.connect(self.plot_pdf) @property def nll_manager(self): if not self.__nll_manager: self.__nll_manager = NllManager(self.__pick_output_path, self.__dataless_dir) return self.__nll_manager @property def firstpolarity_manager(self): if not self.__first_polarity: self.__first_polarity = FirstPolarity() return self.__first_polarity def on_click_select_metadata_file(self): selected = pw.QFileDialog.getOpenFileName( self, "Select metadata/stations coordinates file") if isinstance(selected[0], str) and os.path.isfile(selected[0]): self.stationsPath.setText(selected[0]) self.set_dataless_dir(self.stationsPath.text()) def set_dataless_dir(self, dir_path): self.__dataless_dir = dir_path self.nll_manager.set_dataless_dir(dir_path) def set_pick_output_path(self, file_path): self.__pick_output_path = file_path self.nll_manager.set_observation_file(file_path) def info_message(self, msg, detailed_message=None): md = MessageDialog(self) md.set_info_message(msg, detailed_message) def subprocess_feedback(self, err_msg: str, set_default_complete=True): """ This method is used as a subprocess feedback. It runs when a raise expect is detected. :param err_msg: The error message from the except. :param set_default_complete: If True it will set a completed successfully message. Otherwise nothing will be displayed. :return: """ if err_msg: md = MessageDialog(self) if "Error code" in err_msg: md.set_error_message( "Click in show details detail for more info.", err_msg) else: md.set_warning_message("Click in show details for more info.", err_msg) else: if set_default_complete: md = MessageDialog(self) md.set_info_message("Completed Successfully.") @parse_excepts(lambda self, msg: self.subprocess_feedback(msg)) def on_click_run_vel_to_grid(self): self.nll_manager.vel_to_grid( self.grid_latitude_bind.value, self.grid_longitude_bind.value, self.grid_depth_bind.value, self.grid_xnode_bind.value, self.grid_ynode_bind.value, self.grid_znode_bind.value, self.grid_dxsize_bind.value, self.grid_dysize_bind.value, self.grid_dzsize_bind.value, self.comboBox_gridtype.currentText(), self.comboBox_wavetype.currentText(), self.modelCB.currentText()) @parse_excepts(lambda self, msg: self.subprocess_feedback(msg)) def on_click_run_grid_to_time(self): if self.distanceSB.value() > 0: limit = self.distanceSB.value() else: limit = np.sqrt( (self.grid_xnode_bind.value * self.grid_dxsize_bind.value)**2 + (self.grid_xnode_bind.value * self.grid_dxsize_bind.value)**2) self.nll_manager.grid_to_time(self.grid_latitude_bind.value, self.grid_longitude_bind.value, self.grid_depth_bind.value, self.comboBox_grid.currentText(), self.comboBox_angles.currentText(), self.comboBox_ttwave.currentText(), limit) @parse_excepts(lambda self, msg: self.subprocess_feedback( msg, set_default_complete=False)) def on_click_run_loc(self): transform = self.transCB.currentText() std_out = self.nll_manager.run_nlloc(self.grid_latitude_bind.value, self.grid_longitude_bind.value, self.grid_depth_bind.value, transform) self.info_message("Location complete. Check details.", std_out) @parse_excepts(lambda self, msg: self.subprocess_feedback(msg)) def on_click_plot_map(self): origin = self.nll_manager.get_NLL_info() scatter_x, scatter_y, scatter_z, pdf = self.nll_manager.get_NLL_scatter( ) lat = origin.latitude lon = origin.longitude stations = self.nll_manager.stations_match() self.cartopy_canvas.plot_map(lon, lat, scatter_x, scatter_y, scatter_z, 0, resolution='high', stations=stations) # Writing Location information self.add_earthquake_info(origin) xp, yp, xs, ys = self.nll_manager.ger_NLL_residuals() self.plot_residuals(xp, yp, xs, ys) def plot_pdf(self): scatter_x, scatter_y, scatter_z, pdf = self.nll_manager.get_NLL_scatter( ) self.pdf = PDFmanger(scatter_x, scatter_y, scatter_z, pdf) self.pdf.plot_scatter() def plot_residuals(self, xp, yp, xs, ys): artist = self.residuals_canvas.plot(xp, yp, axes_index=0, linewidth=0.5) self.residuals_canvas.set_xlabel(0, "Station") self.residuals_canvas.set_ylabel(0, "P wave Res") self.residuals_canvas.set_yaxis_color(self.residuals_canvas.get_axe(0), artist.get_color(), is_left=True) self.residuals_canvas.plot(xs, ys, 0, is_twinx=True, color="red", linewidth=0.5) self.residuals_canvas.set_ylabel_twinx(0, "S wave Res") self.residuals_canvas.plot(xp, yp, axes_index=0, linewidth=0.5) def first_polarity(self): import pandas as pd path_output = os.path.join(ROOT_DIR, "earthquakeAnalisysis", "location_output", "loc", "first_polarity.fp") self.firstpolarity_manager.create_input() self.firstpolarity_manager.run_focmec() Station, Az, Dip, Motion = self.firstpolarity_manager.get_dataframe() cat, Plane_A = self.firstpolarity_manager.extract_focmec_info() #print(cat[0].focal_mechanisms[0]) strike_A = Plane_A.strike dip_A = Plane_A.dip rake_A = Plane_A.rake misfit_first_polarity = cat[0].focal_mechanisms[0].misfit azimuthal_gap = cat[0].focal_mechanisms[0].azimuthal_gap number_of_polarities = cat[0].focal_mechanisms[ 0].station_polarity_count first_polarity_results = { "First_Polarity": [ "Strike", "Dip", "Rake", "misfit_first_polarity", "azimuthal_gap", "number_of_polarities" ], "results": [ strike_A, dip_A, rake_A, misfit_first_polarity, azimuthal_gap, number_of_polarities ] } df = pd.DataFrame(first_polarity_results, columns=["First_Polarity", "results"]) df.to_csv(path_output, sep=' ', index=False) self.focmec_canvas.drawFocMec(strike_A, dip_A, rake_A, Station, Az, Dip, Motion, 0) self.add_first_polarity_info(first_polarity_results) def add_first_polarity_info(self, first_polarity_results): self.FirstPolarityInfoText.setPlainText("First Polarity Results") self.FirstPolarityInfoText.appendPlainText( "Strike: {Strike:.3f}".format( Strike=first_polarity_results["results"][0])) self.FirstPolarityInfoText.appendPlainText( "Dip: {Dip:.3f}".format(Dip=first_polarity_results["results"][1])) self.FirstPolarityInfoText.appendPlainText("Rake: {Rake:.3f}".format( Rake=first_polarity_results["results"][2])) self.FirstPolarityInfoText.appendPlainText( "Misfit: {Misfit:.3f}".format( Misfit=first_polarity_results["results"][3])) self.FirstPolarityInfoText.appendPlainText( "GAP: {GAP:.3f}".format(GAP=first_polarity_results["results"][4])) self.FirstPolarityInfoText.appendPlainText( "Number of polarities: {NP:.3f}".format( NP=first_polarity_results["results"][5])) def add_earthquake_info(self, origin: Origin): self.EarthquakeInfoText.setPlainText( " Origin time and RMS: {origin_time} {standard_error:.3f}" .format(origin_time=origin.time, standard_error=origin.quality.standard_error)) self.EarthquakeInfoText.appendPlainText( " Hypocenter Geographic Coordinates: " "Latitude {lat:.3f} " "Longitude {long:.3f} Depth {depth:.3f} " "Uncertainty {unc:.3f}".format( lat=origin.latitude, long=origin.longitude, depth=origin.depth / 1000, unc=origin.depth_errors['uncertainty'])) self.EarthquakeInfoText.appendPlainText( " Horizontal Ellipse: Max Horizontal Err {:.3f} " "Min Horizontal Err {:.3f} " "Azimuth {:.3f}".format( origin.origin_uncertainty.max_horizontal_uncertainty, origin.origin_uncertainty.min_horizontal_uncertainty, origin.origin_uncertainty.azimuth_max_horizontal_uncertainty)) self.EarthquakeInfoText.appendPlainText( " Quality Parameters: Number of Phases {:.3f} " "Azimuthal GAP {:.3f} Minimum Distance {:.3f} " "Maximum Distance {:.3f}".format(origin.quality.used_phase_count, origin.quality.azimuthal_gap, origin.quality.minimum_distance, origin.quality.maximum_distance))
class SyntheticsAnalisysFrame(pw.QMainWindow, UiSyntheticsAnalisysFrame): def __init__(self, parent: pw.QWidget = None): super(SyntheticsAnalisysFrame, self).__init__(parent) self.setupUi(self) ParentWidget.set_parent(parent, self) self.setWindowTitle('Synthetics Analysis Frame') self.setWindowIcon(pqg.QIcon(':\icons\pen-icon.png')) #Initialize parametrs for plot rotation self._z = {} self._r = {} self._t = {} self._st = {} self.inventory = {} parameters = {} self._generator = SyntheticsGeneratorDialog(self) # 3C_Component self.focmec_canvas = FocCanvas(self.widget_fp) self.canvas = MatplotlibCanvas(self.plotMatWidget_3C) self.canvas.set_new_subplot(3, ncols=1) # Map self.cartopy_canvas = CartopyCanvas(self.map_widget) # binds self.root_path_bind_3C = BindPyqtObject(self.rootPathForm_3C, self.onChange_root_path_3C) self.vertical_form_bind = BindPyqtObject(self.verticalQLineEdit) self.north_form_bind = BindPyqtObject(self.northQLineEdit) self.east_form_bind = BindPyqtObject(self.eastQLineEdit) self.generation_params_bind = BindPyqtObject(self.paramsPathLineEdit) # accept drops self.vertical_form_bind.accept_dragFile(drop_event_callback=self.drop_event) self.north_form_bind.accept_dragFile(drop_event_callback=self.drop_event) self.east_form_bind.accept_dragFile(drop_event_callback=self.drop_event) self.generation_params_bind.accept_dragFile(drop_event_callback=self.drop_event) self.paramsPathLineEdit.textChanged.connect(self._generationParamsChanged) # Add file selector to the widget self.file_selector = FilesView(self.root_path_bind_3C.value, parent=self.fileSelectorWidget) self.file_selector.setDragEnabled(True) self.selectDirBtn_3C.clicked.connect(self.on_click_select_directory_3C) self.plotBtn.clicked.connect(self.on_click_rotate) ### self.stationsBtn.clicked.connect(self.stationsInfo) ### self.actionGenerate_synthetics.triggered.connect(lambda : self._generator.show()) def info_message(self, msg): md = MessageDialog(self) md.set_info_message(msg) def _generationParamsChanged(self): with open(self.generation_params_file, 'rb') as f: self.params = pickle.load(f) depth_est =self.params['sourcedepthinmeters'] depth_est =(float(depth_est))/1000 #self.paramsTextEdit.setPlainText(str(params)) self.paramsTextEdit.setPlainText("Earth Model: {model}".format(model=self.params['model'])) self.paramsTextEdit.appendPlainText("Event Coords: {lat} {lon} {depth}".format( lat=self.params['sourcelatitude'],lon=self.params['sourcelongitude'], depth=str(depth_est))) self.paramsTextEdit.appendPlainText("Time: {time}".format(time=self.params['origintime'])) self.paramsTextEdit.appendPlainText("Units: {units}".format(units=self.params['units'])) if 'sourcedoublecouple' in self.params: self.paramsTextEdit.appendPlainText("Source: {source}".format(source= self.params['sourcedoublecouple'])) if 'sourcemomenttensor' in self.params: self.paramsTextEdit.appendPlainText("Source: {source}".format(source= self.params['sourcemomenttensor'])) @staticmethod def drop_event(event: pqg.QDropEvent, bind_object: BindPyqtObject): data = event.mimeData() url = data.urls()[0] bind_object.value = url.fileName() @property def north_component_file(self): return os.path.join(self.root_path_bind_3C.value, self.north_form_bind.value) @property def vertical_component_file(self): return os.path.join(self.root_path_bind_3C.value, self.vertical_form_bind.value) @property def east_component_file(self): return os.path.join(self.root_path_bind_3C.value, self.east_form_bind.value) @property def generation_params_file(self): return os.path.join(self.root_path_bind_3C.value, self.generation_params_bind.value) def onChange_root_path_3C(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) # Function added for 3C Components def on_click_select_directory_3C(self): if "darwin" == platform: dir_path = pw.QFileDialog.getExistingDirectory(self, 'Select Directory', self.root_path_bind_3C.value) else: dir_path = pw.QFileDialog.getExistingDirectory(self, 'Select Directory', self.root_path_bind_3C.value, pw.QFileDialog.DontUseNativeDialog) if dir_path: self.root_path_bind_3C.value = dir_path def on_click_rotate(self, canvas): time1 = convert_qdatetime_utcdatetime(self.dateTimeEdit_4) time2 = convert_qdatetime_utcdatetime(self.dateTimeEdit_5) try: sd = SeismogramData(self.vertical_component_file) z = sd.get_waveform() sd = SeismogramData(self.north_component_file) n = sd.get_waveform() sd = SeismogramData(self.east_component_file) e = sd.get_waveform() seismograms = [z, n, e] time = z.times("matplotlib") self._st = Stream(traces=seismograms) for index, data in enumerate(seismograms): self.canvas.plot(time, data, index, color="black", linewidth=0.5) info = "{}.{}.{}".format(self._st[index].stats.network, self._st[index].stats.station, self._st[index].stats.channel) ax = self.canvas.get_axe(0) ax.set_xlim(time1.matplotlib_date, time2.matplotlib_date) formatter = mdt.DateFormatter('%Y/%m/%d/%H:%M:%S') ax.xaxis.set_major_formatter(formatter) self.canvas.set_plot_label(index, info) self.canvas.set_xlabel(2, "Time (s)") if 'sourcedoublecouple' in self.params: self.focmec_canvas.drawSynthFocMec(0, first_polarity = self.params['sourcedoublecouple'], mti = []) if 'sourcemomenttensor' in self.params: self.focmec_canvas.drawSynthFocMec(0, first_polarity= [], mti=self.params['sourcemomenttensor']) except InvalidFile: self.info_message("Invalid mseed files. Please, make sure you have generated correctly the synthetics") self.__map_coords() def stationsInfo(self): files = [] try: if self.vertical_component_file and self.north_component_file and self.east_component_file: files = [self.vertical_component_file, self.north_component_file, self.east_component_file] except: pass sd = [] if len(files)==3: for file in files: try: 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) except: pass self._stations_info = StationsInfo(sd) self._stations_info.show() def __map_coords(self): map_dict = {} sd = [] with open(self.generation_params_file, 'rb') as f: params = pickle.load(f) n = len(params["bulk"]) for j in range(n): for key in params["bulk"][j]: if key == "latitude": lat = params["bulk"][j][key] elif key == "longitude": lon = params["bulk"][j][key] #elif key == "networkcode": # net = params["bulk"][j][key] elif key == "stationcode": sta = params["bulk"][j][key] sd.append(sta) map_dict[sta] = [lon, lat] self.cartopy_canvas.plot_map(params['sourcelongitude'], params['sourcelatitude'], 0, 0, 0, 0, resolution='low', stations=map_dict)