diff --git a/PyLoT.py b/PyLoT.py index de4700a9..71bbbe4a 100755 --- a/PyLoT.py +++ b/PyLoT.py @@ -76,7 +76,7 @@ from pylot.core.util.utils import fnConstructor, getLogin, \ full_range, readFilterInformation, pick_color_plt, \ pick_linestyle_plt, identifyPhaseID, excludeQualityClasses, \ transform_colors_mpl, transform_colors_mpl_str, getAutoFilteroptions, check_all_obspy, \ - check_all_pylot, get_bool, get_None + check_all_pylot, get_bool, get_None, get_pylot_eventfile_with_extension from pylot.core.util.gui import make_pen from pylot.core.util.event import Event from pylot.core.io.location import create_creation_info, create_event @@ -84,7 +84,7 @@ from pylot.core.util.widgets import FilterOptionsDialog, NewEventDlg, \ PylotCanvas, WaveformWidgetPG, PropertiesDlg, HelpForm, createAction, PickDlg, \ ComparisonWidget, TuneAutopicker, PylotParaBox, AutoPickDlg, CanvasWidget, AutoPickWidget, \ CompareEventsWidget, ProgressBarWidget, AddMetadataWidget, SingleTextLineDialog, LogWidget, PickQualitiesFromXml, \ - SourceSpecWindow, ChooseWaveFormWindow, SpectrogramTab + SourceSpecWindow, ChooseWaveFormWindow, SpectrogramTab, SearchFileByExtensionDialog from pylot.core.util.array_map import Array_map from pylot.core.util.structure import DATASTRUCTURE from pylot.core.util.thread import Thread, Worker @@ -1006,16 +1006,15 @@ class MainWindow(QMainWindow): return refresh = False events = self.project.eventlist - sld = SingleTextLineDialog(label='Specify file extension: ', default_text='.xml') + sld = SearchFileByExtensionDialog(label='Specify file extension: ', default_text='.xml', + events=events) if not sld.exec_(): return fext = sld.lineEdit.text() # fext = '.xml' for event in events: - path = event.path - eventname = path.split('/')[-1] # or event.pylot_id - filename = os.path.join(path, 'PyLoT_' + eventname + fext) - if os.path.isfile(filename): + filename = get_pylot_eventfile_with_extension(event, fext) + if filename: self.load_data(filename, draw=False, event=event, overwrite=True) refresh = True if not refresh: diff --git a/pylot/core/util/dataprocessing.py b/pylot/core/util/dataprocessing.py index 72ac922e..794a06b1 100644 --- a/pylot/core/util/dataprocessing.py +++ b/pylot/core/util/dataprocessing.py @@ -2,6 +2,7 @@ # -*- coding: utf-8 -*- import glob +import logging import os import sys @@ -189,7 +190,12 @@ class Metadata(object): metadata = self.get_metadata(seed_id, time) if not metadata: return - return metadata['data'].get_coordinates(seed_id, time) + try: + metadata['data'].get_coordinates(seed_id, time) + # no specific exception defined in obspy inventory + except Exception as e: + logging.warning(f'Could not get metadata for {seed_id}') + return def get_all_coordinates(self): def stat_info_from_parser(parser): diff --git a/pylot/core/util/utils.py b/pylot/core/util/utils.py index fb76f30d..42e500b2 100644 --- a/pylot/core/util/utils.py +++ b/pylot/core/util/utils.py @@ -2,6 +2,7 @@ # -*- coding: utf-8 -*- import hashlib +import logging import os import platform import re @@ -899,6 +900,18 @@ def check_for_nan(data, nan_value=0.): np.nan_to_num(trace.data, copy=False, nan=nan_value) +def get_pylot_eventfile_with_extension(event, fext): + if hasattr(event, 'path'): + eventpath = event.path + else: + logging.warning('No attribute path found for event.') + return + eventname = eventpath.split('/')[-1] # or event.pylot_id + filename = os.path.join(eventpath, 'PyLoT_' + eventname + fext) + if os.path.isfile(filename): + return filename + + def get_stations(data): """ Get list of all station names in data stream diff --git a/pylot/core/util/widgets.py b/pylot/core/util/widgets.py index 0c403f67..3858dce0 100644 --- a/pylot/core/util/widgets.py +++ b/pylot/core/util/widgets.py @@ -54,7 +54,7 @@ from pylot.core.util.utils import prepTimeAxis, full_range, demeanTrace, isSorte check4rotated, check4doubled, check_for_gaps_and_merge, check_for_nan, identifyPhase, \ loopIdentifyPhase, trim_station_components, transformFilteroptions2String, \ identifyPhaseID, get_bool, get_None, pick_color, getAutoFilteroptions, SetChannelComponents, \ - station_id_remove_channel + station_id_remove_channel, get_pylot_eventfile_with_extension from autoPyLoT import autoPyLoT from pylot.core.util.thread import Thread from pylot.core.util.dataprocessing import Metadata @@ -1568,6 +1568,78 @@ class PylotCanvas(FigureCanvas): self.draw() +class SearchFileByExtensionDialog(QtWidgets.QDialog): + def __init__(self, parent=None, label='Text: ', default_text='.xml', events=None): + super(SearchFileByExtensionDialog, self).__init__(parent) + self.events = events + self.filepaths = [] + self.default_text = default_text + self.label = label + self.setButtons() + self.setupUi() + self.connectSignals() + self.showPaths() + + self.resize(800, 450) + + + def setupUi(self): + self.main_layout = QtWidgets.QVBoxLayout() + self.header_layout = QtWidgets.QHBoxLayout() + # + self.setLayout(self.main_layout) + + # widgets inside the dialog + self.textLabel = QtWidgets.QLabel(self.label) + self.lineEdit = QtWidgets.QLineEdit(self.default_text) + + # optional search button, currently disabled. List refreshed when text changes + self.searchButton = QtWidgets.QPushButton('Search') + self.searchButton.setVisible(False) + + self.textWidget = QtWidgets.QTextEdit() + self.textWidget.setMaximumWidth(1e5) + self.textWidget.setReadOnly(True) + + self.statusText = QtWidgets.QLabel() + + self.header_layout.addWidget(self.textLabel) + self.header_layout.addWidget(self.lineEdit) + self.header_layout.addWidget(self.searchButton) + + self.main_layout.addLayout(self.header_layout) + self.main_layout.addWidget(self.textWidget) + self.main_layout.addWidget(self.statusText) + self.main_layout.addWidget(self._buttonbox) + + def showPaths(self): + self.filepaths = [] + fext = self.lineEdit.text() + for event in self.events: + filename = get_pylot_eventfile_with_extension(event, fext) + if filename: + self.filepaths.append(filename) + self.textWidget.append(f'{filename}') + if len(self.filepaths) > 0: + status_text = f'Found {len(self.filepaths)} eventfiles. Do you want to load them?' + else: + status_text = 'Did not find any files for specified file mask.' + self.textWidget.setText('') + self.statusText.setText(status_text) + + + def setButtons(self): + self._buttonbox = QDialogButtonBox(QDialogButtonBox.Ok | + QDialogButtonBox.Cancel) + + def connectSignals(self): + self._buttonbox.accepted.connect(self.accept) + self._buttonbox.rejected.connect(self.reject) + self.lineEdit.textChanged.connect(self.showPaths) + self.searchButton.clicked.connect(self.showPaths) + + + class SingleTextLineDialog(QtWidgets.QDialog): def __init__(self, parent=None, label='Text: ', default_text='.xml'): super(SingleTextLineDialog, self).__init__(parent)