2014-03-13 13:27:34 +01:00
|
|
|
#!/usr/bin/env python
|
2014-03-31 12:57:08 +02:00
|
|
|
# -*- coding: utf-8 -*-
|
|
|
|
"""
|
|
|
|
PyLoT: Main program
|
|
|
|
===================
|
|
|
|
PyLoT is a seismic data processing software capable of picking seismic
|
|
|
|
phases (symmetric and asymmetric error assignment), exporting these to
|
|
|
|
several common phase data formats and post process the data, e.g. locating
|
|
|
|
events, via external localization software.
|
|
|
|
Additionally PyLoT is meant as an interface to autoPyLoT which can
|
|
|
|
automatically pick seismic phases, if the parameters have properly been
|
|
|
|
chosen for the particular data set.
|
|
|
|
|
2014-11-28 09:19:16 +01:00
|
|
|
Some icons are out of a free of charge icon set, which can be found here:
|
|
|
|
https://www.iconfinder.com/iconsets/flavour
|
|
|
|
|
2017-04-10 09:50:53 +02:00
|
|
|
:authors:
|
2017-04-27 10:42:31 +02:00
|
|
|
Sebastian Wehling-Benatelli / Ludger Küperkoch / Marcel Paffrath
|
2014-03-31 12:57:08 +02:00
|
|
|
:copyright:
|
|
|
|
The PyLoT Development Team (https://ariadne.geophysik.rub.de/trac/PyLoT)
|
|
|
|
:license:
|
|
|
|
GNU Lesser General Public License, Version 3
|
|
|
|
(http://www.gnu.org/copyleft/lesser.html)
|
|
|
|
"""
|
2014-01-09 10:43:40 +01:00
|
|
|
|
2016-01-29 07:21:17 +01:00
|
|
|
import os
|
|
|
|
import sys
|
2016-09-23 15:12:04 +02:00
|
|
|
import matplotlib
|
|
|
|
|
2015-07-06 09:51:59 +02:00
|
|
|
matplotlib.use('Qt4Agg')
|
|
|
|
matplotlib.rcParams['backend.qt4'] = 'PySide'
|
2014-12-04 05:13:32 +01:00
|
|
|
|
2017-04-19 15:31:08 +02:00
|
|
|
from PySide import QtGui, QtCore
|
2015-03-11 12:05:52 +01:00
|
|
|
from PySide.QtCore import QCoreApplication, QSettings, Signal, QFile, \
|
2017-04-06 13:16:28 +02:00
|
|
|
QFileInfo, Qt, QSize
|
2015-02-16 10:24:17 +01:00
|
|
|
from PySide.QtGui import QMainWindow, QInputDialog, QIcon, QFileDialog, \
|
2017-04-18 16:24:26 +02:00
|
|
|
QWidget, QHBoxLayout, QVBoxLayout, QStyle, QKeySequence, QLabel, QFrame, QAction, \
|
2015-07-07 14:21:11 +02:00
|
|
|
QDialog, QErrorMessage, QApplication, QPixmap, QMessageBox, QSplashScreen, \
|
2017-04-18 16:24:26 +02:00
|
|
|
QActionGroup, QListWidget, QDockWidget, QLineEdit, QListView, QAbstractItemView, \
|
2017-04-19 15:31:08 +02:00
|
|
|
QTreeView, QComboBox, QTabWidget, QPushButton, QGridLayout
|
2015-07-07 10:39:51 +02:00
|
|
|
import numpy as np
|
2015-11-18 09:30:32 +01:00
|
|
|
from obspy import UTCDateTime
|
2015-02-16 10:24:17 +01:00
|
|
|
|
2016-09-27 15:15:53 +02:00
|
|
|
from pylot.core.analysis.magnitude import RichterMagnitude, MomentMagnitude
|
2016-05-01 21:10:30 +02:00
|
|
|
from pylot.core.io.data import Data
|
|
|
|
from pylot.core.io.inputs import FilterOptions, AutoPickParameter
|
2017-04-06 13:16:28 +02:00
|
|
|
from autoPyLoT import autoPyLoT
|
2016-06-07 13:51:03 +02:00
|
|
|
from pylot.core.pick.compare import Comparison
|
2016-09-23 15:12:04 +02:00
|
|
|
from pylot.core.pick.utils import symmetrize_error
|
2016-05-03 13:54:59 +02:00
|
|
|
from pylot.core.io.phases import picksdict_from_picks
|
2016-08-25 13:31:51 +02:00
|
|
|
import pylot.core.loc.nll as nll
|
2017-04-06 13:16:28 +02:00
|
|
|
from pylot.core.util.defaults import FILTERDEFAULTS, COMPNAME_MAP
|
2016-01-29 07:21:17 +01:00
|
|
|
from pylot.core.util.errors import FormatError, DatastructureError, \
|
2016-09-27 15:15:53 +02:00
|
|
|
OverwriteError, ProcessingError
|
2015-07-10 09:22:58 +02:00
|
|
|
from pylot.core.util.connection import checkurl
|
2016-09-27 15:15:53 +02:00
|
|
|
from pylot.core.util.dataprocessing import read_metadata, restitute_data
|
2016-05-27 11:25:47 +02:00
|
|
|
from pylot.core.util.utils import fnConstructor, getLogin, \
|
2016-09-19 11:42:52 +02:00
|
|
|
full_range
|
2016-05-20 14:46:10 +02:00
|
|
|
from pylot.core.io.location import create_creation_info, create_event
|
2016-01-29 07:21:17 +01:00
|
|
|
from pylot.core.util.widgets import FilterOptionsDialog, NewEventDlg, \
|
2016-06-07 13:51:03 +02:00
|
|
|
WaveformWidget, PropertiesDlg, HelpForm, createAction, PickDlg, \
|
|
|
|
getDataType, ComparisonDialog
|
2017-04-12 16:43:29 +02:00
|
|
|
from pylot.core.util.map_projection import map_projection
|
2015-02-13 11:12:47 +01:00
|
|
|
from pylot.core.util.structure import DATASTRUCTURE
|
2017-04-18 16:24:26 +02:00
|
|
|
from pylot.core.util.thread import AutoPickThread, Thread
|
2015-07-10 09:22:58 +02:00
|
|
|
from pylot.core.util.version import get_git_version as _getVersionString
|
2015-04-02 18:36:21 +02:00
|
|
|
import icons_rc
|
2015-02-16 10:24:17 +01:00
|
|
|
|
2016-08-25 13:31:51 +02:00
|
|
|
locateTool = dict(nll=nll)
|
2015-06-11 10:07:21 +02:00
|
|
|
|
2016-01-29 07:21:17 +01:00
|
|
|
|
2014-01-10 05:45:03 +01:00
|
|
|
class MainWindow(QMainWindow):
|
2015-09-18 09:54:29 +02:00
|
|
|
__version__ = _getVersionString()
|
2014-12-08 10:26:14 +01:00
|
|
|
closing = Signal()
|
|
|
|
|
2014-01-10 05:45:03 +01:00
|
|
|
def __init__(self, parent=None):
|
|
|
|
super(MainWindow, self).__init__(parent)
|
2014-03-13 13:27:34 +01:00
|
|
|
|
2017-04-06 13:16:28 +02:00
|
|
|
# check for default pylot.in-file
|
2016-09-08 15:31:23 +02:00
|
|
|
infile = os.path.join(os.path.expanduser('~'), '.pylot', 'pylot.in')
|
2017-04-06 13:16:28 +02:00
|
|
|
if os.path.isfile(infile)== False:
|
2017-05-04 11:50:28 +02:00
|
|
|
infile = QFileDialog().getOpenFileName(caption='Choose PyLoT-input file')
|
2017-04-10 09:50:53 +02:00
|
|
|
if not os.path.exists(infile[0]):
|
|
|
|
QMessageBox.warning(self, "PyLoT Warning",
|
|
|
|
"No PyLoT-input file declared!")
|
|
|
|
sys.exit(0)
|
2017-04-06 13:16:28 +02:00
|
|
|
self.infile = infile[0]
|
|
|
|
else:
|
2017-04-10 14:54:47 +02:00
|
|
|
self.infile = infile
|
2017-05-04 11:50:28 +02:00
|
|
|
self._inputs = AutoPickParameter(infile)
|
2017-04-10 14:54:47 +02:00
|
|
|
|
2017-04-20 12:05:34 +02:00
|
|
|
self.project = Project()
|
2017-04-18 17:17:46 +02:00
|
|
|
self.array_map = None
|
|
|
|
self._metadata = None
|
2017-04-20 17:06:36 +02:00
|
|
|
self._eventChanged = [False, False]
|
2017-04-18 17:17:46 +02:00
|
|
|
|
2017-04-19 15:31:08 +02:00
|
|
|
self.poS_id = None
|
|
|
|
self.ae_id = None
|
|
|
|
|
2017-04-10 14:24:39 +02:00
|
|
|
# UI has to be set up before(!) children widgets are about to show up
|
2015-03-04 11:52:04 +01:00
|
|
|
self.createAction = createAction
|
2016-09-08 14:02:21 +02:00
|
|
|
# read settings
|
2014-11-28 11:15:49 +01:00
|
|
|
settings = QSettings()
|
2017-04-10 14:24:39 +02:00
|
|
|
self.recentfiles = settings.value("data/recentEvents", [])
|
|
|
|
self.dispComponent = str(settings.value("plotting/dispComponent", "Z"))
|
2017-04-19 15:31:08 +02:00
|
|
|
|
|
|
|
# initialize event data
|
|
|
|
if self.recentfiles:
|
|
|
|
lastEvent = self.getLastEvent()
|
|
|
|
self.data = Data(self, lastEvent)
|
|
|
|
else:
|
|
|
|
self.data = Data(self)
|
|
|
|
self.autodata = Data(self)
|
|
|
|
|
|
|
|
self.dirty = False
|
|
|
|
|
|
|
|
# setup UI
|
2017-04-10 14:24:39 +02:00
|
|
|
self.setupUi()
|
2017-04-06 13:16:28 +02:00
|
|
|
|
2014-12-08 10:26:14 +01:00
|
|
|
if settings.value("user/FullName", None) is None:
|
|
|
|
fulluser = QInputDialog.getText(self, "Enter Name:", "Full name")
|
|
|
|
settings.setValue("user/FullName", fulluser)
|
2015-03-04 11:52:04 +01:00
|
|
|
settings.setValue("user/Login", getLogin())
|
2015-03-06 09:03:04 +01:00
|
|
|
if settings.value("agency_id", None) is None:
|
2015-06-11 10:07:21 +02:00
|
|
|
agency = QInputDialog.getText(self,
|
2017-04-06 13:16:28 +02:00
|
|
|
"Enter authority/institution name:",
|
2015-06-11 10:07:21 +02:00
|
|
|
"Authority")
|
2015-03-11 12:05:52 +01:00
|
|
|
settings.setValue("agency_id", agency)
|
2016-05-27 11:25:47 +02:00
|
|
|
self.fname = dict(manual=None, auto=None, loc=None)
|
2015-02-13 11:17:18 +01:00
|
|
|
self.fnames = None
|
2016-05-31 17:27:59 +02:00
|
|
|
self._stime = None
|
2015-06-23 13:22:30 +02:00
|
|
|
structure_setting = settings.value("data/Structure", "PILOT")
|
|
|
|
self.dataStructure = DATASTRUCTURE[structure_setting]()
|
2014-11-28 11:15:49 +01:00
|
|
|
self.seismicPhase = str(settings.value("phase", "P"))
|
2014-12-08 10:26:14 +01:00
|
|
|
if settings.value("data/dataRoot", None) is None:
|
2015-01-29 08:53:01 +01:00
|
|
|
dirname = QFileDialog().getExistingDirectory(
|
2016-03-30 07:00:31 +02:00
|
|
|
caption='Choose data root ...')
|
2014-12-08 10:26:14 +01:00
|
|
|
settings.setValue("data/dataRoot", dirname)
|
2015-03-06 09:03:04 +01:00
|
|
|
settings.sync()
|
2014-11-28 11:15:49 +01:00
|
|
|
|
2015-03-01 10:31:49 +01:00
|
|
|
self.filteroptions = {}
|
2015-03-09 11:21:33 +01:00
|
|
|
self.pickDlgs = {}
|
2015-07-07 10:32:56 +02:00
|
|
|
self.picks = {}
|
2015-11-30 09:50:47 +01:00
|
|
|
self.autopicks = {}
|
2015-11-14 11:46:46 +01:00
|
|
|
self.loc = False
|
2014-03-13 13:27:34 +01:00
|
|
|
|
2015-02-17 13:17:01 +01:00
|
|
|
def setupUi(self):
|
2014-11-26 08:46:16 +01:00
|
|
|
try:
|
2015-01-29 08:53:01 +01:00
|
|
|
self.startTime = min(
|
2016-03-30 07:00:31 +02:00
|
|
|
[tr.stats.starttime for tr in self.data.wfdata])
|
2014-11-26 08:46:16 +01:00
|
|
|
except:
|
|
|
|
self.startTime = UTCDateTime()
|
2014-03-28 05:25:46 +01:00
|
|
|
|
2015-04-02 18:36:21 +02:00
|
|
|
pylot_icon = QIcon()
|
2015-07-07 11:21:06 +02:00
|
|
|
pylot_icon.addPixmap(QPixmap(':/icons/pylot.png'))
|
2015-04-02 18:36:21 +02:00
|
|
|
|
2015-03-01 10:31:49 +01:00
|
|
|
self.setWindowTitle("PyLoT - do seismic processing the python way")
|
2015-04-02 18:36:21 +02:00
|
|
|
self.setWindowIcon(pylot_icon)
|
2015-01-29 08:41:38 +01:00
|
|
|
|
2015-03-29 08:07:46 +02:00
|
|
|
xlab = self.startTime.strftime('seconds since %Y/%m/%d %H:%M:%S (%Z)')
|
2015-01-29 08:41:38 +01:00
|
|
|
|
|
|
|
_widget = QWidget()
|
2017-04-18 17:17:46 +02:00
|
|
|
self._main_layout = QVBoxLayout()
|
|
|
|
|
2017-04-18 16:24:26 +02:00
|
|
|
# add event combo box
|
2017-04-20 14:03:26 +02:00
|
|
|
self.eventBox = self.createEventBox()
|
2017-04-18 16:24:26 +02:00
|
|
|
self.eventBox.setMaxVisibleItems(30)
|
|
|
|
self.eventBox.setEnabled(False)
|
2017-04-18 17:17:46 +02:00
|
|
|
self._event_layout = QHBoxLayout()
|
|
|
|
self._event_layout.addWidget(QLabel('Event: '))
|
|
|
|
self._event_layout.addWidget(self.eventBox)
|
|
|
|
self._event_layout.setStretch(1,1) #set stretch of item 1 to 1
|
|
|
|
self._main_layout.addLayout(self._event_layout)
|
2017-04-19 16:05:45 +02:00
|
|
|
self.eventBox.activated.connect(self.refreshEvents)
|
2017-04-18 16:24:26 +02:00
|
|
|
|
2017-04-18 17:17:46 +02:00
|
|
|
# add tabs
|
|
|
|
self.tabs = QTabWidget()
|
|
|
|
self._main_layout.addWidget(self.tabs)
|
2017-04-19 15:31:08 +02:00
|
|
|
self.tabs.currentChanged.connect(self.refreshTabs)
|
2015-02-07 09:03:03 +01:00
|
|
|
|
2015-02-16 10:31:25 +01:00
|
|
|
# create central matplotlib figure canvas widget
|
2017-04-18 17:17:46 +02:00
|
|
|
plottitle = "Overview: {0} components ".format(self.getComponent())
|
2017-04-19 15:31:08 +02:00
|
|
|
self.dataPlot = WaveformWidget(parent=self, xlabel=xlab, ylabel=None,
|
2016-06-06 14:10:46 +02:00
|
|
|
title=plottitle)
|
2017-04-19 15:31:08 +02:00
|
|
|
self.dataPlot.setCursor(Qt.CrossCursor)
|
2017-04-20 12:05:34 +02:00
|
|
|
wf_tab = QtGui.QWidget()
|
|
|
|
array_tab = QtGui.QWidget()
|
|
|
|
events_tab = QtGui.QWidget()
|
2017-05-03 15:16:48 +02:00
|
|
|
self.wf_scroll_area = QtGui.QScrollArea()
|
2017-04-20 12:05:34 +02:00
|
|
|
self.wf_layout = QtGui.QVBoxLayout()
|
|
|
|
self.array_layout = QtGui.QVBoxLayout()
|
|
|
|
self.events_layout = QtGui.QVBoxLayout()
|
|
|
|
wf_tab.setLayout(self.wf_layout)
|
|
|
|
array_tab.setLayout(self.array_layout)
|
|
|
|
events_tab.setLayout(self.events_layout)
|
|
|
|
self.tabs.addTab(wf_tab, 'Waveform Plot')
|
|
|
|
self.tabs.addTab(array_tab, 'Array Map')
|
|
|
|
self.tabs.addTab(events_tab, 'Eventlist')
|
|
|
|
|
2017-05-03 15:16:48 +02:00
|
|
|
self.wf_layout.addWidget(self.wf_scroll_area)
|
|
|
|
self.wf_scroll_area.setWidget(self.dataPlot)
|
|
|
|
self.wf_scroll_area.setWidgetResizable(True)
|
2017-04-19 15:31:08 +02:00
|
|
|
self.init_array_tab()
|
2017-04-20 12:05:34 +02:00
|
|
|
self.init_event_table()
|
|
|
|
self.tabs.setCurrentIndex(0)
|
2017-04-18 17:17:46 +02:00
|
|
|
|
2015-01-29 08:41:38 +01:00
|
|
|
quitIcon = self.style().standardIcon(QStyle.SP_MediaStop)
|
|
|
|
saveIcon = self.style().standardIcon(QStyle.SP_DriveHDIcon)
|
2017-04-18 16:24:26 +02:00
|
|
|
openIcon = self.style().standardIcon(QStyle.SP_DirOpenIcon)
|
2015-01-29 08:41:38 +01:00
|
|
|
helpIcon = self.style().standardIcon(QStyle.SP_DialogHelpButton)
|
|
|
|
newIcon = self.style().standardIcon(QStyle.SP_FileIcon)
|
2017-04-18 16:24:26 +02:00
|
|
|
newFolderIcon = self.style().standardIcon(QStyle.SP_FileDialogNewFolder)
|
|
|
|
|
2015-04-02 18:36:21 +02:00
|
|
|
# create resource icons
|
2017-04-06 13:16:28 +02:00
|
|
|
locactionicon = QIcon()
|
|
|
|
locactionicon.addPixmap(QPixmap(':/icons/locactionicon.png'))
|
|
|
|
manupicksicon = QIcon()
|
|
|
|
manupicksicon.addPixmap(QPixmap(':/icons/manupicsicon.png'))
|
|
|
|
autopicksicon = QIcon()
|
|
|
|
autopicksicon.addPixmap(QPixmap(':/icons/autopicsicon.png'))
|
2017-04-21 15:46:57 +02:00
|
|
|
self.autopicksicon_small = QIcon()
|
2017-04-27 10:42:31 +02:00
|
|
|
self.autopicksicon_small.addPixmap(QPixmap(':/icons/autopicksicon_small.png'))
|
2017-04-21 15:46:57 +02:00
|
|
|
self.manupicksicon_small = QIcon()
|
2017-04-27 10:42:31 +02:00
|
|
|
self.manupicksicon_small.addPixmap(QPixmap(':/icons/manupicksicon_small.png'))
|
2017-04-28 13:42:57 +02:00
|
|
|
saveProjectIcon = QIcon()
|
|
|
|
saveProjectIcon.addPixmap(QPixmap(':/icons/Library-icon.png'))
|
2017-04-06 13:16:28 +02:00
|
|
|
loadpiloticon = QIcon()
|
|
|
|
loadpiloticon.addPixmap(QPixmap(':/icons/Matlab_PILOT_icon.png'))
|
2015-04-02 18:36:21 +02:00
|
|
|
p_icon = QIcon()
|
2015-07-07 10:31:39 +02:00
|
|
|
p_icon.addPixmap(QPixmap(':/icons/key_P.png'))
|
2015-04-02 18:36:21 +02:00
|
|
|
s_icon = QIcon()
|
2015-07-07 10:31:39 +02:00
|
|
|
s_icon.addPixmap(QPixmap(':/icons/key_S.png'))
|
2015-04-02 18:36:21 +02:00
|
|
|
print_icon = QIcon()
|
|
|
|
print_icon.addPixmap(QPixmap(':/icons/printer.png'))
|
2015-07-07 10:31:39 +02:00
|
|
|
filter_icon = QIcon()
|
|
|
|
filter_icon.addPixmap(QPixmap(':/icons/filter.png'))
|
2015-07-07 14:21:11 +02:00
|
|
|
z_icon = QIcon()
|
2015-07-09 11:37:03 +02:00
|
|
|
z_icon.addPixmap(QPixmap(':/icons/key_Z.png'))
|
2015-07-07 14:21:11 +02:00
|
|
|
n_icon = QIcon()
|
2015-07-09 11:37:03 +02:00
|
|
|
n_icon.addPixmap(QPixmap(':/icons/key_N.png'))
|
2015-07-07 14:21:11 +02:00
|
|
|
e_icon = QIcon()
|
2015-07-09 11:37:03 +02:00
|
|
|
e_icon.addPixmap(QPixmap(':/icons/key_E.png'))
|
2017-04-10 14:24:39 +02:00
|
|
|
auto_icon = QIcon(':/icons/autopick_button.png')
|
2017-04-06 13:16:28 +02:00
|
|
|
auto_icon.addPixmap(QPixmap(':/icons/autopick_button.png'))
|
2015-11-09 08:53:26 +01:00
|
|
|
locate_icon = QIcon()
|
2017-04-06 13:16:28 +02:00
|
|
|
locate_icon.addPixmap(QPixmap(':/icons/locate_button.png'))
|
2016-06-06 14:10:46 +02:00
|
|
|
compare_icon = QIcon()
|
2017-04-06 13:16:28 +02:00
|
|
|
compare_icon.addPixmap(QPixmap(':/icons/compare_button.png'))
|
2017-04-18 16:24:26 +02:00
|
|
|
self.newProjectAction = self.createAction(self, "&New project ...",
|
|
|
|
self.createNewProject,
|
2015-01-29 08:41:38 +01:00
|
|
|
QKeySequence.New, newIcon,
|
2017-04-18 16:24:26 +02:00
|
|
|
"Create a new Project.")
|
|
|
|
self.openProjectAction = self.createAction(self, "Load project ...",
|
|
|
|
self.loadProject,
|
|
|
|
QKeySequence.Open,
|
|
|
|
openIcon,
|
|
|
|
"Load project file")
|
|
|
|
self.saveProjectAction = self.createAction(self, "Save project ...",
|
|
|
|
self.saveProject,
|
|
|
|
QKeySequence.Save,
|
2017-04-28 13:42:57 +02:00
|
|
|
saveProjectIcon,
|
2017-04-18 16:24:26 +02:00
|
|
|
"Save project file")
|
2017-04-28 13:47:24 +02:00
|
|
|
self.saveProjectAction.setEnabled(False)
|
2017-04-18 16:24:26 +02:00
|
|
|
# newEventAction = self.createAction(self, "&New event ...",
|
|
|
|
# self.createNewEvent,
|
|
|
|
# QKeySequence.New, newIcon,
|
|
|
|
# "Create a new event.")
|
2017-04-10 14:24:39 +02:00
|
|
|
self.openmanualpicksaction = self.createAction(self, "Load &picks ...",
|
2016-05-27 11:25:47 +02:00
|
|
|
self.load_data,
|
|
|
|
QKeySequence.Open,
|
|
|
|
manupicksicon,
|
2017-04-06 13:16:28 +02:00
|
|
|
"Load manual picks for "
|
|
|
|
"the displayed event.")
|
2017-04-10 14:24:39 +02:00
|
|
|
self.openmanualpicksaction.setEnabled(False)
|
|
|
|
self.openmanualpicksaction.setData(None)
|
|
|
|
|
|
|
|
self.openautopicksaction = self.createAction(self, "Load &automatic picks "
|
2016-05-27 11:25:47 +02:00
|
|
|
"...",
|
|
|
|
self.load_autopicks,
|
|
|
|
"Ctrl+A",
|
|
|
|
autopicksicon,
|
2017-04-06 13:16:28 +02:00
|
|
|
"Load automatic picks "
|
|
|
|
"for the displayed event.")
|
2017-04-10 14:24:39 +02:00
|
|
|
self.openautopicksaction.setEnabled(False)
|
|
|
|
self.openautopicksaction.setData(None)
|
2016-05-27 11:25:47 +02:00
|
|
|
|
2017-04-28 13:56:28 +02:00
|
|
|
self.loadlocationaction = self.createAction(self, "Load &location ...",
|
2016-05-27 11:25:47 +02:00
|
|
|
self.load_loc, "Ctrl+L",
|
|
|
|
locactionicon,
|
|
|
|
"Load location information on "
|
2017-04-06 13:16:28 +02:00
|
|
|
"the displayed event.")
|
2017-04-28 13:56:28 +02:00
|
|
|
self.loadlocationaction.setEnabled(False)
|
2017-04-10 14:24:39 +02:00
|
|
|
self.loadpilotevent = self.createAction(self, "Load PILOT &event ...",
|
2017-04-19 16:05:45 +02:00
|
|
|
self.load_pilotevent, "Ctrl+E",
|
|
|
|
loadpiloticon,
|
|
|
|
"Load PILOT event from information "
|
|
|
|
"MatLab binary collections (created"
|
|
|
|
" in former MatLab based version).")
|
2017-04-10 14:24:39 +02:00
|
|
|
self.loadpilotevent.setEnabled(False)
|
|
|
|
|
|
|
|
self.saveEventAction = self.createAction(self, "&Save event ...",
|
2015-03-11 12:05:52 +01:00
|
|
|
self.saveData, QKeySequence.Save,
|
|
|
|
saveIcon, "Save actual event data.")
|
2017-04-10 14:24:39 +02:00
|
|
|
self.saveEventAction.setEnabled(False)
|
|
|
|
|
2017-04-18 16:24:26 +02:00
|
|
|
self.addEventDataAction = self.createAction(self, "Add &events ...",
|
|
|
|
self.add_events,
|
|
|
|
"Ctrl+W", newFolderIcon,
|
|
|
|
"Add event data")
|
2015-03-11 12:05:52 +01:00
|
|
|
prefsEventAction = self.createAction(self, "Preferences",
|
|
|
|
self.PyLoTprefs,
|
2015-01-29 08:41:38 +01:00
|
|
|
QKeySequence.Preferences,
|
|
|
|
QIcon(None),
|
|
|
|
"Edit PyLoT app preferences.")
|
2015-03-04 15:40:25 +01:00
|
|
|
quitAction = self.createAction(self, "&Quit",
|
2015-01-29 08:41:38 +01:00
|
|
|
QCoreApplication.instance().quit,
|
|
|
|
QKeySequence.Close, quitIcon,
|
|
|
|
"Close event and quit PyLoT")
|
2015-06-11 10:07:21 +02:00
|
|
|
self.filterAction = self.createAction(self, "&Filter ...",
|
|
|
|
self.filterWaveformData,
|
2015-07-07 10:31:39 +02:00
|
|
|
"Ctrl+F", filter_icon,
|
2015-06-11 10:07:21 +02:00
|
|
|
"""Toggle un-/filtered waveforms
|
2015-01-29 08:41:38 +01:00
|
|
|
to be displayed, according to the
|
|
|
|
desired seismic phase.""", True)
|
2015-03-04 15:40:25 +01:00
|
|
|
filterEditAction = self.createAction(self, "&Filter parameter ...",
|
2015-01-29 08:41:38 +01:00
|
|
|
self.adjustFilterOptions,
|
|
|
|
"Alt+F", QIcon(None),
|
|
|
|
"""Adjust filter parameters.""")
|
2015-06-11 10:07:21 +02:00
|
|
|
self.selectPAction = self.createAction(self, "&P", self.alterPhase,
|
|
|
|
"Alt+P",
|
|
|
|
p_icon,
|
|
|
|
"Toggle P phase.", True)
|
|
|
|
self.selectSAction = self.createAction(self, "&S", self.alterPhase,
|
|
|
|
"Alt+S",
|
|
|
|
s_icon,
|
|
|
|
"Toggle S phase", True)
|
2016-06-06 14:10:46 +02:00
|
|
|
self.compare_action = self.createAction(self, "&Compare picks...",
|
|
|
|
self.comparePicks, "Alt+C",
|
|
|
|
compare_icon, "Comparison of "
|
|
|
|
"manual and "
|
|
|
|
"automatic pick "
|
|
|
|
"data.", False)
|
2017-04-10 14:24:39 +02:00
|
|
|
self.compare_action.setEnabled(False)
|
|
|
|
|
2015-03-04 15:40:25 +01:00
|
|
|
printAction = self.createAction(self, "&Print event ...",
|
2016-09-02 14:21:59 +02:00
|
|
|
self.show_event_information, QKeySequence.Print,
|
2015-04-02 18:36:21 +02:00
|
|
|
print_icon,
|
2017-04-06 13:16:28 +02:00
|
|
|
"Print waveform section.")
|
2015-03-04 15:40:25 +01:00
|
|
|
helpAction = self.createAction(self, "&Help ...", self.helpHelp,
|
2015-01-29 08:41:38 +01:00
|
|
|
QKeySequence.HelpContents, helpIcon,
|
|
|
|
"""Show either the documentation
|
|
|
|
homepage (internet connection available),
|
|
|
|
or shipped documentation files.""")
|
|
|
|
self.fileMenu = self.menuBar().addMenu('&File')
|
2017-04-18 16:24:26 +02:00
|
|
|
self.fileMenuActions = (self.newProjectAction, self.addEventDataAction,
|
|
|
|
self.openProjectAction, self.saveProjectAction,
|
|
|
|
self.openmanualpicksaction, self.saveEventAction, None,
|
2015-01-29 08:41:38 +01:00
|
|
|
prefsEventAction, quitAction)
|
|
|
|
self.fileMenu.aboutToShow.connect(self.updateFileMenu)
|
|
|
|
self.updateFileMenu()
|
|
|
|
|
|
|
|
self.editMenu = self.menuBar().addMenu('&Edit')
|
2015-02-20 08:30:17 +01:00
|
|
|
editActions = (self.filterAction, filterEditAction, None,
|
|
|
|
self.selectPAction, self.selectSAction, None,
|
|
|
|
printAction)
|
2015-02-23 14:47:38 +01:00
|
|
|
self.addActions(self.editMenu, editActions)
|
2015-01-29 08:41:38 +01:00
|
|
|
|
|
|
|
self.helpMenu = self.menuBar().addMenu('&Help')
|
2015-06-11 10:07:21 +02:00
|
|
|
helpActions = (helpAction,)
|
2015-02-23 14:47:38 +01:00
|
|
|
self.addActions(self.helpMenu, helpActions)
|
|
|
|
|
|
|
|
fileToolBar = self.addToolBar("FileTools")
|
2017-04-18 16:24:26 +02:00
|
|
|
fileToolActions = (self.newProjectAction, self.addEventDataAction,
|
|
|
|
self.openProjectAction, self.saveProjectAction,
|
|
|
|
self.openmanualpicksaction,
|
2017-04-28 13:56:28 +02:00
|
|
|
self.openautopicksaction, self.loadlocationaction,
|
2017-04-10 14:24:39 +02:00
|
|
|
self.loadpilotevent, self.saveEventAction)
|
2015-02-23 14:47:38 +01:00
|
|
|
fileToolBar.setObjectName("FileTools")
|
|
|
|
self.addActions(fileToolBar, fileToolActions)
|
|
|
|
|
2015-10-30 08:37:00 +01:00
|
|
|
# phaseToolBar = self.addToolBar("PhaseTools")
|
|
|
|
# phaseToolActions = (self.selectPAction, self.selectSAction)
|
|
|
|
# phaseToolBar.setObjectName("PhaseTools")
|
|
|
|
# self.addActions(phaseToolBar, phaseToolActions)
|
2015-01-29 08:41:38 +01:00
|
|
|
|
2015-07-07 14:21:11 +02:00
|
|
|
# create button group for component selection
|
|
|
|
|
|
|
|
componentGroup = QActionGroup(self)
|
|
|
|
componentGroup.setExclusive(True)
|
|
|
|
|
2017-04-10 14:24:39 +02:00
|
|
|
self.z_action = self.createAction(parent=componentGroup, text='Z',
|
2015-07-07 14:21:11 +02:00
|
|
|
slot=self.plotZ, shortcut='Alt+Z',
|
|
|
|
icon=z_icon, tip='Display the vertical (Z)'
|
|
|
|
' component.',
|
|
|
|
checkable=True)
|
2017-04-10 14:24:39 +02:00
|
|
|
self.z_action.setChecked(True)
|
|
|
|
self.z_action.setEnabled(False)
|
2015-07-07 14:21:11 +02:00
|
|
|
|
2017-04-10 14:24:39 +02:00
|
|
|
self.n_action = self.createAction(parent=componentGroup, text='N',
|
2015-07-07 14:21:11 +02:00
|
|
|
slot=self.plotN, shortcut='Alt+N',
|
|
|
|
icon=n_icon,
|
|
|
|
tip='Display the north-south (N) '
|
|
|
|
'component.', checkable=True)
|
2017-04-10 14:24:39 +02:00
|
|
|
self.n_action.setEnabled(False)
|
2015-07-07 14:21:11 +02:00
|
|
|
|
2017-04-10 14:24:39 +02:00
|
|
|
self.e_action = self.createAction(parent=componentGroup, text='E',
|
2015-07-07 14:21:11 +02:00
|
|
|
slot=self.plotE, shortcut='Alt+E',
|
|
|
|
icon=e_icon,
|
|
|
|
tip='Display the east-west (E) component.',
|
|
|
|
checkable=True)
|
2017-04-10 14:24:39 +02:00
|
|
|
self.e_action.setEnabled(False)
|
2015-07-07 14:21:11 +02:00
|
|
|
|
|
|
|
componentToolBar = self.addToolBar("ComponentSelection")
|
2017-04-10 14:24:39 +02:00
|
|
|
componentActions = (self.z_action, self.n_action, self.e_action)
|
2015-07-07 14:21:11 +02:00
|
|
|
componentToolBar.setObjectName("PhaseTools")
|
|
|
|
self.addActions(componentToolBar, componentActions)
|
|
|
|
|
2017-04-10 14:24:39 +02:00
|
|
|
self.auto_pick = self.createAction(parent=self, text='autoPick',
|
2015-07-09 11:37:03 +02:00
|
|
|
slot=self.autoPick, shortcut='Alt+Ctrl+A',
|
|
|
|
icon=auto_icon, tip='Automatically pick'
|
2017-04-10 14:24:39 +02:00
|
|
|
' the displayed waveforms.')
|
|
|
|
self.auto_pick.setEnabled(False)
|
2015-07-09 11:37:03 +02:00
|
|
|
|
|
|
|
autoPickToolBar = self.addToolBar("autoPyLoT")
|
2017-04-10 14:24:39 +02:00
|
|
|
autoPickActions = (self.auto_pick, self.compare_action)
|
2015-07-09 11:37:03 +02:00
|
|
|
self.addActions(autoPickToolBar, autoPickActions)
|
|
|
|
|
2015-04-02 18:48:06 +02:00
|
|
|
# pickToolBar = self.addToolBar("PickTools")
|
|
|
|
# pickToolActions = (selectStation, )
|
|
|
|
# pickToolBar.setObjectName("PickTools")
|
|
|
|
# self.addActions(pickToolBar, pickToolActions)
|
2017-04-10 14:24:39 +02:00
|
|
|
self.locateEvent = self.createAction(parent=self, text='locate the event',
|
2016-08-31 12:16:48 +02:00
|
|
|
slot=self.locate_event,
|
2016-05-27 11:25:47 +02:00
|
|
|
shortcut='Alt+Ctrl+L',
|
|
|
|
icon=locate_icon,
|
|
|
|
tip='Locate the event using '
|
2017-04-06 13:16:28 +02:00
|
|
|
'the displayed manual arrivals.')
|
2017-04-10 14:24:39 +02:00
|
|
|
self.locateEvent.setEnabled(False)
|
2015-11-09 08:53:26 +01:00
|
|
|
|
|
|
|
locationToolBar = self.addToolBar("LocationTools")
|
2017-04-10 14:24:39 +02:00
|
|
|
locationToolActions = (self.locateEvent,)
|
2015-11-09 08:53:26 +01:00
|
|
|
locationToolBar.setObjectName("LocationTools")
|
|
|
|
self.addActions(locationToolBar, locationToolActions)
|
|
|
|
|
2015-01-29 08:41:38 +01:00
|
|
|
self.eventLabel = QLabel()
|
|
|
|
self.eventLabel.setFrameStyle(QFrame.StyledPanel | QFrame.Sunken)
|
|
|
|
status = self.statusBar()
|
|
|
|
status.setSizeGripEnabled(False)
|
|
|
|
status.addPermanentWidget(self.eventLabel)
|
|
|
|
status.showMessage("Ready", 500)
|
|
|
|
|
2017-04-18 17:17:46 +02:00
|
|
|
_widget.setLayout(self._main_layout)
|
2015-03-11 12:05:52 +01:00
|
|
|
_widget.showFullScreen()
|
2014-10-27 11:57:34 +01:00
|
|
|
|
2015-03-11 12:05:52 +01:00
|
|
|
self.setCentralWidget(_widget)
|
2014-11-27 10:13:17 +01:00
|
|
|
|
2016-09-22 14:12:24 +02:00
|
|
|
|
|
|
|
@property
|
|
|
|
def metadata(self):
|
|
|
|
return self._metadata
|
|
|
|
|
|
|
|
|
|
|
|
@metadata.setter
|
|
|
|
def metadata(self, value):
|
|
|
|
self._metadata = value
|
|
|
|
|
|
|
|
|
2014-12-01 12:37:52 +01:00
|
|
|
def updateFileMenu(self):
|
|
|
|
|
|
|
|
self.fileMenu.clear()
|
2015-01-20 13:44:35 +01:00
|
|
|
for action in self.fileMenuActions[:-1]:
|
|
|
|
if action is None:
|
|
|
|
self.fileMenu.addSeparator()
|
|
|
|
else:
|
|
|
|
self.fileMenu.addAction(action)
|
|
|
|
try:
|
2015-02-13 11:15:48 +01:00
|
|
|
current = self.data.getID()
|
2015-01-20 13:44:35 +01:00
|
|
|
except AttributeError:
|
|
|
|
current = None
|
2014-12-01 12:37:52 +01:00
|
|
|
recentEvents = []
|
2016-05-27 11:25:47 +02:00
|
|
|
for eventID in self.recentfiles:
|
2014-12-01 12:37:52 +01:00
|
|
|
fname = fnConstructor(eventID)
|
|
|
|
if eventID != current and QFile.exists(fname):
|
|
|
|
recentEvents.append(eventID)
|
2015-02-13 11:16:20 +01:00
|
|
|
recentEvents.reverse()
|
2016-05-27 11:25:47 +02:00
|
|
|
self.recentfiles = recentEvents[0:5]
|
2015-02-13 11:16:20 +01:00
|
|
|
settings = QSettings()
|
|
|
|
settings.setValue()
|
2014-12-01 12:37:52 +01:00
|
|
|
if recentEvents:
|
|
|
|
for i, eventID in enumerate(recentEvents):
|
|
|
|
fname = fnConstructor(eventID)
|
2015-07-07 10:31:39 +02:00
|
|
|
action = QAction(self.windowIcon(),
|
2014-12-01 12:37:52 +01:00
|
|
|
"&{0} {1}".format(i + 1,
|
|
|
|
QFileInfo(fname).fileName()),
|
|
|
|
self)
|
|
|
|
action.setData(fname)
|
2015-02-16 10:28:28 +01:00
|
|
|
self.connect(action, Signal("triggered()"),
|
2016-05-27 11:25:47 +02:00
|
|
|
self.load_data)
|
2014-12-01 12:37:52 +01:00
|
|
|
self.fileMenu.addAction(action)
|
|
|
|
self.fileMenu.addSeparator()
|
|
|
|
self.fileMenu.addAction(self.fileMenuActions[-1])
|
|
|
|
|
2016-09-08 15:31:23 +02:00
|
|
|
@property
|
|
|
|
def inputs(self):
|
|
|
|
return self._inputs
|
|
|
|
|
2015-07-18 16:11:20 +02:00
|
|
|
def getRoot(self):
|
|
|
|
settings = QSettings()
|
|
|
|
return settings.value("data/dataRoot")
|
|
|
|
|
2016-05-27 11:25:47 +02:00
|
|
|
def load_autopicks(self, fname=None):
|
|
|
|
self.load_data(fname, type='auto')
|
|
|
|
|
|
|
|
def load_loc(self, fname=None):
|
2016-06-02 09:39:01 +02:00
|
|
|
type = getDataType(self)
|
|
|
|
self.load_data(fname, type=type, loc=True)
|
2016-05-27 11:25:47 +02:00
|
|
|
|
|
|
|
def load_pilotevent(self):
|
2016-06-02 09:39:01 +02:00
|
|
|
filt = "PILOT location files (*LOC*.mat)"
|
2016-05-31 17:36:00 +02:00
|
|
|
caption = "Select PILOT location file"
|
2016-05-27 11:25:47 +02:00
|
|
|
fn_loc = QFileDialog().getOpenFileName(self, caption=caption,
|
2016-05-27 12:53:34 +02:00
|
|
|
filter=filt, dir=self.getRoot())
|
|
|
|
fn_loc = fn_loc[0]
|
|
|
|
loc_dir = os.path.split(fn_loc)[0]
|
2016-06-02 09:39:01 +02:00
|
|
|
filt = "PILOT phases files (*PHASES*.mat)"
|
2016-05-27 11:25:47 +02:00
|
|
|
caption = "Select PILOT phases file"
|
|
|
|
fn_phases = QFileDialog().getOpenFileName(self, caption=caption,
|
2016-05-27 12:53:34 +02:00
|
|
|
filter=filt, dir=loc_dir)
|
|
|
|
fn_phases = fn_phases[0]
|
2016-03-29 11:26:08 +02:00
|
|
|
|
2016-06-02 09:39:01 +02:00
|
|
|
type = getDataType(self)
|
2016-05-27 11:25:47 +02:00
|
|
|
|
|
|
|
fname_dict = dict(phasfn=fn_phases, locfn=fn_loc)
|
|
|
|
self.load_data(fname_dict, type=type)
|
|
|
|
|
2016-06-02 09:39:01 +02:00
|
|
|
def load_data(self, fname=None, type='manual', loc=False):
|
2015-09-03 13:21:46 +02:00
|
|
|
if not self.okToContinue():
|
2015-09-18 09:54:29 +02:00
|
|
|
return
|
2014-12-01 12:37:52 +01:00
|
|
|
if fname is None:
|
2015-09-17 17:45:10 +02:00
|
|
|
action = self.sender()
|
|
|
|
if isinstance(action, QAction):
|
2016-05-27 11:25:47 +02:00
|
|
|
fname = self.filename_from_action(action)
|
|
|
|
self.set_fname(fname, type)
|
2016-06-01 08:55:43 +02:00
|
|
|
data = dict(auto=self.autodata, manual=self.data)
|
|
|
|
data[type] += Data(self, evtdata=fname)
|
2016-06-02 09:39:01 +02:00
|
|
|
if not loc:
|
2016-05-27 11:25:47 +02:00
|
|
|
self.updatePicks(type=type)
|
2016-06-01 08:55:43 +02:00
|
|
|
self.drawPicks(picktype=type)
|
2016-05-31 17:27:59 +02:00
|
|
|
self.draw()
|
2014-11-26 08:46:16 +01:00
|
|
|
|
2017-04-19 16:51:19 +02:00
|
|
|
def getCurrentEvent(self):
|
|
|
|
for event in self.project.eventlist:
|
2017-04-20 14:03:26 +02:00
|
|
|
if event.path == self.getCurrentEventPath():
|
2017-04-19 16:51:19 +02:00
|
|
|
return event
|
2017-04-20 14:03:26 +02:00
|
|
|
|
|
|
|
def getCurrentEventPath(self):
|
|
|
|
return str(self.eventBox.currentText().split('|')[0]).strip()
|
2017-04-19 16:51:19 +02:00
|
|
|
|
2015-02-13 11:23:01 +01:00
|
|
|
def getLastEvent(self):
|
2016-05-27 11:25:47 +02:00
|
|
|
return self.recentfiles[0]
|
2015-02-13 11:23:01 +01:00
|
|
|
|
2016-05-27 11:25:47 +02:00
|
|
|
def add_recentfile(self, event):
|
|
|
|
self.recentfiles.insert(0, event)
|
2015-08-31 13:37:18 +02:00
|
|
|
|
2015-01-22 16:41:52 +01:00
|
|
|
def getWFFnames(self):
|
2015-01-26 21:11:53 +01:00
|
|
|
try:
|
2016-09-02 14:21:59 +02:00
|
|
|
evt = self.get_data().get_evt_data()
|
2015-01-26 21:11:53 +01:00
|
|
|
if evt.picks:
|
|
|
|
for pick in evt.picks:
|
2015-01-29 08:48:25 +01:00
|
|
|
try:
|
|
|
|
if pick.waveform_id is not None:
|
|
|
|
fname = pick.waveform_id.getSEEDstring()
|
|
|
|
if fname not in self.fnames:
|
|
|
|
self.fnames.append(fname)
|
|
|
|
except:
|
|
|
|
continue
|
2015-01-26 21:11:53 +01:00
|
|
|
else:
|
|
|
|
if self.dataStructure:
|
|
|
|
searchPath = self.dataStructure.expandDataPath()
|
2015-02-17 13:17:01 +01:00
|
|
|
fnames = QFileDialog.getOpenFileNames(self,
|
2015-06-11 10:07:21 +02:00
|
|
|
"Select waveform "
|
|
|
|
"files:",
|
|
|
|
dir=searchPath)
|
2015-02-20 08:37:21 +01:00
|
|
|
self.fnames = fnames[0]
|
2015-02-13 11:19:10 +01:00
|
|
|
|
2015-01-29 08:48:25 +01:00
|
|
|
else:
|
2015-02-17 13:17:01 +01:00
|
|
|
raise DatastructureError('not specified')
|
2016-03-22 10:49:06 +01:00
|
|
|
if not self.fnames:
|
|
|
|
return None
|
2015-01-29 08:48:25 +01:00
|
|
|
return self.fnames
|
2015-09-25 15:06:59 +02:00
|
|
|
except DatastructureError as e:
|
|
|
|
print(e)
|
2015-01-29 08:48:25 +01:00
|
|
|
props = PropertiesDlg(self)
|
|
|
|
if props.exec_() == QDialog.Accepted:
|
|
|
|
return self.getWFFnames()
|
|
|
|
else:
|
|
|
|
return
|
2015-01-22 16:41:52 +01:00
|
|
|
|
2017-04-18 16:24:26 +02:00
|
|
|
def getWFFnames_from_eventlist(self):
|
|
|
|
if self.dataStructure:
|
|
|
|
searchPath = self.dataStructure.expandDataPath()
|
2017-04-20 14:03:26 +02:00
|
|
|
directory = self.getCurrentEventPath()
|
2017-04-18 16:24:26 +02:00
|
|
|
self.fnames = [os.path.join(directory, f) for f in os.listdir(directory)]
|
|
|
|
else:
|
|
|
|
raise DatastructureError('not specified')
|
|
|
|
if not self.fnames:
|
|
|
|
return None
|
|
|
|
return self.fnames
|
|
|
|
|
|
|
|
def add_events(self):
|
|
|
|
if not self.project:
|
|
|
|
self.project = Project()
|
|
|
|
ed = getExistingDirectories(self, 'Select event directories...')
|
|
|
|
if ed.exec_():
|
|
|
|
eventlist = ed.selectedFiles()
|
|
|
|
# select only folders that start with 'e', containin two dots and have length 12
|
|
|
|
eventlist = [item for item in eventlist if item.split('/')[-1].startswith('e')
|
|
|
|
and len(item.split('/')[-1].split('.')) == 3
|
|
|
|
and len(item.split('/')[-1]) == 12]
|
|
|
|
else:
|
|
|
|
return
|
|
|
|
if not self.project:
|
|
|
|
print('No project found.')
|
|
|
|
return
|
|
|
|
self.project.add_eventlist(eventlist)
|
|
|
|
self.init_events()
|
|
|
|
|
2017-04-20 14:03:26 +02:00
|
|
|
def createEventBox(self):
|
|
|
|
qcb = QComboBox()
|
|
|
|
palette = qcb.palette()
|
|
|
|
palette.setBrush(QtGui.QPalette.Inactive, QtGui.QPalette.Highlight,
|
|
|
|
QtGui.QBrush(QtGui.QColor(0,0,127,127)))
|
|
|
|
palette.setBrush(QtGui.QPalette.Active, QtGui.QPalette.Highlight,
|
|
|
|
QtGui.QBrush(QtGui.QColor(0,0,127,127)))
|
|
|
|
qcb.setPalette(palette)
|
|
|
|
return qcb
|
|
|
|
|
|
|
|
|
2017-04-18 16:24:26 +02:00
|
|
|
def init_events(self, new=False):
|
|
|
|
nitems = self.eventBox.count()
|
|
|
|
if len(self.project.eventlist) == 0:
|
|
|
|
print('No events to init.')
|
2017-04-19 15:31:08 +02:00
|
|
|
self.clearWaveformDataPlot()
|
2017-04-18 16:24:26 +02:00
|
|
|
return
|
|
|
|
self.eventBox.setEnabled(True)
|
2017-04-20 14:03:26 +02:00
|
|
|
self.fill_eventbox()
|
2017-04-18 16:24:26 +02:00
|
|
|
if new:
|
|
|
|
self.eventBox.setCurrentIndex(0)
|
|
|
|
else:
|
|
|
|
self.eventBox.setCurrentIndex(nitems)
|
2017-04-19 16:05:45 +02:00
|
|
|
self.refreshEvents()
|
2017-04-20 12:05:34 +02:00
|
|
|
tabindex = self.tabs.currentIndex()
|
2017-04-18 16:24:26 +02:00
|
|
|
|
2017-04-20 14:03:26 +02:00
|
|
|
def fill_eventbox(self):
|
|
|
|
index=self.eventBox.currentIndex()
|
2017-04-21 15:46:57 +02:00
|
|
|
tv=QtGui.QTableView()
|
|
|
|
header = tv.horizontalHeader()
|
|
|
|
header.setResizeMode(QtGui.QHeaderView.ResizeToContents)
|
|
|
|
header.setStretchLastSection(True)
|
|
|
|
header.hide()
|
|
|
|
tv.verticalHeader().hide()
|
|
|
|
tv.setSelectionBehavior(QtGui.QAbstractItemView.SelectRows)
|
|
|
|
|
|
|
|
self.eventBox.setView(tv)
|
2017-04-20 14:03:26 +02:00
|
|
|
self.eventBox.clear()
|
2017-04-19 15:31:08 +02:00
|
|
|
model = self.eventBox.model()
|
2017-04-21 15:46:57 +02:00
|
|
|
plmax=0
|
|
|
|
for event in self.project.eventlist:
|
|
|
|
pl = len(event.path)
|
|
|
|
if pl > plmax:
|
|
|
|
plmax=pl
|
|
|
|
|
2017-04-19 15:31:08 +02:00
|
|
|
for event in self.project.eventlist:
|
2017-04-20 14:03:26 +02:00
|
|
|
event_path = event.path
|
|
|
|
event_npicks = 0
|
|
|
|
event_nautopicks = 0
|
|
|
|
if event.picks:
|
|
|
|
event_npicks = len(event.picks)
|
|
|
|
if event.autopicks:
|
|
|
|
event_nautopicks = len(event.autopicks)
|
|
|
|
event_ref = event.isRefEvent()
|
|
|
|
event_test = event.isTestEvent()
|
|
|
|
|
2017-04-21 15:46:57 +02:00
|
|
|
text = '{path:{plen}} | manual: [{p:3d}] | auto: [{a:3d}]'
|
2017-04-20 14:03:26 +02:00
|
|
|
text = text.format(path=event_path,
|
2017-04-21 15:46:57 +02:00
|
|
|
plen=plmax,
|
2017-04-20 14:03:26 +02:00
|
|
|
p=event_npicks,
|
2017-04-21 15:46:57 +02:00
|
|
|
a=event_nautopicks)
|
|
|
|
|
|
|
|
item_path = QtGui.QStandardItem('{path:{plen}}'.format(path=event_path, plen=plmax))
|
|
|
|
item_nmp = QtGui.QStandardItem(str(event_npicks))
|
|
|
|
item_nmp.setIcon(self.manupicksicon_small)
|
|
|
|
item_nap = QtGui.QStandardItem(str(event_nautopicks))
|
|
|
|
item_nap.setIcon(self.autopicksicon_small)
|
|
|
|
item_ref = QtGui.QStandardItem()#str(event_ref))
|
|
|
|
item_test = QtGui.QStandardItem()#str(event_test))
|
2017-04-20 14:03:26 +02:00
|
|
|
if event_ref:
|
2017-04-21 15:46:57 +02:00
|
|
|
item_ref.setBackground(QtGui.QColor(200, 210, 230, 255))
|
2017-04-20 14:03:26 +02:00
|
|
|
if event_test:
|
2017-04-21 15:46:57 +02:00
|
|
|
item_test.setBackground(QtGui.QColor(200, 230, 200, 255))
|
|
|
|
item_notes = QtGui.QStandardItem(event.notes)
|
|
|
|
|
|
|
|
openIcon = self.style().standardIcon(QStyle.SP_DirOpenIcon)
|
|
|
|
item_path.setIcon(openIcon)
|
|
|
|
# if ref: set different color e.g.
|
|
|
|
# if event_ref:
|
|
|
|
# item.setBackground(QtGui.QColor(200, 210, 230, 255))
|
|
|
|
# if event_test:
|
|
|
|
# item.setBackground(QtGui.QColor(200, 230, 200, 255))
|
|
|
|
# item.setForeground(QtGui.QColor('black'))
|
|
|
|
# font = item.font()
|
|
|
|
# font.setPointSize(10)
|
|
|
|
# item.setFont(font)
|
|
|
|
# item2.setForeground(QtGui.QColor('black'))
|
|
|
|
# item2.setFont(font)
|
|
|
|
itemlist = [item_path, item_nmp, item_nap, item_ref, item_test, item_notes]
|
|
|
|
model.appendRow(itemlist)
|
2017-04-20 14:03:26 +02:00
|
|
|
self.eventBox.setCurrentIndex(index)
|
|
|
|
|
2016-05-27 11:25:47 +02:00
|
|
|
def filename_from_action(self, action):
|
|
|
|
if action.data() is None:
|
|
|
|
filt = "Supported file formats" \
|
|
|
|
" (*.mat *.qml *.xml *.kor *.evt)"
|
|
|
|
caption = "Open an event file"
|
2016-06-02 09:39:01 +02:00
|
|
|
fname = QFileDialog().getOpenFileName(self, caption=caption,
|
|
|
|
filter=filt,
|
|
|
|
dir=self.getRoot())
|
2016-05-27 11:25:47 +02:00
|
|
|
fname = fname[0]
|
|
|
|
else:
|
|
|
|
fname = str(action.data().toString())
|
|
|
|
return fname
|
|
|
|
|
2016-09-08 09:54:43 +02:00
|
|
|
def get_fnames(self, type='manual'):
|
|
|
|
return self.fname[type]
|
2015-08-31 13:37:18 +02:00
|
|
|
|
2016-05-27 11:25:47 +02:00
|
|
|
def set_fname(self, fname, type):
|
2016-09-08 09:54:43 +02:00
|
|
|
if self.get_fnames(type) is not None:
|
|
|
|
self.add_recentfile(self.get_fnames(type))
|
2016-05-27 11:25:47 +02:00
|
|
|
self.fname[type] = fname
|
2015-08-31 13:37:18 +02:00
|
|
|
|
2016-09-08 09:54:43 +02:00
|
|
|
def getEventFileName(self, type='manual'):
|
|
|
|
if self.get_fnames(type) is None:
|
|
|
|
self.set_fname(self.get_data().getEventFileName(), type)
|
|
|
|
return self.get_fnames(type)
|
2015-07-18 16:11:20 +02:00
|
|
|
|
2014-11-28 11:15:49 +01:00
|
|
|
def saveData(self):
|
2015-08-31 13:37:18 +02:00
|
|
|
|
|
|
|
def getSavePath(e):
|
2015-09-25 15:06:59 +02:00
|
|
|
print('warning: {0}'.format(e))
|
2016-09-19 11:33:08 +02:00
|
|
|
directory = os.path.realpath(self.getRoot())
|
2016-05-27 11:25:47 +02:00
|
|
|
file_filter = "QuakeML file (*.xml);;VELEST observation file " \
|
|
|
|
"format (*.cnv);;NonLinLoc observation file (*.obs)"
|
|
|
|
title = 'Save event data ...'
|
|
|
|
fname, selected_filter = QFileDialog.getSaveFileName(self,
|
|
|
|
title,
|
|
|
|
directory,
|
|
|
|
file_filter)
|
2015-08-31 13:37:18 +02:00
|
|
|
|
2016-03-02 11:04:11 +01:00
|
|
|
fbasename, exform = os.path.splitext(fname)
|
|
|
|
|
|
|
|
if not exform and selected_filter:
|
|
|
|
exform = selected_filter.split('*')[1][:-1]
|
2015-08-31 13:37:18 +02:00
|
|
|
|
|
|
|
return fbasename, exform
|
|
|
|
|
2014-12-17 12:16:32 +01:00
|
|
|
settings = QSettings()
|
2015-08-31 13:37:18 +02:00
|
|
|
fbasename = self.getEventFileName()
|
2015-07-08 15:12:35 +02:00
|
|
|
exform = settings.value('data/exportFormat', 'QUAKEML')
|
2015-08-27 12:55:34 +02:00
|
|
|
try:
|
2016-09-02 14:21:59 +02:00
|
|
|
self.get_data().applyEVTData(self.getPicks())
|
2015-08-27 12:55:34 +02:00
|
|
|
except OverwriteError:
|
|
|
|
msgBox = QMessageBox()
|
|
|
|
msgBox.setText("Picks have been modified!")
|
2016-05-27 11:25:47 +02:00
|
|
|
msgBox.setInformativeText(
|
|
|
|
"Do you want to save the changes and overwrite the picks?")
|
2016-09-02 14:21:59 +02:00
|
|
|
msgBox.setDetailedText(self.get_data().getPicksStr())
|
2015-08-28 16:01:42 +02:00
|
|
|
msgBox.setStandardButtons(QMessageBox.Save | QMessageBox.Cancel)
|
2015-08-27 12:55:34 +02:00
|
|
|
msgBox.setDefaultButton(QMessageBox.Save)
|
|
|
|
ret = msgBox.exec_()
|
|
|
|
if ret == QMessageBox.Save:
|
2016-09-02 14:21:59 +02:00
|
|
|
self.get_data().resetPicks()
|
2016-03-03 13:17:10 +01:00
|
|
|
return self.saveData()
|
2015-08-28 16:01:42 +02:00
|
|
|
elif ret == QMessageBox.Cancel:
|
|
|
|
return False
|
2014-12-17 12:16:32 +01:00
|
|
|
try:
|
2016-09-02 14:21:59 +02:00
|
|
|
self.get_data().exportEvent(fbasename, exform)
|
2015-08-31 13:37:18 +02:00
|
|
|
except FormatError as e:
|
|
|
|
fbasename, exform = getSavePath(e)
|
|
|
|
except AttributeError as e:
|
|
|
|
fbasename, exform = getSavePath(e)
|
2016-09-08 09:54:43 +02:00
|
|
|
|
|
|
|
# catch all possible cases before going on
|
2015-08-31 13:37:18 +02:00
|
|
|
if not fbasename:
|
|
|
|
return False
|
2016-09-08 09:54:43 +02:00
|
|
|
# warn overwriting
|
|
|
|
elif os.path.exists(fbasename + exform):
|
|
|
|
ans = QMessageBox.question(self, self.tr("Overwrite file..."),
|
|
|
|
self.tr("File already exists: {0}\n".format(fbasename + exform) + \
|
|
|
|
"Overwrite file anyway?"),
|
2017-04-06 13:16:28 +02:00
|
|
|
QMessageBox.Yes | QMessageBox.No | QMessageBox.Cancel)
|
2016-09-08 09:54:43 +02:00
|
|
|
# only negative answers have to be caught
|
|
|
|
if ans == QMessageBox.No:
|
|
|
|
self.saveData()
|
|
|
|
elif ans == QMessageBox.Cancel:
|
|
|
|
return False
|
|
|
|
|
|
|
|
# export to given path
|
2016-09-02 14:21:59 +02:00
|
|
|
self.get_data().exportEvent(fbasename, exform)
|
2016-09-08 09:54:43 +02:00
|
|
|
# all files save (ui clean)
|
2015-08-31 13:37:18 +02:00
|
|
|
self.setDirty(False)
|
2016-09-02 14:21:59 +02:00
|
|
|
self.update_status('Event saved as %s' % (fbasename + exform))
|
2014-12-08 10:26:14 +01:00
|
|
|
return True
|
2014-11-28 11:15:49 +01:00
|
|
|
|
2017-04-06 13:16:28 +02:00
|
|
|
def getinfile(self):
|
|
|
|
return self.infile
|
|
|
|
|
2015-02-07 09:03:03 +01:00
|
|
|
def getComponent(self):
|
|
|
|
return self.dispComponent
|
2014-03-28 22:26:15 +01:00
|
|
|
|
2015-07-07 14:21:11 +02:00
|
|
|
def setComponent(self, component):
|
|
|
|
self.dispComponent = component
|
|
|
|
|
2016-09-02 14:21:59 +02:00
|
|
|
def get_data(self, type='manual'):
|
2016-05-27 07:43:54 +02:00
|
|
|
if type == 'auto':
|
|
|
|
return self.autodata
|
2014-11-13 11:27:52 +01:00
|
|
|
return self.data
|
|
|
|
|
2015-11-30 09:50:47 +01:00
|
|
|
def getPicks(self, type='manual'):
|
|
|
|
rdict = dict(auto=self.autopicks, manual=self.picks)
|
|
|
|
return rdict[type]
|
2015-07-07 10:32:56 +02:00
|
|
|
|
2015-11-30 09:50:47 +01:00
|
|
|
def getPicksOnStation(self, station, type='manual'):
|
2015-07-07 10:32:56 +02:00
|
|
|
try:
|
2015-11-30 09:50:47 +01:00
|
|
|
return self.getPicks(type)[station]
|
2015-07-07 10:32:56 +02:00
|
|
|
except KeyError:
|
|
|
|
return None
|
|
|
|
|
2016-06-06 14:10:46 +02:00
|
|
|
def comparePicks(self):
|
|
|
|
if self.check4Comparison():
|
2016-06-07 13:51:03 +02:00
|
|
|
co = Comparison(auto=self.getPicks('auto'), manu=self.getPicks())
|
|
|
|
compare_dlg = ComparisonDialog(co, self)
|
|
|
|
compare_dlg.exec_()
|
2016-06-06 14:10:46 +02:00
|
|
|
|
2015-03-04 11:52:04 +01:00
|
|
|
def getPlotWidget(self):
|
2017-04-19 15:31:08 +02:00
|
|
|
return self.dataPlot
|
2014-11-13 11:27:52 +01:00
|
|
|
|
2015-06-11 10:07:21 +02:00
|
|
|
@staticmethod
|
|
|
|
def getWFID(gui_event):
|
2015-03-11 12:05:52 +01:00
|
|
|
|
2015-04-02 18:48:06 +02:00
|
|
|
ycoord = gui_event.ydata
|
2015-03-11 12:05:52 +01:00
|
|
|
|
2016-05-31 15:53:23 +02:00
|
|
|
try:
|
|
|
|
statID = int(round(ycoord))
|
|
|
|
except TypeError as e:
|
|
|
|
if 'a float is required' in e.message:
|
|
|
|
return None
|
|
|
|
else:
|
|
|
|
raise e
|
2015-03-11 12:05:52 +01:00
|
|
|
|
|
|
|
return statID
|
2015-03-09 11:21:33 +01:00
|
|
|
|
2015-07-07 10:39:01 +02:00
|
|
|
def getStationID(self, station):
|
|
|
|
for wfID in self.getPlotWidget().getPlotDict().keys():
|
|
|
|
actual_station = self.getPlotWidget().getPlotDict()[wfID][0]
|
|
|
|
if station == actual_station:
|
|
|
|
return wfID
|
|
|
|
return None
|
|
|
|
|
2016-05-31 17:27:59 +02:00
|
|
|
def getStime(self):
|
|
|
|
return self._stime
|
|
|
|
|
2015-02-23 14:38:26 +01:00
|
|
|
def addActions(self, target, actions):
|
2015-01-22 16:41:52 +01:00
|
|
|
for action in actions:
|
2015-01-20 13:48:19 +01:00
|
|
|
if action is None:
|
2015-02-23 14:38:26 +01:00
|
|
|
target.addSeparator()
|
2015-01-20 13:48:19 +01:00
|
|
|
else:
|
2015-02-23 14:38:26 +01:00
|
|
|
target.addAction(action)
|
2015-01-20 13:48:19 +01:00
|
|
|
|
2014-12-01 12:41:13 +01:00
|
|
|
def okToContinue(self):
|
|
|
|
if self.dirty:
|
|
|
|
return self.saveData()
|
|
|
|
return True
|
2014-03-28 05:25:46 +01:00
|
|
|
|
2017-04-19 16:05:45 +02:00
|
|
|
def refreshEvents(self):
|
2017-04-20 17:06:36 +02:00
|
|
|
self._eventChanged = [True, True]
|
2017-04-19 16:05:45 +02:00
|
|
|
self.refreshTabs()
|
|
|
|
|
2017-04-19 15:31:08 +02:00
|
|
|
def refreshTabs(self):
|
2017-04-20 17:06:36 +02:00
|
|
|
if self._eventChanged[0] or self._eventChanged[1]:
|
|
|
|
event = self.getCurrentEvent()
|
|
|
|
if not event.picks:
|
|
|
|
self.picks = {}
|
|
|
|
else:
|
|
|
|
self.picks = event.picks
|
|
|
|
if not event.autopicks:
|
|
|
|
self.autopicks = {}
|
|
|
|
else:
|
|
|
|
self.autopicks = event.autopicks
|
|
|
|
if self.tabs.currentIndex() == 0:
|
|
|
|
if hasattr(self.project, 'eventlist'):
|
|
|
|
if len(self.project.eventlist) > 0:
|
|
|
|
if self._eventChanged[0]:
|
|
|
|
self.newWFplot()
|
|
|
|
if self.tabs.currentIndex() == 1:
|
|
|
|
if self._eventChanged[1]:
|
|
|
|
self.refresh_array_map()
|
2017-04-20 12:05:34 +02:00
|
|
|
if self.tabs.currentIndex() == 2:
|
|
|
|
self.init_event_table()
|
2017-04-19 16:51:19 +02:00
|
|
|
|
|
|
|
def newWFplot(self):
|
|
|
|
self.loadWaveformDataThread()
|
2017-04-20 17:06:36 +02:00
|
|
|
self._eventChanged[0] = False
|
2017-04-19 15:31:08 +02:00
|
|
|
|
2017-04-18 16:24:26 +02:00
|
|
|
def loadWaveformDataThread(self):
|
2017-04-19 15:31:08 +02:00
|
|
|
wfd_thread = Thread(self, self.loadWaveformData, progressText='Reading data input...')
|
2017-04-18 16:24:26 +02:00
|
|
|
wfd_thread.finished.connect(self.plotWaveformDataThread)
|
|
|
|
wfd_thread.start()
|
|
|
|
|
2015-02-16 10:27:32 +01:00
|
|
|
def loadWaveformData(self):
|
2017-04-18 16:24:26 +02:00
|
|
|
# if self.fnames and self.okToContinue():
|
|
|
|
# self.setDirty(True)
|
|
|
|
# ans = self.data.setWFData(self.fnames)
|
|
|
|
# elif self.fnames is None and self.okToContinue():
|
|
|
|
# ans = self.data.setWFData(self.getWFFnames())
|
|
|
|
# else:
|
|
|
|
# ans = False
|
|
|
|
self.data.setWFData(self.getWFFnames_from_eventlist())
|
2016-09-19 11:42:52 +02:00
|
|
|
self._stime = full_range(self.get_data().getWFData())[0]
|
2017-04-18 16:24:26 +02:00
|
|
|
|
2017-04-19 15:31:08 +02:00
|
|
|
def connectWFplotEvents(self):
|
|
|
|
if not self.poS_id:
|
|
|
|
self.poS_id = self.dataPlot.mpl_connect('button_press_event',
|
|
|
|
self.pickOnStation)
|
|
|
|
if not self.ae_id:
|
|
|
|
self.ae_id = self.dataPlot.mpl_connect('axes_enter_event',
|
|
|
|
lambda event: self.tutor_user())
|
|
|
|
|
|
|
|
def disconnectWFplotEvents(self):
|
|
|
|
if self.poS_id:
|
|
|
|
self.dataPlot.mpl_disconnect(self.poS_id)
|
|
|
|
if self.ae_id:
|
|
|
|
self.dataPlot.mpl_disconnect(self.ae_id)
|
|
|
|
self.poS_id = None
|
|
|
|
self.ae_id = None
|
|
|
|
|
2017-04-18 16:24:26 +02:00
|
|
|
def finishWaveformDataPlot(self):
|
2017-04-19 15:31:08 +02:00
|
|
|
self.connectWFplotEvents()
|
2017-04-28 13:56:28 +02:00
|
|
|
self.loadlocationaction.setEnabled(True)
|
2017-04-28 13:47:24 +02:00
|
|
|
self.saveProjectAction.setEnabled(True)
|
2017-04-10 14:24:39 +02:00
|
|
|
self.auto_pick.setEnabled(True)
|
|
|
|
self.z_action.setEnabled(True)
|
|
|
|
self.e_action.setEnabled(True)
|
|
|
|
self.n_action.setEnabled(True)
|
|
|
|
self.openmanualpicksaction.setEnabled(True)
|
|
|
|
self.openautopicksaction.setEnabled(True)
|
|
|
|
self.loadpilotevent.setEnabled(True)
|
|
|
|
self.saveEventAction.setEnabled(True)
|
2017-04-19 16:51:19 +02:00
|
|
|
event = self.getCurrentEvent()
|
|
|
|
if event.picks:
|
|
|
|
self.picks = event.picks
|
|
|
|
self.drawPicks(picktype='manual')
|
|
|
|
if event.autopicks:
|
|
|
|
self.autopicks = event.autopicks
|
|
|
|
self.drawPicks(picktype='auto')
|
2017-04-18 16:24:26 +02:00
|
|
|
self.draw()
|
2015-01-29 08:48:25 +01:00
|
|
|
|
2017-04-19 15:31:08 +02:00
|
|
|
def clearWaveformDataPlot(self):
|
|
|
|
self.disconnectWFplotEvents()
|
|
|
|
self.dataPlot.getAxes().cla()
|
2017-04-28 16:01:31 +02:00
|
|
|
self.loadlocationaction.setEnabled(False)
|
|
|
|
self.saveProjectAction.setEnabled(False)
|
2017-04-19 15:31:08 +02:00
|
|
|
self.auto_pick.setEnabled(False)
|
|
|
|
self.z_action.setEnabled(False)
|
|
|
|
self.e_action.setEnabled(False)
|
|
|
|
self.n_action.setEnabled(False)
|
|
|
|
self.openmanualpicksaction.setEnabled(False)
|
|
|
|
self.openautopicksaction.setEnabled(False)
|
|
|
|
self.loadpilotevent.setEnabled(False)
|
|
|
|
self.saveEventAction.setEnabled(False)
|
|
|
|
self.draw()
|
|
|
|
|
2017-04-18 16:24:26 +02:00
|
|
|
def plotWaveformDataThread(self):
|
2017-04-19 15:31:08 +02:00
|
|
|
wfp_thread = Thread(self, self.plotWaveformData, progressText='Plotting waveform data...')
|
2017-04-18 16:24:26 +02:00
|
|
|
wfp_thread.finished.connect(self.finishWaveformDataPlot)
|
|
|
|
wfp_thread.start()
|
|
|
|
|
2015-02-17 13:17:01 +01:00
|
|
|
def plotWaveformData(self):
|
2015-03-29 08:07:46 +02:00
|
|
|
zne_text = {'Z': 'vertical', 'N': 'north-south', 'E': 'east-west'}
|
|
|
|
comp = self.getComponent()
|
2015-09-25 15:06:59 +02:00
|
|
|
title = 'section: {0} components'.format(zne_text[comp])
|
2016-03-29 14:06:57 +02:00
|
|
|
alter_comp = COMPNAME_MAP[comp]
|
2016-09-02 14:21:59 +02:00
|
|
|
wfst = self.get_data().getWFData().select(component=comp)
|
|
|
|
wfst += self.get_data().getWFData().select(component=alter_comp)
|
2017-05-03 15:16:48 +02:00
|
|
|
height_need = len(self.data.getWFData())*12
|
|
|
|
plotWidget = self.getPlotWidget()
|
|
|
|
if plotWidget.frameSize().height() < height_need:
|
|
|
|
plotWidget.setFixedHeight(height_need)
|
|
|
|
else:
|
|
|
|
plotWidget.setFixedHeight(plotWidget.frameSize().height())
|
|
|
|
plotWidget.figure.tight_layout()
|
|
|
|
plotWidget.plotWFData(wfdata=wfst, title=title, mapping=False)
|
|
|
|
plotDict = plotWidget.getPlotDict()
|
2015-07-13 06:36:33 +02:00
|
|
|
pos = plotDict.keys()
|
|
|
|
labels = [plotDict[n][0] for n in pos]
|
2017-05-03 15:16:48 +02:00
|
|
|
plotWidget.setYTickLabels(pos, labels)
|
|
|
|
plotWidget.figure.tight_layout()
|
2014-03-19 12:24:41 +01:00
|
|
|
|
2015-07-07 14:21:11 +02:00
|
|
|
def plotZ(self):
|
|
|
|
self.setComponent('Z')
|
2017-04-18 16:24:26 +02:00
|
|
|
self.plotWaveformDataThread()
|
2015-07-07 14:21:11 +02:00
|
|
|
self.drawPicks()
|
2016-05-31 17:27:59 +02:00
|
|
|
self.draw()
|
2015-07-07 14:21:11 +02:00
|
|
|
|
|
|
|
def plotN(self):
|
|
|
|
self.setComponent('N')
|
2017-04-18 16:24:26 +02:00
|
|
|
self.plotWaveformDataThread()
|
2015-07-07 14:21:11 +02:00
|
|
|
self.drawPicks()
|
2016-05-31 17:27:59 +02:00
|
|
|
self.draw()
|
2015-07-07 14:21:11 +02:00
|
|
|
|
|
|
|
def plotE(self):
|
|
|
|
self.setComponent('E')
|
2017-04-18 16:24:26 +02:00
|
|
|
self.plotWaveformDataThread()
|
2015-07-07 14:21:11 +02:00
|
|
|
self.drawPicks()
|
2016-05-31 17:27:59 +02:00
|
|
|
self.draw()
|
2015-07-07 14:21:11 +02:00
|
|
|
|
2015-10-31 00:07:24 +01:00
|
|
|
def pushFilterWF(self, param_args):
|
2016-09-02 14:21:59 +02:00
|
|
|
self.get_data().filterWFData(param_args)
|
2015-10-31 00:07:24 +01:00
|
|
|
|
2015-02-17 13:17:01 +01:00
|
|
|
def filterWaveformData(self):
|
2016-09-02 14:21:59 +02:00
|
|
|
if self.get_data():
|
2015-10-30 08:39:51 +01:00
|
|
|
if self.getFilterOptions() and self.filterAction.isChecked():
|
|
|
|
kwargs = self.getFilterOptions().parseFilterOptions()
|
2015-10-31 00:07:24 +01:00
|
|
|
self.pushFilterWF(kwargs)
|
2015-10-30 08:39:51 +01:00
|
|
|
elif self.filterAction.isChecked():
|
|
|
|
self.adjustFilterOptions()
|
2015-02-20 08:38:26 +01:00
|
|
|
else:
|
2016-09-02 14:21:59 +02:00
|
|
|
self.get_data().resetWFData()
|
2015-02-20 08:38:26 +01:00
|
|
|
self.plotWaveformData()
|
2016-03-29 12:09:26 +02:00
|
|
|
self.drawPicks()
|
2016-05-31 17:27:59 +02:00
|
|
|
self.draw()
|
2014-11-28 11:15:49 +01:00
|
|
|
|
2014-11-06 15:07:05 +01:00
|
|
|
def adjustFilterOptions(self):
|
2014-11-13 11:27:52 +01:00
|
|
|
fstring = "Filter Options ({0})".format(self.getSeismicPhase())
|
|
|
|
filterDlg = FilterOptionsDialog(titleString=fstring,
|
2015-10-31 00:07:24 +01:00
|
|
|
parent=self)
|
2014-12-01 12:42:50 +01:00
|
|
|
if filterDlg.exec_():
|
2014-12-09 05:25:43 +01:00
|
|
|
filteroptions = filterDlg.getFilterOptions()
|
2015-03-05 14:52:34 +01:00
|
|
|
self.setFilterOptions(filteroptions)
|
2015-10-31 00:07:24 +01:00
|
|
|
if self.filterAction.isChecked():
|
|
|
|
kwargs = self.getFilterOptions().parseFilterOptions()
|
|
|
|
self.pushFilterWF(kwargs)
|
|
|
|
self.plotWaveformData()
|
2014-11-13 11:27:52 +01:00
|
|
|
|
|
|
|
def getFilterOptions(self):
|
2015-03-01 10:31:49 +01:00
|
|
|
try:
|
|
|
|
return self.filteroptions[self.getSeismicPhase()]
|
2015-09-25 15:06:59 +02:00
|
|
|
except AttributeError as e:
|
|
|
|
print(e)
|
2015-03-01 10:31:49 +01:00
|
|
|
return FilterOptions(None, None, None)
|
|
|
|
|
|
|
|
def getFilters(self):
|
2014-11-13 11:27:52 +01:00
|
|
|
return self.filteroptions
|
|
|
|
|
2015-03-01 10:31:49 +01:00
|
|
|
def setFilterOptions(self, filterOptions, seismicPhase=None):
|
|
|
|
if seismicPhase is None:
|
|
|
|
self.getFilters()[self.getSeismicPhase()] = filterOptions
|
|
|
|
else:
|
|
|
|
self.getFilters()[seismicPhase] = filterOptions
|
|
|
|
|
2014-03-28 05:25:46 +01:00
|
|
|
def updateFilterOptions(self):
|
2014-10-27 12:04:01 +01:00
|
|
|
try:
|
2015-03-01 10:31:49 +01:00
|
|
|
settings = QSettings()
|
2015-06-11 10:07:21 +02:00
|
|
|
if settings.value("filterdefaults",
|
|
|
|
None) is None and not self.getFilters():
|
2015-09-25 15:06:59 +02:00
|
|
|
for key, value in FILTERDEFAULTS.items():
|
2015-03-01 10:31:49 +01:00
|
|
|
self.setFilterOptions(FilterOptions(**value), key)
|
|
|
|
elif settings.value("filterdefaults", None) is not None:
|
|
|
|
for key, value in settings.value("filterdefaults"):
|
|
|
|
self.setFilterOptions(FilterOptions(**value), key)
|
2015-09-25 15:06:59 +02:00
|
|
|
except Exception as e:
|
2016-09-02 14:21:59 +02:00
|
|
|
self.update_status('Error ...')
|
2014-11-28 11:15:49 +01:00
|
|
|
emsg = QErrorMessage(self)
|
|
|
|
emsg.showMessage('Error: {0}'.format(e))
|
2014-10-27 12:04:01 +01:00
|
|
|
else:
|
2016-09-02 14:21:59 +02:00
|
|
|
self.update_status('Filter loaded ... '
|
2015-06-11 10:07:21 +02:00
|
|
|
'[{0}: {1} Hz]'.format(
|
2016-03-30 07:00:31 +02:00
|
|
|
self.getFilterOptions().getFilterType(),
|
|
|
|
self.getFilterOptions().getFreq()))
|
2015-02-20 08:38:26 +01:00
|
|
|
if self.filterAction.isChecked():
|
|
|
|
self.filterWaveformData()
|
2014-03-28 22:26:15 +01:00
|
|
|
|
2014-11-13 11:27:52 +01:00
|
|
|
def getSeismicPhase(self):
|
|
|
|
return self.seismicPhase
|
|
|
|
|
2015-03-09 11:21:33 +01:00
|
|
|
def getStationName(self, wfID):
|
2015-04-02 18:48:06 +02:00
|
|
|
return self.getPlotWidget().getPlotDict()[wfID][0]
|
2015-03-09 11:21:33 +01:00
|
|
|
|
2014-11-28 11:15:49 +01:00
|
|
|
def alterPhase(self):
|
|
|
|
pass
|
|
|
|
|
2014-11-13 11:27:52 +01:00
|
|
|
def setSeismicPhase(self, phase):
|
2014-11-28 09:19:16 +01:00
|
|
|
self.seismicPhase = self.seismicPhaseButtonGroup.getValue()
|
2016-09-02 14:21:59 +02:00
|
|
|
self.update_status('Seismic phase changed to '
|
2015-02-23 14:46:18 +01:00
|
|
|
'{0}'.format(self.getSeismicPhase()))
|
2014-11-13 11:27:52 +01:00
|
|
|
|
2015-04-02 18:48:06 +02:00
|
|
|
def pickOnStation(self, gui_event):
|
2015-03-09 11:21:33 +01:00
|
|
|
|
2015-04-02 18:48:06 +02:00
|
|
|
wfID = self.getWFID(gui_event)
|
2015-03-09 11:21:33 +01:00
|
|
|
|
2016-06-10 09:01:37 +02:00
|
|
|
if wfID is None: return
|
2016-05-31 15:53:23 +02:00
|
|
|
|
2015-03-09 11:21:33 +01:00
|
|
|
station = self.getStationName(wfID)
|
2016-09-02 14:21:59 +02:00
|
|
|
self.update_status('picking on station {0}'.format(station))
|
|
|
|
data = self.get_data().getWFData()
|
2017-04-06 13:16:28 +02:00
|
|
|
pickDlg = PickDlg(self, infile=self.getinfile(),
|
|
|
|
data=data.select(station=station),
|
2015-07-07 11:02:46 +02:00
|
|
|
station=station,
|
2017-04-10 15:06:30 +02:00
|
|
|
picks=self.getPicksOnStation(station, 'manual'),
|
|
|
|
autopicks=self.getPicksOnStation(station, 'auto'))
|
2015-03-29 08:07:46 +02:00
|
|
|
if pickDlg.exec_():
|
2015-07-18 16:11:20 +02:00
|
|
|
self.setDirty(True)
|
2016-09-02 14:21:59 +02:00
|
|
|
self.update_status('picks accepted ({0})'.format(station))
|
2015-09-25 15:06:59 +02:00
|
|
|
replot = self.addPicks(station, pickDlg.getPicks())
|
|
|
|
if replot:
|
|
|
|
self.plotWaveformData()
|
|
|
|
self.drawPicks()
|
2016-05-31 17:27:59 +02:00
|
|
|
self.draw()
|
2015-09-25 15:06:59 +02:00
|
|
|
else:
|
|
|
|
self.drawPicks(station)
|
2016-05-31 17:27:59 +02:00
|
|
|
self.draw()
|
2015-03-29 08:07:46 +02:00
|
|
|
else:
|
2016-09-02 14:21:59 +02:00
|
|
|
self.update_status('picks discarded ({0})'.format(station))
|
|
|
|
if not self.get_loc_flag() and self.check4Loc():
|
2017-04-10 14:43:11 +02:00
|
|
|
self.locateEvent.setEnabled(True)
|
2016-09-02 14:21:59 +02:00
|
|
|
self.set_loc_flag(True)
|
|
|
|
elif self.get_loc_flag() and not self.check4Loc():
|
|
|
|
self.set_loc_flag(False)
|
2015-03-12 13:59:29 +01:00
|
|
|
|
2015-11-26 05:17:26 +01:00
|
|
|
def addListItem(self, text):
|
|
|
|
self.listWidget.addItem(text)
|
|
|
|
self.listWidget.scrollToBottom()
|
|
|
|
|
2015-07-09 11:37:03 +02:00
|
|
|
def autoPick(self):
|
2017-04-06 13:16:28 +02:00
|
|
|
self.autosave = QFileDialog().getExistingDirectory(caption='Select autoPyLoT output')
|
2017-04-10 09:50:53 +02:00
|
|
|
if not os.path.exists(self.autosave):
|
|
|
|
QMessageBox.warning(self, "PyLoT Warning",
|
|
|
|
"No autoPyLoT output declared!")
|
|
|
|
return
|
2015-11-26 05:17:26 +01:00
|
|
|
self.listWidget = QListWidget()
|
2015-07-18 16:11:20 +02:00
|
|
|
self.setDirty(True)
|
2015-11-30 09:55:33 +01:00
|
|
|
self.logDockWidget = QDockWidget("AutoPickLog", self)
|
|
|
|
self.logDockWidget.setObjectName("LogDockWidget")
|
2016-05-27 11:25:47 +02:00
|
|
|
self.logDockWidget.setAllowedAreas(
|
|
|
|
Qt.LeftDockWidgetArea | Qt.RightDockWidgetArea)
|
2015-11-30 09:55:33 +01:00
|
|
|
self.logDockWidget.setWidget(self.listWidget)
|
|
|
|
self.addDockWidget(Qt.LeftDockWidgetArea, self.logDockWidget)
|
2017-04-06 13:16:28 +02:00
|
|
|
self.addListItem('Loading default values from PyLoT-input file %s'
|
|
|
|
% self.infile)
|
|
|
|
autopick_parameter = self._inputs
|
2015-11-26 05:17:26 +01:00
|
|
|
self.addListItem(str(autopick_parameter))
|
2015-07-09 11:37:03 +02:00
|
|
|
|
2015-07-14 08:10:49 +02:00
|
|
|
self.thread = AutoPickThread(parent=self,
|
2017-04-06 13:16:28 +02:00
|
|
|
func=autoPyLoT,
|
|
|
|
infile = self.infile,
|
|
|
|
fnames=self.fnames,
|
|
|
|
savepath=self.autosave)
|
|
|
|
|
2015-11-26 05:17:26 +01:00
|
|
|
self.thread.message.connect(self.addListItem)
|
2015-07-09 11:37:03 +02:00
|
|
|
self.thread.start()
|
2015-12-01 05:03:55 +01:00
|
|
|
self.thread.finished.connect(self.finalizeAutoPick)
|
|
|
|
|
|
|
|
def finalizeAutoPick(self):
|
|
|
|
self.drawPicks(picktype='auto')
|
2016-05-31 17:27:59 +02:00
|
|
|
self.draw()
|
2015-12-01 05:03:55 +01:00
|
|
|
self.thread.quit()
|
2015-07-09 11:37:03 +02:00
|
|
|
|
2015-11-30 09:50:47 +01:00
|
|
|
def addPicks(self, station, picks, type='manual'):
|
|
|
|
stat_picks = self.getPicksOnStation(station, type)
|
2015-09-25 15:06:59 +02:00
|
|
|
rval = False
|
2015-07-07 10:37:54 +02:00
|
|
|
if not stat_picks:
|
|
|
|
stat_picks = picks
|
|
|
|
else:
|
|
|
|
msgBox = QMessageBox()
|
|
|
|
msgBox.setText("The picks for station {0} have been "
|
|
|
|
"changed.".format(station))
|
|
|
|
msgBox.setDetailedText("Old picks:\n"
|
2016-01-29 07:21:17 +01:00
|
|
|
"{old_picks}\n\n"
|
|
|
|
"New picks:\n"
|
|
|
|
"{new_picks}".format(old_picks=stat_picks,
|
|
|
|
new_picks=picks))
|
2015-07-07 10:37:54 +02:00
|
|
|
msgBox.setInformativeText("Do you want to save your changes?")
|
|
|
|
msgBox.setStandardButtons(QMessageBox.Save | QMessageBox.Cancel)
|
|
|
|
msgBox.setDefaultButton(QMessageBox.Save)
|
|
|
|
ret = msgBox.exec_()
|
|
|
|
if ret == QMessageBox.Save:
|
|
|
|
stat_picks = picks
|
2015-09-25 15:06:59 +02:00
|
|
|
rval = True
|
2015-07-07 10:37:54 +02:00
|
|
|
elif ret == QMessageBox.Cancel:
|
|
|
|
pass
|
|
|
|
else:
|
|
|
|
raise Exception('FATAL: Should never occur!')
|
2015-11-30 09:50:47 +01:00
|
|
|
self.getPicks(type=type)[station] = stat_picks
|
2015-09-25 15:06:59 +02:00
|
|
|
return rval
|
2015-07-07 10:37:54 +02:00
|
|
|
|
2016-03-29 10:30:45 +02:00
|
|
|
def updatePicks(self, type='manual'):
|
2016-09-02 14:21:59 +02:00
|
|
|
picks = picksdict_from_picks(evt=self.get_data(type).get_evt_data())
|
2016-03-29 10:30:45 +02:00
|
|
|
if type == 'manual':
|
2017-04-19 16:51:19 +02:00
|
|
|
self.getCurrentEvent().addPicks(picks)
|
2016-03-29 10:30:45 +02:00
|
|
|
self.picks.update(picks)
|
|
|
|
elif type == 'auto':
|
2017-04-19 16:51:19 +02:00
|
|
|
self.getCurrentEvent().addAutopicks(picks)
|
2016-03-29 10:30:45 +02:00
|
|
|
self.autopicks.update(picks)
|
2016-06-06 14:10:46 +02:00
|
|
|
self.check4Comparison()
|
2015-09-03 13:21:46 +02:00
|
|
|
|
2015-11-30 09:50:47 +01:00
|
|
|
def drawPicks(self, station=None, picktype='manual'):
|
2015-07-07 10:39:01 +02:00
|
|
|
# if picks to draw not specified, draw all picks available
|
|
|
|
if not station:
|
2015-11-30 09:50:47 +01:00
|
|
|
for station in self.getPicks(type=picktype):
|
|
|
|
self.drawPicks(station, picktype=picktype)
|
2015-07-07 10:39:01 +02:00
|
|
|
return
|
|
|
|
# plotting picks
|
|
|
|
plotID = self.getStationID(station)
|
2017-04-20 15:28:43 +02:00
|
|
|
if plotID is None:
|
2016-09-08 15:29:37 +02:00
|
|
|
return
|
2015-07-07 10:39:01 +02:00
|
|
|
ax = self.getPlotWidget().axes
|
|
|
|
ylims = np.array([-.5, +.5]) + plotID
|
2016-05-27 11:25:47 +02:00
|
|
|
phase_col = {
|
2017-04-10 15:06:30 +02:00
|
|
|
'P': ('c', 'c--', 'b-', 'bv', 'b^', 'b'),
|
|
|
|
'S': ('m', 'm--', 'r-', 'rv', 'r^', 'r')
|
2016-05-27 11:25:47 +02:00
|
|
|
}
|
2015-07-07 10:39:01 +02:00
|
|
|
|
2015-11-30 09:50:47 +01:00
|
|
|
stat_picks = self.getPicks(type=picktype)[station]
|
2015-07-07 10:39:01 +02:00
|
|
|
|
2016-05-31 17:27:59 +02:00
|
|
|
stime = self.getStime()
|
|
|
|
|
2015-07-07 10:39:01 +02:00
|
|
|
for phase in stat_picks:
|
|
|
|
picks = stat_picks[phase]
|
2015-11-30 09:50:47 +01:00
|
|
|
if type(stat_picks[phase]) is not dict:
|
|
|
|
return
|
2015-07-07 10:39:01 +02:00
|
|
|
colors = phase_col[phase[0].upper()]
|
|
|
|
|
2015-07-13 06:39:25 +02:00
|
|
|
mpp = picks['mpp'] - stime
|
|
|
|
epp = picks['epp'] - stime
|
|
|
|
lpp = picks['lpp'] - stime
|
2015-07-07 10:39:01 +02:00
|
|
|
spe = picks['spe']
|
2016-09-21 14:12:58 +02:00
|
|
|
if not spe:
|
|
|
|
spe = symmetrize_error(mpp - epp, lpp - mpp)
|
2015-07-07 10:39:01 +02:00
|
|
|
|
2015-11-30 09:50:47 +01:00
|
|
|
if picktype == 'manual':
|
|
|
|
ax.fill_between([epp, lpp], ylims[0], ylims[1],
|
2017-04-10 15:06:30 +02:00
|
|
|
alpha=.25, color=colors[0])
|
2015-11-30 09:50:47 +01:00
|
|
|
ax.plot([mpp - spe, mpp - spe], ylims, colors[1],
|
|
|
|
[mpp, mpp], ylims, colors[2],
|
|
|
|
[mpp + spe, mpp + spe], ylims, colors[1])
|
|
|
|
elif picktype == 'auto':
|
|
|
|
ax.plot(mpp, ylims[1], colors[3],
|
|
|
|
mpp, ylims[0], colors[4])
|
2017-04-12 12:14:01 +02:00
|
|
|
ax.vlines(mpp, ylims[0], ylims[1], colors[5], linestyles='dotted')
|
2015-11-30 09:50:47 +01:00
|
|
|
else:
|
2017-04-10 15:06:30 +02:00
|
|
|
raise TypeError('Unknown picktype {0}'.format(picktype))
|
2015-07-07 10:39:01 +02:00
|
|
|
|
2016-08-31 12:16:48 +02:00
|
|
|
def locate_event(self):
|
2016-08-25 21:32:41 +02:00
|
|
|
"""
|
|
|
|
locate event using the manually picked phases
|
|
|
|
:return:
|
|
|
|
"""
|
|
|
|
if not self.okToContinue():
|
|
|
|
return
|
2015-11-13 14:05:29 +01:00
|
|
|
settings = QSettings()
|
2016-08-25 13:31:51 +02:00
|
|
|
# get location tool hook
|
2015-11-13 14:05:29 +01:00
|
|
|
loctool = settings.value("loc/tool", "nll")
|
2016-08-25 13:31:51 +02:00
|
|
|
lt = locateTool[loctool]
|
|
|
|
# get working directory
|
|
|
|
locroot = settings.value("{0}/rootPath".format(loctool), None)
|
2016-08-26 10:48:16 +02:00
|
|
|
if locroot is None:
|
|
|
|
self.PyLoTprefs()
|
2016-08-31 12:16:48 +02:00
|
|
|
self.locate_event()
|
2016-08-26 14:36:33 +02:00
|
|
|
|
2016-08-25 13:31:51 +02:00
|
|
|
infile = settings.value("{0}/inputFile".format(loctool), None)
|
2016-08-26 14:36:33 +02:00
|
|
|
|
|
|
|
if not infile:
|
|
|
|
caption = 'Select {0} input file'.format(loctool)
|
|
|
|
filt = "Supported file formats" \
|
|
|
|
" (*.in *.ini *.conf *.cfg)"
|
|
|
|
ans = QFileDialog().getOpenFileName(self, caption=caption,
|
|
|
|
filter=filt, dir=locroot)
|
2016-09-08 15:28:40 +02:00
|
|
|
if ans[0]:
|
|
|
|
infile = ans[0]
|
|
|
|
else:
|
|
|
|
QMessageBox.information(self,
|
|
|
|
self.tr('No infile selected'),
|
|
|
|
self.tr('Inputfile necessary for localization.'))
|
|
|
|
return
|
2016-08-26 14:36:33 +02:00
|
|
|
settings.setValue("{0}/inputFile".format(loctool), infile)
|
|
|
|
settings.sync()
|
2016-08-29 15:52:58 +02:00
|
|
|
if loctool == 'nll':
|
|
|
|
ttt = settings.value("{0}/travelTimeTables", None)
|
|
|
|
ok = False
|
|
|
|
if ttt is None:
|
|
|
|
while not ok:
|
|
|
|
text, ok = QInputDialog.getText(self, 'Pattern for travel time tables',
|
|
|
|
'Base name of travel time tables',
|
|
|
|
echo=QLineEdit.Normal,
|
|
|
|
text="ttime")
|
|
|
|
ttt = text
|
|
|
|
|
|
|
|
outfile = settings.value("{0}/outputFile".format(loctool),
|
|
|
|
os.path.split(os.tempnam())[-1])
|
2016-08-26 14:36:33 +02:00
|
|
|
phasefile = os.path.split(os.tempnam())[-1]
|
|
|
|
phasepath = os.path.join(locroot, 'obs', phasefile)
|
2016-08-25 21:32:41 +02:00
|
|
|
locpath = os.path.join(locroot, 'loc', outfile)
|
|
|
|
lt.export(self.getPicks(), phasepath)
|
2016-08-29 15:52:58 +02:00
|
|
|
lt.modify_inputs(infile, locroot, outfile, phasefile, ttt)
|
2016-08-25 21:32:41 +02:00
|
|
|
try:
|
|
|
|
lt.locate(infile)
|
|
|
|
except RuntimeError as e:
|
|
|
|
print(e.message)
|
|
|
|
finally:
|
|
|
|
os.remove(phasepath)
|
|
|
|
|
2016-09-02 14:21:59 +02:00
|
|
|
self.get_data().applyEVTData(lt.read_location(locpath), type='event')
|
2016-09-29 12:08:59 +02:00
|
|
|
self.get_data().applyEVTData(self.calc_magnitude(), type='event')
|
2016-09-02 14:21:59 +02:00
|
|
|
|
2017-04-19 15:31:08 +02:00
|
|
|
def init_array_tab(self):
|
2017-04-20 12:05:34 +02:00
|
|
|
self.metadata_widget = QWidget(self)
|
2017-04-19 15:31:08 +02:00
|
|
|
grid_layout = QGridLayout()
|
|
|
|
grid_layout.setColumnStretch(0, 1)
|
|
|
|
grid_layout.setColumnStretch(2, 1)
|
|
|
|
grid_layout.setRowStretch(0, 1)
|
|
|
|
grid_layout.setRowStretch(3, 1)
|
|
|
|
|
|
|
|
label = QLabel('No inventory set...')
|
|
|
|
new_inv_button = QPushButton('Set &inventory file')
|
|
|
|
new_inv_button.clicked.connect(self.get_metadata)
|
|
|
|
|
|
|
|
grid_layout.addWidget(label, 1, 1)
|
|
|
|
grid_layout.addWidget(new_inv_button, 2, 1)
|
|
|
|
|
2017-04-20 12:05:34 +02:00
|
|
|
self.metadata_widget.setLayout(grid_layout)
|
|
|
|
self.array_layout.addWidget(self.metadata_widget)
|
2017-04-19 15:31:08 +02:00
|
|
|
|
2017-04-19 16:05:45 +02:00
|
|
|
def init_array_map(self, index=1):
|
2017-05-03 11:28:43 +02:00
|
|
|
self.tabs.setCurrentIndex(1)
|
|
|
|
self.array_layout.removeWidget(self.metadata_widget)
|
|
|
|
self.array_layout.removeWidget(self.array_map)
|
2017-04-12 16:43:29 +02:00
|
|
|
if not self.array_map:
|
|
|
|
self.get_metadata()
|
|
|
|
if not self.metadata:
|
|
|
|
return
|
2017-04-19 16:05:45 +02:00
|
|
|
self.array_map = map_projection(self)
|
2017-04-20 12:05:34 +02:00
|
|
|
self.array_layout.addWidget(self.array_map)
|
2017-04-19 16:05:45 +02:00
|
|
|
self.tabs.setCurrentIndex(index)
|
2017-04-20 17:06:36 +02:00
|
|
|
self.refresh_array_map()
|
2017-04-18 17:17:46 +02:00
|
|
|
|
2017-04-19 15:31:08 +02:00
|
|
|
def refresh_array_map(self):
|
2017-04-18 17:17:46 +02:00
|
|
|
if not self.array_map:
|
|
|
|
return
|
2017-04-19 15:31:08 +02:00
|
|
|
# refresh with new picks here!!!
|
2017-04-20 17:06:36 +02:00
|
|
|
self.array_map.refresh_drawings(self.picks)
|
|
|
|
self._eventChanged[1] = False
|
2017-04-19 15:31:08 +02:00
|
|
|
|
2017-04-20 12:05:34 +02:00
|
|
|
def init_event_table(self, index=2):
|
|
|
|
def set_enabled(item, enabled=True, checkable=False):
|
|
|
|
if enabled and not checkable:
|
|
|
|
item.setFlags(QtCore.Qt.ItemIsEnabled | QtCore.Qt.ItemIsSelectable)
|
|
|
|
elif enabled and checkable:
|
2017-04-21 15:46:57 +02:00
|
|
|
item.setFlags(QtCore.Qt.ItemIsEnabled | QtCore.Qt.ItemIsUserCheckable | QtCore.Qt.ItemIsSelectable)
|
2017-04-20 12:05:34 +02:00
|
|
|
else:
|
|
|
|
item.setFlags(QtCore.Qt.ItemIsSelectable)
|
|
|
|
|
|
|
|
if self.project:
|
|
|
|
eventlist = self.project.eventlist
|
|
|
|
else:
|
|
|
|
eventlist = []
|
|
|
|
|
|
|
|
def cell_changed(row=None, column=None):
|
|
|
|
table = self.project._table
|
|
|
|
event = self.project.getEventFromPath(table[row][0].text())
|
2017-04-21 15:46:57 +02:00
|
|
|
if column == 3 or column == 4:
|
2017-04-20 12:05:34 +02:00
|
|
|
#toggle checked states (exclusive)
|
2017-04-21 15:46:57 +02:00
|
|
|
item_ref = table[row][3]
|
|
|
|
item_test = table[row][4]
|
|
|
|
if column == 3 and item_ref.checkState():
|
2017-04-20 12:05:34 +02:00
|
|
|
item_test.setCheckState(QtCore.Qt.Unchecked)
|
|
|
|
event.setRefEvent(True)
|
2017-04-21 15:46:57 +02:00
|
|
|
elif column == 3 and not item_ref.checkState():
|
2017-04-20 12:05:34 +02:00
|
|
|
event.setRefEvent(False)
|
2017-04-21 15:46:57 +02:00
|
|
|
elif column == 4 and item_test.checkState():
|
2017-04-20 12:05:34 +02:00
|
|
|
item_ref.setCheckState(QtCore.Qt.Unchecked)
|
|
|
|
event.setTestEvent(True)
|
2017-04-21 15:46:57 +02:00
|
|
|
elif column == 4 and not item_test.checkState():
|
2017-04-20 14:03:26 +02:00
|
|
|
event.setTestEvent(False)
|
|
|
|
self.fill_eventbox()
|
2017-04-21 15:46:57 +02:00
|
|
|
elif column == 5:
|
2017-04-20 12:05:34 +02:00
|
|
|
#update event notes
|
2017-04-21 15:46:57 +02:00
|
|
|
notes = table[row][5].text()
|
2017-04-20 12:05:34 +02:00
|
|
|
event.addNotes(notes)
|
2017-04-21 15:46:57 +02:00
|
|
|
self.fill_eventbox()
|
2017-04-20 12:05:34 +02:00
|
|
|
|
|
|
|
if hasattr(self, 'qtl'):
|
|
|
|
self.events_layout.removeWidget(self.qtl)
|
|
|
|
self.qtl = QtGui.QTableWidget()
|
2017-04-21 15:46:57 +02:00
|
|
|
self.qtl.setColumnCount(6)
|
2017-04-20 12:05:34 +02:00
|
|
|
self.qtl.setRowCount(len(eventlist))
|
2017-04-21 15:46:57 +02:00
|
|
|
self.qtl.setHorizontalHeaderLabels(['Event', '[N] MP',
|
2017-05-03 15:38:54 +02:00
|
|
|
'[N] AP', 'Tuning Set',
|
2017-04-21 15:46:57 +02:00
|
|
|
'Test Set', 'Notes'])
|
2017-04-20 12:05:34 +02:00
|
|
|
|
|
|
|
self.project._table = []
|
|
|
|
for index, event in enumerate(eventlist):
|
2017-04-21 15:46:57 +02:00
|
|
|
event_npicks = 0
|
|
|
|
event_nautopicks = 0
|
|
|
|
if event.picks:
|
|
|
|
event_npicks = len(event.picks)
|
|
|
|
if event.autopicks:
|
|
|
|
event_nautopicks = len(event.autopicks)
|
2017-04-20 12:05:34 +02:00
|
|
|
item_path = QtGui.QTableWidgetItem()
|
2017-04-21 15:46:57 +02:00
|
|
|
item_nmp = QtGui.QTableWidgetItem(str(event_npicks))
|
|
|
|
item_nmp.setIcon(self.manupicksicon_small)
|
|
|
|
item_nap = QtGui.QTableWidgetItem(str(event_nautopicks))
|
|
|
|
item_nap.setIcon(self.autopicksicon_small)
|
2017-04-20 12:05:34 +02:00
|
|
|
item_ref = QtGui.QTableWidgetItem()
|
|
|
|
item_test = QtGui.QTableWidgetItem()
|
2017-04-20 14:03:26 +02:00
|
|
|
item_notes = QtGui.QTableWidgetItem()
|
2017-04-21 15:46:57 +02:00
|
|
|
|
|
|
|
item_ref.setBackground(QtGui.QColor(200, 210, 230, 255))
|
|
|
|
item_test.setBackground(QtGui.QColor(200, 230, 200, 255))
|
2017-04-20 12:05:34 +02:00
|
|
|
item_path.setText(event.path)
|
|
|
|
item_notes.setText(event.notes)
|
2017-04-21 15:46:57 +02:00
|
|
|
set_enabled(item_path, True, False)
|
|
|
|
set_enabled(item_nmp, True, False)
|
|
|
|
set_enabled(item_nap, True, False)
|
2017-04-20 12:05:34 +02:00
|
|
|
if event.picks:
|
|
|
|
set_enabled(item_ref, True, True)
|
|
|
|
set_enabled(item_test, True, True)
|
|
|
|
else:
|
|
|
|
set_enabled(item_ref, False, True)
|
|
|
|
set_enabled(item_test, False, True)
|
|
|
|
|
|
|
|
if event.isRefEvent():
|
|
|
|
item_ref.setCheckState(QtCore.Qt.Checked)
|
|
|
|
else:
|
|
|
|
item_ref.setCheckState(QtCore.Qt.Unchecked)
|
|
|
|
if event.isTestEvent():
|
|
|
|
item_test.setCheckState(QtCore.Qt.Checked)
|
|
|
|
else:
|
|
|
|
item_test.setCheckState(QtCore.Qt.Unchecked)
|
|
|
|
|
2017-04-21 15:46:57 +02:00
|
|
|
column=[item_path, item_nmp, item_nap, item_ref, item_test, item_notes]
|
2017-04-20 12:05:34 +02:00
|
|
|
self.project._table.append(column)
|
|
|
|
|
|
|
|
for r_index, row in enumerate(self.project._table):
|
|
|
|
for c_index, item in enumerate(row):
|
|
|
|
self.qtl.setItem(r_index, c_index, item)
|
|
|
|
|
|
|
|
header = self.qtl.horizontalHeader()
|
|
|
|
header.setResizeMode(QtGui.QHeaderView.ResizeToContents)
|
|
|
|
header.setStretchLastSection(True)
|
|
|
|
self.qtl.cellChanged[int, int].connect(cell_changed)
|
2017-04-20 14:03:26 +02:00
|
|
|
|
2017-04-20 12:05:34 +02:00
|
|
|
self.events_layout.addWidget(self.qtl)
|
|
|
|
self.tabs.setCurrentIndex(index)
|
|
|
|
|
2017-04-19 15:31:08 +02:00
|
|
|
def read_metadata_thread(self, fninv):
|
|
|
|
self.rm_thread = Thread(self, read_metadata, arg=fninv, progressText='Reading metadata...')
|
|
|
|
self.rm_thread.finished.connect(self.set_metadata)
|
|
|
|
self.rm_thread.start()
|
|
|
|
|
|
|
|
def set_metadata(self):
|
|
|
|
self.metadata = self.rm_thread.data
|
2017-04-19 16:05:45 +02:00
|
|
|
self.project.metadata = self.rm_thread.data
|
2017-04-19 15:31:08 +02:00
|
|
|
self.init_array_map()
|
2017-04-12 16:43:29 +02:00
|
|
|
|
|
|
|
def get_metadata(self):
|
2016-09-28 14:37:24 +02:00
|
|
|
def set_inv(settings):
|
2016-09-23 15:12:04 +02:00
|
|
|
fninv, _ = QFileDialog.getOpenFileName(self, self.tr(
|
|
|
|
"Select inventory..."), self.tr("Select file"))
|
2016-09-28 14:37:24 +02:00
|
|
|
if not fninv:
|
|
|
|
return False
|
2016-09-23 15:12:04 +02:00
|
|
|
ans = QMessageBox.question(self, self.tr("Make default..."),
|
|
|
|
self.tr(
|
|
|
|
"New inventory filename set.\n" + \
|
|
|
|
"Do you want to make it the default value?"),
|
|
|
|
QMessageBox.Yes | QMessageBox.No,
|
|
|
|
QMessageBox.No)
|
|
|
|
if ans == QMessageBox.Yes:
|
|
|
|
settings.setValue("inventoryFile", fninv)
|
|
|
|
settings.sync()
|
2017-04-19 15:31:08 +02:00
|
|
|
self.read_metadata_thread(fninv)
|
2016-09-28 14:37:24 +02:00
|
|
|
return True
|
2017-04-19 16:05:45 +02:00
|
|
|
|
|
|
|
if hasattr(self.project, 'metadata'):
|
|
|
|
self.metadata = self.project.metadata
|
|
|
|
return True
|
2016-09-28 14:37:24 +02:00
|
|
|
|
2016-09-02 14:21:59 +02:00
|
|
|
settings = QSettings()
|
2016-09-28 14:37:24 +02:00
|
|
|
fninv = settings.value("inventoryFile", None)
|
|
|
|
|
|
|
|
if fninv is None and not self.metadata:
|
|
|
|
if not set_inv(settings):
|
|
|
|
return None
|
|
|
|
elif fninv is not None and not self.metadata:
|
|
|
|
ans = QMessageBox.question(self, self.tr("Use default..."),
|
|
|
|
self.tr(
|
|
|
|
"Do you want to use the default value?"),
|
|
|
|
QMessageBox.Yes | QMessageBox.No,
|
|
|
|
QMessageBox.Yes)
|
|
|
|
if ans == QMessageBox.No:
|
|
|
|
if not set_inv(settings):
|
|
|
|
return None
|
|
|
|
else:
|
2017-04-19 15:31:08 +02:00
|
|
|
self.read_metadata_thread(fninv)
|
2017-04-12 16:43:29 +02:00
|
|
|
|
|
|
|
def calc_magnitude(self, type='ML'):
|
|
|
|
self.get_metadata()
|
|
|
|
if not self.metadata:
|
|
|
|
return None
|
|
|
|
|
2016-09-27 15:15:53 +02:00
|
|
|
wf_copy = self.get_data().getWFData().copy()
|
2017-04-06 15:37:54 +02:00
|
|
|
corr_wf = restitute_data(wf_copy, *self.metadata)
|
|
|
|
# if not rest_flag:
|
|
|
|
# raise ProcessingError('Restitution of waveform data failed!')
|
2016-09-22 11:39:07 +02:00
|
|
|
if type == 'ML':
|
2016-09-28 14:37:24 +02:00
|
|
|
local_mag = RichterMagnitude(corr_wf, self.get_data().get_evt_data(), self.inputs.get('sstop'), verbosity = True)
|
2016-09-29 12:08:59 +02:00
|
|
|
return local_mag.updated_event()
|
2016-09-22 11:39:07 +02:00
|
|
|
elif type == 'Mw':
|
2016-09-28 14:37:24 +02:00
|
|
|
moment_mag = MomentMagnitude(corr_wf, self.get_data().get_evt_data(), self.inputs.get('vp'), self.inputs.get('Qp'), self.inputs.get('rho'), verbosity = True)
|
2016-09-29 12:08:59 +02:00
|
|
|
return moment_mag.updated_event()
|
2016-09-02 14:21:59 +02:00
|
|
|
else:
|
|
|
|
return None
|
2014-12-08 10:26:14 +01:00
|
|
|
|
2015-11-06 08:20:08 +01:00
|
|
|
def check4Loc(self):
|
2017-04-10 14:43:11 +02:00
|
|
|
return self.picksNum() >= 4
|
2015-11-06 08:20:08 +01:00
|
|
|
|
2016-06-06 14:10:46 +02:00
|
|
|
def check4Comparison(self):
|
|
|
|
mpicks = self.getPicks()
|
|
|
|
apicks = self.getPicks('auto')
|
|
|
|
for station, phases in mpicks.items():
|
|
|
|
try:
|
|
|
|
aphases = apicks[station]
|
|
|
|
for phase in phases.keys():
|
|
|
|
if phase in aphases.keys():
|
|
|
|
return True
|
|
|
|
except KeyError:
|
|
|
|
continue
|
|
|
|
return False
|
|
|
|
|
|
|
|
def picksNum(self, type='manual'):
|
2015-11-06 08:20:08 +01:00
|
|
|
num = 0
|
2016-06-06 14:10:46 +02:00
|
|
|
for phases in self.getPicks(type).values():
|
2015-11-06 08:20:08 +01:00
|
|
|
num += len(phases)
|
|
|
|
return num
|
|
|
|
|
2016-09-02 14:21:59 +02:00
|
|
|
def get_loc_flag(self):
|
2015-11-06 15:40:21 +01:00
|
|
|
return self.loc
|
|
|
|
|
2016-09-02 14:21:59 +02:00
|
|
|
def set_loc_flag(self, value):
|
2015-11-06 15:40:21 +01:00
|
|
|
self.loc = value
|
2015-11-06 08:20:08 +01:00
|
|
|
|
2016-09-02 14:21:59 +02:00
|
|
|
def check_loc_plt(self):
|
|
|
|
evt = self.get_data().get_evt_data()
|
|
|
|
if evt.origins and evt.magnitudes:
|
|
|
|
return True
|
|
|
|
return False
|
|
|
|
|
|
|
|
def update_status(self, message, duration=5000):
|
2015-11-09 08:53:26 +01:00
|
|
|
self.statusBar().showMessage(message, duration)
|
2016-09-02 14:21:59 +02:00
|
|
|
if self.get_data() is not None:
|
|
|
|
if not self.get_data().isNew():
|
2015-11-09 08:53:26 +01:00
|
|
|
self.setWindowTitle(
|
2016-09-02 14:21:59 +02:00
|
|
|
"PyLoT - processing event %s[*]" % self.get_data().getID())
|
|
|
|
elif self.get_data().isNew():
|
2017-04-18 16:24:26 +02:00
|
|
|
self.setWindowTitle("PyLoT - New project [*]")
|
2015-11-09 08:53:26 +01:00
|
|
|
else:
|
|
|
|
self.setWindowTitle(
|
2016-03-30 07:00:31 +02:00
|
|
|
"PyLoT - seismic processing the python way[*]")
|
2015-11-09 08:53:26 +01:00
|
|
|
self.setWindowModified(self.dirty)
|
|
|
|
|
2016-09-02 14:21:59 +02:00
|
|
|
def tutor_user(self):
|
|
|
|
self.update_status('select trace to pick on station ...', 10000)
|
2015-07-07 10:45:42 +02:00
|
|
|
|
2016-09-02 14:21:59 +02:00
|
|
|
def show_event_information(self):
|
2014-11-28 11:15:49 +01:00
|
|
|
pass
|
|
|
|
|
2015-01-22 16:41:52 +01:00
|
|
|
def createNewEvent(self):
|
|
|
|
if self.okToContinue():
|
|
|
|
new = NewEventDlg()
|
2015-01-23 10:21:34 +01:00
|
|
|
if new.exec_() != QDialog.Rejected:
|
2015-01-22 16:41:52 +01:00
|
|
|
evtpar = new.getValues()
|
2016-05-20 14:46:10 +02:00
|
|
|
cinfo = create_creation_info(agency_id=self.agency)
|
|
|
|
event = create_event(evtpar['origintime'], cinfo)
|
2015-06-11 10:12:50 +02:00
|
|
|
self.data = Data(self, evtdata=event)
|
2015-07-18 16:11:20 +02:00
|
|
|
self.setDirty(True)
|
2015-01-22 16:41:52 +01:00
|
|
|
|
2017-04-18 16:24:26 +02:00
|
|
|
def createNewProject(self, exists=False):
|
|
|
|
if self.okToContinue():
|
|
|
|
dlg = QFileDialog()
|
|
|
|
fnm = dlg.getSaveFileName(self, 'Create a new project file...', filter='Pylot project (*.plp)')
|
|
|
|
filename = fnm[0]
|
2017-04-20 17:06:36 +02:00
|
|
|
if not len(fnm[0]):
|
|
|
|
return
|
2017-04-18 16:24:26 +02:00
|
|
|
if not filename.split('.')[-1] == 'plp':
|
|
|
|
filename = fnm[0] + '.plp'
|
|
|
|
if not exists:
|
|
|
|
self.project = Project()
|
2017-04-19 15:31:08 +02:00
|
|
|
self.init_events(new=True)
|
2017-04-18 16:24:26 +02:00
|
|
|
self.project.save(filename)
|
2017-04-20 17:06:36 +02:00
|
|
|
return True
|
2017-04-19 15:31:08 +02:00
|
|
|
|
2017-04-18 16:24:26 +02:00
|
|
|
def loadProject(self):
|
|
|
|
if self.project:
|
|
|
|
if self.project.dirty:
|
|
|
|
qmb = QMessageBox(icon=QMessageBox.Question, text='Save changes in current project?')
|
|
|
|
qmb.setStandardButtons(QMessageBox.Yes | QMessageBox.No | QMessageBox.Cancel)
|
|
|
|
qmb.setDefaultButton(QMessageBox.Yes)
|
2017-05-03 11:28:43 +02:00
|
|
|
answer = qmb.exec_()
|
|
|
|
if answer == 16384:
|
2017-04-18 16:24:26 +02:00
|
|
|
self.saveProject()
|
2017-05-03 11:28:43 +02:00
|
|
|
elif answer == 65536:
|
2017-04-18 16:24:26 +02:00
|
|
|
pass
|
2017-05-03 11:28:43 +02:00
|
|
|
elif answer == 4194304:
|
2017-04-18 16:24:26 +02:00
|
|
|
return
|
|
|
|
dlg = QFileDialog()
|
|
|
|
fnm = dlg.getOpenFileName(self, 'Open project file...', filter='Pylot project (*.plp)')
|
|
|
|
if fnm[0]:
|
|
|
|
self.project = Project.load(fnm[0])
|
|
|
|
self.init_events(new=True)
|
2017-04-19 16:05:45 +02:00
|
|
|
if hasattr(self.project, 'metadata'):
|
|
|
|
self.init_array_map(index=0)
|
2017-04-18 16:24:26 +02:00
|
|
|
|
|
|
|
def saveProject(self):
|
|
|
|
if self.project:
|
2017-04-19 16:05:45 +02:00
|
|
|
if not self.project.location:
|
2017-04-20 17:06:36 +02:00
|
|
|
if not self.createNewProject(exists=True):
|
|
|
|
return
|
2017-04-19 16:05:45 +02:00
|
|
|
else:
|
|
|
|
self.project.save()
|
2017-04-18 16:24:26 +02:00
|
|
|
if not self.project.dirty:
|
|
|
|
qmb = QMessageBox(icon=QMessageBox.Information, text='Saved back project to file:\n{}'.format(self.project.location))
|
|
|
|
qmb.exec_()
|
|
|
|
return
|
|
|
|
else:
|
|
|
|
# if still dirty because saving failed
|
|
|
|
qmb = QMessageBox(icon=QMessageBox.Warning, text='Could not save back to original file.\n'
|
|
|
|
'Choose new file')
|
|
|
|
qmb.setStandardButtons(QMessageBox.Ok)
|
|
|
|
qmb.exec_()
|
|
|
|
self.createNewProject(exists=True)
|
|
|
|
|
2015-07-07 10:39:01 +02:00
|
|
|
def draw(self):
|
2017-04-20 14:54:57 +02:00
|
|
|
self.fill_eventbox()
|
2015-07-07 10:39:01 +02:00
|
|
|
self.getPlotWidget().draw()
|
|
|
|
|
2015-07-18 16:11:20 +02:00
|
|
|
def setDirty(self, value):
|
|
|
|
self.dirty = value
|
|
|
|
|
2014-12-08 10:26:14 +01:00
|
|
|
def closeEvent(self, event):
|
|
|
|
if self.okToContinue():
|
|
|
|
self.closing.emit()
|
|
|
|
QMainWindow.closeEvent(self, event)
|
2014-11-28 11:15:49 +01:00
|
|
|
|
2014-12-17 06:33:34 +01:00
|
|
|
def PyLoTprefs(self):
|
2017-04-06 13:16:28 +02:00
|
|
|
props = PropertiesDlg(self, infile=self.getinfile())
|
2014-12-17 06:33:34 +01:00
|
|
|
if props.exec_():
|
|
|
|
return
|
|
|
|
|
2014-03-28 22:26:15 +01:00
|
|
|
def helpHelp(self):
|
2014-06-11 15:19:37 +02:00
|
|
|
if checkurl():
|
2015-01-29 08:53:01 +01:00
|
|
|
form = HelpForm(
|
2016-03-30 07:00:31 +02:00
|
|
|
'https://ariadne.geophysik.ruhr-uni-bochum.de/trac/PyLoT/wiki')
|
2014-06-11 15:19:37 +02:00
|
|
|
else:
|
|
|
|
form = HelpForm(':/help.html')
|
|
|
|
form.show()
|
2014-03-28 22:26:15 +01:00
|
|
|
|
2014-01-10 05:45:03 +01:00
|
|
|
|
2017-04-18 16:24:26 +02:00
|
|
|
class Project(object):
|
|
|
|
'''
|
|
|
|
Pickable class containing information of a QtPyLoT project, like event lists and file locations.
|
|
|
|
'''
|
|
|
|
def __init__(self):
|
|
|
|
self.eventlist = []
|
|
|
|
self.location = None
|
|
|
|
self.dirty = False
|
2017-04-20 12:05:34 +02:00
|
|
|
self._table = None
|
2017-04-18 16:24:26 +02:00
|
|
|
|
|
|
|
def add_eventlist(self, eventlist):
|
|
|
|
if len(eventlist) == 0:
|
|
|
|
return
|
|
|
|
for item in eventlist:
|
2017-04-19 16:51:19 +02:00
|
|
|
event = Event(item)
|
|
|
|
if not event in self.eventlist:
|
|
|
|
self.eventlist.append(event)
|
2017-04-18 16:24:26 +02:00
|
|
|
self.setDirty()
|
|
|
|
|
|
|
|
def setDirty(self):
|
|
|
|
self.dirty = True
|
|
|
|
|
|
|
|
def setClean(self):
|
|
|
|
self.dirty = False
|
|
|
|
|
2017-04-20 12:05:34 +02:00
|
|
|
def getEventFromPath(self, path):
|
|
|
|
for event in self.eventlist:
|
|
|
|
if event.path == path:
|
|
|
|
return event
|
|
|
|
|
2017-04-18 16:24:26 +02:00
|
|
|
def save(self, filename=None):
|
|
|
|
'''
|
|
|
|
Save PyLoT Project to a file.
|
|
|
|
Can be loaded by using project.load(filename).
|
|
|
|
'''
|
|
|
|
try:
|
|
|
|
import cPickle
|
|
|
|
except ImportError:
|
|
|
|
import _pickle as cPickle
|
|
|
|
|
|
|
|
if filename:
|
|
|
|
self.location = filename
|
|
|
|
else:
|
|
|
|
filename = self.location
|
|
|
|
|
|
|
|
try:
|
|
|
|
outfile = open(filename, 'wb')
|
|
|
|
cPickle.dump(self, outfile, -1)
|
|
|
|
self.setClean()
|
|
|
|
except Exception as e:
|
|
|
|
print('Could not pickle PyLoT project. Reason: {}'.format(e))
|
|
|
|
self.setDirty()
|
|
|
|
|
|
|
|
@staticmethod
|
|
|
|
def load(filename):
|
|
|
|
try:
|
|
|
|
import cPickle
|
|
|
|
except ImportError:
|
|
|
|
import _pickle as cPickle
|
|
|
|
infile = open(filename, 'rb')
|
|
|
|
project = cPickle.load(infile)
|
|
|
|
print('Loaded %s' % filename)
|
|
|
|
return project
|
|
|
|
|
|
|
|
|
2017-04-19 16:51:19 +02:00
|
|
|
class Event(object):
|
2017-04-18 16:24:26 +02:00
|
|
|
'''
|
|
|
|
Pickable class containing information on a single event.
|
|
|
|
'''
|
2017-04-19 16:51:19 +02:00
|
|
|
def __init__(self, path):
|
|
|
|
self.path = path
|
2017-04-19 15:31:08 +02:00
|
|
|
self.autopicks = None
|
|
|
|
self.picks = None
|
2017-04-20 12:05:34 +02:00
|
|
|
self.notes = None
|
|
|
|
self._testEvent = False
|
|
|
|
self._refEvent = False
|
2017-04-19 15:31:08 +02:00
|
|
|
|
|
|
|
def addPicks(self, picks):
|
|
|
|
self.picks = picks
|
|
|
|
|
|
|
|
def addAutopicks(self, autopicks):
|
|
|
|
self.autopicks = autopicks
|
2017-04-20 12:05:34 +02:00
|
|
|
|
|
|
|
def addNotes(self, notes):
|
|
|
|
self.notes = notes
|
|
|
|
|
|
|
|
def clearNotes(self):
|
|
|
|
self.notes = None
|
|
|
|
|
|
|
|
def isRefEvent(self):
|
|
|
|
return self._refEvent
|
|
|
|
|
|
|
|
def isTestEvent(self):
|
|
|
|
return self._testEvent
|
|
|
|
|
|
|
|
def setRefEvent(self, bool):
|
|
|
|
self._refEvent = bool
|
|
|
|
if bool: self._testEvent = False
|
|
|
|
|
|
|
|
def setTestEvent(self, bool):
|
|
|
|
self._testEvent = bool
|
|
|
|
if bool: self._refEvent = False
|
2017-04-18 16:24:26 +02:00
|
|
|
|
|
|
|
|
|
|
|
class getExistingDirectories(QFileDialog):
|
|
|
|
def __init__(self, *args):
|
|
|
|
super(getExistingDirectories, self).__init__(*args)
|
|
|
|
self.setOption(self.DontUseNativeDialog, True)
|
2017-05-02 12:13:55 +02:00
|
|
|
self.setOption(self.ReadOnly, True)
|
2017-04-18 16:24:26 +02:00
|
|
|
self.setFileMode(self.Directory)
|
|
|
|
self.setOption(self.ShowDirsOnly, True)
|
|
|
|
self.findChildren(QListView)[0].setSelectionMode(QAbstractItemView.ExtendedSelection)
|
|
|
|
self.findChildren(QTreeView)[0].setSelectionMode(QAbstractItemView.ExtendedSelection)
|
|
|
|
|
|
|
|
|
2017-04-10 13:32:53 +02:00
|
|
|
def create_window():
|
|
|
|
app_created = False
|
|
|
|
app = QCoreApplication.instance()
|
|
|
|
#check for existing app (when using ipython)
|
|
|
|
if app is None:
|
|
|
|
app = QApplication(sys.argv)
|
|
|
|
app_created = True
|
|
|
|
app.references = set()
|
|
|
|
#app.references.add(window)
|
|
|
|
#window.show()
|
|
|
|
return app, app_created
|
|
|
|
|
|
|
|
|
2014-03-28 22:26:15 +01:00
|
|
|
def main():
|
2014-11-06 15:07:05 +01:00
|
|
|
# create the Qt application
|
2017-04-10 13:32:53 +02:00
|
|
|
pylot_app, app_created = create_window()
|
|
|
|
#pylot_app = QApplication(sys.argv)
|
2015-07-07 12:14:18 +02:00
|
|
|
pixmap = QPixmap(":/splash/splash.png")
|
|
|
|
splash = QSplashScreen(pixmap)
|
|
|
|
splash.show()
|
2015-04-02 18:36:21 +02:00
|
|
|
|
|
|
|
app_icon = QIcon()
|
2015-07-07 11:21:06 +02:00
|
|
|
app_icon.addPixmap(QPixmap(':/icons/pylot.png'))
|
2014-01-09 10:43:40 +01:00
|
|
|
|
2015-09-18 09:54:29 +02:00
|
|
|
# create the main window
|
|
|
|
pylot_form = MainWindow()
|
2017-04-06 13:16:28 +02:00
|
|
|
icon = QIcon()
|
|
|
|
pylot_form.setWindowIcon(icon)
|
|
|
|
pylot_form.setIconSize(QSize(60, 60))
|
|
|
|
|
2015-09-18 09:54:29 +02:00
|
|
|
splash.showMessage('Loading. Please wait ...')
|
|
|
|
pylot_app.processEvents()
|
|
|
|
|
2014-03-28 22:26:15 +01:00
|
|
|
# set Application Information
|
2017-04-06 13:16:28 +02:00
|
|
|
pylot_app.setOrganizationName("Ruhr-University Bochum / BESTEC")
|
2014-03-28 22:26:15 +01:00
|
|
|
pylot_app.setOrganizationDomain("rub.de")
|
2015-09-18 09:54:29 +02:00
|
|
|
pylot_app.processEvents()
|
2014-03-28 22:26:15 +01:00
|
|
|
pylot_app.setApplicationName("PyLoT")
|
2015-09-18 09:54:29 +02:00
|
|
|
pylot_app.setApplicationVersion(pylot_form.__version__)
|
2015-04-02 18:36:21 +02:00
|
|
|
pylot_app.setWindowIcon(app_icon)
|
2015-07-07 12:14:18 +02:00
|
|
|
pylot_app.processEvents()
|
2014-01-09 10:43:40 +01:00
|
|
|
|
2014-03-13 13:27:34 +01:00
|
|
|
# Show main window and run the app
|
2015-06-25 10:25:08 +02:00
|
|
|
pylot_form.showMaximized()
|
2015-09-18 09:54:29 +02:00
|
|
|
pylot_app.processEvents()
|
|
|
|
|
2015-07-07 12:14:18 +02:00
|
|
|
splash.finish(pylot_form)
|
2017-04-10 13:32:53 +02:00
|
|
|
if app_created:
|
|
|
|
pylot_app.exec_()
|
2017-04-10 14:01:08 +02:00
|
|
|
else:
|
|
|
|
return pylot_form
|
2014-03-28 22:26:15 +01:00
|
|
|
|
2015-01-29 08:53:01 +01:00
|
|
|
|
2014-04-11 19:39:29 +02:00
|
|
|
if __name__ == "__main__":
|
2014-12-08 10:26:14 +01:00
|
|
|
sys.exit(main())
|