From 536019259e54341011933864a8edb7d62c744671 Mon Sep 17 00:00:00 2001 From: Sebastianw Wehling-Benatelli Date: Mon, 6 Jun 2016 14:10:46 +0200 Subject: [PATCH] [adresses 195] preparing GUI elements for a new dialog widget for interactive comparison --- QtPyLoT.py | 38 ++++++++++++++--- icons.qrc | 1 + icons/compare.png | Bin 0 -> 3108 bytes icons_rc.py | 8 ++-- inputs/autoPyLoT.in | 1 + pylot/core/pick/compare.py | 16 +++++-- pylot/core/util/widgets.py | 84 +++++++++++++++++++++++++++++++++++-- 7 files changed, 131 insertions(+), 17 deletions(-) create mode 100644 icons/compare.png diff --git a/QtPyLoT.py b/QtPyLoT.py index 5b0f5f31..e8709d0c 100755 --- a/QtPyLoT.py +++ b/QtPyLoT.py @@ -53,7 +53,7 @@ from pylot.core.util.utils import fnConstructor, getLogin, \ getGlobalTimes from pylot.core.io.location import create_creation_info, create_event from pylot.core.util.widgets import FilterOptionsDialog, NewEventDlg, \ - MPLWidget, PropertiesDlg, HelpForm, createAction, PickDlg, getDataType + WaveformWidget, PropertiesDlg, HelpForm, createAction, PickDlg, getDataType from pylot.core.util.structure import DATASTRUCTURE from pylot.core.util.thread import AutoPickThread from pylot.core.util.version import get_git_version as _getVersionString @@ -142,8 +142,8 @@ class MainWindow(QMainWindow): plottitle = "Overview: {0} components ".format(self.getComponent()) # create central matplotlib figure canvas widget - self.DataPlot = MPLWidget(parent=self, xlabel=xlab, ylabel=None, - title=plottitle) + self.DataPlot = WaveformWidget(parent=self, xlabel=xlab, ylabel=None, + title=plottitle) self.DataPlot.mpl_connect('button_press_event', self.pickOnStation) self.DataPlot.mpl_connect('axes_enter_event', @@ -178,6 +178,8 @@ class MainWindow(QMainWindow): auto_icon.addPixmap(QPixmap(':/icons/sync.png')) locate_icon = QIcon() locate_icon.addPixmap(QPixmap(':/icons/locate.png')) + compare_icon = QIcon() + compare_icon.addPixmap(QPixmap(':/icons/compare.png')) newEventAction = self.createAction(self, "&New event ...", self.createNewEvent, @@ -244,6 +246,12 @@ class MainWindow(QMainWindow): "Alt+S", s_icon, "Toggle S phase", True) + self.compare_action = self.createAction(self, "&Compare picks...", + self.comparePicks, "Alt+C", + compare_icon, "Comparison of " + "manual and " + "automatic pick " + "data.", False) printAction = self.createAction(self, "&Print event ...", self.printEvent, QKeySequence.Print, print_icon, @@ -318,7 +326,7 @@ class MainWindow(QMainWindow): ' displayed!') autoPickToolBar = self.addToolBar("autoPyLoT") - autoPickActions = (auto_pick,) + autoPickActions = (auto_pick, self.compare_action) self.addActions(autoPickToolBar, autoPickActions) # pickToolBar = self.addToolBar("PickTools") @@ -568,6 +576,10 @@ class MainWindow(QMainWindow): except KeyError: return None + def comparePicks(self): + if self.check4Comparison(): + compare_dlg = ComparisonDialog(self) + def getPlotWidget(self): return self.DataPlot @@ -828,6 +840,7 @@ class MainWindow(QMainWindow): self.picks.update(picks) elif type == 'auto': self.autopicks.update(picks) + self.check4Comparison() def drawPicks(self, station=None, picktype='manual'): # if picks to draw not specified, draw all picks available @@ -882,9 +895,22 @@ class MainWindow(QMainWindow): def check4Loc(self): return self.picksNum() > 4 - def picksNum(self): + 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 - for phases in self.getPicks().values(): + for phases in self.getPicks(type).values(): num += len(phases) return num diff --git a/icons.qrc b/icons.qrc index 8b2065fc..96b8126c 100644 --- a/icons.qrc +++ b/icons.qrc @@ -5,6 +5,7 @@ icons/locate.png icons/printer.png icons/delete.png + icons/compare.png icons/key_E.png icons/key_N.png icons/key_P.png diff --git a/icons/compare.png b/icons/compare.png new file mode 100644 index 0000000000000000000000000000000000000000..be28ca746ce1746a285f3c01f03674928775e3e6 GIT binary patch literal 3108 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 everything AUTOPHASES_AIC_HOS4_ARH #phasefile# %name of autoPILOT output phase file diff --git a/pylot/core/pick/compare.py b/pylot/core/pick/compare.py index 1a828c2a..d246be67 100644 --- a/pylot/core/pick/compare.py +++ b/pylot/core/pick/compare.py @@ -29,7 +29,10 @@ class Comparison(object): names = list() self._pdfs = dict() for name, fn in kwargs.items(): - self._pdfs[name] = PDFDictionary.from_quakeml(fn) + if not isinstance(PDFDictionary, fn): + self._pdfs[name] = PDFDictionary.from_quakeml(fn) + else: + self._pdfs[name] = fn names.append(name) if len(names) > 2: raise ValueError('Comparison is only defined for two ' @@ -101,14 +104,19 @@ class Comparison(object): return compare_pdfs - def plot(self): - nstations = self.nstations - stations = self.stations + def plot(self, stations=None): + if stations is None: + nstations = self.nstations + stations = self.stations + else: + nstations = len(stations) istations = range(nstations) fig, axarr = plt.subplots(nstations, 2, sharex='col', sharey='row') for n in istations: station = stations[n] + if station not in self.comparison.keys(): + continue compare_pdf = self.comparison[station] for l, phase in enumerate(compare_pdf.keys()): axarr[n, l].plot(compare_pdf[phase].axis, diff --git a/pylot/core/util/widgets.py b/pylot/core/util/widgets.py index bf916aff..0b30c0c8 100644 --- a/pylot/core/util/widgets.py +++ b/pylot/core/util/widgets.py @@ -64,8 +64,86 @@ def createAction(parent, text, slot=None, shortcut=None, icon=None, action.setCheckable(True) return action +class ComparsionDialog(QDialog): + def __init__(self, c, parent=None): + self._data = c + self._stats = c.keys() + self._canvas = PlotWidget(parent) + super(ComparsionDialog, self).__init__(parent) + self -class MPLWidget(FigureCanvas): + def setupUI(self): + pass + + @property + def canvas(self): + return self._canvas + + @property + def stations(self): + return self._stats + + @stations.setter + def stations(self, stations): + self._stats = stations + + @property + def data(self): + return self._data + + @data.setter + def data(self, data): + self.stations = data.keys() + self._data = data + + +class PlotWidget(FigureCanvas): + def __init__(self, parent=None, xlabel='x', ylabel='y', title='Title'): + self._parent = parent + self._fig = Figure() + self._xl = xlabel + self._yl = ylabel + self._title = title + super(PlotWidget, self).__init__(self.figure) + + @property + def figure(self): + return self._fig + + @figure.setter + def figure(self, fig): + self._fig = fig + + @property + def xlabel(self): + return self._xl + + @xlabel.setter + def xlabel(self, label): + self._xl = label + + @property + def ylabel(self): + return self._yl + + @ylabel.setter + def ylabel(self, label): + self._yl = label + + @property + def title(self): + return self._title + + @title.setter + def title(self, title): + self._title = title + + @property + def parent(self): + return self._parent + + +class WaveformWidget(FigureCanvas): def __init__(self, parent=None, xlabel='x', ylabel='y', title='Title'): self._parent = None @@ -79,7 +157,7 @@ class MPLWidget(FigureCanvas): # clear axes each time plot is called self.axes.hold(True) # initialize super class - super(MPLWidget, self).__init__(self.figure) + super(WaveformWidget, self).__init__(self.figure) # add an cursor for station selection self.multiCursor = MultiCursor(self.figure.canvas, (self.axes,), horizOn=True, @@ -223,7 +301,7 @@ class PickDlg(QDialog): self.stime, self.etime = getGlobalTimes(self.getWFData()) # initialize plotting widget - self.multicompfig = MPLWidget(self) + self.multicompfig = WaveformWidget(self) # setup ui self.setupUi()