From eaa7a993af48a56ea64a824a4fcad9d80f679887 Mon Sep 17 00:00:00 2001 From: Marcel Date: Thu, 31 Aug 2017 11:16:13 +0200 Subject: [PATCH] [add] compare widget for multiple events added --- QtPyLoT.py | 105 ++++++++++++++++---------- pylot/core/util/widgets.py | 149 ++++++++++++++----------------------- 2 files changed, 122 insertions(+), 132 deletions(-) diff --git a/QtPyLoT.py b/QtPyLoT.py index fec61ca5..632d746d 100755 --- a/QtPyLoT.py +++ b/QtPyLoT.py @@ -79,7 +79,8 @@ from pylot.core.util.event import Event from pylot.core.io.location import create_creation_info, create_event from pylot.core.util.widgets import FilterOptionsDialog, NewEventDlg, \ WaveformWidget, WaveformWidgetPG, PropertiesDlg, HelpForm, createAction, PickDlg, \ - getDataType, ComparisonWidget, TuneAutopicker, PylotParaBox, AutoPickDlg, CanvasWidget, AutoPickWidget + getDataType, ComparisonWidget, TuneAutopicker, PylotParaBox, AutoPickDlg, CanvasWidget, AutoPickWidget, \ + CompareEventsWidget from pylot.core.util.map_projection import map_projection from pylot.core.util.structure import DATASTRUCTURE from pylot.core.util.thread import Thread, Worker @@ -201,6 +202,14 @@ class MainWindow(QMainWindow): s_filter['order'])} self.loc = False + # init event selection options for compare/autopick + self.pickoptions =[('current event', self.get_current_event), + ('tune events', self.get_ref_events), + ('test events', self.get_test_events), + ('all (picked) events', self.get_manu_picked_events), + ('all events', self.get_all_events)] + + def setupUi(self): try: self.startTime = min( @@ -1230,17 +1239,27 @@ class MainWindow(QMainWindow): return None def comparePicks(self): - if self.check4Comparison(): - comparisons = {} - for event in self.project.eventlist: - autopicks = excludeQualityClasses(event.getAutopicks(), [4], - self._inputs['timeerrorsP'], self._inputs['timeerrorsS']) - manupicks = excludeQualityClasses(event.getPicks(), [4], - self._inputs['timeerrorsP'], self._inputs['timeerrorsS']) - co = Comparison(auto=autopicks, manu=manupicks) - comparisons[event.pylot_id] = co - compare_dlg = ComparisonWidget(comparisons[self.get_current_event_name()], self) - compare_dlg.show() + comparisons = {} + eventdict = {} + for event in self.project.eventlist: + if not self.comparable[event.pylot_id]: + continue + autopicks = excludeQualityClasses(event.getAutopicks(), [4], + self._inputs['timeerrorsP'], self._inputs['timeerrorsS']) + manupicks = excludeQualityClasses(event.getPicks(), [4], + self._inputs['timeerrorsP'], self._inputs['timeerrorsS']) + co = Comparison(auto=autopicks, manu=manupicks) + comparisons[event.pylot_id] = co + eventdict[event.pylot_id] = event + if len(eventdict) < 1: + return + pickoptions = self.pickoptions.copy() + pickoptions.pop(-1) + pickoptions.pop(0) + compare_multi = CompareEventsWidget(self, pickoptions, eventdict, comparisons) + compare_multi.show() + #compare_dlg = ComparisonWidget(comparisons[self.get_current_event_name()], self) + #compare_dlg.show() def getPlotWidget(self): return self.dataPlot @@ -1491,6 +1510,7 @@ class MainWindow(QMainWindow): self.dataPlot.plotWidget.showAxis('bottom') def finishWaveformDataPlot(self): + self.comparable = self.checkEvents4comparison() if self.pg: self.finish_pg_plot() else: @@ -1524,15 +1544,31 @@ class MainWindow(QMainWindow): self.locateEvent.setEnabled(True) if event.pylot_autopicks: self.drawPicks(picktype='auto') - if event.pylot_picks and event.pylot_autopicks: - for key in event.pylot_picks: - for akey in event.pylot_autopicks: - if (akey == key) and (event.pylot_autopicks[akey]['P']['spe'] is not None \ - or event.pylot_autopicks[akey]['S']['spe'] is not None): - self.compare_action.setEnabled(True) - break + if True in self.comparable.values(): + self.compare_action.setEnabled(True) self.draw() + def checkEvent4comparison(self, event): + if event.pylot_picks and event.pylot_autopicks: + for station in event.pylot_picks: + if station in event.pylot_autopicks: + autopick_p = event.pylot_autopicks[station]['P']['spe'] + manupick_p = event.pylot_picks[station]['P']['spe'] + autopick_s = event.pylot_autopicks[station]['S']['spe'] + manupick_s = event.pylot_picks[station]['S']['spe'] + if autopick_p and manupick_p: + return True + elif autopick_s and manupick_s: + return True + return False + + def checkEvents4comparison(self): + # init dict to keep track whether event can be compared + comparable = {} + for event in self.project.eventlist: + comparable[event.pylot_id] = self.checkEvent4comparison(event) + return comparable + def clearWaveformDataPlot(self): self.disconnectWFplotEvents() if self.pg: @@ -1919,12 +1955,6 @@ class MainWindow(QMainWindow): "No autoPyLoT output declared!") return - self.pickoptions =[('current event', self.get_current_event), - ('tune events', self.get_ref_events), - ('test events', self.get_test_events), - ('all (picked) events', self.get_manu_picked_events), - ('all events', self.get_all_events)] - self.listWidget = QListWidget() self.setDirty(True) self.apw = AutoPickWidget(self, self.pickoptions) @@ -2096,7 +2126,6 @@ class MainWindow(QMainWindow): #event.picks.update(picks) MP MP idea elif type == 'auto': event.addAutopicks(picksdict['auto']) - self.check4Comparison() def drawPicks(self, station=None, picktype=None): # if picktype not specified, draw both @@ -2636,18 +2665,18 @@ class MainWindow(QMainWindow): def check4Loc(self): return self.picksNum() >= 4 - def check4Comparison(self): - mpicks = self.getPicks() - apicks = self.getPicks('auto') - for station, phases in mpicks.items(): - try: - aphases = apicks[station] - for phase in phases.keys(): - if phase in aphases.keys(): - return True - except KeyError: - continue - return False + # def check4Comparison(self): + # mpicks = self.getPicks() + # apicks = self.getPicks('auto') + # for station, phases in mpicks.items(): + # try: + # aphases = apicks[station] + # for phase in phases.keys(): + # if phase in aphases.keys(): + # return True + # except KeyError: + # continue + # return False def picksNum(self, type='manual'): num = 0 diff --git a/pylot/core/util/widgets.py b/pylot/core/util/widgets.py index e157c8d5..ad606721 100644 --- a/pylot/core/util/widgets.py +++ b/pylot/core/util/widgets.py @@ -121,7 +121,7 @@ def createAction(parent, text, slot=None, shortcut=None, icon=None, class ComparisonWidget(QWidget): - def __init__(self, c, parent=None): + def __init__(self, c, parent=None, windowflag=1): self._data = c self._stats = c.stations self._canvas = PlotWidget(self) @@ -130,7 +130,7 @@ class ComparisonWidget(QWidget): histCheckBox=None) self._phases = 'PS' self._plotprops = dict(station=list(self.stations)[0], phase=list(self.phases)[0]) - super(ComparisonWidget, self).__init__(parent, 1) + super(ComparisonWidget, self).__init__(parent, windowflag) self.setupUI() self.resize(1280, 720) self.plotcomparison() @@ -2092,6 +2092,22 @@ class MultiEventWidget(QWidget): self.main_layout.insertLayout(0, self.rb_layout) + def refresh_tooltips(self): + for key, func in self.pickoptions: + eventlist = func() + if not type(eventlist) == list: + eventlist = [eventlist] + tooltip='' + for index, event in enumerate(eventlist): + if not event: + continue + tooltip += '{}'.format(event.pylot_id) + if not index + 1 == len(eventlist): + tooltip += '\n' + if not tooltip: + tooltip = 'No events for this selection' + self.rb_dict[key].setToolTip(tooltip) + def enable(self, bool): for rb in self.rb_dict.values(): rb.setEnabled(bool) @@ -2111,6 +2127,7 @@ class AutoPickWidget(MultiEventWidget): self.init_log_layout() self.reinitEvents2plot() self.setWindowTitle('Autopick events interactively') + self.set_main_stretch() def connect_buttons(self): self.start_button.clicked.connect(self.run) @@ -2167,6 +2184,10 @@ class AutoPickWidget(MultiEventWidget): self.eventbox_layout.setStretch(0, 1) self.plot_layout.insertLayout(0, self.eventbox_layout) + def set_main_stretch(self): + self.main_layout.setStretch(0, 0) + self.main_layout.setStretch(1, 1) + def reinitEvents2plot(self): self.events2plot = {} self.eventbox.clear() @@ -2175,119 +2196,59 @@ class AutoPickWidget(MultiEventWidget): def refresh_plot_tabs(self): self.tab_plots.clear() - def refresh_tooltips(self): - for key, func in self.pickoptions: - eventlist = func() - if not type(eventlist) == list: - eventlist = [eventlist] - tooltip='' - for index, event in enumerate(eventlist): - if not event: - continue - tooltip += '{}'.format(event.pylot_id) - if not index + 1 == len(eventlist): - tooltip += '\n' - if not tooltip: - tooltip = 'No events for this selection' - self.rb_dict[key].setToolTip(tooltip) - def run(self): self.refresh_plot_tabs() self.start.emit() + class CompareEventsWidget(MultiEventWidget): ''' ''' - def __init__(self, parent, pickoptions): + def __init__(self, parent, pickoptions, eventdict, comparisons): MultiEventWidget.__init__(self, pickoptions, parent, 1) + self.eventdict = eventdict + self.comparisons = comparisons + self.init_eventbox() self.connect_buttons() - self.init_plot_layout() - self.init_log_layout() - self.reinitEvents2plot() - self.setWindowTitle('Autopick events interactively') + self.setWindowTitle('Compare events') + self.set_main_stretch() def connect_buttons(self): self.start_button.clicked.connect(self.run) - self.button_clear.clicked.connect(self.reinitEvents2plot) - def init_plot_layout(self): - # init tab widget - self.tab_plots = QtGui.QTabWidget() - self.gb_plots = QtGui.QGroupBox('Plots') - self.gb_plots.setMinimumSize(100, 100) - self.main_splitter.insertWidget(1, self.gb_plots) - self.plot_layout = QtGui.QVBoxLayout() - self.plot_layout.insertWidget(1, self.tab_plots) - self.gb_plots.setLayout(self.plot_layout) + def init_eventbox(self): + self.eventbox_layout = QtGui.QHBoxLayout() + self.eventbox_layout.addWidget(self.eventbox) + self.main_layout.insertLayout(1, self.eventbox_layout) + self.fill_eventbox() + self.eventbox.currentIndexChanged.connect(self.update_comparison) - def init_log_layout(self): - self.gb_log = QtGui.QGroupBox('Log') - self.gb_log.setMinimumSize(100, 100) - self.main_splitter.insertWidget(0, self.gb_log) + def fill_eventbox(self): + event_ids = list(self.eventdict.keys()) + for event_id in sorted(event_ids): + self.eventbox.addItem(str(event_id)) + self.update_comparison() - def insert_log_widget(self, widget): - vl = QtGui.QVBoxLayout() - vl.addWidget(widget) - self.gb_log.setLayout(vl) - - def add_plot_widget(self, widget, key, eventID): - eventID += ' [picked: {}]'.format(time.strftime('%X %x %z')) - if not eventID in self.events2plot.keys(): - self.events2plot[eventID] = {} - self.events2plot[eventID][key] = widget - - def generate_combobox(self): + def update_eventbox(self): self.eventbox.clear() - for eventID, widgets in self.events2plot.items(): - self.eventbox.addItem(str(eventID), widgets) - self.eventbox.currentIndexChanged.connect(self.draw_plots) - self.draw_plots() + self.fill_eventbox() - def draw_plots(self, index=0): - self.refresh_plot_tabs() - widgets = self.eventbox.itemData(index) - if not widgets: - return - for key, widget in widgets.items(): - self.tab_plots.addTab(widget, str(key)) + def update_comparison(self, index=0): + if hasattr(self, 'compare_widget'): + self.compare_widget.setParent(None) + self.compare_widget = ComparisonWidget( + self.comparisons[self.eventbox.currentText()], self, 0) + self.main_layout.insertWidget(2, self.compare_widget) + self.set_main_stretch() - def update_plots(self): - self.refresh_plot_tabs() - if len(self.events2plot) > 0: - self.eventbox_layout = QtGui.QHBoxLayout() - self.generate_combobox() - self.eventbox_layout.addWidget(self.eventbox) - self.eventbox_layout.addWidget(self.button_clear) - self.eventbox_layout.setStretch(0, 1) - self.plot_layout.insertLayout(0, self.eventbox_layout) - - def reinitEvents2plot(self): - self.events2plot = {} - self.eventbox.clear() - self.refresh_plot_tabs() - - def refresh_plot_tabs(self): - self.tab_plots.clear() - - def refresh_tooltips(self): - for key, func in self.pickoptions: - eventlist = func() - if not type(eventlist) == list: - eventlist = [eventlist] - tooltip='' - for index, event in enumerate(eventlist): - if not event: - continue - tooltip += '{}'.format(event.pylot_id) - if not index + 1 == len(eventlist): - tooltip += '\n' - if not tooltip: - tooltip = 'No events for this selection' - self.rb_dict[key].setToolTip(tooltip) + def set_main_stretch(self): + self.main_layout.setStretch(0, 0) + self.main_layout.setStretch(1, 0) + self.main_layout.setStretch(2, 1) + self.main_layout.setStretch(3, 0) def run(self): - self.refresh_plot_tabs() self.start.emit()