From 26a4cc568a7fdcddf113854affcae6710d633eef Mon Sep 17 00:00:00 2001 From: Marcel Date: Mon, 13 Aug 2018 11:24:48 +0200 Subject: [PATCH 01/15] [new] perform jackknife on gradient of stations in array map and highlight them in case of high std --- pylot/core/util/array_map.py | 56 +++++++++++++++++++++++++++++++++++- 1 file changed, 55 insertions(+), 1 deletion(-) diff --git a/pylot/core/util/array_map.py b/pylot/core/util/array_map.py index 262bbd7f..d8b3ba84 100644 --- a/pylot/core/util/array_map.py +++ b/pylot/core/util/array_map.py @@ -30,6 +30,8 @@ class Array_map(QtGui.QWidget): self.autopicks_dict = None self.eventLoc = None self.figure = figure + self.picks_rel = {} + self.marked_stations = [] self.init_graphics() self.init_stations() self.init_basemap(resolution='l') @@ -297,10 +299,51 @@ class Array_map(QtGui.QWidget): return picks, latitudes, longitudes def draw_contour_filled(self, nlevel='50'): + #self.test_gradient() + levels = np.linspace(self.get_min_from_picks(), self.get_max_from_picks(), nlevel) self.contourf = self.basemap.contourf(self.longrid, self.latgrid, self.picksgrid_active, levels, latlon=True, zorder=9, alpha=0.5) + def test_gradient(self): + st_ids = self.picks_rel.keys() + x, y = np.gradient(self.picksgrid_active) + gradient_modulus = np.sqrt(x ** 2 + y ** 2) + global_mean_gradient = np.nanmean(gradient_modulus) + delta_gradient = [] + for st_id in st_ids: + pick_item = self.picks_rel.pop(st_id) + self.init_picksgrid() + x, y = np.gradient(self.picksgrid_active) + gradient_modulus = np.sqrt(x**2 + y**2) + mean_gradient = np.nanmean(gradient_modulus) + dgradient = global_mean_gradient - mean_gradient + # print('station: {}, mean gradient: {}'.format(st_id, dgradient)) + delta_gradient.append(dgradient) + self.picks_rel[st_id] = pick_item + global_std_gradient = np.nanstd(delta_gradient) + marked_stations = [] + for st_id, dg in zip(st_ids, delta_gradient): + if abs(dg) > global_std_gradient: + marked_stations.append(st_id) + self.marked_stations = marked_stations + self.init_picksgrid() + + # fig = plt.figure() + # x = list(range(len(st_ids))) + # gradients = zip(x, delta_gradient) + # gradients.sort(key=lambda a: a[1]) + # plt.plot(gradients[0], gradients[1]) + + # global_var_gradient = np.nanvar(delta_gradient) + # plt.plot(x, delta_gradient) + # plt.axhline(global_std_gradient, color='green') + # plt.axhline(2 * global_std_gradient, color='blue') + # plt.axhline(global_var_gradient, color='red') + # plt.xticks(x, st_ids) + # plt.show() + + def scatter_all_stations(self): stations, lats, lons = self.get_st_lat_lon_for_plot() self.sc = self.basemap.scatter(lons, lats, s=50, facecolor='none', latlon=True, @@ -330,9 +373,20 @@ class Array_map(QtGui.QWidget): def annotate_ax(self): self.annotations = [] stations, xs, ys = self.get_st_x_y_for_plot() + # MP MP test + if self.picks_rel: + self.test_gradient() + color_marked = {True: 'red', + False: 'white'} for st, x, y in zip(stations, xs, ys): + if st in self.picks_rel: + color = 'white' + else: + color = 'black' + if st in self.marked_stations: + color = 'red' self.annotations.append(self.main_ax.annotate(' %s' % st, xy=(x, y), - fontsize='x-small', color='white', zorder=12)) + fontsize='x-small', color=color, zorder=12)) self.legend = self.main_ax.legend(loc=1) self.legend.get_frame().set_facecolor((1, 1, 1, 0.75)) From f22f7845cb43c7b9977795b7762b2c654f7c0fce Mon Sep 17 00:00:00 2001 From: Marcel Date: Mon, 13 Aug 2018 12:49:48 +0200 Subject: [PATCH 02/15] [new] remove picks on map with middle-click [bugfix] remove old annotations --- pylot/core/util/array_map.py | 60 ++++++++++++++++++++++++++++++++---- 1 file changed, 54 insertions(+), 6 deletions(-) diff --git a/pylot/core/util/array_map.py b/pylot/core/util/array_map.py index d8b3ba84..aa740712 100644 --- a/pylot/core/util/array_map.py +++ b/pylot/core/util/array_map.py @@ -59,8 +59,55 @@ class Array_map(QtGui.QWidget): def onpick(self, event): ind = event.ind button = event.mouseevent.button - if ind == [] or not button == 1: + if ind == []: return + if button == 1: + self.openPickDlg(ind) + elif button == 2: + self.deletePick(ind) + elif button == 3: + self.pickInfo(ind) + + def deletePick(self, ind): + for index in ind: + network, station = self._station_onpick_ids[index].split('.')[:2] + try: + phase = self.comboBox_phase.currentText() + picks = self.current_picks_dict()[station] + pick = picks.get(phase) + if pick: + picker = pick['picker'] + if picker == 'auto': + del(self.autopicks_dict[station]) + message = 'Removed automatic pick for station {}, phase {}'.format(station, phase) + elif picker == 'manual': + del(self.picks_dict[station]) + message = 'Removed manual pick for station {}, phase {}'.format(station, phase) + else: + raise TypeError('Unknown "picker" {}'.format(picker)) + print(message) + pyl_mw = self._parent + pyl_mw.setDirty(True) + pyl_mw.update_status(message) + self._refresh_drawings() + pyl_mw.drawPicks(station) + pyl_mw.draw() + except Exception as e: + print('Could not delete pick for station {}.{}: {}'.format(network, station, e)) + + def pickInfo(self, ind): + for index in ind: + network, station = self._station_onpick_ids[index].split('.')[:2] + dic = self.current_picks_dict()[station] + for phase, picks in dic.items(): + # because of wadati... + if phase == 'SPt': + continue + print('{} - Pick:'.format(phase)) + for key, info in picks.items(): + print('{}: {}'.format(key, info)) + + def openPickDlg(self, ind): data = self._parent.get_data().getWFData() for index in ind: network, station = self._station_onpick_ids[index].split('.')[:2] @@ -361,13 +408,13 @@ class Array_map(QtGui.QWidget): return # workaround because of an issue with latlon transformation of arrays with len <3 if len(lons) <= 2 and len(lats) <= 2: - self.sc_picked = self.basemap.scatter(lons[0], lats[0], s=50, facecolor='white', + self.sc_picked = self.basemap.scatter(lons[0], lats[0], s=50, edgecolors='white', c=picks[0], latlon=True, zorder=11, label='Picked') if len(lons) == 2 and len(lats) == 2: - self.sc_picked = self.basemap.scatter(lons[1], lats[1], s=50, facecolor='white', + self.sc_picked = self.basemap.scatter(lons[1], lats[1], s=50, edgecolors='white', c=picks[1], latlon=True, zorder=11) else: - self.sc_picked = self.basemap.scatter(lons, lats, s=50, facecolor='white', + self.sc_picked = self.basemap.scatter(lons, lats, s=50, edgecolors='white', c=picks, latlon=True, zorder=11, label='Picked') def annotate_ax(self): @@ -382,11 +429,11 @@ class Array_map(QtGui.QWidget): if st in self.picks_rel: color = 'white' else: - color = 'black' + color = 'lightgrey' if st in self.marked_stations: color = 'red' self.annotations.append(self.main_ax.annotate(' %s' % st, xy=(x, y), - fontsize='x-small', color=color, zorder=12)) + fontsize='x-small', color=color, zorder=14)) self.legend = self.main_ax.legend(loc=1) self.legend.get_frame().set_facecolor((1, 1, 1, 0.75)) @@ -435,6 +482,7 @@ class Array_map(QtGui.QWidget): self.canvas.draw() def remove_drawings(self): + self.remove_annotations() if hasattr(self, 'cbar'): self.cbar.remove() self.cbax_bg.remove() From a82a1cddc8f78d6d3837b6e070bd6bb1b8fb3e04 Mon Sep 17 00:00:00 2001 From: Marcel Date: Mon, 13 Aug 2018 17:44:24 +0200 Subject: [PATCH 03/15] [minor] changed message for pick deletion --- pylot/core/util/array_map.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/pylot/core/util/array_map.py b/pylot/core/util/array_map.py index aa740712..da6257ed 100644 --- a/pylot/core/util/array_map.py +++ b/pylot/core/util/array_map.py @@ -77,12 +77,13 @@ class Array_map(QtGui.QWidget): pick = picks.get(phase) if pick: picker = pick['picker'] + message = 'Deleted {} pick for phase {}, station {}.{} at timestamp {}' + message = message.format(picker, phase, network, station, + pick['mpp']) if picker == 'auto': del(self.autopicks_dict[station]) - message = 'Removed automatic pick for station {}, phase {}'.format(station, phase) elif picker == 'manual': del(self.picks_dict[station]) - message = 'Removed manual pick for station {}, phase {}'.format(station, phase) else: raise TypeError('Unknown "picker" {}'.format(picker)) print(message) From 402248f340a5da4a800a1ea4748deb9cc36a70e9 Mon Sep 17 00:00:00 2001 From: Marcel Date: Tue, 14 Aug 2018 14:21:32 +0200 Subject: [PATCH 04/15] [new] minor, add recently used projects (WIP) --- PyLoT.py | 28 ++++++++++++++++++++++++++-- 1 file changed, 26 insertions(+), 2 deletions(-) diff --git a/PyLoT.py b/PyLoT.py index 316173a9..4bf9b738 100755 --- a/PyLoT.py +++ b/PyLoT.py @@ -204,6 +204,7 @@ class MainWindow(QMainWindow): if settings.value('autoFilter', None) is None: settings.setValue('autoFilter', True) settings.sync() + print(settings.value('recentProjects')) # setup UI self.setupUi() @@ -542,6 +543,7 @@ class MainWindow(QMainWindow): self.updateFileMenu() self.editMenu = self.menuBar().addMenu('&Edit') + editActions = (self.filterActionP, self.filterActionS, filterEditAction, None, # self.selectPAction, self.selectSAction, None, self.inventoryAction, self.initMapAction, None, @@ -553,6 +555,7 @@ class MainWindow(QMainWindow): self.autoPickMenu = self.pickMenu.addMenu(self.autopicksicon_small, 'Automatic picking') self.autoPickMenu.setEnabled(False) + autoPickActions = (self.auto_pick, self.auto_pick_local, self.auto_pick_sge) self.helpMenu = self.menuBar().addMenu('&Help') @@ -685,6 +688,7 @@ class MainWindow(QMainWindow): self.setCentralWidget(_widget) + def init_wfWidget(self): xlab = self.startTime.strftime('seconds since %Y/%m/%d %H:%M:%S (%Z)') plottitle = None # "Overview: {0} components ".format(self.getComponent()) @@ -830,8 +834,9 @@ class MainWindow(QMainWindow): s_filter['order'])} def updateFileMenu(self): - + settings = QSettings() self.fileMenu.clear() + self.recentProjectsMenu = self.fileMenu.addMenu('Recent Projects') for action in self.fileMenuActions[:-1]: if action is None: self.fileMenu.addSeparator() @@ -848,7 +853,6 @@ class MainWindow(QMainWindow): recentEvents.append(eventID) recentEvents.reverse() self.recentfiles = recentEvents[0:5] - settings = QSettings() settings.setValue() if recentEvents: for i, eventID in enumerate(recentEvents): @@ -864,6 +868,16 @@ class MainWindow(QMainWindow): self.fileMenu.addSeparator() self.fileMenu.addAction(self.fileMenuActions[-1]) + # add recent projects + recentProjects = settings.value('recentProjects', []) + for project in reversed(recentProjects): + action = self.createAction(self, project, + self.createNewProject, + None, None) + + self.recentProjectsMenu.addAction(action) + + @property def inputs(self): return self._inputs @@ -3294,6 +3308,16 @@ class MainWindow(QMainWindow): self.init_array_tab() self.set_metadata() + self.add2recentProjects(fnm) + + def add2recentProjects(self, fnm): + settings = QtCore.QSettings() + recent = settings.value('recentProjects', []) + if not type(recent) == list: + recent = [recent] + recent.append(fnm) + new_recent = recent[-5:] + settings.setValue('recentProjects', new_recent) def saveProjectAs(self, exists=False): ''' From 8a187905cb05da55234f846927638acc78202d0c Mon Sep 17 00:00:00 2001 From: Marcel Date: Wed, 15 Aug 2018 15:39:43 +0200 Subject: [PATCH 05/15] [update] finalized recent projects [minor] some small fixes, improvements --- PyLoT.py | 15 +++++++++++---- pylot/core/util/array_map.py | 6 +++--- 2 files changed, 14 insertions(+), 7 deletions(-) diff --git a/PyLoT.py b/PyLoT.py index 4bf9b738..07e47ac6 100755 --- a/PyLoT.py +++ b/PyLoT.py @@ -204,7 +204,6 @@ class MainWindow(QMainWindow): if settings.value('autoFilter', None) is None: settings.setValue('autoFilter', True) settings.sync() - print(settings.value('recentProjects')) # setup UI self.setupUi() @@ -870,10 +869,12 @@ class MainWindow(QMainWindow): # add recent projects recentProjects = settings.value('recentProjects', []) + if not type(recentProjects) == list: + recentProjects = [recentProjects] for project in reversed(recentProjects): action = self.createAction(self, project, - self.createNewProject, - None, None) + lambda fnm=project: self.loadProject(fnm), + None, None) self.recentProjectsMenu.addAction(action) @@ -3306,6 +3307,10 @@ class MainWindow(QMainWindow): self.setDirty(False) self.init_metadata() + message = 'Opened project file {}.'.format(fnm) + print(message) + self.update_status(message) + self.init_array_tab() self.set_metadata() self.add2recentProjects(fnm) @@ -3315,9 +3320,11 @@ class MainWindow(QMainWindow): recent = settings.value('recentProjects', []) if not type(recent) == list: recent = [recent] - recent.append(fnm) + if not fnm in recent: + recent.append(fnm) new_recent = recent[-5:] settings.setValue('recentProjects', new_recent) + settings.sync() def saveProjectAs(self, exists=False): ''' diff --git a/pylot/core/util/array_map.py b/pylot/core/util/array_map.py index da6257ed..ef5efff7 100644 --- a/pylot/core/util/array_map.py +++ b/pylot/core/util/array_map.py @@ -421,9 +421,9 @@ class Array_map(QtGui.QWidget): def annotate_ax(self): self.annotations = [] stations, xs, ys = self.get_st_x_y_for_plot() - # MP MP test - if self.picks_rel: - self.test_gradient() + # MP MP testing station highlighting if they have high impact on mean gradient of color map + # if self.picks_rel: + # self.test_gradient() color_marked = {True: 'red', False: 'white'} for st, x, y in zip(stations, xs, ys): From ce1564c2f8c47f2b4ee6898f6660052be2158f7e Mon Sep 17 00:00:00 2001 From: Marcel Date: Wed, 15 Aug 2018 15:51:41 +0200 Subject: [PATCH 06/15] [minor] improved convenience, small bugfix --- PyLoT.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/PyLoT.py b/PyLoT.py index 07e47ac6..9da69c69 100755 --- a/PyLoT.py +++ b/PyLoT.py @@ -3288,10 +3288,13 @@ class MainWindow(QMainWindow): return if not fnm: dlg = QFileDialog(parent=self) - fnm = dlg.getOpenFileName(self, 'Open project file...', filter='Pylot project (*.plp)') + fnm = dlg.getOpenFileName(self, 'Open project file...', filter='Pylot project (*.plp)')[0] if not fnm: return - fnm = fnm[0] + if not os.path.exists(fnm): + QMessageBox.warning(self, 'Could not open file', + 'Could not open project file {}. File does not exist.'.format(fnm)) + return if fnm: self.project = Project.load(fnm) if hasattr(self.project, 'parameter'): @@ -3343,6 +3346,7 @@ class MainWindow(QMainWindow): self.setDirty(False) self.saveProjectAsAction.setEnabled(True) self.update_status('Saved new project to {}'.format(filename), duration=5000) + self.add2recentProjects(filename) return True def saveProject(self, new=False): From 6546f8f19698488edae885b99e79a26ac3f55abd Mon Sep 17 00:00:00 2001 From: Marcel Date: Thu, 16 Aug 2018 16:14:48 +0200 Subject: [PATCH 07/15] [update] warn user in case of low SNR for manual pick --- pylot/core/util/widgets.py | 37 ++++++++++++++++++++++++++++--------- 1 file changed, 28 insertions(+), 9 deletions(-) diff --git a/pylot/core/util/widgets.py b/pylot/core/util/widgets.py index 23f65826..296fe6c0 100644 --- a/pylot/core/util/widgets.py +++ b/pylot/core/util/widgets.py @@ -1203,7 +1203,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, - plot_additional=False, additional_channel=None, scaleToChannel=None): + plot_additional=False, additional_channel=None, scaleToChannel=None, + snr=None): ax = self.axes[0] ax.cla() @@ -1323,6 +1324,14 @@ class PylotCanvas(FigureCanvas): self.setXLims(ax, zoomx) if zoomy is not None: self.setYLims(ax, zoomy) + if snr is not None: + if snr < 2: + warning = 'LOW SNR' + if snr < 1.5: + warning = 'VERY LOW SNR' + ax.text(0.1, 0.9, 'WARNING - {}'.format(warning), ha='center', va='center', transform=ax.transAxes, + color='red') + self.draw() @staticmethod @@ -2280,6 +2289,12 @@ class PickDlg(QDialog): filterphase = 'S' return filterphase + def getNoiseWin(self, phase): + twins_phase = {'P': 'tsnrz', + 'S': 'tsnrh'} + + return self.parameter.get(twins_phase[phase])[:3] + def setIniPickP(self, gui_event): self.setIniPickPS(gui_event, phase='P') @@ -2291,17 +2306,12 @@ class PickDlg(QDialog): nfac_phase = {'P': 'nfacP', 'S': 'nfacS'} - twins_phase = {'P': 'tsnrz', - 'S': 'tsnrh'} parameter = self.parameter ini_pick = gui_event.xdata nfac = parameter.get(nfac_phase[phase]) - twins = parameter.get(twins_phase[phase]) - noise_win = twins[0] - gap_win = twins[1] - signal_win = twins[2] + noise_win, gap_win, signal_win = self.getNoiseWin(phase) stime = self.getStartTime() @@ -2355,12 +2365,14 @@ class PickDlg(QDialog): trace.data *= noiseScaleFactor noiselevels[channel] *= noiseScaleFactor - x_res = getResolutionWindow(np.mean(snr), parameter.get('extent')) + mean_snr = np.mean(snr) + x_res = getResolutionWindow(mean_snr, parameter.get('extent')) xlims = [ini_pick - x_res, ini_pick + x_res] ylims = list(np.array([-.5, .5]) + [0, len(data) - 1]) title = self.getStation() + ' picking mode' + title += ' | SNR: {}'.format(mean_snr) if filterphase: filtops_str = transformFilteroptions2String(filteroptions) title += ' | Filteroptions: {}'.format(filtops_str) @@ -2375,7 +2387,9 @@ class PickDlg(QDialog): scaleddata=True, iniPick=ini_pick, plot_additional=plot_additional, - additional_channel=additional_channel) + additional_channel=additional_channel, + snr=mean_snr) + def setPick(self, gui_event): @@ -2447,6 +2461,11 @@ class PickDlg(QDialog): self.zoomAction.setEnabled(True) # self.pick_block = self.togglPickBlocker() # self.resetZoom() + noise_win, gap_win, signal_win = self.getNoiseWin(phase) + snr, snrDB, noiselevel = getSNR(wfdata, (noise_win, gap_win, signal_win), pick - stime_diff) + print('SNR of final pick: {}'.format(snr)) + if snr < 1.5: + QMessageBox.warning(self, 'SNR too low', 'WARNING! SNR of final pick below 1.5! SNR = {}'.format(snr)) self.leave_picking_mode() def savePick(self, phase, phasepicks): From c23bbfae8a9a4a89521e3a2529c815a6edea9d31 Mon Sep 17 00:00:00 2001 From: Marcel Date: Thu, 16 Aug 2018 16:21:28 +0200 Subject: [PATCH 08/15] [bugfix] enhanced emergency reset loop for corrupted QSettings --- PyLoT.py | 48 ++++++++++++++++++++++++------------------------ 1 file changed, 24 insertions(+), 24 deletions(-) diff --git a/PyLoT.py b/PyLoT.py index 9da69c69..ef5b7348 100755 --- a/PyLoT.py +++ b/PyLoT.py @@ -155,6 +155,9 @@ class MainWindow(QMainWindow): self.data._new = False self.autodata = Data(self) + self.fnames = None + self._stime = None + while True: try: if settings.value("user/FullName", None) is None: @@ -166,6 +169,27 @@ class MainWindow(QMainWindow): "Enter authority/institution name:", "Authority") settings.setValue("agency_id", agency) + structure_setting = settings.value("data/Structure", "PILOT") + if not structure_setting: + structure_setting = 'PILOT' + self.dataStructure = DATASTRUCTURE[structure_setting]() + self.seismicPhase = str(settings.value("phase", "P")) + if settings.value("data/dataRoot", None) is None: + dirname = QFileDialog().getExistingDirectory( + caption='Choose data root ...') + settings.setValue("data/dataRoot", dirname) + if settings.value('compclass', None) is None: + settings.setValue('compclass', SetChannelComponents()) + if settings.value('useGuiFilter') is None: + settings.setValue('useGuiFilter', False) + if settings.value('output/Format', None) is None: + outformat = QInputDialog.getText(self, + "Enter output format (*.xml, *.cnv, *.obs):", + "Format") + settings.setValue("output/Format", outformat) + if settings.value('autoFilter', None) is None: + settings.setValue('autoFilter', True) + settings.sync() break except Exception as e: qmb = QMessageBox(self, icon=QMessageBox.Question, @@ -181,30 +205,6 @@ class MainWindow(QMainWindow): sys.exit() print('Settings cleared!') - self.fnames = None - self._stime = None - structure_setting = settings.value("data/Structure", "PILOT") - if not structure_setting: - structure_setting = 'PILOT' - self.dataStructure = DATASTRUCTURE[structure_setting]() - self.seismicPhase = str(settings.value("phase", "P")) - if settings.value("data/dataRoot", None) is None: - dirname = QFileDialog().getExistingDirectory( - caption='Choose data root ...') - settings.setValue("data/dataRoot", dirname) - if settings.value('compclass', None) is None: - settings.setValue('compclass', SetChannelComponents()) - if settings.value('useGuiFilter') is None: - settings.setValue('useGuiFilter', False) - if settings.value('output/Format', None) is None: - outformat = QInputDialog.getText(self, - "Enter output format (*.xml, *.cnv, *.obs):", - "Format") - settings.setValue("output/Format", outformat) - if settings.value('autoFilter', None) is None: - settings.setValue('autoFilter', True) - settings.sync() - # setup UI self.setupUi() From 739a6e89f4fff42f31b0460aeac464e2809d7f43 Mon Sep 17 00:00:00 2001 From: Marcel Date: Thu, 16 Aug 2018 17:34:05 +0200 Subject: [PATCH 09/15] [pycharm] optimized imports --- PyLoT.py | 22 +++++++------- autoPyLoT.py | 8 ++--- pylot/core/analysis/magnitude.py | 5 ++-- pylot/core/io/data.py | 9 +++--- pylot/core/io/phases.py | 10 +++---- pylot/core/loc/nll.py | 2 +- pylot/core/pick/autopick.py | 7 ++--- pylot/core/pick/compare.py | 8 ++--- pylot/core/pick/picker.py | 6 ++-- pylot/core/pick/utils.py | 4 +-- pylot/core/util/array_map.py | 17 +++++------ pylot/core/util/dataprocessing.py | 8 ++--- pylot/core/util/defaults.py | 4 +-- pylot/core/util/event.py | 2 +- pylot/core/util/pdf.py | 4 +-- pylot/core/util/thread.py | 8 +++-- pylot/core/util/utils.py | 18 +++++------ pylot/core/util/widgets.py | 45 ++++++++++++++-------------- tests/test_Metadata/test_Metadata.py | 6 ++-- tests/utils.py | 2 +- 20 files changed, 93 insertions(+), 102 deletions(-) diff --git a/PyLoT.py b/PyLoT.py index ef5b7348..18bc73d7 100755 --- a/PyLoT.py +++ b/PyLoT.py @@ -24,12 +24,11 @@ https://www.iconfinder.com/iconsets/flavour """ import argparse +import matplotlib import os import platform import sys -import matplotlib - matplotlib.use('Qt4Agg') matplotlib.rcParams['backend.qt4'] = 'PySide' matplotlib.rcParams['savefig.dpi'] = 300 @@ -40,8 +39,8 @@ from PySide.QtCore import QCoreApplication, QSettings, Signal, QFile, \ QFileInfo, Qt, QSize from PySide.QtGui import QMainWindow, QInputDialog, QIcon, QFileDialog, \ QWidget, QHBoxLayout, QVBoxLayout, QStyle, QKeySequence, QLabel, QFrame, QAction, \ - QDialog, QErrorMessage, QApplication, QPixmap, QMessageBox, QSplashScreen, \ - QActionGroup, QListWidget, QLineEdit, QListView, QAbstractItemView, \ + QDialog, QApplication, QPixmap, QMessageBox, QSplashScreen, \ + QActionGroup, QListWidget, QListView, QAbstractItemView, \ QTreeView, QComboBox, QTabWidget, QPushButton, QGridLayout import numpy as np from obspy import UTCDateTime @@ -56,7 +55,6 @@ try: from matplotlib.backends.backend_qt4agg import FigureCanvas except ImportError: from matplotlib.backends.backend_qt4agg import FigureCanvasQTAgg as FigureCanvas -from matplotlib.backends.backend_qt4agg import NavigationToolbar2QT as NavigationToolbar from matplotlib.figure import Figure from pylot.core.analysis.magnitude import LocalMagnitude, MomentMagnitude @@ -64,24 +62,23 @@ from pylot.core.io.data import Data from pylot.core.io.inputs import FilterOptions, PylotParameter from autoPyLoT import autoPyLoT from pylot.core.pick.compare import Comparison -from pylot.core.pick.utils import symmetrize_error, getQualityFromUncertainty, getPickQuality +from pylot.core.pick.utils import getQualityFromUncertainty from pylot.core.io.phases import picksdict_from_picks import pylot.core.loc.nll as nll -from pylot.core.util.defaults import FILTERDEFAULTS from pylot.core.util.errors import DatastructureError, \ OverwriteError from pylot.core.util.connection import checkurl from pylot.core.util.dataprocessing import Metadata, restitute_data from pylot.core.util.utils import fnConstructor, getLogin, \ - full_range, readFilterInformation, trim_station_components, check4gaps, make_pen, pick_color_plt, \ - pick_linestyle_plt, remove_underscores, check4doubled, identifyPhaseID, excludeQualityClasses, \ - check4rotated, transform_colors_mpl, transform_colors_mpl_str, getAutoFilteroptions, check_all_obspy, \ + full_range, readFilterInformation, make_pen, pick_color_plt, \ + pick_linestyle_plt, identifyPhaseID, excludeQualityClasses, \ + transform_colors_mpl, transform_colors_mpl_str, getAutoFilteroptions, check_all_obspy, \ check_all_pylot, real_Bool, SetChannelComponents 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, \ PylotCanvas, WaveformWidgetPG, PropertiesDlg, HelpForm, createAction, PickDlg, \ - getDataType, ComparisonWidget, TuneAutopicker, PylotParaBox, AutoPickDlg, CanvasWidget, AutoPickWidget, \ + ComparisonWidget, TuneAutopicker, PylotParaBox, AutoPickDlg, CanvasWidget, AutoPickWidget, \ CompareEventsWidget, ProgressBarWidget, AddMetadataWidget from pylot.core.util.array_map import Array_map from pylot.core.util.structure import DATASTRUCTURE @@ -97,6 +94,9 @@ elif sys.version_info.major == 2: else: raise ImportError('Could not determine python version.') +# workaround to prevent PyCharm from deleting icons_rc import when optimizing imports +icons_rc = icons_rc + locateTool = dict(nll=nll) diff --git a/autoPyLoT.py b/autoPyLoT.py index e24500fe..df9f20a4 100755 --- a/autoPyLoT.py +++ b/autoPyLoT.py @@ -8,6 +8,8 @@ import datetime import glob import os import traceback +from obspy import read_events +from obspy.core.event import ResourceIdentifier import pylot.core.loc.focmec as focmec import pylot.core.loc.hash as hash @@ -16,18 +18,16 @@ import pylot.core.loc.hypodd as hypodd import pylot.core.loc.hyposat as hyposat import pylot.core.loc.nll as nll import pylot.core.loc.velest as velest -from obspy import read_events -from obspy.core.event import ResourceIdentifier # from PySide.QtGui import QWidget, QInputDialog from pylot.core.analysis.magnitude import MomentMagnitude, LocalMagnitude from pylot.core.io.data import Data from pylot.core.io.inputs import PylotParameter from pylot.core.pick.autopick import autopickevent, iteratepicker -from pylot.core.util.dataprocessing import restitute_data, read_metadata, Metadata +from pylot.core.util.dataprocessing import restitute_data, Metadata from pylot.core.util.defaults import SEPARATOR from pylot.core.util.event import Event from pylot.core.util.structure import DATASTRUCTURE -from pylot.core.util.utils import real_None, remove_underscores, trim_station_components, check4gaps, check4doubled, \ +from pylot.core.util.utils import real_None, trim_station_components, check4gaps, check4doubled, \ check4rotated from pylot.core.util.version import get_git_version as _getVersionString diff --git a/pylot/core/analysis/magnitude.py b/pylot/core/analysis/magnitude.py index 0fa854bc..0a270ce8 100644 --- a/pylot/core/analysis/magnitude.py +++ b/pylot/core/analysis/magnitude.py @@ -11,11 +11,12 @@ import matplotlib.pyplot as plt import numpy as np import obspy.core.event as ope from obspy.geodetics import degrees2kilometers +from scipy import integrate, signal +from scipy.optimize import curve_fit + from pylot.core.pick.utils import getsignalwin, crossings_nonzero_all, \ select_for_phase from pylot.core.util.utils import common_range, fit_curve -from scipy import integrate, signal -from scipy.optimize import curve_fit def richter_magnitude_scaling(delta): diff --git a/pylot/core/io/data.py b/pylot/core/io/data.py index f1f3443d..82381126 100644 --- a/pylot/core/io/data.py +++ b/pylot/core/io/data.py @@ -3,19 +3,18 @@ import copy import os - from obspy import read_events from obspy.core import read, Stream, UTCDateTime from obspy.core.event import Event as ObsPyEvent from obspy.io.sac import SacIOError + +import pylot.core.loc.velest as velest from pylot.core.io.phases import readPILOTEvent, picks_from_picksdict, \ picksdict_from_pilot, merge_picks from pylot.core.util.errors import FormatError, OverwriteError from pylot.core.util.event import Event -from pylot.core.util.utils import fnConstructor, full_range, remove_underscores, check4gaps, check4doubled, \ - check4rotated, trim_station_components -import pylot.core.loc.velest as velest from pylot.core.util.obspyDMT_interface import qml_from_obspyDMT +from pylot.core.util.utils import fnConstructor, full_range, check4rotated, trim_station_components class Data(object): @@ -405,7 +404,7 @@ class Data(object): # various pre-processing steps: # remove possible underscores in station names - #self.wfdata = remove_underscores(self.wfdata) + # self.wfdata = remove_underscores(self.wfdata) # check for stations with rotated components if checkRotated and metadata is not None: self.wfdata = check4rotated(self.wfdata, metadata, verbosity=0) diff --git a/pylot/core/io/phases.py b/pylot/core/io/phases.py index 1aee1936..8c91f9ad 100644 --- a/pylot/core/io/phases.py +++ b/pylot/core/io/phases.py @@ -2,22 +2,22 @@ # -*- coding: utf-8 -*- import glob -import os -import warnings - import matplotlib.pyplot as plt import numpy as np import obspy.core.event as ope +import os import scipy.io as sio +import warnings from obspy.core import UTCDateTime from obspy.core.event import read_events from obspy.core.util import AttribDict + from pylot.core.io.inputs import PylotParameter from pylot.core.io.location import create_event, \ create_magnitude from pylot.core.pick.utils import select_for_phase -from pylot.core.util.utils import getOwner, full_range, four_digits, transformFilteroptions2String, \ - transformFilterString4Export, backtransformFilterString +from pylot.core.util.utils import getOwner, full_range, four_digits, transformFilterString4Export, \ + backtransformFilterString def add_amplitudes(event, amplitudes): diff --git a/pylot/core/loc/nll.py b/pylot/core/loc/nll.py index 47ef4e10..d7a664cc 100644 --- a/pylot/core/loc/nll.py +++ b/pylot/core/loc/nll.py @@ -4,8 +4,8 @@ import glob import os import subprocess - from obspy import read_events + from pylot.core.io.phases import writephases from pylot.core.util.utils import getPatternLine, runProgram, which from pylot.core.util.version import get_git_version as _getVersionString diff --git a/pylot/core/pick/autopick.py b/pylot/core/pick/autopick.py index b25b38bf..5477bbd6 100644 --- a/pylot/core/pick/autopick.py +++ b/pylot/core/pick/autopick.py @@ -8,10 +8,11 @@ function conglomerate utils. :author: MAGS2 EP3 working group / Ludger Kueperkoch """ -import traceback - import matplotlib.pyplot as plt import numpy as np +import traceback +from obspy.taup import TauPyModel + from pylot.core.pick.charfuns import CharacteristicFunction from pylot.core.pick.charfuns import HOScf, AICcf, ARZcf, ARHcf, AR3Ccf from pylot.core.pick.picker import AICPicker, PragPicker @@ -20,8 +21,6 @@ from pylot.core.pick.utils import checksignallength, checkZ4S, earllatepicker, \ from pylot.core.util.utils import getPatternLine, gen_Pool, \ real_Bool, identifyPhaseID -from obspy.taup import TauPyModel - def autopickevent(data, param, iplot=0, fig_dict=None, fig_dict_wadatijack=None, ncores=0, metadata=None, origin=None): """ diff --git a/pylot/core/pick/compare.py b/pylot/core/pick/compare.py index 8b181d51..185e1242 100644 --- a/pylot/core/pick/compare.py +++ b/pylot/core/pick/compare.py @@ -2,14 +2,12 @@ # -*- coding: utf-8 -*- import copy -import operator -import os - import matplotlib.pyplot as plt import numpy as np -from obspy import read_events +import operator +import os from obspy.core import AttribDict -from pylot.core.io.phases import picksdict_from_picks + from pylot.core.util.pdf import ProbabilityDensityFunction from pylot.core.util.utils import find_in_list from pylot.core.util.version import get_git_version as _getVersionString diff --git a/pylot/core/pick/picker.py b/pylot/core/pick/picker.py index f13e0d65..e83438fb 100644 --- a/pylot/core/pick/picker.py +++ b/pylot/core/pick/picker.py @@ -19,11 +19,11 @@ calculated after Diehl & Kissling (2009). :author: MAGS2 EP3 working group / Ludger Kueperkoch """ -import warnings - import matplotlib.pyplot as plt import numpy as np +import warnings from scipy.signal import argrelmax, argrelmin + from pylot.core.pick.charfuns import CharacteristicFunction from pylot.core.pick.utils import getnoisewin, getsignalwin @@ -265,7 +265,7 @@ class AICPicker(AutoPicker): else: islope = np.where((self.Tcf <= min([self.Pick + tslope, self.Tcf[-1]])) \ & ( - self.Tcf >= self.Pick + tsafety)) # TODO: put this in a seperate function like getsignalwin + self.Tcf >= self.Pick + tsafety)) # TODO: put this in a seperate function like getsignalwin # find maximum within slope determination window # 'cause slope should be calculated up to first local minimum only! try: diff --git a/pylot/core/pick/utils.py b/pylot/core/pick/utils.py index 20385535..91421475 100644 --- a/pylot/core/pick/utils.py +++ b/pylot/core/pick/utils.py @@ -8,11 +8,11 @@ :author: Ludger Kueperkoch, BESTEC GmbH """ -import warnings - import matplotlib.pyplot as plt import numpy as np +import warnings from obspy.core import Stream, UTCDateTime + from pylot.core.util.utils import real_Bool, real_None, SetChannelComponents diff --git a/pylot/core/util/array_map.py b/pylot/core/util/array_map.py index ef5efff7..ab4923c6 100644 --- a/pylot/core/util/array_map.py +++ b/pylot/core/util/array_map.py @@ -1,17 +1,18 @@ #!/usr/bin/env python # -*- coding: utf-8 -*- -import traceback import matplotlib.pyplot as plt import numpy as np import obspy +import traceback from PySide import QtGui -from mpl_toolkits.basemap import Basemap from matplotlib.figure import Figure from mpl_toolkits.axes_grid1.inset_locator import inset_axes -from pylot.core.util.widgets import PickDlg, PylotCanvas +from mpl_toolkits.basemap import Basemap from scipy.interpolate import griddata +from pylot.core.util.widgets import PickDlg, PylotCanvas + plt.interactive(False) @@ -47,7 +48,6 @@ class Array_map(QtGui.QWidget): hybrids_dict[station] = pick return hybrids_dict - def init_map(self): self.init_lat_lon_dimensions() self.init_lat_lon_grid() @@ -81,9 +81,9 @@ class Array_map(QtGui.QWidget): message = message.format(picker, phase, network, station, pick['mpp']) if picker == 'auto': - del(self.autopicks_dict[station]) + del (self.autopicks_dict[station]) elif picker == 'manual': - del(self.picks_dict[station]) + del (self.picks_dict[station]) else: raise TypeError('Unknown "picker" {}'.format(picker)) print(message) @@ -347,7 +347,7 @@ class Array_map(QtGui.QWidget): return picks, latitudes, longitudes def draw_contour_filled(self, nlevel='50'): - #self.test_gradient() + # self.test_gradient() levels = np.linspace(self.get_min_from_picks(), self.get_max_from_picks(), nlevel) self.contourf = self.basemap.contourf(self.longrid, self.latgrid, self.picksgrid_active, @@ -363,7 +363,7 @@ class Array_map(QtGui.QWidget): pick_item = self.picks_rel.pop(st_id) self.init_picksgrid() x, y = np.gradient(self.picksgrid_active) - gradient_modulus = np.sqrt(x**2 + y**2) + gradient_modulus = np.sqrt(x ** 2 + y ** 2) mean_gradient = np.nanmean(gradient_modulus) dgradient = global_mean_gradient - mean_gradient # print('station: {}, mean gradient: {}'.format(st_id, dgradient)) @@ -391,7 +391,6 @@ class Array_map(QtGui.QWidget): # plt.xticks(x, st_ids) # plt.show() - def scatter_all_stations(self): stations, lats, lons = self.get_st_lat_lon_for_plot() self.sc = self.basemap.scatter(lons, lats, s=50, facecolor='none', latlon=True, diff --git a/pylot/core/util/dataprocessing.py b/pylot/core/util/dataprocessing.py index 18a99a57..55a229c9 100644 --- a/pylot/core/util/dataprocessing.py +++ b/pylot/core/util/dataprocessing.py @@ -2,14 +2,14 @@ # -*- coding: utf-8 -*- import glob +import numpy as np import os import sys - -import numpy as np from obspy import UTCDateTime, read_inventory, read from obspy.io.xseed import Parser + from pylot.core.util.utils import key_for_set_value, find_in_list, \ - remove_underscores, gen_Pool + gen_Pool class Metadata(object): @@ -616,7 +616,7 @@ def restitute_data(data, metadata, unit='VEL', force=False, ncores=0): restflag = list() - #data = remove_underscores(data) + # data = remove_underscores(data) # loop over traces input_tuples = [] diff --git a/pylot/core/util/defaults.py b/pylot/core/util/defaults.py index 04ae60a4..bdfb292d 100644 --- a/pylot/core/util/defaults.py +++ b/pylot/core/util/defaults.py @@ -9,12 +9,12 @@ Created on Wed Feb 26 12:31:25 2014 import os import platform -from pylot.core.util.utils import readDefaultFilterInformation from pylot.core.loc import hypo71 from pylot.core.loc import hypodd from pylot.core.loc import hyposat from pylot.core.loc import nll from pylot.core.loc import velest +from pylot.core.util.utils import readDefaultFilterInformation # determine system dependent path separator system_name = platform.system() @@ -39,5 +39,3 @@ OUTPUTFORMATS = {'.xml': 'QUAKEML', '.obs': 'NLLOC_OBS'} LOCTOOLS = dict(nll=nll, hyposat=hyposat, velest=velest, hypo71=hypo71, hypodd=hypodd) - - diff --git a/pylot/core/util/event.py b/pylot/core/util/event.py index d721a7fe..de407c87 100644 --- a/pylot/core/util/event.py +++ b/pylot/core/util/event.py @@ -2,10 +2,10 @@ # -*- coding: utf-8 -*- import os - from obspy import UTCDateTime from obspy.core.event import Event as ObsPyEvent from obspy.core.event import Origin, ResourceIdentifier + from pylot.core.io.phases import picks_from_picksdict from pylot.core.util.obspyDMT_interface import qml_from_obspyDMT diff --git a/pylot/core/util/pdf.py b/pylot/core/util/pdf.py index de05727d..44b44bb4 100644 --- a/pylot/core/util/pdf.py +++ b/pylot/core/util/pdf.py @@ -1,10 +1,10 @@ #!/usr/bin/env python # -*- coding: utf-8 -*- -import warnings - import numpy as np +import warnings from obspy import UTCDateTime + from pylot.core.util.utils import fit_curve, clims from pylot.core.util.version import get_git_version as _getVersionString diff --git a/pylot/core/util/thread.py b/pylot/core/util/thread.py index 17f54c12..d5ca3ef4 100644 --- a/pylot/core/util/thread.py +++ b/pylot/core/util/thread.py @@ -1,8 +1,11 @@ # -*- coding: utf-8 -*- -import sys, os, traceback import multiprocessing +import os +import sys +import traceback + from PySide.QtCore import QThread, Signal, Qt, Slot, QRunnable, QObject -from PySide.QtGui import QDialog, QProgressBar, QLabel, QHBoxLayout, QPushButton +from PySide.QtGui import QDialog, QProgressBar, QLabel, QHBoxLayout class Thread(QThread): @@ -40,7 +43,6 @@ class Thread(QThread): def showProgressbar(self): if self.progressText: - # # generate widget if not given in init # if not self.pb_widget: # self.pb_widget = ProgressBarWidget(self.parent()) diff --git a/pylot/core/util/utils.py b/pylot/core/util/utils.py index d8daf39c..5f4313f9 100644 --- a/pylot/core/util/utils.py +++ b/pylot/core/util/utils.py @@ -2,27 +2,23 @@ # -*- coding: utf-8 -*- import hashlib +import numpy as np import os import platform +import pyqtgraph as pg import re import subprocess import warnings - -import numpy as np +from PySide import QtCore from obspy import UTCDateTime, read from obspy.core import AttribDict from obspy.signal.rotate import rotate2zne -from obspy.io.xseed.utils import SEEDParserException - -from pylot.core.util.obspyDMT_interface import check_obspydmt_eventfolder +from scipy.interpolate import splrep, splev from pylot.core.io.inputs import PylotParameter, FilterOptions +from pylot.core.util.obspyDMT_interface import check_obspydmt_eventfolder from pylot.styles import style_settings -from scipy.interpolate import splrep, splev -from PySide import QtCore, QtGui - -import pyqtgraph as pg def _pickle_method(m): if m.im_self is None: @@ -835,7 +831,7 @@ def remove_underscores(data): :return: data stream :rtype: `~obspy.core.stream.Stream` """ - #for tr in data: + # for tr in data: # # remove underscores # tr.stats.station = tr.stats.station.strip('_') return data @@ -1279,4 +1275,4 @@ class SetChannelComponents(object): return self.compPosition_Map[self.compName_Map[component]] else: errMsg = 'getCompPosition: Unrecognized component {}. Expecting one of {} or {}.' - raise ValueError(errMsg.format(component, self.compPosition_Map.keys(), self.compName_Map.keys())) \ No newline at end of file + raise ValueError(errMsg.format(component, self.compPosition_Map.keys(), self.compName_Map.keys())) diff --git a/pylot/core/util/widgets.py b/pylot/core/util/widgets.py index 296fe6c0..ecb7f889 100644 --- a/pylot/core/util/widgets.py +++ b/pylot/core/util/widgets.py @@ -8,16 +8,14 @@ Created on Wed Mar 19 11:27:35 2014 import copy import datetime import getpass +import matplotlib import multiprocessing +import numpy as np import os import subprocess import sys import time -import numpy as np - -import matplotlib - matplotlib.use('QT4Agg') from matplotlib.figure import Figure @@ -28,8 +26,6 @@ except ImportError: from matplotlib.backends.backend_qt4agg import FigureCanvasQTAgg as FigureCanvas from matplotlib.backends.backend_qt4agg import NavigationToolbar2QT from matplotlib.widgets import MultiCursor -from matplotlib.tight_layout import get_renderer, get_subplotspec_list, get_tight_layout_figure -from scipy.signal import argrelmin, argrelmax from obspy import read from PySide import QtCore, QtGui @@ -38,7 +34,7 @@ from PySide.QtGui import QAction, QApplication, QCheckBox, QComboBox, \ QGridLayout, QIcon, QLabel, QLineEdit, QMessageBox, \ QPixmap, QSpinBox, QTabWidget, QToolBar, QVBoxLayout, QHBoxLayout, QWidget, \ QPushButton, QFileDialog, QInputDialog, QKeySequence -from PySide.QtCore import QSettings, Qt, QUrl, Signal, Slot +from PySide.QtCore import QSettings, Qt, QUrl, Signal from PySide.QtWebKit import QWebView from obspy import Stream, Trace, UTCDateTime from obspy.core.util import AttribDict @@ -50,9 +46,9 @@ from pylot.core.pick.utils import getSNR, earllatepicker, getnoisewin, \ getResolutionWindow, getQualityFromUncertainty from pylot.core.pick.compare import Comparison from pylot.core.util.defaults import OUTPUTFORMATS, FILTERDEFAULTS -from pylot.core.util.utils import prepTimeAxis, full_range, scaleWFData, \ - demeanTrace, isSorted, findComboBoxIndex, clims, pick_linestyle_plt, pick_color_plt, \ - check4rotated, check4doubled, check4gaps, merge_stream, remove_underscores, find_horizontals, identifyPhase, \ +from pylot.core.util.utils import prepTimeAxis, full_range, demeanTrace, isSorted, findComboBoxIndex, clims, \ + pick_linestyle_plt, pick_color_plt, \ + check4rotated, check4doubled, merge_stream, identifyPhase, \ loopIdentifyPhase, trim_station_components, transformFilteroptions2String, \ identifyPhaseID, real_Bool, pick_color, getAutoFilteroptions, SetChannelComponents from autoPyLoT import autoPyLoT @@ -66,6 +62,9 @@ elif sys.version_info.major == 2: else: raise ImportError('Could not determine python version.') +# workaround to prevent PyCharm from deleting icons_rc import when optimizing imports +icons_rc = icons_rc + def getDataType(parent): type = QInputDialog().getItem(parent, "Select phases type", "Type:", @@ -148,7 +147,7 @@ class AddMetadataWidget(QWidget): self.center() self.show() - #self.__test__() + # self.__test__() def __test__(self): self.add_item(r'/rscratch/minos14/marcel/git/pylot/tests') @@ -739,7 +738,8 @@ class WaveformWidgetPG(QtGui.QWidget): # list containing tuples of network, station, channel (for sorting) nslc = [] for trace in st_select: - nslc.append(trace.get_id())#(trace.stats.network, trace.stats.station, trace.stats.location trace.stats.channel)) + nslc.append( + trace.get_id()) # (trace.stats.network, trace.stats.station, trace.stats.location trace.stats.channel)) nslc.sort() nslc.reverse() plots = [] @@ -2390,7 +2390,6 @@ class PickDlg(QDialog): additional_channel=additional_channel, snr=mean_snr) - def setPick(self, gui_event): parameter = self.parameter @@ -2539,25 +2538,25 @@ class PickDlg(QDialog): linestyle_mpp, width_mpp = pick_linestyle_plt(picktype, 'mpp') vl = ax.axvline(mpp, ylims[0], ylims[1], color=color, linestyle=linestyle_mpp, linewidth=width_mpp, label='{}-{}-Pick (quality: {})'.format(phase, picktype, quality), picker=5, - zorder=baseorder+9) + zorder=baseorder + 9) phaseLineKey = '{}-{}'.format(phase, picktype) self.phaseLines[phaseLineKey] = vl if spe: ax.fill_between([mpp - spe, mpp + spe], ylims[0], ylims[1], - alpha=.25, color=color, label='{}-{}-SPE'.format(phase, picktype), zorder=baseorder+1) + alpha=.25, color=color, label='{}-{}-SPE'.format(phase, picktype), zorder=baseorder + 1) if picks['epp']: linestyle_epp, width_epp = pick_linestyle_plt(picktype, 'epp') ax.axvline(epp, ylims[0], ylims[1], color=color, linestyle=linestyle_epp, - linewidth=width_epp, label='{}-{}-EPP'.format(phase, picktype), zorder=baseorder+2) + linewidth=width_epp, label='{}-{}-EPP'.format(phase, picktype), zorder=baseorder + 2) if picks['lpp']: linestyle_lpp, width_lpp = pick_linestyle_plt(picktype, 'lpp') ax.axvline(lpp, ylims[0], ylims[1], color=color, linestyle=linestyle_lpp, - linewidth=width_lpp, label='{}-{}-LPP'.format(phase, picktype), zorder=baseorder+2) + linewidth=width_lpp, label='{}-{}-LPP'.format(phase, picktype), zorder=baseorder + 2) if picktype == 'auto': - ax.plot(mpp, ylims[1], color=color, marker='v', zorder=baseorder+3) - ax.plot(mpp, ylims[0], color=color, marker='^', zorder=baseorder+3) + ax.plot(mpp, ylims[1], color=color, marker='v', zorder=baseorder + 3) + ax.plot(mpp, ylims[0], color=color, marker='^', zorder=baseorder + 3) # append phase text (if textOnly: draw with current ylims) - self.phaseText.append(ax.text(mpp, ylims[1], phase, color=color, zorder=baseorder+10)) + self.phaseText.append(ax.text(mpp, ylims[1], phase, color=color, zorder=baseorder + 10)) ax.legend(loc=1) def connect_mouse_motion(self): @@ -3345,11 +3344,11 @@ class TuneAutopicker(QWidget): self.data.setWFData(fnames) wfdat = self.data.getWFData() # all available streams # remove possible underscores in station names - #wfdat = remove_underscores(wfdat) + # wfdat = remove_underscores(wfdat) # rotate misaligned stations to ZNE # check for gaps and doubled channels wfdat, gaps = merge_stream(wfdat) - #check4gaps(wfdat) + # check4gaps(wfdat) check4doubled(wfdat) wfdat = check4rotated(wfdat, self.parent().metadata, verbosity=0) # trim station components to same start value @@ -4606,7 +4605,7 @@ class GraphicsTab(PropTab): super(GraphicsTab, self).__init__(parent) self.pylot_mainwindow = parent._pylot_mainwindow self.init_layout() - #self.add_pg_cb() + # self.add_pg_cb() self.add_nth_sample() self.add_style_settings() self.setLayout(self.main_layout) diff --git a/tests/test_Metadata/test_Metadata.py b/tests/test_Metadata/test_Metadata.py index 28e73e1d..72927d2f 100644 --- a/tests/test_Metadata/test_Metadata.py +++ b/tests/test_Metadata/test_Metadata.py @@ -1,9 +1,9 @@ -import unittest import os - +import unittest from obspy import UTCDateTime -from obspy.io.xseed.utils import SEEDParserException from obspy.io.xseed import Parser +from obspy.io.xseed.utils import SEEDParserException + from pylot.core.util.dataprocessing import Metadata from tests.utils import HidePrints diff --git a/tests/utils.py b/tests/utils.py index 9c154e63..4c04b112 100644 --- a/tests/utils.py +++ b/tests/utils.py @@ -3,8 +3,8 @@ """Utilities/helpers for testing""" -import sys import os +import sys class HidePrints: From cf7fafbe62989e284a5a426aaac1a9f2234130fd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ludger=20K=C3=BCperkoch?= Date: Wed, 10 Oct 2018 11:17:58 +0200 Subject: [PATCH 10/15] Additional possible suffix for metadata file. --- pylot/core/util/dataprocessing.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/pylot/core/util/dataprocessing.py b/pylot/core/util/dataprocessing.py index 55a229c9..7aebca25 100644 --- a/pylot/core/util/dataprocessing.py +++ b/pylot/core/util/dataprocessing.py @@ -274,6 +274,7 @@ class Metadata(object): """ # functions used to read metadata for different file endings (or file types) read_functions = {'dless': self._read_dless, + 'dataless': self._read_dless, 'dseed': self._read_dless, 'xml': self._read_inventory_file, 'resp': self._read_inventory_file} @@ -281,6 +282,7 @@ class Metadata(object): if file_ending in read_functions.keys(): robj, exc = read_functions[file_ending](path_to_inventory_filename) if exc is not None: + print("Nicht None") raise exc return file_ending, robj # in case file endings did not match the above keys, try and error From dfe3f9b32af7cc4b8ad8baae53e5b61f98367bbb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ludger=20K=C3=BCperkoch?= Date: Wed, 10 Oct 2018 11:40:11 +0200 Subject: [PATCH 11/15] [Bugfix]: There might be no network nor location information available, strange! --- pylot/core/util/widgets.py | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/pylot/core/util/widgets.py b/pylot/core/util/widgets.py index ecb7f889..97a8a398 100644 --- a/pylot/core/util/widgets.py +++ b/pylot/core/util/widgets.py @@ -3416,6 +3416,7 @@ class TuneAutopicker(QWidget): return str(self.stationBox.currentText()).split('.')[1] def get_current_station_id(self): + print(self.stationBox, self.stationBox.currentText()) return str(self.stationBox.currentText()) @staticmethod @@ -3433,7 +3434,15 @@ class TuneAutopicker(QWidget): self.pdlg_widget = None return self.load_wf_data() - network, station, location, channel = self.get_current_station_id() + try: + network, station, location, channel = self.get_current_station_id() + except ValueError as e: + vmsg = '{0}'.format(e) + print(vmsg) + station = self.get_current_station() + location = None + network = None + wfdata = self.data.getWFData() metadata = self.parent().metadata event = self.get_current_event() From 5e6d2e7211135edd34f4d10de7530c5edb0296b3 Mon Sep 17 00:00:00 2001 From: Darius Arnold Date: Fri, 30 Nov 2018 09:42:22 +0100 Subject: [PATCH 12/15] [Bugfix] Merge traces treating overlaps as data instead of gaps Could not open the Pickwindow on some stations. Gaps were merged so that overlapping values were marked as gaps, which lead to an error when those traces were processed. Method 1 takes data from traces instead, see https://docs.obspy.org/packages/autogen/obspy.core.trace.Trace.__add__.html --- pylot/core/util/utils.py | 2 +- pylot/core/util/widgets.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/pylot/core/util/utils.py b/pylot/core/util/utils.py index 5f4313f9..463e76f4 100644 --- a/pylot/core/util/utils.py +++ b/pylot/core/util/utils.py @@ -870,7 +870,7 @@ def merge_stream(stream): if gaps: # list of merged stations (seed_ids) merged = ['{}.{}.{}.{}'.format(*gap[:4]) for gap in gaps] - stream.merge() + stream.merge(method=1) print('Merged the following stations because of gaps:') for merged_station in merged: print(merged_station) diff --git a/pylot/core/util/widgets.py b/pylot/core/util/widgets.py index 97a8a398..9cae2b04 100644 --- a/pylot/core/util/widgets.py +++ b/pylot/core/util/widgets.py @@ -1233,7 +1233,7 @@ class PylotCanvas(FigureCanvas): gaps = st_select.get_gaps() if gaps: merged = ['{}.{}.{}.{}'.format(*gap[:4]) for gap in gaps] - st_select.merge() + st_select.merge(method=1) print('Merged the following stations because of gaps:') for merged_station in merged: print(merged_station) From 718172dcd1367137a2a8e20e9ccb9723adf7f0e0 Mon Sep 17 00:00:00 2001 From: Darius Arnold Date: Sat, 26 Aug 2017 19:30:46 +0200 Subject: [PATCH 13/15] [minor] change axis label for comparison dialog --- pylot/core/util/widgets.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pylot/core/util/widgets.py b/pylot/core/util/widgets.py index 9cae2b04..b35de6ac 100644 --- a/pylot/core/util/widgets.py +++ b/pylot/core/util/widgets.py @@ -528,7 +528,7 @@ class ComparisonWidget(QWidget): legend.draggable() for ax in axes_dict['P'].values(): - ax.set_ylabel('Frequency [-]') + ax.set_ylabel('number of picks [-]') self.canvas.draw() else: From 815a18f2f38288a9ea17e63624d8437572a7908b Mon Sep 17 00:00:00 2001 From: Darius Arnold Date: Fri, 30 Nov 2018 10:21:54 +0100 Subject: [PATCH 14/15] [bugfix] error in check during loading of event info csv file Original condition didn't check for eventID in event.origins. --- PyLoT.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/PyLoT.py b/PyLoT.py index 18bc73d7..417cefc4 100755 --- a/PyLoT.py +++ b/PyLoT.py @@ -3494,7 +3494,7 @@ class Project(object): print(e, datetime, filename) continue for event in self.eventlist: - if eventID in str(event.resource_id) or event.origins: + if eventID in str(event.resource_id) or eventID in event.origins: if event.origins: origin = event.origins[0] # should have only one origin if origin.time == datetime: From 6afb61b666fb8b446963a9b59796d54453db4bf3 Mon Sep 17 00:00:00 2001 From: Darius Arnold Date: Fri, 30 Nov 2018 10:26:57 +0100 Subject: [PATCH 15/15] [change] order to Day/Month/Year when reading csv file for event info --- PyLoT.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/PyLoT.py b/PyLoT.py index 417cefc4..9fe47d00 100755 --- a/PyLoT.py +++ b/PyLoT.py @@ -3480,7 +3480,7 @@ class Project(object): eventID, date, time, mag, lat, lon, depth = line.split(separator)[:7] # skip first line try: - month, day, year = date.split('/') + day, month, year = date.split('/') except: continue year = int(year)