From 08703bf691b374e07210a56d271d1a5f7e4f95d3 Mon Sep 17 00:00:00 2001 From: Marcel Date: Mon, 8 Jan 2018 13:47:40 +0100 Subject: [PATCH 01/13] [add] some hacks to display air pressure in plot --- pylot/core/util/widgets.py | 32 ++++++++++++++++++++++++++------ 1 file changed, 26 insertions(+), 6 deletions(-) diff --git a/pylot/core/util/widgets.py b/pylot/core/util/widgets.py index f755965e..e2b2b6ab 100644 --- a/pylot/core/util/widgets.py +++ b/pylot/core/util/widgets.py @@ -901,7 +901,8 @@ class PylotCanvas(FigureCanvas): def plotWFData(self, wfdata, title=None, zoomx=None, zoomy=None, noiselevel=None, scaleddata=False, mapping=True, - component='*', nth_sample=1, iniPick=None, verbosity=0): + component='*', nth_sample=1, iniPick=None, verbosity=0, + plot_additional=False): ax = self.axes[0] ax.cla() @@ -965,6 +966,17 @@ class PylotCanvas(FigureCanvas): color = linecolor, linestyle = 'dashed') self.setPlotDict(n, (station, channel, network)) + if plot_additional: + pressure = wfdata.select(channel='MDO') + if pressure: + p_data = pressure[0].data + #normalize + p_max = max(abs(p_data)) + p_data /= p_max + for index in range(3): + ax.plot(times, p_data, color='red', alpha=0.5, linewidth=0.7) + p_data += 1 + if iniPick: ax.vlines(iniPick, ax.get_ylim()[0], ax.get_ylim()[1], colors='m', linestyles='dashed', @@ -1166,6 +1178,8 @@ class PickDlg(QDialog): self.filteroptions = FILTERDEFAULTS self.pick_block = False self.nextStation = QtGui.QCheckBox('Continue with next station.') + self.additionalChannel = QtGui.QCheckBox('Additional Channel') + self.additionalChannel.stateChanged.connect(self.resetPlot) # initialize panning attributes self.press = None @@ -1326,6 +1340,7 @@ class PickDlg(QDialog): 'padding-left:5px}') _dialtoolbar.addWidget(est_label) _dialtoolbar.addWidget(self.plot_arrivals_button) + _dialtoolbar.addWidget(self.additionalChannel) # layout the innermost widget _innerlayout = QVBoxLayout() @@ -1614,7 +1629,8 @@ class PickDlg(QDialog): self.reset_p_button() self.reset_s_button() self.multicompfig.plotWFData(wfdata=self.getWFData(), - title=self.getStation()) + title=self.getStation(), + plot_additional=self.additionalChannel.isChecked()) self.drawAllPicks() self.drawArrivals() self.setPlotLabels() @@ -1822,7 +1838,8 @@ class PickDlg(QDialog): zoomy=self.getYLims(), noiselevel=(trace_number + noiselevel, trace_number - noiselevel), - iniPick=ini_pick) + iniPick=ini_pick, + plot_additional=self.additionalChannel.isChecked()) def setIniPickS(self, gui_event, wfdata): @@ -1890,7 +1907,8 @@ class PickDlg(QDialog): zoomy=self.getYLims(), noiselevel=noiselevels, scaleddata=True, - iniPick=ini_pick) + iniPick=ini_pick, + plot_additional=self.additionalChannel.isChecked()) def setPick(self, gui_event): @@ -2154,7 +2172,8 @@ class PickDlg(QDialog): title = old_title self.multicompfig.plotWFData(wfdata=data, title=title, zoomx=self.getXLims(), - zoomy=self.getYLims()) + zoomy=self.getYLims(), + plot_additional=self.additionalChannel.isChecked()) self.setPlotLabels() self.drawAllPicks() self.draw() @@ -2165,7 +2184,8 @@ class PickDlg(QDialog): title = self.multicompfig.axes[0].get_title() self.multicompfig.plotWFData(wfdata=data, title=title, zoomx=self.getXLims(), - zoomy=self.getYLims()) + zoomy=self.getYLims(), + plot_additional=self.additionalChannel.isChecked()) self.setPlotLabels() self.drawAllPicks() self.draw() From 4835c0ca8a4d80a8f20493d5ffc898837f77b411 Mon Sep 17 00:00:00 2001 From: Marcel Date: Mon, 15 Jan 2018 15:29:46 +0100 Subject: [PATCH 02/13] [change] possible to select one of all available channels for comparison --- pylot/RELEASE-VERSION | 2 +- pylot/core/util/widgets.py | 77 ++++++++++++++++++++++++-------------- 2 files changed, 49 insertions(+), 30 deletions(-) diff --git a/pylot/RELEASE-VERSION b/pylot/RELEASE-VERSION index 878d172c..89074407 100644 --- a/pylot/RELEASE-VERSION +++ b/pylot/RELEASE-VERSION @@ -1 +1 @@ -f483-dirty +975b-dirty diff --git a/pylot/core/util/widgets.py b/pylot/core/util/widgets.py index 23c2380b..d8e4fbc9 100644 --- a/pylot/core/util/widgets.py +++ b/pylot/core/util/widgets.py @@ -902,7 +902,7 @@ class PylotCanvas(FigureCanvas): def plotWFData(self, wfdata, title=None, zoomx=None, zoomy=None, noiselevel=None, scaleddata=False, mapping=True, component='*', nth_sample=1, iniPick=None, verbosity=0, - plot_additional=False): + plot_additional=False, additional_channel=None): ax = self.axes[0] ax.cla() @@ -966,13 +966,19 @@ class PylotCanvas(FigureCanvas): color = linecolor, linestyle = 'dashed') self.setPlotDict(n, (station, channel, network)) - if plot_additional: - pressure = wfdata.select(channel='MDO') - if pressure: - p_data = pressure[0].data - #normalize - p_max = max(abs(p_data)) - p_data /= p_max + if plot_additional and additional_channel: + compare_stream = wfdata.select(channel=additional_channel) + if compare_stream: + trace = compare_stream[0] + if not scaleddata: + trace.detrend('constant') + trace.normalize(np.max(np.abs(trace.data)) * 2) + time_ax = prepTimeAxis(stime, trace) + times = [time for index, time in enumerate(time_ax) if not index % nth_sample] + p_data = compare_stream[0].data + # #normalize + # p_max = max(abs(p_data)) + # p_data /= p_max for index in range(3): ax.plot(times, p_data, color='red', alpha=0.5, linewidth=0.7) p_data += 1 @@ -1180,8 +1186,10 @@ class PickDlg(QDialog): self.filteroptions = FILTERDEFAULTS self.pick_block = False self.nextStation = QtGui.QCheckBox('Continue with next station ') - self.additionalChannel = QtGui.QCheckBox('Additional Channel') - self.additionalChannel.stateChanged.connect(self.resetPlot) + + # comparison channel + self.compareChannel = QtGui.QComboBox() + self.compareChannel.activated.connect(self.resetPlot) # initialize panning attributes self.press = None @@ -1204,6 +1212,11 @@ class PickDlg(QDialog): self.stime, self.etime = full_range(self.getWFData()) + # fill compare channels + self.compareChannel.addItem('', None) + for trace in self.getWFData(): + self.compareChannel.addItem(trace.stats.channel, trace) + # initialize plotting widget self.multicompfig = PylotCanvas(parent=self, multicursor=True) self.phaseplot = PhasePlotWidget(self) @@ -1211,7 +1224,7 @@ class PickDlg(QDialog): # plot data self.multicompfig.plotWFData(wfdata=self.getWFData(), - title=self.getStation()) + title=self.getStation()) self.multicompfig.setZoomBorders2content() @@ -1351,6 +1364,7 @@ class PickDlg(QDialog): # layout the outermost appearance of the Pick Dialog _outerlayout = QVBoxLayout() _dialtoolbar = QToolBar() + _dialtoolbar.setStyleSheet('QToolBar{spacing:5px;}') # fill toolbar with content _dialtoolbar.addAction(self.filterActionP) @@ -1382,7 +1396,9 @@ class PickDlg(QDialog): 'padding-left:5px}') _dialtoolbar.addWidget(est_label) _dialtoolbar.addWidget(self.plot_arrivals_button) - _dialtoolbar.addWidget(self.additionalChannel) + _dialtoolbar.addSeparator() + _dialtoolbar.addWidget(QtGui.QLabel('Compare to channel: ')) + _dialtoolbar.addWidget(self.compareChannel) # layout the innermost widget _innerlayout = QVBoxLayout() @@ -1915,14 +1931,15 @@ class PickDlg(QDialog): self.setYLims(np.array([-noiselevel * 3.5, noiselevel * 3.5]) + trace_number) self.multicompfig.plotWFData(wfdata=data, - title=self.getStation() + + title=self.getStation() + ' picking mode', - zoomx=self.getXLims(), - zoomy=self.getYLims(), - noiselevel=(trace_number + noiselevel, - trace_number - noiselevel), - iniPick=ini_pick, - plot_additional=self.additionalChannel.isChecked()) + zoomx=self.getXLims(), + zoomy=self.getYLims(), + noiselevel=(trace_number + noiselevel, + trace_number - noiselevel), + iniPick=ini_pick, + plot_additional=bool(self.compareChannel.currentText()), + additional_channel=self.compareChannel.currentText()) def setIniPickS(self, gui_event, wfdata): @@ -1984,14 +2001,15 @@ class PickDlg(QDialog): [trace - 1 / (2.5 * 2) for trace in traces] self.multicompfig.plotWFData(wfdata=data, - title=self.getStation() + + title=self.getStation() + ' picking mode', - zoomx=self.getXLims(), - zoomy=self.getYLims(), - noiselevel=noiselevels, - scaleddata=True, - iniPick=ini_pick, - plot_additional=self.additionalChannel.isChecked()) + zoomx=self.getXLims(), + zoomy=self.getYLims(), + noiselevel=noiselevels, + scaleddata=True, + iniPick=ini_pick, + plot_additional=bool(self.compareChannel.currentText()), + additional_channel=self.compareChannel.currentText()) def setPick(self, gui_event): @@ -2346,9 +2364,10 @@ class PickDlg(QDialog): filtops_str = transformFilteroptions2String(filtoptions) title += ' | Filteroptions: {}'.format(filtops_str) self.multicompfig.plotWFData(wfdata=data, title=title, - zoomx=self.getXLims(), - zoomy=self.getYLims(), - plot_additional=self.additionalChannel.isChecked()) + zoomx=self.getXLims(), + zoomy=self.getYLims(), + plot_additional=bool(self.compareChannel.currentText()), + additional_channel=self.compareChannel.currentText()) self.setPlotLabels() self.drawAllPicks() self.draw() From a22e64889d7f63512d1c8bd13d3405326a2db3c4 Mon Sep 17 00:00:00 2001 From: Marcel Date: Mon, 15 Jan 2018 16:35:19 +0100 Subject: [PATCH 03/13] [add] scaling by channel (untested) --- pylot/RELEASE-VERSION | 2 +- pylot/core/util/widgets.py | 55 +++++++++++++++++++++++++++++++------- 2 files changed, 46 insertions(+), 11 deletions(-) diff --git a/pylot/RELEASE-VERSION b/pylot/RELEASE-VERSION index 89074407..afa29563 100644 --- a/pylot/RELEASE-VERSION +++ b/pylot/RELEASE-VERSION @@ -1 +1 @@ -975b-dirty +4835-dirty diff --git a/pylot/core/util/widgets.py b/pylot/core/util/widgets.py index d8e4fbc9..d0280531 100644 --- a/pylot/core/util/widgets.py +++ b/pylot/core/util/widgets.py @@ -902,7 +902,7 @@ class PylotCanvas(FigureCanvas): def plotWFData(self, wfdata, title=None, zoomx=None, zoomy=None, noiselevel=None, scaleddata=False, mapping=True, component='*', nth_sample=1, iniPick=None, verbosity=0, - plot_additional=False, additional_channel=None): + plot_additional=False, additional_channel=None, scaleToChannel=None): ax = self.axes[0] ax.cla() @@ -940,7 +940,7 @@ class PylotCanvas(FigureCanvas): for n, (network, station, channel) in enumerate(nsc): st = st_select.select(network=network, station=station, channel=channel) - trace = st[0] + trace = st[0].copy() if mapping: comp = channel[-1] n = compclass.getPlotPosition(str(comp)) @@ -953,9 +953,17 @@ class PylotCanvas(FigureCanvas): stime = trace.stats.starttime - wfstart time_ax = prepTimeAxis(stime, trace) if time_ax is not None: + if scaleToChannel: + st_scale = wfdata.select(channel=scaleToChannel) + if st_scale: + tr = st_scale[0] + trace.detrend('constant') + trace.normalize(np.max(np.abs(tr.data)) * 2) + scaleddata = True if not scaleddata: trace.detrend('constant') trace.normalize(np.max(np.abs(trace.data)) * 2) + times = [time for index, time in enumerate(time_ax) if not index % nth_sample] data = [datum + n for index, datum in enumerate(trace.data) if not index % nth_sample] ax.plot(times, data, color=linecolor, linewidth=0.7) @@ -970,6 +978,13 @@ class PylotCanvas(FigureCanvas): compare_stream = wfdata.select(channel=additional_channel) if compare_stream: trace = compare_stream[0] + if scaleToChannel: + st_scale = wfdata.select(channel=scaleToChannel) + if st_scale: + tr = st_scale[0] + trace.detrend('constant') + trace.normalize(np.max(np.abs(tr.data)) * 2) + scaleddata = True if not scaleddata: trace.detrend('constant') trace.normalize(np.max(np.abs(trace.data)) * 2) @@ -1191,6 +1206,10 @@ class PickDlg(QDialog): self.compareChannel = QtGui.QComboBox() self.compareChannel.activated.connect(self.resetPlot) + # scale channel + self.scaleChannel = QtGui.QComboBox() + self.scaleChannel.activated.connect(self.resetPlot) + # initialize panning attributes self.press = None self.xpress = None @@ -1212,10 +1231,12 @@ class PickDlg(QDialog): self.stime, self.etime = full_range(self.getWFData()) - # fill compare channels - self.compareChannel.addItem('', None) + # fill compare and scale channels + self.compareChannel.addItem('-', None) + self.scaleChannel.addItem('normalized', None) for trace in self.getWFData(): self.compareChannel.addItem(trace.stats.channel, trace) + self.scaleChannel.addItem(trace.stats.channel, trace) # initialize plotting widget self.multicompfig = PylotCanvas(parent=self, multicursor=True) @@ -1399,6 +1420,9 @@ class PickDlg(QDialog): _dialtoolbar.addSeparator() _dialtoolbar.addWidget(QtGui.QLabel('Compare to channel: ')) _dialtoolbar.addWidget(self.compareChannel) + _dialtoolbar.addSeparator() + _dialtoolbar.addWidget(QtGui.QLabel('Scale: ')) + _dialtoolbar.addWidget(self.scaleChannel) # layout the innermost widget _innerlayout = QVBoxLayout() @@ -1930,6 +1954,9 @@ class PickDlg(QDialog): self.setXLims([ini_pick - x_res, ini_pick + x_res]) self.setYLims(np.array([-noiselevel * 3.5, noiselevel * 3.5]) + trace_number) + plot_additional = bool(self.compareChannel.currentText()) + additional_channel = self.compareChannel.currentText() + scale_channel = self.scaleChannel.currentText() self.multicompfig.plotWFData(wfdata=data, title=self.getStation() + ' picking mode', @@ -1938,8 +1965,9 @@ class PickDlg(QDialog): noiselevel=(trace_number + noiselevel, trace_number - noiselevel), iniPick=ini_pick, - plot_additional=bool(self.compareChannel.currentText()), - additional_channel=self.compareChannel.currentText()) + plot_additional=plot_additional, + additional_channel=additional_channel, + scaleToChannel=scale_channel) def setIniPickS(self, gui_event, wfdata): @@ -2000,6 +2028,8 @@ class PickDlg(QDialog): noiselevels = [trace + 1 / (2.5 * 2) for trace in traces] + \ [trace - 1 / (2.5 * 2) for trace in traces] + plot_additional = bool(self.compareChannel.currentText()) + additional_channel = self.compareChannel.currentText() self.multicompfig.plotWFData(wfdata=data, title=self.getStation() + ' picking mode', @@ -2008,8 +2038,8 @@ class PickDlg(QDialog): noiselevel=noiselevels, scaleddata=True, iniPick=ini_pick, - plot_additional=bool(self.compareChannel.currentText()), - additional_channel=self.compareChannel.currentText()) + plot_additional=plot_additional, + additional_channel=additional_channel) def setPick(self, gui_event): @@ -2363,11 +2393,16 @@ class PickDlg(QDialog): data.filter(**filtoptions) filtops_str = transformFilteroptions2String(filtoptions) title += ' | Filteroptions: {}'.format(filtops_str) + + plot_additional = bool(self.compareChannel.currentText()) + additional_channel = self.compareChannel.currentText() + scale_channel = self.scaleChannel.currentText() self.multicompfig.plotWFData(wfdata=data, title=title, zoomx=self.getXLims(), zoomy=self.getYLims(), - plot_additional=bool(self.compareChannel.currentText()), - additional_channel=self.compareChannel.currentText()) + plot_additional=plot_additional, + additional_channel=additional_channel, + scaleToChannel=scale_channel) self.setPlotLabels() self.drawAllPicks() self.draw() From ec394d447d3c914ee3706cac38968121ca76ae30 Mon Sep 17 00:00:00 2001 From: Marcel Date: Tue, 16 Jan 2018 13:33:12 +0100 Subject: [PATCH 04/13] [new] choose channels to pick on for each phase --- pylot/RELEASE-VERSION | 2 +- pylot/core/util/widgets.py | 89 ++++++++++++++++++++++++++++++++++---- 2 files changed, 82 insertions(+), 9 deletions(-) diff --git a/pylot/RELEASE-VERSION b/pylot/RELEASE-VERSION index afa29563..7cfc29c1 100644 --- a/pylot/RELEASE-VERSION +++ b/pylot/RELEASE-VERSION @@ -1 +1 @@ -4835-dirty +a22e-dirty diff --git a/pylot/core/util/widgets.py b/pylot/core/util/widgets.py index d0280531..dfd554b2 100644 --- a/pylot/core/util/widgets.py +++ b/pylot/core/util/widgets.py @@ -1231,17 +1231,26 @@ class PickDlg(QDialog): self.stime, self.etime = full_range(self.getWFData()) + # initialize plotting widget + self.multicompfig = PylotCanvas(parent=self, multicursor=True) + self.phaseplot = PhasePlotWidget(self) + self.phaseplot.hide() + + # setup ui + self.setupUi() + # fill compare and scale channels self.compareChannel.addItem('-', None) self.scaleChannel.addItem('normalized', None) for trace in self.getWFData(): self.compareChannel.addItem(trace.stats.channel, trace) self.scaleChannel.addItem(trace.stats.channel, trace) - - # initialize plotting widget - self.multicompfig = PylotCanvas(parent=self, multicursor=True) - self.phaseplot = PhasePlotWidget(self) - self.phaseplot.hide() + actionP = self.pChannels.addAction(str(trace.stats.channel)) + actionS = self.sChannels.addAction(str(trace.stats.channel)) + actionP.setCheckable(True) + actionS.setCheckable(True) + actionP.setChecked(self.getChannelSettingsP(trace.stats.channel)) + actionS.setChecked(self.getChannelSettingsS(trace.stats.channel)) # plot data self.multicompfig.plotWFData(wfdata=self.getWFData(), @@ -1254,9 +1263,6 @@ class PickDlg(QDialog): self.multicompfig.setFocus() - # setup ui - self.setupUi() - # set plot labels self.setPlotLabels() @@ -1348,6 +1354,11 @@ class PickDlg(QDialog): self.addPickPhases(menuBar) + self.pChannels = menuBar.addMenu('P-Channels') + self.sChannels = menuBar.addMenu('S-Channels') + self.pChannels.triggered.connect(self.updateChannelSettingsP) + self.sChannels.triggered.connect(self.updateChannelSettingsS) + settings = QSettings() self.autoFilterAction.setChecked(real_Bool(settings.value('autoFilter'))) @@ -1622,6 +1633,7 @@ class PickDlg(QDialog): filterMenu.addAction(self.autoFilterAction) filterMenu.addAction(filterOptionsAction) + def filterOptions(self): if self.orig_parent.adjustFilterOptions(): phase = None @@ -1877,6 +1889,17 @@ class PickDlg(QDialog): self.multicompfig.connectEvents() self.draw() + def getPickPhases(self, data, phase): + st = Stream() + phases = {'P': self.pChannels, + 'S': self.sChannels} + if not phase in phases.keys(): + raise ValueError('Unknown phase ID {}'.format(phase)) + for action in phases[phase].actions(): + if action.isChecked(): + st += data.select(channel=action.text()) + return st + def setIniPick(self, gui_event): self.multicompfig.set_frame_color('green') trace_number = round(gui_event.ydata) @@ -1921,6 +1944,12 @@ class PickDlg(QDialog): # copy data for plotting data = self.getWFData().copy() + data = self.getPickPhases(data, 'P') + if not data: + QtGui.QMessageBox.warning(self, 'No channel to plot', + 'No channel to plot for phase: {}.'.format('P')) + self.leave_picking_mode() + return # filter data and trace on which is picked prior to determination of SNR phase = self.currentPhase @@ -1964,6 +1993,7 @@ class PickDlg(QDialog): zoomy=self.getYLims(), noiselevel=(trace_number + noiselevel, trace_number - noiselevel), + scaleddata=True, iniPick=ini_pick, plot_additional=plot_additional, additional_channel=additional_channel, @@ -1985,6 +2015,12 @@ class PickDlg(QDialog): # copy data for plotting data = self.getWFData().copy() + data = self.getPickPhases(data, 'S') + if not data: + QtGui.QMessageBox.warning(self, 'No channel to plot', + 'No channel to plot for phase: {}.'.format('S')) + self.leave_picking_mode() + return # filter data and trace on which is picked prior to determination of SNR phase = self.currentPhase @@ -2425,6 +2461,43 @@ class PickDlg(QDialog): settings = QSettings() settings.setValue('autoFilter', self.autoFilterAction.isChecked()) + def updateChannelSettingsP(self, action): + settings = QSettings() + settings.setValue('p_channel_{}'.format(action.text()), action.isChecked()) + + def updateChannelSettingsS(self, action): + settings = QSettings() + settings.setValue('s_channel_{}'.format(action.text()), action.isChecked()) + + def getChannelSettingsP(self, channel): + settings = QSettings() + rval = real_Bool(settings.value('p_channel_{}'.format(channel))) + compclass = settings.value('compclass') + components = ['Z'] + for component in components[:]: + components.append(compclass.getCompPosition(component)) + if not rval in [True, False]: + if any([channel.endswith(component) for component in components]): + rval = True + else: + rval = False + return rval + + def getChannelSettingsS(self, channel): + settings = QSettings() + rval = real_Bool(settings.value('s_channel_{}'.format(channel))) + compclass = settings.value('compclass') + components = ['N', 'E'] + for component in components[:]: + components.append(compclass.getCompPosition(component)) + if not rval in [True, False]: + if any([channel.endswith(component) for component in components]): + rval = True + else: + rval = False + return rval + + def resetPlot(self): self.resetZoom() self.refreshPlot() From c520c7c2128ffa95456caefb0aba0bedb114d104 Mon Sep 17 00:00:00 2001 From: Marcel Date: Tue, 16 Jan 2018 16:06:24 +0100 Subject: [PATCH 05/13] [new] HUGE rearrangement of initial pick behavior (untested) - zooms on selected channels after initial pick - ylims not relying on noiselevel anymore (better overview and not possible with more than one phase), xlims now based on mean snr of all selected channels for initial pick instead of snr of one 'random' channel --- pylot/RELEASE-VERSION | 2 +- pylot/core/util/widgets.py | 129 ++++++++++++++++++++++--------------- 2 files changed, 77 insertions(+), 54 deletions(-) diff --git a/pylot/RELEASE-VERSION b/pylot/RELEASE-VERSION index 7cfc29c1..d888ad24 100644 --- a/pylot/RELEASE-VERSION +++ b/pylot/RELEASE-VERSION @@ -1 +1 @@ -a22e-dirty +ec39-dirty diff --git a/pylot/core/util/widgets.py b/pylot/core/util/widgets.py index dfd554b2..531d7d3c 100644 --- a/pylot/core/util/widgets.py +++ b/pylot/core/util/widgets.py @@ -899,6 +899,22 @@ class PylotCanvas(FigureCanvas): def clearPlotDict(self): self.plotdict = dict() + def calcPlotPositions(self, wfdata, compclass): + possible_plot_pos = list(range(len(wfdata))) + plot_positions = {} + for trace in wfdata: + comp = trace.stats.channel[-1] + plot_positions[trace.stats.channel] = compclass.getPlotPosition(str(comp)) + for channel, plot_pos in plot_positions.items(): + while not plot_pos in possible_plot_pos or not plot_pos - 1 in plot_positions.values(): + if plot_pos == 0: + break + plot_pos -= 1 + if plot_pos < 0: + raise Exception('Plot position lower zero. This should not happen.') + plot_positions[channel] = plot_pos + return plot_positions + def plotWFData(self, wfdata, title=None, zoomx=None, zoomy=None, noiselevel=None, scaleddata=False, mapping=True, component='*', nth_sample=1, iniPick=None, verbosity=0, @@ -925,9 +941,12 @@ class PylotCanvas(FigureCanvas): else: st_select = wfdata - # list containing tuples of network, station, channel (for sorting) + if mapping: + plot_positions = self.calcPlotPositions(st_select, compclass) + + # list containing tuples of network, station, channel and plot position (for sorting) nsc = [] - for trace in st_select: + for plot_pos, trace in enumerate(st_select): if not trace.stats.channel[-1] in ['Z', 'N', 'E', '1', '2', '3']: print('Warning: Unrecognized channel {}'.format(trace.stats.channel)) continue @@ -942,9 +961,7 @@ class PylotCanvas(FigureCanvas): st = st_select.select(network=network, station=station, channel=channel) trace = st[0].copy() if mapping: - comp = channel[-1] - n = compclass.getPlotPosition(str(comp)) - # n = n[0] + n = plot_positions[trace.stats.channel] if n > nmax: nmax = n if verbosity: @@ -968,9 +985,9 @@ class PylotCanvas(FigureCanvas): data = [datum + n for index, datum in enumerate(trace.data) if not index % nth_sample] ax.plot(times, data, color=linecolor, linewidth=0.7) if noiselevel is not None: - for level in noiselevel: + for level in [-noiselevel[channel], noiselevel[channel]]: ax.plot([time_ax[0], time_ax[-1]], - [level, level], + [n+level, n+level], color = linecolor, linestyle = 'dashed') self.setPlotDict(n, (station, channel, network)) @@ -1945,6 +1962,7 @@ class PickDlg(QDialog): # copy data for plotting data = self.getWFData().copy() data = self.getPickPhases(data, 'P') + data.normalize(global_max=True) if not data: QtGui.QMessageBox.warning(self, 'No channel to plot', 'No channel to plot for phase: {}.'.format('P')) @@ -1963,36 +1981,41 @@ class PickDlg(QDialog): 'Denied', 'setIniPickP: Could not filter waveform: {}'.format(e)) self.qmb.show() - result = getSNR(data, (noise_win, gap_win, signal_win), ini_pick - stime_diff, itrace) - snr = result[0] - noiselevel = result[2] - if noiselevel: - noiselevel *= nfac - else: - noiselevel = nfac + snr = [] + noiselevels = {} + # determine SNR and noiselevel + for trace in data.traces: + st = data.select(channel=trace.stats.channel) + result = getSNR(st, (noise_win, gap_win, signal_win), ini_pick - stime_diff) + snr.append(result[0]) + noiselevel = result[2] + if noiselevel: + noiselevel *= nfac + else: + noiselevel = nfac + noiselevels[trace.stats.channel] = noiselevel - x_res = getResolutionWindow(snr, parameter.get('extent')) - - # remove mean noise level from waveforms + # prepare plotting of data for trace in data: t = prepTimeAxis(trace.stats.starttime - stime, trace) inoise = getnoisewin(t, ini_pick, noise_win, gap_win) - trace = demeanTrace(trace=trace, window=inoise) + trace = demeanTrace(trace, inoise) + + x_res = getResolutionWindow(np.mean(snr), parameter.get('extent')) + + xlims = [ini_pick - x_res, ini_pick + x_res] + ylims = list(np.array([-.5, .5]) + [0, len(data)-1]) - self.setXLims([ini_pick - x_res, ini_pick + x_res]) - self.setYLims(np.array([-noiselevel * 3.5, noiselevel * 3.5]) + - trace_number) plot_additional = bool(self.compareChannel.currentText()) additional_channel = self.compareChannel.currentText() scale_channel = self.scaleChannel.currentText() self.multicompfig.plotWFData(wfdata=data, title=self.getStation() + ' picking mode', - zoomx=self.getXLims(), - zoomy=self.getYLims(), - noiselevel=(trace_number + noiselevel, - trace_number - noiselevel), + zoomx=xlims, + zoomy=ylims, + noiselevel=noiselevels, scaleddata=True, iniPick=ini_pick, plot_additional=plot_additional, @@ -2016,6 +2039,7 @@ class PickDlg(QDialog): # copy data for plotting data = self.getWFData().copy() data = self.getPickPhases(data, 'S') + data.normalize(global_max=True) if not data: QtGui.QMessageBox.warning(self, 'No channel to plot', 'No channel to plot for phase: {}.'.format('S')) @@ -2034,43 +2058,42 @@ class PickDlg(QDialog): 'Denied', 'setIniPickS: Could not filter waveform: {}'.format(e)) self.qmb.show() - # determine SNR and noiselevel - result = getSNR(wfdata, (noise_win, gap_win, signal_win), ini_pick - stime_diff) - snr = result[0] - noiselevel = result[2] + snr = [] + noiselevels = {} + # determine SNR and noiselevel + for trace in data.traces: + st = data.select(channel=trace.stats.channel) + result = getSNR(st, (noise_win, gap_win, signal_win), ini_pick - stime_diff) + snr.append(result[0]) + noiselevel = result[2] + if noiselevel: + noiselevel *= nfac + else: + noiselevel = nfac + noiselevels[trace.stats.channel] = noiselevel - if noiselevel: - noiselevel *= nfac - else: - noiselevel = nfac - - # prepare plotting of data - for trace in data: - t = prepTimeAxis(trace.stats.starttime - stime, trace) - inoise = getnoisewin(t, ini_pick, noise_win, gap_win) - trace = demeanTrace(trace, inoise) + # prepare plotting of data + for trace in data: + t = prepTimeAxis(trace.stats.starttime - stime, trace) + inoise = getnoisewin(t, ini_pick, noise_win, gap_win) + trace = demeanTrace(trace, inoise) # scale waveform for plotting - horiz_comp = find_horizontals(data) - data = scaleWFData(data, noiselevel * 2.5, horiz_comp) + #horiz_comp = find_horizontals(data) + #data = scaleWFData(data, noiselevel * 2.5, horiz_comp) - x_res = getResolutionWindow(snr, parameter.get('extent')) + x_res = getResolutionWindow(np.mean(snr), parameter.get('extent')) - self.setXLims(tuple([ini_pick - x_res, ini_pick + x_res])) - traces = self.getTraceID(horiz_comp) - traces.sort() - self.setYLims(tuple(np.array([-1.0, +1.0]) + - np.array(traces))) - noiselevels = [trace + 1 / (2.5 * 2) for trace in traces] + \ - [trace - 1 / (2.5 * 2) for trace in traces] + xlims = [ini_pick - x_res, ini_pick + x_res] + ylims = list(np.array([-.5, .5]) + [0, len(data) - 1]) plot_additional = bool(self.compareChannel.currentText()) additional_channel = self.compareChannel.currentText() self.multicompfig.plotWFData(wfdata=data, title=self.getStation() + ' picking mode', - zoomx=self.getXLims(), - zoomy=self.getYLims(), + zoomx=xlims, + zoomy=ylims, noiselevel=noiselevels, scaleddata=True, iniPick=ini_pick, @@ -2535,8 +2558,8 @@ class PickDlg(QDialog): # set channel labels self.multicompfig.setYTickLabels(pos, labels) - self.multicompfig.setXLims(ax, self.getXLims()) - self.multicompfig.setYLims(ax, self.getYLims()) + #self.multicompfig.setXLims(ax, self.getXLims()) + #self.multicompfig.setYLims(ax, self.getYLims()) def zoom(self): if self.zoomAction.isChecked() and self.pick_block: From f4632ac1f5bee6b16b8f456e3a729e8030841a47 Mon Sep 17 00:00:00 2001 From: Marcel Date: Tue, 16 Jan 2018 16:10:47 +0100 Subject: [PATCH 06/13] [update] enable/disable comboboxes in pick mode --- pylot/RELEASE-VERSION | 2 +- pylot/core/util/widgets.py | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/pylot/RELEASE-VERSION b/pylot/RELEASE-VERSION index d888ad24..6ddcab46 100644 --- a/pylot/RELEASE-VERSION +++ b/pylot/RELEASE-VERSION @@ -1 +1 @@ -ec39-dirty +c520-dirty diff --git a/pylot/core/util/widgets.py b/pylot/core/util/widgets.py index 531d7d3c..4de95be1 100644 --- a/pylot/core/util/widgets.py +++ b/pylot/core/util/widgets.py @@ -1765,6 +1765,8 @@ class PickDlg(QDialog): def activatePicking(self): self.leave_rename_phase() self.renamePhaseAction.setEnabled(False) + self.compareChannel.setEnabled(False) + self.scaleChannel.setEnabled(False) phase = self.currentPhase phaseID = self.getPhaseID(phase) if not phaseID: @@ -1796,6 +1798,8 @@ class PickDlg(QDialog): self.disconnectPressEvent() self.multicompfig.connectEvents() self.renamePhaseAction.setEnabled(True) + self.compareChannel.setEnabled(True) + self.scaleChannel.setEnabled(True) self.connect_pick_delete() self.draw() From 98f7ff84063261f14787c895855a4e294882bece Mon Sep 17 00:00:00 2001 From: Marcel Date: Tue, 16 Jan 2018 16:17:18 +0100 Subject: [PATCH 07/13] [update] resetZoom after picking --- pylot/RELEASE-VERSION | 2 +- pylot/core/util/widgets.py | 7 ++++--- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/pylot/RELEASE-VERSION b/pylot/RELEASE-VERSION index 6ddcab46..9a645abe 100644 --- a/pylot/RELEASE-VERSION +++ b/pylot/RELEASE-VERSION @@ -1 +1 @@ -c520-dirty +f463-dirty diff --git a/pylot/core/util/widgets.py b/pylot/core/util/widgets.py index 4de95be1..053de0a3 100644 --- a/pylot/core/util/widgets.py +++ b/pylot/core/util/widgets.py @@ -1449,7 +1449,7 @@ class PickDlg(QDialog): _dialtoolbar.addWidget(QtGui.QLabel('Compare to channel: ')) _dialtoolbar.addWidget(self.compareChannel) _dialtoolbar.addSeparator() - _dialtoolbar.addWidget(QtGui.QLabel('Scale: ')) + _dialtoolbar.addWidget(QtGui.QLabel('Scale by: ')) _dialtoolbar.addWidget(self.scaleChannel) # layout the innermost widget @@ -2166,6 +2166,7 @@ class PickDlg(QDialog): self.enable_ar_buttons() self.zoomAction.setEnabled(True) #self.pick_block = self.togglPickBlocker() + self.resetZoom() self.leave_picking_mode() def savePick(self, phase, phasepicks): @@ -2547,8 +2548,8 @@ class PickDlg(QDialog): def resetZoom(self): ax = self.multicompfig.axes[0] - self.setXLims(self.multicompfig.getGlobalLimits(ax, 'x')) - self.setYLims(self.multicompfig.getGlobalLimits(ax, 'y')) + self.multicompfig.setXLims(ax, self.multicompfig.getGlobalLimits(ax, 'x')) + self.multicompfig.setYLims(ax, self.multicompfig.getGlobalLimits(ax, 'y')) if not self.zoomAction.isChecked(): self.multicompfig.connectEvents() From 473529961e26559d626c624f160995b7e28191cd Mon Sep 17 00:00:00 2001 From: Marcel Date: Wed, 17 Jan 2018 11:47:52 +0100 Subject: [PATCH 08/13] [update] EVERY trace now scaled relative to its own noiselevel --- pylot/RELEASE-VERSION | 2 +- pylot/core/util/widgets.py | 75 +++++++++++++++++++++----------------- 2 files changed, 42 insertions(+), 35 deletions(-) diff --git a/pylot/RELEASE-VERSION b/pylot/RELEASE-VERSION index 33a2193d..4396b8bb 100644 --- a/pylot/RELEASE-VERSION +++ b/pylot/RELEASE-VERSION @@ -1 +1 @@ -98f7-dirty +d243-dirty diff --git a/pylot/core/util/widgets.py b/pylot/core/util/widgets.py index 053de0a3..51df828d 100644 --- a/pylot/core/util/widgets.py +++ b/pylot/core/util/widgets.py @@ -1921,6 +1921,12 @@ class PickDlg(QDialog): st += data.select(channel=action.text()) return st + def calcNoiseScaleFactor(self, noiselevel, zoomfactor=5., norm=1): + # calculate factor to upscale a trace normed to 'norm' in a way that all values + # zoomfactor*noiselevel are found within -0.5*norm and 0.5*norm + scaleFactor = (norm/2.) / (zoomfactor * noiselevel) + return scaleFactor + def setIniPick(self, gui_event): self.multicompfig.set_frame_color('green') trace_number = round(gui_event.ydata) @@ -1955,18 +1961,13 @@ class PickDlg(QDialog): noise_win = twins[0] gap_win = twins[1] signal_win = twins[2] - itrace = int(trace_number) - - while itrace > len(wfdata) - 1: - itrace -= 1 stime = self.getStartTime() - stime_diff = wfdata[itrace].stats.starttime - stime # copy data for plotting data = self.getWFData().copy() data = self.getPickPhases(data, 'P') - data.normalize(global_max=True) + data.normalize() if not data: QtGui.QMessageBox.warning(self, 'No channel to plot', 'No channel to plot for phase: {}.'.format('P')) @@ -1985,12 +1986,12 @@ class PickDlg(QDialog): 'Denied', 'setIniPickP: Could not filter waveform: {}'.format(e)) self.qmb.show() - snr = [] noiselevels = {} # determine SNR and noiselevel for trace in data.traces: st = data.select(channel=trace.stats.channel) + stime_diff = trace.stats.starttime - stime result = getSNR(st, (noise_win, gap_win, signal_win), ini_pick - stime_diff) snr.append(result[0]) noiselevel = result[2] @@ -2005,6 +2006,12 @@ class PickDlg(QDialog): t = prepTimeAxis(trace.stats.starttime - stime, trace) inoise = getnoisewin(t, ini_pick, noise_win, gap_win) trace = demeanTrace(trace, inoise) + # upscale trace data in a way that each trace is vertically zoomed to noiselevel*factor + channel = trace.stats.channel + noiselevel = noiselevels[channel] + noiseScaleFactor = self.calcNoiseScaleFactor(noiselevel, zoomfactor=5.) + trace.data *= noiseScaleFactor + noiselevels[channel] *= noiseScaleFactor x_res = getResolutionWindow(np.mean(snr), parameter.get('extent')) @@ -2013,7 +2020,6 @@ class PickDlg(QDialog): plot_additional = bool(self.compareChannel.currentText()) additional_channel = self.compareChannel.currentText() - scale_channel = self.scaleChannel.currentText() self.multicompfig.plotWFData(wfdata=data, title=self.getStation() + ' picking mode', @@ -2023,8 +2029,7 @@ class PickDlg(QDialog): scaleddata=True, iniPick=ini_pick, plot_additional=plot_additional, - additional_channel=additional_channel, - scaleToChannel=scale_channel) + additional_channel=additional_channel) def setIniPickS(self, gui_event, wfdata): @@ -2038,12 +2043,11 @@ class PickDlg(QDialog): signal_win = twins[2] stime = self.getStartTime() - stime_diff = wfdata[0].stats.starttime - stime # copy data for plotting data = self.getWFData().copy() data = self.getPickPhases(data, 'S') - data.normalize(global_max=True) + data.normalize() if not data: QtGui.QMessageBox.warning(self, 'No channel to plot', 'No channel to plot for phase: {}.'.format('S')) @@ -2062,29 +2066,32 @@ class PickDlg(QDialog): 'Denied', 'setIniPickS: Could not filter waveform: {}'.format(e)) self.qmb.show() - snr = [] - noiselevels = {} - # determine SNR and noiselevel - for trace in data.traces: - st = data.select(channel=trace.stats.channel) - result = getSNR(st, (noise_win, gap_win, signal_win), ini_pick - stime_diff) - snr.append(result[0]) - noiselevel = result[2] - if noiselevel: - noiselevel *= nfac - else: - noiselevel = nfac - noiselevels[trace.stats.channel] = noiselevel + snr = [] + noiselevels = {} + # determine SNR and noiselevel + for trace in data.traces: + st = data.select(channel=trace.stats.channel) + stime_diff = trace.stats.starttime - stime + result = getSNR(st, (noise_win, gap_win, signal_win), ini_pick - stime_diff) + snr.append(result[0]) + noiselevel = result[2] + if noiselevel: + noiselevel *= nfac + else: + noiselevel = nfac + noiselevels[trace.stats.channel] = noiselevel - # prepare plotting of data - for trace in data: - t = prepTimeAxis(trace.stats.starttime - stime, trace) - inoise = getnoisewin(t, ini_pick, noise_win, gap_win) - trace = demeanTrace(trace, inoise) - - # scale waveform for plotting - #horiz_comp = find_horizontals(data) - #data = scaleWFData(data, noiselevel * 2.5, horiz_comp) + # prepare plotting of data + for trace in data: + t = prepTimeAxis(trace.stats.starttime - stime, trace) + inoise = getnoisewin(t, ini_pick, noise_win, gap_win) + trace = demeanTrace(trace, inoise) + # upscale trace data in a way that each trace is vertically zoomed to noiselevel*factor + channel = trace.stats.channel + noiselevel = noiselevels[channel] + noiseScaleFactor = self.calcNoiseScaleFactor(noiselevel, zoomfactor=5.) + trace.data *= noiseScaleFactor + noiselevels[channel] *= noiseScaleFactor x_res = getResolutionWindow(np.mean(snr), parameter.get('extent')) From 0e057af39b129f5ec4a72c30e851d10477716802 Mon Sep 17 00:00:00 2001 From: Marcel Date: Wed, 17 Jan 2018 12:04:07 +0100 Subject: [PATCH 09/13] [cleanup] simplifaction of setIniPickP/S functions, merge into one --- pylot/RELEASE-VERSION | 2 +- pylot/core/util/widgets.py | 114 +++++++------------------------------ 2 files changed, 22 insertions(+), 94 deletions(-) diff --git a/pylot/RELEASE-VERSION b/pylot/RELEASE-VERSION index 4396b8bb..12a031b1 100644 --- a/pylot/RELEASE-VERSION +++ b/pylot/RELEASE-VERSION @@ -1 +1 @@ -d243-dirty +4735-dirty diff --git a/pylot/core/util/widgets.py b/pylot/core/util/widgets.py index 51df828d..79727873 100644 --- a/pylot/core/util/widgets.py +++ b/pylot/core/util/widgets.py @@ -1931,19 +1931,16 @@ class PickDlg(QDialog): self.multicompfig.set_frame_color('green') trace_number = round(gui_event.ydata) - channel = self.getChannelID(trace_number) - wfdata = self.selectWFData(channel) - self.multicompfig.disconnectEvents() self.disconnectPressEvent() self.cidpress = self.multicompfig.connectPressEvent(self.setPick) if self.getPhaseID(self.currentPhase) == 'P': self.set_button_border_color(self.p_button, 'green') - self.setIniPickP(gui_event, wfdata, trace_number) + self.setIniPickP(gui_event) elif self.getPhaseID(self.currentPhase) == 'S': self.set_button_border_color(self.s_button, 'green') - self.setIniPickS(gui_event, wfdata) + self.setIniPickS(gui_event) self.zoomAction.setEnabled(False) @@ -1951,13 +1948,25 @@ class PickDlg(QDialog): self.setPlotLabels() self.draw() - def setIniPickP(self, gui_event, wfdata, trace_number): + def setIniPickP(self, gui_event): + self.setIniPickPS(gui_event, phase='P') + + def setIniPickS(self, gui_event): + self.setIniPickPS(gui_event, phase='P') + + def setIniPickPS(self, gui_event, phase): + phase = self.getPhaseID(phase) + + nfac_phase = {'P': 'nfacP', + 'S': 'nfacS'} + twins_phase = {'P': 'tsnrz', + 'S': 'tsnrh'} parameter = self.parameter ini_pick = gui_event.xdata - nfac = parameter.get('nfacP') - twins = parameter.get('tsnrz') + nfac = parameter.get(nfac_phase[phase]) + twins = parameter.get(twins_phase[phase]) noise_win = twins[0] gap_win = twins[1] signal_win = twins[2] @@ -1966,24 +1975,23 @@ class PickDlg(QDialog): # copy data for plotting data = self.getWFData().copy() - data = self.getPickPhases(data, 'P') + data = self.getPickPhases(data, phase) data.normalize() if not data: QtGui.QMessageBox.warning(self, 'No channel to plot', - 'No channel to plot for phase: {}.'.format('P')) + 'No channel to plot for phase: {}.'.format(phase)) self.leave_picking_mode() return # filter data and trace on which is picked prior to determination of SNR - phase = self.currentPhase - filteroptions = self.getFilterOptions(self.getPhaseID(phase)).parseFilterOptions() + filteroptions = self.getFilterOptions(phase).parseFilterOptions() if filteroptions: try: data.filter(**filteroptions) #wfdata.filter(**filteroptions)# MP MP removed filtering of original data except ValueError as e: self.qmb = QtGui.QMessageBox(QtGui.QMessageBox.Icon.Information, - 'Denied', 'setIniPickP: Could not filter waveform: {}'.format(e)) + 'Denied', 'setIniPick{}: Could not filter waveform: {}'.format(phase, e)) self.qmb.show() snr = [] @@ -2031,86 +2039,6 @@ class PickDlg(QDialog): plot_additional=plot_additional, additional_channel=additional_channel) - def setIniPickS(self, gui_event, wfdata): - - parameter = self.parameter - ini_pick = gui_event.xdata - - nfac = parameter.get('nfacS') - twins = parameter.get('tsnrh') - noise_win = twins[0] - gap_win = twins[1] - signal_win = twins[2] - - stime = self.getStartTime() - - # copy data for plotting - data = self.getWFData().copy() - data = self.getPickPhases(data, 'S') - data.normalize() - if not data: - QtGui.QMessageBox.warning(self, 'No channel to plot', - 'No channel to plot for phase: {}.'.format('S')) - self.leave_picking_mode() - return - - # filter data and trace on which is picked prior to determination of SNR - phase = self.currentPhase - filteroptions = self.getFilterOptions(self.getPhaseID(phase)).parseFilterOptions() - if filteroptions: - try: - data.filter(**filteroptions) - #wfdata.filter(**filteroptions) MP MP as above - except ValueError as e: - self.qmb = QtGui.QMessageBox(QtGui.QMessageBox.Icon.Information, - 'Denied', 'setIniPickS: Could not filter waveform: {}'.format(e)) - self.qmb.show() - - snr = [] - noiselevels = {} - # determine SNR and noiselevel - for trace in data.traces: - st = data.select(channel=trace.stats.channel) - stime_diff = trace.stats.starttime - stime - result = getSNR(st, (noise_win, gap_win, signal_win), ini_pick - stime_diff) - snr.append(result[0]) - noiselevel = result[2] - if noiselevel: - noiselevel *= nfac - else: - noiselevel = nfac - noiselevels[trace.stats.channel] = noiselevel - - # prepare plotting of data - for trace in data: - t = prepTimeAxis(trace.stats.starttime - stime, trace) - inoise = getnoisewin(t, ini_pick, noise_win, gap_win) - trace = demeanTrace(trace, inoise) - # upscale trace data in a way that each trace is vertically zoomed to noiselevel*factor - channel = trace.stats.channel - noiselevel = noiselevels[channel] - noiseScaleFactor = self.calcNoiseScaleFactor(noiselevel, zoomfactor=5.) - trace.data *= noiseScaleFactor - noiselevels[channel] *= noiseScaleFactor - - x_res = getResolutionWindow(np.mean(snr), parameter.get('extent')) - - xlims = [ini_pick - x_res, ini_pick + x_res] - ylims = list(np.array([-.5, .5]) + [0, len(data) - 1]) - - plot_additional = bool(self.compareChannel.currentText()) - additional_channel = self.compareChannel.currentText() - self.multicompfig.plotWFData(wfdata=data, - title=self.getStation() + - ' picking mode', - zoomx=xlims, - zoomy=ylims, - noiselevel=noiselevels, - scaleddata=True, - iniPick=ini_pick, - plot_additional=plot_additional, - additional_channel=additional_channel) - def setPick(self, gui_event): parameter = self.parameter From c6cd6b2d69686ca5839b5c539089260312969c97 Mon Sep 17 00:00:00 2001 From: Marcel Date: Wed, 17 Jan 2018 12:19:32 +0100 Subject: [PATCH 10/13] [bugfix] use filter selected for ini pick not auto, save this filteropt. --- pylot/RELEASE-VERSION | 2 +- pylot/core/util/widgets.py | 18 +++++++++++++++--- 2 files changed, 16 insertions(+), 4 deletions(-) diff --git a/pylot/RELEASE-VERSION b/pylot/RELEASE-VERSION index 12a031b1..77e6ace6 100644 --- a/pylot/RELEASE-VERSION +++ b/pylot/RELEASE-VERSION @@ -1 +1 @@ -4735-dirty +0e05-dirty diff --git a/pylot/core/util/widgets.py b/pylot/core/util/widgets.py index 79727873..c2f1d39a 100644 --- a/pylot/core/util/widgets.py +++ b/pylot/core/util/widgets.py @@ -1948,6 +1948,14 @@ class PickDlg(QDialog): self.setPlotLabels() self.draw() + def currentFilterPhase(self): + filterphase = None + if self.filterActionP.isChecked(): + filterphase = 'P' + elif self.filterActionS.isChecked(): + filterphase = 'S' + return filterphase + def setIniPickP(self, gui_event): self.setIniPickPS(gui_event, phase='P') @@ -1984,8 +1992,9 @@ class PickDlg(QDialog): return # filter data and trace on which is picked prior to determination of SNR - filteroptions = self.getFilterOptions(phase).parseFilterOptions() - if filteroptions: + filterphase = self.currentFilterPhase() + if filterphase: + filteroptions = self.getFilterOptions(filterphase).parseFilterOptions() try: data.filter(**filteroptions) #wfdata.filter(**filteroptions)# MP MP removed filtering of original data @@ -2049,12 +2058,14 @@ class PickDlg(QDialog): # setting pick pick = gui_event.xdata # get pick time relative to the traces timeaxis not to the global channel = self.getChannelID(round(gui_event.ydata)) + # TODO: channel ID not correct when calcPlotPositions altered positions? # get name of phase actually picked phase = self.currentPhase # get filter parameter for the phase to be picked - filteroptions = self.getFilterOptions(self.getPhaseID(phase)).parseFilterOptions() + filterphase = self.currentFilterPhase() + filteroptions = self.getFilterOptions(self.getPhaseID(filterphase)).parseFilterOptions() # copy and filter data for earliest and latest possible picks wfdata = self.getWFData().copy().select(channel=channel) @@ -2067,6 +2078,7 @@ class PickDlg(QDialog): self.qmb.show() # get earliest and latest possible pick and symmetric pick error + # TODO: Hardcoded channel 3 for Z! if wfdata[0].stats.channel[2] == 'Z' or wfdata[0].stats.channel[2] == '3': nfac = parameter.get('nfacP') TSNR = parameter.get('tsnrz') From 60a2863629767a4b6faff9c6d681989d0f61d45b Mon Sep 17 00:00:00 2001 From: Marcel Date: Wed, 17 Jan 2018 16:28:50 +0100 Subject: [PATCH 11/13] [bugfix] copy/paste failure --- pylot/RELEASE-VERSION | 2 +- pylot/core/util/widgets.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/pylot/RELEASE-VERSION b/pylot/RELEASE-VERSION index 77e6ace6..0ba2ad03 100644 --- a/pylot/RELEASE-VERSION +++ b/pylot/RELEASE-VERSION @@ -1 +1 @@ -0e05-dirty +c6cd-dirty diff --git a/pylot/core/util/widgets.py b/pylot/core/util/widgets.py index c2f1d39a..29f0c676 100644 --- a/pylot/core/util/widgets.py +++ b/pylot/core/util/widgets.py @@ -1960,7 +1960,7 @@ class PickDlg(QDialog): self.setIniPickPS(gui_event, phase='P') def setIniPickS(self, gui_event): - self.setIniPickPS(gui_event, phase='P') + self.setIniPickPS(gui_event, phase='S') def setIniPickPS(self, gui_event, phase): phase = self.getPhaseID(phase) From 819e4d70765de85af53718165f893fde85154625 Mon Sep 17 00:00:00 2001 From: Marcel Date: Wed, 17 Jan 2018 16:38:11 +0100 Subject: [PATCH 12/13] [bugfix] skip unknown channels for everything but comparison option --- pylot/RELEASE-VERSION | 2 +- pylot/core/util/widgets.py | 23 ++++++++++++++++------- 2 files changed, 17 insertions(+), 8 deletions(-) diff --git a/pylot/RELEASE-VERSION b/pylot/RELEASE-VERSION index 0ba2ad03..67769430 100644 --- a/pylot/RELEASE-VERSION +++ b/pylot/RELEASE-VERSION @@ -1 +1 @@ -c6cd-dirty +60a2-dirty diff --git a/pylot/core/util/widgets.py b/pylot/core/util/widgets.py index 29f0c676..2582dcc8 100644 --- a/pylot/core/util/widgets.py +++ b/pylot/core/util/widgets.py @@ -904,7 +904,11 @@ class PylotCanvas(FigureCanvas): plot_positions = {} for trace in wfdata: comp = trace.stats.channel[-1] - plot_positions[trace.stats.channel] = compclass.getPlotPosition(str(comp)) + try: + position = compclass.getPlotPosition(str(comp)) + except ValueError as e: + continue + plot_positions[trace.stats.channel] = position for channel, plot_pos in plot_positions.items(): while not plot_pos in possible_plot_pos or not plot_pos - 1 in plot_positions.values(): if plot_pos == 0: @@ -1259,15 +1263,20 @@ class PickDlg(QDialog): # fill compare and scale channels self.compareChannel.addItem('-', None) self.scaleChannel.addItem('normalized', None) + for trace in self.getWFData(): - self.compareChannel.addItem(trace.stats.channel, trace) - self.scaleChannel.addItem(trace.stats.channel, trace) - actionP = self.pChannels.addAction(str(trace.stats.channel)) - actionS = self.sChannels.addAction(str(trace.stats.channel)) + channel = trace.stats.channel + self.compareChannel.addItem(channel, trace) + if not channel[-1] in ['Z', 'N', 'E', '1', '2', '3']: + print('Skipping unknown channel for scaling: {}'.format(channel)) + continue + self.scaleChannel.addItem(channel, trace) + actionP = self.pChannels.addAction(str(channel)) + actionS = self.sChannels.addAction(str(channel)) actionP.setCheckable(True) actionS.setCheckable(True) - actionP.setChecked(self.getChannelSettingsP(trace.stats.channel)) - actionS.setChecked(self.getChannelSettingsS(trace.stats.channel)) + actionP.setChecked(self.getChannelSettingsP(channel)) + actionS.setChecked(self.getChannelSettingsS(channel)) # plot data self.multicompfig.plotWFData(wfdata=self.getWFData(), From ff65fd2290bd70d979d56d57181e463ccf47fc57 Mon Sep 17 00:00:00 2001 From: Marcel Date: Wed, 21 Feb 2018 13:36:43 +0100 Subject: [PATCH 13/13] [minor] some updates --- pylot/RELEASE-VERSION | 2 +- pylot/core/io/phases.py | 11 ++++++++--- pylot/core/util/widgets.py | 1 + 3 files changed, 10 insertions(+), 4 deletions(-) diff --git a/pylot/RELEASE-VERSION b/pylot/RELEASE-VERSION index 67769430..9f4ddf13 100644 --- a/pylot/RELEASE-VERSION +++ b/pylot/RELEASE-VERSION @@ -1 +1 @@ -60a2-dirty +819e-dirty diff --git a/pylot/core/io/phases.py b/pylot/core/io/phases.py index 55a496e2..fa0e7587 100644 --- a/pylot/core/io/phases.py +++ b/pylot/core/io/phases.py @@ -255,10 +255,15 @@ def picksdict_from_picks(evt): lpp = mpp + pick.time_errors.upper_uncertainty epp = mpp - pick.time_errors.lower_uncertainty except TypeError as e: - msg = e + ',\n falling back to symmetric uncertainties' + if not spe: + msg = 'No uncertainties found for pick: {}. Uncertainty set to 0'.format(pick) + lpp = mpp + epp = mpp + else: + msg = str(e) + ',\n falling back to symmetric uncertainties' + lpp = mpp + spe + epp = mpp - spe warnings.warn(msg) - lpp = mpp + spe - epp = mpp - spe phase['mpp'] = mpp phase['epp'] = epp phase['lpp'] = lpp diff --git a/pylot/core/util/widgets.py b/pylot/core/util/widgets.py index 2582dcc8..37161a80 100644 --- a/pylot/core/util/widgets.py +++ b/pylot/core/util/widgets.py @@ -987,6 +987,7 @@ class PylotCanvas(FigureCanvas): times = [time for index, time in enumerate(time_ax) if not index % nth_sample] data = [datum + n for index, datum in enumerate(trace.data) if not index % nth_sample] + ax.axhline(n, color="0.5", lw=0.5) ax.plot(times, data, color=linecolor, linewidth=0.7) if noiselevel is not None: for level in [-noiselevel[channel], noiselevel[channel]]: