Merge branch 'project_events' into develop
This commit is contained in:
commit
686ca4489c
701
QtPyLoT.py
701
QtPyLoT.py
@ -30,12 +30,14 @@ import matplotlib
|
|||||||
matplotlib.use('Qt4Agg')
|
matplotlib.use('Qt4Agg')
|
||||||
matplotlib.rcParams['backend.qt4'] = 'PySide'
|
matplotlib.rcParams['backend.qt4'] = 'PySide'
|
||||||
|
|
||||||
|
from PySide import QtGui, QtCore
|
||||||
from PySide.QtCore import QCoreApplication, QSettings, Signal, QFile, \
|
from PySide.QtCore import QCoreApplication, QSettings, Signal, QFile, \
|
||||||
QFileInfo, Qt, QSize
|
QFileInfo, Qt, QSize
|
||||||
from PySide.QtGui import QMainWindow, QInputDialog, QIcon, QFileDialog, \
|
from PySide.QtGui import QMainWindow, QInputDialog, QIcon, QFileDialog, \
|
||||||
QWidget, QHBoxLayout, QStyle, QKeySequence, QLabel, QFrame, QAction, \
|
QWidget, QHBoxLayout, QVBoxLayout, QStyle, QKeySequence, QLabel, QFrame, QAction, \
|
||||||
QDialog, QErrorMessage, QApplication, QPixmap, QMessageBox, QSplashScreen, \
|
QDialog, QErrorMessage, QApplication, QPixmap, QMessageBox, QSplashScreen, \
|
||||||
QActionGroup, QListWidget, QDockWidget, QLineEdit
|
QActionGroup, QListWidget, QDockWidget, QLineEdit, QListView, QAbstractItemView, \
|
||||||
|
QTreeView, QComboBox, QTabWidget, QPushButton, QGridLayout
|
||||||
import numpy as np
|
import numpy as np
|
||||||
from obspy import UTCDateTime
|
from obspy import UTCDateTime
|
||||||
|
|
||||||
@ -60,7 +62,7 @@ from pylot.core.util.widgets import FilterOptionsDialog, NewEventDlg, \
|
|||||||
getDataType, ComparisonDialog
|
getDataType, ComparisonDialog
|
||||||
from pylot.core.util.map_projection import map_projection
|
from pylot.core.util.map_projection import map_projection
|
||||||
from pylot.core.util.structure import DATASTRUCTURE
|
from pylot.core.util.structure import DATASTRUCTURE
|
||||||
from pylot.core.util.thread import AutoPickThread
|
from pylot.core.util.thread import AutoPickThread, Thread
|
||||||
from pylot.core.util.version import get_git_version as _getVersionString
|
from pylot.core.util.version import get_git_version as _getVersionString
|
||||||
import icons_rc
|
import icons_rc
|
||||||
|
|
||||||
@ -86,12 +88,32 @@ class MainWindow(QMainWindow):
|
|||||||
else:
|
else:
|
||||||
self.infile = infile
|
self.infile = infile
|
||||||
|
|
||||||
|
self.project = Project()
|
||||||
|
self.array_map = None
|
||||||
|
self._metadata = None
|
||||||
|
self._eventChanged = [False, False]
|
||||||
|
|
||||||
|
self.poS_id = None
|
||||||
|
self.ae_id = None
|
||||||
|
|
||||||
# UI has to be set up before(!) children widgets are about to show up
|
# UI has to be set up before(!) children widgets are about to show up
|
||||||
self.createAction = createAction
|
self.createAction = createAction
|
||||||
# read settings
|
# read settings
|
||||||
settings = QSettings()
|
settings = QSettings()
|
||||||
self.recentfiles = settings.value("data/recentEvents", [])
|
self.recentfiles = settings.value("data/recentEvents", [])
|
||||||
self.dispComponent = str(settings.value("plotting/dispComponent", "Z"))
|
self.dispComponent = str(settings.value("plotting/dispComponent", "Z"))
|
||||||
|
|
||||||
|
# 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
|
||||||
self.setupUi()
|
self.setupUi()
|
||||||
|
|
||||||
if settings.value("user/FullName", None) is None:
|
if settings.value("user/FullName", None) is None:
|
||||||
@ -120,22 +142,8 @@ class MainWindow(QMainWindow):
|
|||||||
self.picks = {}
|
self.picks = {}
|
||||||
self.autopicks = {}
|
self.autopicks = {}
|
||||||
self.loc = False
|
self.loc = False
|
||||||
self._metadata = None
|
|
||||||
|
|
||||||
self.array_map = None
|
|
||||||
|
|
||||||
# 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
|
|
||||||
|
|
||||||
def setupUi(self):
|
def setupUi(self):
|
||||||
|
|
||||||
try:
|
try:
|
||||||
self.startTime = min(
|
self.startTime = min(
|
||||||
[tr.stats.starttime for tr in self.data.wfdata])
|
[tr.stats.starttime for tr in self.data.wfdata])
|
||||||
@ -151,24 +159,53 @@ class MainWindow(QMainWindow):
|
|||||||
xlab = self.startTime.strftime('seconds since %Y/%m/%d %H:%M:%S (%Z)')
|
xlab = self.startTime.strftime('seconds since %Y/%m/%d %H:%M:%S (%Z)')
|
||||||
|
|
||||||
_widget = QWidget()
|
_widget = QWidget()
|
||||||
_widget.setCursor(Qt.CrossCursor)
|
self._main_layout = QVBoxLayout()
|
||||||
_layout = QHBoxLayout()
|
|
||||||
|
|
||||||
plottitle = "Overview: {0} components ".format(self.getComponent())
|
# add event combo box
|
||||||
|
self.eventBox = self.createEventBox()
|
||||||
|
self.eventBox.setMaxVisibleItems(30)
|
||||||
|
self.eventBox.setEnabled(False)
|
||||||
|
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)
|
||||||
|
self.eventBox.activated.connect(self.refreshEvents)
|
||||||
|
|
||||||
|
# add tabs
|
||||||
|
self.tabs = QTabWidget()
|
||||||
|
self._main_layout.addWidget(self.tabs)
|
||||||
|
self.tabs.currentChanged.connect(self.refreshTabs)
|
||||||
|
|
||||||
# create central matplotlib figure canvas widget
|
# create central matplotlib figure canvas widget
|
||||||
self.DataPlot = WaveformWidget(parent=self, xlabel=xlab, ylabel=None,
|
plottitle = "Overview: {0} components ".format(self.getComponent())
|
||||||
|
self.dataPlot = WaveformWidget(parent=self, xlabel=xlab, ylabel=None,
|
||||||
title=plottitle)
|
title=plottitle)
|
||||||
self.DataPlot.mpl_connect('button_press_event',
|
self.dataPlot.setCursor(Qt.CrossCursor)
|
||||||
self.pickOnStation)
|
wf_tab = QtGui.QWidget()
|
||||||
self.DataPlot.mpl_connect('axes_enter_event',
|
array_tab = QtGui.QWidget()
|
||||||
lambda event: self.tutor_user())
|
events_tab = QtGui.QWidget()
|
||||||
_layout.addWidget(self.DataPlot)
|
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')
|
||||||
|
|
||||||
|
self.wf_layout.addWidget(self.dataPlot)
|
||||||
|
self.init_array_tab()
|
||||||
|
self.init_event_table()
|
||||||
|
self.tabs.setCurrentIndex(0)
|
||||||
|
|
||||||
quitIcon = self.style().standardIcon(QStyle.SP_MediaStop)
|
quitIcon = self.style().standardIcon(QStyle.SP_MediaStop)
|
||||||
saveIcon = self.style().standardIcon(QStyle.SP_DriveHDIcon)
|
saveIcon = self.style().standardIcon(QStyle.SP_DriveHDIcon)
|
||||||
|
openIcon = self.style().standardIcon(QStyle.SP_DirOpenIcon)
|
||||||
helpIcon = self.style().standardIcon(QStyle.SP_DialogHelpButton)
|
helpIcon = self.style().standardIcon(QStyle.SP_DialogHelpButton)
|
||||||
newIcon = self.style().standardIcon(QStyle.SP_FileIcon)
|
newIcon = self.style().standardIcon(QStyle.SP_FileIcon)
|
||||||
|
newFolderIcon = self.style().standardIcon(QStyle.SP_FileDialogNewFolder)
|
||||||
|
|
||||||
# create resource icons
|
# create resource icons
|
||||||
locactionicon = QIcon()
|
locactionicon = QIcon()
|
||||||
@ -177,6 +214,14 @@ class MainWindow(QMainWindow):
|
|||||||
manupicksicon.addPixmap(QPixmap(':/icons/manupicsicon.png'))
|
manupicksicon.addPixmap(QPixmap(':/icons/manupicsicon.png'))
|
||||||
autopicksicon = QIcon()
|
autopicksicon = QIcon()
|
||||||
autopicksicon.addPixmap(QPixmap(':/icons/autopicsicon.png'))
|
autopicksicon.addPixmap(QPixmap(':/icons/autopicsicon.png'))
|
||||||
|
self.autopicksicon_small = QIcon()
|
||||||
|
self.autopicksicon_small.addPixmap(QPixmap(':/icons/autopicsicon.png'))
|
||||||
|
self.manupicksicon_small = QIcon()
|
||||||
|
self.manupicksicon_small.addPixmap(QPixmap(':/icons/manupicsicon.png'))
|
||||||
|
# self.autopicksicon_small = QIcon()
|
||||||
|
# self.autopicksicon_small.addPixmap(QPixmap(':/icons/autopicksicon_small.png'))
|
||||||
|
# self.manupicksicon_small = QIcon()
|
||||||
|
# self.manupicksicon_small.addPixmap(QPixmap(':/icons/manupicksicon_small.png'))
|
||||||
loadpiloticon = QIcon()
|
loadpiloticon = QIcon()
|
||||||
loadpiloticon.addPixmap(QPixmap(':/icons/Matlab_PILOT_icon.png'))
|
loadpiloticon.addPixmap(QPixmap(':/icons/Matlab_PILOT_icon.png'))
|
||||||
p_icon = QIcon()
|
p_icon = QIcon()
|
||||||
@ -199,10 +244,24 @@ class MainWindow(QMainWindow):
|
|||||||
locate_icon.addPixmap(QPixmap(':/icons/locate_button.png'))
|
locate_icon.addPixmap(QPixmap(':/icons/locate_button.png'))
|
||||||
compare_icon = QIcon()
|
compare_icon = QIcon()
|
||||||
compare_icon.addPixmap(QPixmap(':/icons/compare_button.png'))
|
compare_icon.addPixmap(QPixmap(':/icons/compare_button.png'))
|
||||||
newEventAction = self.createAction(self, "&New event ...",
|
self.newProjectAction = self.createAction(self, "&New project ...",
|
||||||
self.createNewEvent,
|
self.createNewProject,
|
||||||
QKeySequence.New, newIcon,
|
QKeySequence.New, newIcon,
|
||||||
"Create a new event.")
|
"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,
|
||||||
|
saveIcon,
|
||||||
|
"Save project file")
|
||||||
|
# newEventAction = self.createAction(self, "&New event ...",
|
||||||
|
# self.createNewEvent,
|
||||||
|
# QKeySequence.New, newIcon,
|
||||||
|
# "Create a new event.")
|
||||||
self.openmanualpicksaction = self.createAction(self, "Load &picks ...",
|
self.openmanualpicksaction = self.createAction(self, "Load &picks ...",
|
||||||
self.load_data,
|
self.load_data,
|
||||||
QKeySequence.Open,
|
QKeySequence.Open,
|
||||||
@ -240,11 +299,10 @@ class MainWindow(QMainWindow):
|
|||||||
saveIcon, "Save actual event data.")
|
saveIcon, "Save actual event data.")
|
||||||
self.saveEventAction.setEnabled(False)
|
self.saveEventAction.setEnabled(False)
|
||||||
|
|
||||||
openWFDataAction = self.createAction(self, "Open &waveforms ...",
|
self.addEventDataAction = self.createAction(self, "Add &events ...",
|
||||||
self.loadWaveformData,
|
self.add_events,
|
||||||
"Ctrl+W", QIcon(":/wfIcon.png"),
|
"Ctrl+W", newFolderIcon,
|
||||||
"Open waveform data (event will "
|
"Add event data")
|
||||||
"be closed)")
|
|
||||||
prefsEventAction = self.createAction(self, "Preferences",
|
prefsEventAction = self.createAction(self, "Preferences",
|
||||||
self.PyLoTprefs,
|
self.PyLoTprefs,
|
||||||
QKeySequence.Preferences,
|
QKeySequence.Preferences,
|
||||||
@ -290,8 +348,9 @@ class MainWindow(QMainWindow):
|
|||||||
homepage (internet connection available),
|
homepage (internet connection available),
|
||||||
or shipped documentation files.""")
|
or shipped documentation files.""")
|
||||||
self.fileMenu = self.menuBar().addMenu('&File')
|
self.fileMenu = self.menuBar().addMenu('&File')
|
||||||
self.fileMenuActions = (newEventAction, self.openmanualpicksaction,
|
self.fileMenuActions = (self.newProjectAction, self.addEventDataAction,
|
||||||
self.saveEventAction, openWFDataAction, None,
|
self.openProjectAction, self.saveProjectAction,
|
||||||
|
self.openmanualpicksaction, self.saveEventAction, None,
|
||||||
prefsEventAction, quitAction)
|
prefsEventAction, quitAction)
|
||||||
self.fileMenu.aboutToShow.connect(self.updateFileMenu)
|
self.fileMenu.aboutToShow.connect(self.updateFileMenu)
|
||||||
self.updateFileMenu()
|
self.updateFileMenu()
|
||||||
@ -307,7 +366,9 @@ class MainWindow(QMainWindow):
|
|||||||
self.addActions(self.helpMenu, helpActions)
|
self.addActions(self.helpMenu, helpActions)
|
||||||
|
|
||||||
fileToolBar = self.addToolBar("FileTools")
|
fileToolBar = self.addToolBar("FileTools")
|
||||||
fileToolActions = (newEventAction, self.openmanualpicksaction,
|
fileToolActions = (self.newProjectAction, self.addEventDataAction,
|
||||||
|
self.openProjectAction, self.saveProjectAction,
|
||||||
|
self.openmanualpicksaction,
|
||||||
self.openautopicksaction, loadlocationaction,
|
self.openautopicksaction, loadlocationaction,
|
||||||
self.loadpilotevent, self.saveEventAction)
|
self.loadpilotevent, self.saveEventAction)
|
||||||
fileToolBar.setObjectName("FileTools")
|
fileToolBar.setObjectName("FileTools")
|
||||||
@ -384,7 +445,7 @@ class MainWindow(QMainWindow):
|
|||||||
status.addPermanentWidget(self.eventLabel)
|
status.addPermanentWidget(self.eventLabel)
|
||||||
status.showMessage("Ready", 500)
|
status.showMessage("Ready", 500)
|
||||||
|
|
||||||
_widget.setLayout(_layout)
|
_widget.setLayout(self._main_layout)
|
||||||
_widget.showFullScreen()
|
_widget.showFullScreen()
|
||||||
|
|
||||||
self.setCentralWidget(_widget)
|
self.setCentralWidget(_widget)
|
||||||
@ -483,6 +544,14 @@ class MainWindow(QMainWindow):
|
|||||||
self.drawPicks(picktype=type)
|
self.drawPicks(picktype=type)
|
||||||
self.draw()
|
self.draw()
|
||||||
|
|
||||||
|
def getCurrentEvent(self):
|
||||||
|
for event in self.project.eventlist:
|
||||||
|
if event.path == self.getCurrentEventPath():
|
||||||
|
return event
|
||||||
|
|
||||||
|
def getCurrentEventPath(self):
|
||||||
|
return str(self.eventBox.currentText().split('|')[0]).strip()
|
||||||
|
|
||||||
def getLastEvent(self):
|
def getLastEvent(self):
|
||||||
return self.recentfiles[0]
|
return self.recentfiles[0]
|
||||||
|
|
||||||
@ -523,6 +592,127 @@ class MainWindow(QMainWindow):
|
|||||||
else:
|
else:
|
||||||
return
|
return
|
||||||
|
|
||||||
|
def getWFFnames_from_eventlist(self):
|
||||||
|
if self.dataStructure:
|
||||||
|
searchPath = self.dataStructure.expandDataPath()
|
||||||
|
directory = self.getCurrentEventPath()
|
||||||
|
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()
|
||||||
|
|
||||||
|
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
|
||||||
|
|
||||||
|
|
||||||
|
def init_events(self, new=False):
|
||||||
|
nitems = self.eventBox.count()
|
||||||
|
if len(self.project.eventlist) == 0:
|
||||||
|
print('No events to init.')
|
||||||
|
self.clearWaveformDataPlot()
|
||||||
|
return
|
||||||
|
self.eventBox.setEnabled(True)
|
||||||
|
self.fill_eventbox()
|
||||||
|
if new:
|
||||||
|
self.eventBox.setCurrentIndex(0)
|
||||||
|
else:
|
||||||
|
self.eventBox.setCurrentIndex(nitems)
|
||||||
|
self.refreshEvents()
|
||||||
|
tabindex = self.tabs.currentIndex()
|
||||||
|
|
||||||
|
def fill_eventbox(self):
|
||||||
|
index=self.eventBox.currentIndex()
|
||||||
|
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)
|
||||||
|
self.eventBox.clear()
|
||||||
|
model = self.eventBox.model()
|
||||||
|
plmax=0
|
||||||
|
for event in self.project.eventlist:
|
||||||
|
pl = len(event.path)
|
||||||
|
if pl > plmax:
|
||||||
|
plmax=pl
|
||||||
|
|
||||||
|
for event in self.project.eventlist:
|
||||||
|
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()
|
||||||
|
|
||||||
|
text = '{path:{plen}} | manual: [{p:3d}] | auto: [{a:3d}]'
|
||||||
|
text = text.format(path=event_path,
|
||||||
|
plen=plmax,
|
||||||
|
p=event_npicks,
|
||||||
|
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))
|
||||||
|
if event_ref:
|
||||||
|
item_ref.setBackground(QtGui.QColor(200, 210, 230, 255))
|
||||||
|
if event_test:
|
||||||
|
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)
|
||||||
|
self.eventBox.setCurrentIndex(index)
|
||||||
|
|
||||||
def filename_from_action(self, action):
|
def filename_from_action(self, action):
|
||||||
if action.data() is None:
|
if action.data() is None:
|
||||||
filt = "Supported file formats" \
|
filt = "Supported file formats" \
|
||||||
@ -648,7 +838,7 @@ class MainWindow(QMainWindow):
|
|||||||
compare_dlg.exec_()
|
compare_dlg.exec_()
|
||||||
|
|
||||||
def getPlotWidget(self):
|
def getPlotWidget(self):
|
||||||
return self.DataPlot
|
return self.dataPlot
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def getWFID(gui_event):
|
def getWFID(gui_event):
|
||||||
@ -687,15 +877,70 @@ class MainWindow(QMainWindow):
|
|||||||
return self.saveData()
|
return self.saveData()
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def loadWaveformData(self):
|
def refreshEvents(self):
|
||||||
if self.fnames and self.okToContinue():
|
self._eventChanged = [True, True]
|
||||||
self.setDirty(True)
|
self.refreshTabs()
|
||||||
ans = self.data.setWFData(self.fnames)
|
|
||||||
elif self.fnames is None and self.okToContinue():
|
def refreshTabs(self):
|
||||||
ans = self.data.setWFData(self.getWFFnames())
|
if self._eventChanged[0] or self._eventChanged[1]:
|
||||||
|
event = self.getCurrentEvent()
|
||||||
|
if not event.picks:
|
||||||
|
self.picks = {}
|
||||||
else:
|
else:
|
||||||
ans = False
|
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()
|
||||||
|
if self.tabs.currentIndex() == 2:
|
||||||
|
self.init_event_table()
|
||||||
|
|
||||||
|
def newWFplot(self):
|
||||||
|
self.loadWaveformDataThread()
|
||||||
|
self._eventChanged[0] = False
|
||||||
|
|
||||||
|
def loadWaveformDataThread(self):
|
||||||
|
wfd_thread = Thread(self, self.loadWaveformData, progressText='Reading data input...')
|
||||||
|
wfd_thread.finished.connect(self.plotWaveformDataThread)
|
||||||
|
wfd_thread.start()
|
||||||
|
|
||||||
|
def loadWaveformData(self):
|
||||||
|
# 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())
|
||||||
self._stime = full_range(self.get_data().getWFData())[0]
|
self._stime = full_range(self.get_data().getWFData())[0]
|
||||||
|
|
||||||
|
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
|
||||||
|
|
||||||
|
def finishWaveformDataPlot(self):
|
||||||
|
self.connectWFplotEvents()
|
||||||
self.auto_pick.setEnabled(True)
|
self.auto_pick.setEnabled(True)
|
||||||
self.z_action.setEnabled(True)
|
self.z_action.setEnabled(True)
|
||||||
self.e_action.setEnabled(True)
|
self.e_action.setEnabled(True)
|
||||||
@ -704,11 +949,32 @@ class MainWindow(QMainWindow):
|
|||||||
self.openautopicksaction.setEnabled(True)
|
self.openautopicksaction.setEnabled(True)
|
||||||
self.loadpilotevent.setEnabled(True)
|
self.loadpilotevent.setEnabled(True)
|
||||||
self.saveEventAction.setEnabled(True)
|
self.saveEventAction.setEnabled(True)
|
||||||
if ans:
|
event = self.getCurrentEvent()
|
||||||
self.plotWaveformData()
|
if event.picks:
|
||||||
return ans
|
self.picks = event.picks
|
||||||
else:
|
self.drawPicks(picktype='manual')
|
||||||
return ans
|
if event.autopicks:
|
||||||
|
self.autopicks = event.autopicks
|
||||||
|
self.drawPicks(picktype='auto')
|
||||||
|
self.draw()
|
||||||
|
|
||||||
|
def clearWaveformDataPlot(self):
|
||||||
|
self.disconnectWFplotEvents()
|
||||||
|
self.dataPlot.getAxes().cla()
|
||||||
|
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()
|
||||||
|
|
||||||
|
def plotWaveformDataThread(self):
|
||||||
|
wfp_thread = Thread(self, self.plotWaveformData, progressText='Plotting waveform data...')
|
||||||
|
wfp_thread.finished.connect(self.finishWaveformDataPlot)
|
||||||
|
wfp_thread.start()
|
||||||
|
|
||||||
def plotWaveformData(self):
|
def plotWaveformData(self):
|
||||||
zne_text = {'Z': 'vertical', 'N': 'north-south', 'E': 'east-west'}
|
zne_text = {'Z': 'vertical', 'N': 'north-south', 'E': 'east-west'}
|
||||||
@ -718,7 +984,6 @@ class MainWindow(QMainWindow):
|
|||||||
wfst = self.get_data().getWFData().select(component=comp)
|
wfst = self.get_data().getWFData().select(component=comp)
|
||||||
wfst += self.get_data().getWFData().select(component=alter_comp)
|
wfst += self.get_data().getWFData().select(component=alter_comp)
|
||||||
self.getPlotWidget().plotWFData(wfdata=wfst, title=title, mapping=False)
|
self.getPlotWidget().plotWFData(wfdata=wfst, title=title, mapping=False)
|
||||||
self.draw()
|
|
||||||
plotDict = self.getPlotWidget().getPlotDict()
|
plotDict = self.getPlotWidget().getPlotDict()
|
||||||
pos = plotDict.keys()
|
pos = plotDict.keys()
|
||||||
labels = [plotDict[n][0] for n in pos]
|
labels = [plotDict[n][0] for n in pos]
|
||||||
@ -726,19 +991,19 @@ class MainWindow(QMainWindow):
|
|||||||
|
|
||||||
def plotZ(self):
|
def plotZ(self):
|
||||||
self.setComponent('Z')
|
self.setComponent('Z')
|
||||||
self.plotWaveformData()
|
self.plotWaveformDataThread()
|
||||||
self.drawPicks()
|
self.drawPicks()
|
||||||
self.draw()
|
self.draw()
|
||||||
|
|
||||||
def plotN(self):
|
def plotN(self):
|
||||||
self.setComponent('N')
|
self.setComponent('N')
|
||||||
self.plotWaveformData()
|
self.plotWaveformDataThread()
|
||||||
self.drawPicks()
|
self.drawPicks()
|
||||||
self.draw()
|
self.draw()
|
||||||
|
|
||||||
def plotE(self):
|
def plotE(self):
|
||||||
self.setComponent('E')
|
self.setComponent('E')
|
||||||
self.plotWaveformData()
|
self.plotWaveformDataThread()
|
||||||
self.drawPicks()
|
self.drawPicks()
|
||||||
self.draw()
|
self.draw()
|
||||||
|
|
||||||
@ -924,8 +1189,10 @@ class MainWindow(QMainWindow):
|
|||||||
def updatePicks(self, type='manual'):
|
def updatePicks(self, type='manual'):
|
||||||
picks = picksdict_from_picks(evt=self.get_data(type).get_evt_data())
|
picks = picksdict_from_picks(evt=self.get_data(type).get_evt_data())
|
||||||
if type == 'manual':
|
if type == 'manual':
|
||||||
|
self.getCurrentEvent().addPicks(picks)
|
||||||
self.picks.update(picks)
|
self.picks.update(picks)
|
||||||
elif type == 'auto':
|
elif type == 'auto':
|
||||||
|
self.getCurrentEvent().addAutopicks(picks)
|
||||||
self.autopicks.update(picks)
|
self.autopicks.update(picks)
|
||||||
self.check4Comparison()
|
self.check4Comparison()
|
||||||
|
|
||||||
@ -937,7 +1204,7 @@ class MainWindow(QMainWindow):
|
|||||||
return
|
return
|
||||||
# plotting picks
|
# plotting picks
|
||||||
plotID = self.getStationID(station)
|
plotID = self.getStationID(station)
|
||||||
if not plotID:
|
if plotID is None:
|
||||||
return
|
return
|
||||||
ax = self.getPlotWidget().axes
|
ax = self.getPlotWidget().axes
|
||||||
ylims = np.array([-.5, +.5]) + plotID
|
ylims = np.array([-.5, +.5]) + plotID
|
||||||
@ -1038,14 +1305,153 @@ class MainWindow(QMainWindow):
|
|||||||
self.get_data().applyEVTData(lt.read_location(locpath), type='event')
|
self.get_data().applyEVTData(lt.read_location(locpath), type='event')
|
||||||
self.get_data().applyEVTData(self.calc_magnitude(), type='event')
|
self.get_data().applyEVTData(self.calc_magnitude(), type='event')
|
||||||
|
|
||||||
def show_array_map(self):
|
def init_array_tab(self):
|
||||||
|
self.metadata_widget = QWidget(self)
|
||||||
|
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)
|
||||||
|
|
||||||
|
self.metadata_widget.setLayout(grid_layout)
|
||||||
|
self.array_layout.addWidget(self.metadata_widget)
|
||||||
|
|
||||||
|
def init_array_map(self, index=1):
|
||||||
if not self.array_map:
|
if not self.array_map:
|
||||||
self.get_metadata()
|
self.get_metadata()
|
||||||
if not self.metadata:
|
if not self.metadata:
|
||||||
return
|
return
|
||||||
self.array_map = map_projection(self)
|
self.array_map = map_projection(self)
|
||||||
|
self.array_layout.removeWidget(self.metadata_widget)
|
||||||
|
self.array_layout.addWidget(self.array_map)
|
||||||
|
self.tabs.setCurrentIndex(index)
|
||||||
|
self.refresh_array_map()
|
||||||
|
|
||||||
|
def refresh_array_map(self):
|
||||||
|
if not self.array_map:
|
||||||
|
return
|
||||||
|
# refresh with new picks here!!!
|
||||||
|
self.array_map.refresh_drawings(self.picks)
|
||||||
|
self._eventChanged[1] = False
|
||||||
|
|
||||||
|
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:
|
||||||
|
item.setFlags(QtCore.Qt.ItemIsEnabled | QtCore.Qt.ItemIsUserCheckable | QtCore.Qt.ItemIsSelectable)
|
||||||
else:
|
else:
|
||||||
self.array_map.show()
|
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())
|
||||||
|
if column == 3 or column == 4:
|
||||||
|
#toggle checked states (exclusive)
|
||||||
|
item_ref = table[row][3]
|
||||||
|
item_test = table[row][4]
|
||||||
|
if column == 3 and item_ref.checkState():
|
||||||
|
item_test.setCheckState(QtCore.Qt.Unchecked)
|
||||||
|
event.setRefEvent(True)
|
||||||
|
elif column == 3 and not item_ref.checkState():
|
||||||
|
event.setRefEvent(False)
|
||||||
|
elif column == 4 and item_test.checkState():
|
||||||
|
item_ref.setCheckState(QtCore.Qt.Unchecked)
|
||||||
|
event.setTestEvent(True)
|
||||||
|
elif column == 4 and not item_test.checkState():
|
||||||
|
event.setTestEvent(False)
|
||||||
|
self.fill_eventbox()
|
||||||
|
elif column == 5:
|
||||||
|
#update event notes
|
||||||
|
notes = table[row][5].text()
|
||||||
|
event.addNotes(notes)
|
||||||
|
self.fill_eventbox()
|
||||||
|
|
||||||
|
if hasattr(self, 'qtl'):
|
||||||
|
self.events_layout.removeWidget(self.qtl)
|
||||||
|
self.qtl = QtGui.QTableWidget()
|
||||||
|
self.qtl.setColumnCount(6)
|
||||||
|
self.qtl.setRowCount(len(eventlist))
|
||||||
|
self.qtl.setHorizontalHeaderLabels(['Event', '[N] MP',
|
||||||
|
'[N] AP', 'Reference',
|
||||||
|
'Test Set', 'Notes'])
|
||||||
|
|
||||||
|
self.project._table = []
|
||||||
|
for index, event in enumerate(eventlist):
|
||||||
|
event_npicks = 0
|
||||||
|
event_nautopicks = 0
|
||||||
|
if event.picks:
|
||||||
|
event_npicks = len(event.picks)
|
||||||
|
if event.autopicks:
|
||||||
|
event_nautopicks = len(event.autopicks)
|
||||||
|
item_path = QtGui.QTableWidgetItem()
|
||||||
|
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)
|
||||||
|
item_ref = QtGui.QTableWidgetItem()
|
||||||
|
item_test = QtGui.QTableWidgetItem()
|
||||||
|
item_notes = QtGui.QTableWidgetItem()
|
||||||
|
|
||||||
|
item_ref.setBackground(QtGui.QColor(200, 210, 230, 255))
|
||||||
|
item_test.setBackground(QtGui.QColor(200, 230, 200, 255))
|
||||||
|
item_path.setText(event.path)
|
||||||
|
item_notes.setText(event.notes)
|
||||||
|
set_enabled(item_path, True, False)
|
||||||
|
set_enabled(item_nmp, True, False)
|
||||||
|
set_enabled(item_nap, True, False)
|
||||||
|
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)
|
||||||
|
|
||||||
|
column=[item_path, item_nmp, item_nap, item_ref, item_test, item_notes]
|
||||||
|
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)
|
||||||
|
|
||||||
|
self.events_layout.addWidget(self.qtl)
|
||||||
|
self.tabs.setCurrentIndex(index)
|
||||||
|
|
||||||
|
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
|
||||||
|
self.project.metadata = self.rm_thread.data
|
||||||
|
self.init_array_map()
|
||||||
|
|
||||||
def get_metadata(self):
|
def get_metadata(self):
|
||||||
def set_inv(settings):
|
def set_inv(settings):
|
||||||
@ -1062,7 +1468,11 @@ class MainWindow(QMainWindow):
|
|||||||
if ans == QMessageBox.Yes:
|
if ans == QMessageBox.Yes:
|
||||||
settings.setValue("inventoryFile", fninv)
|
settings.setValue("inventoryFile", fninv)
|
||||||
settings.sync()
|
settings.sync()
|
||||||
self.metadata = read_metadata(fninv)
|
self.read_metadata_thread(fninv)
|
||||||
|
return True
|
||||||
|
|
||||||
|
if hasattr(self.project, 'metadata'):
|
||||||
|
self.metadata = self.project.metadata
|
||||||
return True
|
return True
|
||||||
|
|
||||||
settings = QSettings()
|
settings = QSettings()
|
||||||
@ -1081,7 +1491,7 @@ class MainWindow(QMainWindow):
|
|||||||
if not set_inv(settings):
|
if not set_inv(settings):
|
||||||
return None
|
return None
|
||||||
else:
|
else:
|
||||||
self.metadata = read_metadata(fninv)
|
self.read_metadata_thread(fninv)
|
||||||
|
|
||||||
def calc_magnitude(self, type='ML'):
|
def calc_magnitude(self, type='ML'):
|
||||||
self.get_metadata()
|
self.get_metadata()
|
||||||
@ -1142,7 +1552,7 @@ class MainWindow(QMainWindow):
|
|||||||
self.setWindowTitle(
|
self.setWindowTitle(
|
||||||
"PyLoT - processing event %s[*]" % self.get_data().getID())
|
"PyLoT - processing event %s[*]" % self.get_data().getID())
|
||||||
elif self.get_data().isNew():
|
elif self.get_data().isNew():
|
||||||
self.setWindowTitle("PyLoT - New event [*]")
|
self.setWindowTitle("PyLoT - New project [*]")
|
||||||
else:
|
else:
|
||||||
self.setWindowTitle(
|
self.setWindowTitle(
|
||||||
"PyLoT - seismic processing the python way[*]")
|
"PyLoT - seismic processing the python way[*]")
|
||||||
@ -1164,7 +1574,62 @@ class MainWindow(QMainWindow):
|
|||||||
self.data = Data(self, evtdata=event)
|
self.data = Data(self, evtdata=event)
|
||||||
self.setDirty(True)
|
self.setDirty(True)
|
||||||
|
|
||||||
|
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]
|
||||||
|
if not len(fnm[0]):
|
||||||
|
return
|
||||||
|
if not filename.split('.')[-1] == 'plp':
|
||||||
|
filename = fnm[0] + '.plp'
|
||||||
|
if not exists:
|
||||||
|
self.project = Project()
|
||||||
|
self.init_events(new=True)
|
||||||
|
self.project.save(filename)
|
||||||
|
return True
|
||||||
|
|
||||||
|
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)
|
||||||
|
if qmb.exec_() == 16384:
|
||||||
|
self.saveProject()
|
||||||
|
elif qmb.exec_() == 65536:
|
||||||
|
pass
|
||||||
|
elif qmb.exec_() == 4194304:
|
||||||
|
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)
|
||||||
|
if hasattr(self.project, 'metadata'):
|
||||||
|
self.init_array_map(index=0)
|
||||||
|
|
||||||
|
def saveProject(self):
|
||||||
|
if self.project:
|
||||||
|
if not self.project.location:
|
||||||
|
if not self.createNewProject(exists=True):
|
||||||
|
return
|
||||||
|
else:
|
||||||
|
self.project.save()
|
||||||
|
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)
|
||||||
|
|
||||||
def draw(self):
|
def draw(self):
|
||||||
|
self.fill_eventbox()
|
||||||
self.getPlotWidget().draw()
|
self.getPlotWidget().draw()
|
||||||
|
|
||||||
def setDirty(self, value):
|
def setDirty(self, value):
|
||||||
@ -1189,6 +1654,120 @@ class MainWindow(QMainWindow):
|
|||||||
form.show()
|
form.show()
|
||||||
|
|
||||||
|
|
||||||
|
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
|
||||||
|
self._table = None
|
||||||
|
|
||||||
|
def add_eventlist(self, eventlist):
|
||||||
|
if len(eventlist) == 0:
|
||||||
|
return
|
||||||
|
for item in eventlist:
|
||||||
|
event = Event(item)
|
||||||
|
if not event in self.eventlist:
|
||||||
|
self.eventlist.append(event)
|
||||||
|
self.setDirty()
|
||||||
|
|
||||||
|
def setDirty(self):
|
||||||
|
self.dirty = True
|
||||||
|
|
||||||
|
def setClean(self):
|
||||||
|
self.dirty = False
|
||||||
|
|
||||||
|
def getEventFromPath(self, path):
|
||||||
|
for event in self.eventlist:
|
||||||
|
if event.path == path:
|
||||||
|
return event
|
||||||
|
|
||||||
|
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
|
||||||
|
|
||||||
|
|
||||||
|
class Event(object):
|
||||||
|
'''
|
||||||
|
Pickable class containing information on a single event.
|
||||||
|
'''
|
||||||
|
def __init__(self, path):
|
||||||
|
self.path = path
|
||||||
|
self.autopicks = None
|
||||||
|
self.picks = None
|
||||||
|
self.notes = None
|
||||||
|
self._testEvent = False
|
||||||
|
self._refEvent = False
|
||||||
|
|
||||||
|
def addPicks(self, picks):
|
||||||
|
self.picks = picks
|
||||||
|
|
||||||
|
def addAutopicks(self, autopicks):
|
||||||
|
self.autopicks = autopicks
|
||||||
|
|
||||||
|
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
|
||||||
|
|
||||||
|
|
||||||
|
class getExistingDirectories(QFileDialog):
|
||||||
|
def __init__(self, *args):
|
||||||
|
super(getExistingDirectories, self).__init__(*args)
|
||||||
|
self.setOption(self.DontUseNativeDialog, True)
|
||||||
|
self.setFileMode(self.Directory)
|
||||||
|
self.setOption(self.ShowDirsOnly, True)
|
||||||
|
self.findChildren(QListView)[0].setSelectionMode(QAbstractItemView.ExtendedSelection)
|
||||||
|
self.findChildren(QTreeView)[0].setSelectionMode(QAbstractItemView.ExtendedSelection)
|
||||||
|
|
||||||
|
|
||||||
def create_window():
|
def create_window():
|
||||||
app_created = False
|
app_created = False
|
||||||
app = QCoreApplication.instance()
|
app = QCoreApplication.instance()
|
||||||
|
@ -4,6 +4,8 @@
|
|||||||
<file>icons/pylot.png</file>
|
<file>icons/pylot.png</file>
|
||||||
<file>icons/manupicsicon.png</file>
|
<file>icons/manupicsicon.png</file>
|
||||||
<file>icons/autopicsicon.png</file>
|
<file>icons/autopicsicon.png</file>
|
||||||
|
<file>icons/manupicksicon_small.png</file>
|
||||||
|
<file>icons/autopicksicon_small.png</file>
|
||||||
<file>icons/autopick_button.png</file>
|
<file>icons/autopick_button.png</file>
|
||||||
<file>icons/locactionicon.png</file>
|
<file>icons/locactionicon.png</file>
|
||||||
<file>icons/compare_button.png</file>
|
<file>icons/compare_button.png</file>
|
||||||
|
BIN
icons/autopicksicon_small.png
Normal file
BIN
icons/autopicksicon_small.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 27 KiB |
BIN
icons/manupicksicon_small.png
Normal file
BIN
icons/manupicksicon_small.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 22 KiB |
@ -1 +1 @@
|
|||||||
de38-dirty
|
6b7d-dirty
|
||||||
|
@ -12,10 +12,17 @@ from pylot.core.util.widgets import PickDlg
|
|||||||
plt.interactive(False)
|
plt.interactive(False)
|
||||||
|
|
||||||
class map_projection(QtGui.QWidget):
|
class map_projection(QtGui.QWidget):
|
||||||
def __init__(self, mainwindow):
|
def __init__(self, mainwindow, figure=None):
|
||||||
|
'''
|
||||||
|
:param: picked, can be False, auto, manual
|
||||||
|
:value: str
|
||||||
|
'''
|
||||||
QtGui.QWidget.__init__(self)
|
QtGui.QWidget.__init__(self)
|
||||||
self.pyl_mainwindow = mainwindow
|
self.pyl_mainwindow = mainwindow
|
||||||
self.parser = mainwindow.metadata[1]
|
self.parser = mainwindow.metadata[1]
|
||||||
|
self.picks = None
|
||||||
|
self.picks_dict = None
|
||||||
|
self.figure = figure
|
||||||
self.init_graphics()
|
self.init_graphics()
|
||||||
self.init_stations()
|
self.init_stations()
|
||||||
self.init_lat_lon_dimensions()
|
self.init_lat_lon_dimensions()
|
||||||
@ -24,7 +31,7 @@ class map_projection(QtGui.QWidget):
|
|||||||
self.init_x_y_dimensions()
|
self.init_x_y_dimensions()
|
||||||
self.connectSignals()
|
self.connectSignals()
|
||||||
self.draw_everything()
|
self.draw_everything()
|
||||||
self.show()
|
#self.show()
|
||||||
|
|
||||||
def onpick(self, event):
|
def onpick(self, event):
|
||||||
ind = event.ind
|
ind = event.ind
|
||||||
@ -57,7 +64,7 @@ class map_projection(QtGui.QWidget):
|
|||||||
print('Could not generate Plot for station {st}.\n{er}'.format(st=station, er=e))
|
print('Could not generate Plot for station {st}.\n{er}'.format(st=station, er=e))
|
||||||
|
|
||||||
def connectSignals(self):
|
def connectSignals(self):
|
||||||
self.combobox.currentIndexChanged.connect(self.refresh_drawings)
|
self.comboBox_phase.currentIndexChanged.connect(self._refresh_drawings)
|
||||||
|
|
||||||
def init_graphics(self):
|
def init_graphics(self):
|
||||||
self.main_box = QtGui.QVBoxLayout()
|
self.main_box = QtGui.QVBoxLayout()
|
||||||
@ -66,13 +73,22 @@ class map_projection(QtGui.QWidget):
|
|||||||
self.top_row = QtGui.QHBoxLayout()
|
self.top_row = QtGui.QHBoxLayout()
|
||||||
self.main_box.addLayout(self.top_row)
|
self.main_box.addLayout(self.top_row)
|
||||||
|
|
||||||
self.combobox = QtGui.QComboBox()
|
self.comboBox_phase = QtGui.QComboBox()
|
||||||
self.combobox.insertItem(0, 'P')
|
self.comboBox_phase.insertItem(0, 'P')
|
||||||
self.combobox.insertItem(1, 'S')
|
self.comboBox_phase.insertItem(1, 'S')
|
||||||
self.top_row.addWidget(QtGui.QLabel('Select a phase: '))
|
|
||||||
self.top_row.addWidget(self.combobox)
|
|
||||||
|
|
||||||
|
# self.comboBox_am = QtGui.QComboBox()
|
||||||
|
# self.comboBox_am.insertItem(0, 'auto')
|
||||||
|
# self.comboBox_am.insertItem(1, 'manual')
|
||||||
|
|
||||||
|
self.top_row.addWidget(QtGui.QLabel('Select a phase: '))
|
||||||
|
self.top_row.addWidget(self.comboBox_phase)
|
||||||
|
self.top_row.setStretch(1,1) #set stretch of item 1 to 1
|
||||||
|
|
||||||
|
if not self.figure:
|
||||||
fig = plt.figure()
|
fig = plt.figure()
|
||||||
|
else:
|
||||||
|
fig = self.figure
|
||||||
self.main_ax = fig.add_subplot(111)
|
self.main_ax = fig.add_subplot(111)
|
||||||
self.canvas = fig.canvas
|
self.canvas = fig.canvas
|
||||||
self.main_box.addWidget(self.canvas)
|
self.main_box.addWidget(self.canvas)
|
||||||
@ -99,12 +115,12 @@ class map_projection(QtGui.QWidget):
|
|||||||
self.lon = lon
|
self.lon = lon
|
||||||
|
|
||||||
def init_picks(self):
|
def init_picks(self):
|
||||||
phase = self.combobox.currentText()
|
phase = self.comboBox_phase.currentText()
|
||||||
def get_picks(station_names):
|
def get_picks(station_names):
|
||||||
picks=[]
|
picks=[]
|
||||||
for station in station_names:
|
for station in station_names:
|
||||||
try:
|
try:
|
||||||
picks.append(self.pyl_mainwindow.autopicks[station][phase]['mpp'])
|
picks.append(self.picks_dict[station][phase]['mpp'])
|
||||||
except:
|
except:
|
||||||
picks.append(np.nan)
|
picks.append(np.nan)
|
||||||
return picks
|
return picks
|
||||||
@ -216,30 +232,47 @@ class map_projection(QtGui.QWidget):
|
|||||||
cbar.set_label(label)
|
cbar.set_label(label)
|
||||||
return cbar
|
return cbar
|
||||||
|
|
||||||
def refresh_drawings(self):
|
def refresh_drawings(self, picks=None):
|
||||||
|
self.picks_dict = picks
|
||||||
|
self.remove_drawings()
|
||||||
|
self.draw_everything()
|
||||||
|
|
||||||
|
def _refresh_drawings(self):
|
||||||
self.remove_drawings()
|
self.remove_drawings()
|
||||||
self.draw_everything()
|
self.draw_everything()
|
||||||
|
|
||||||
def draw_everything(self):
|
def draw_everything(self):
|
||||||
|
if self.picks_dict:
|
||||||
self.init_picks()
|
self.init_picks()
|
||||||
self.init_picks_active()
|
self.init_picks_active()
|
||||||
self.init_stations_active()
|
self.init_stations_active()
|
||||||
self.init_picksgrid()
|
self.init_picksgrid()
|
||||||
self.draw_contour_filled()
|
self.draw_contour_filled()
|
||||||
self.scatter_all_stations()
|
self.scatter_all_stations()
|
||||||
|
if self.picks_dict:
|
||||||
self.scatter_picked_stations()
|
self.scatter_picked_stations()
|
||||||
self.annotate_ax()
|
|
||||||
self.cbar = self.add_cbar(label='Time relative to first onset [s]')
|
self.cbar = self.add_cbar(label='Time relative to first onset [s]')
|
||||||
|
self.comboBox_phase.setEnabled(True)
|
||||||
|
else:
|
||||||
|
self.comboBox_phase.setEnabled(False)
|
||||||
|
self.annotate_ax()
|
||||||
self.canvas.draw()
|
self.canvas.draw()
|
||||||
|
|
||||||
def remove_drawings(self):
|
def remove_drawings(self):
|
||||||
|
if hasattr(self, 'sc_picked'):
|
||||||
self.sc_picked.remove()
|
self.sc_picked.remove()
|
||||||
self.sc.remove()
|
del(self.sc_picked)
|
||||||
|
if hasattr(self, 'cbar'):
|
||||||
self.cbar.remove()
|
self.cbar.remove()
|
||||||
self.remove_annotations()
|
del(self.cbar)
|
||||||
self.legend.remove()
|
if hasattr(self, 'contourf'):
|
||||||
self.remove_contourf()
|
self.remove_contourf()
|
||||||
|
del(self.contourf)
|
||||||
|
if hasattr(self, 'cid'):
|
||||||
self.canvas.mpl_disconnect(self.cid)
|
self.canvas.mpl_disconnect(self.cid)
|
||||||
|
del(self.cid)
|
||||||
|
self.sc.remove()
|
||||||
|
self.legend.remove()
|
||||||
self.canvas.draw()
|
self.canvas.draw()
|
||||||
|
|
||||||
def remove_contourf(self):
|
def remove_contourf(self):
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
import sys
|
import sys
|
||||||
from PySide.QtCore import QThread, Signal
|
from PySide.QtCore import QThread, Signal, Qt
|
||||||
|
from PySide.QtGui import QDialog, QProgressBar, QLabel, QVBoxLayout
|
||||||
|
|
||||||
|
|
||||||
class AutoPickThread(QThread):
|
class AutoPickThread(QThread):
|
||||||
@ -35,3 +36,42 @@ class AutoPickThread(QThread):
|
|||||||
|
|
||||||
def flush(self):
|
def flush(self):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class Thread(QThread):
|
||||||
|
def __init__(self, parent, func, arg=None, progressText=None):
|
||||||
|
QThread.__init__(self, parent)
|
||||||
|
self.func = func
|
||||||
|
self.arg = arg
|
||||||
|
self.progressText = progressText
|
||||||
|
self.pbdlg = None
|
||||||
|
self.finished.connect(self.hideProgressbar)
|
||||||
|
self.showProgressbar()
|
||||||
|
|
||||||
|
def run(self):
|
||||||
|
if self.arg:
|
||||||
|
self.data = self.func(self.arg)
|
||||||
|
else:
|
||||||
|
self.data = self.func()
|
||||||
|
|
||||||
|
def __del__(self):
|
||||||
|
self.wait()
|
||||||
|
|
||||||
|
def showProgressbar(self):
|
||||||
|
if self.progressText:
|
||||||
|
self.pbdlg = QDialog(self.parent())
|
||||||
|
self.pbdlg.setModal(True)
|
||||||
|
vl = QVBoxLayout()
|
||||||
|
pb = QProgressBar()
|
||||||
|
pb.setRange(0, 0)
|
||||||
|
vl.addWidget(pb)
|
||||||
|
vl.addWidget(QLabel(self.progressText))
|
||||||
|
self.pbdlg.setLayout(vl)
|
||||||
|
self.pbdlg.setWindowFlags(Qt.SplashScreen)
|
||||||
|
self.pbdlg.show()
|
||||||
|
|
||||||
|
def hideProgressbar(self):
|
||||||
|
if self.pbdlg:
|
||||||
|
self.pbdlg.hide()
|
||||||
|
|
||||||
|
|
||||||
|
@ -397,7 +397,7 @@ class WaveformWidget(FigureCanvas):
|
|||||||
self.setParent(parent)
|
self.setParent(parent)
|
||||||
self.figure = Figure()
|
self.figure = Figure()
|
||||||
self.figure.set_facecolor((.92, .92, .92))
|
self.figure.set_facecolor((.92, .92, .92))
|
||||||
# attribute plotdict is an dictionary connecting position and a name
|
# attribute plotdict is a dictionary connecting position and a name
|
||||||
self.plotdict = dict()
|
self.plotdict = dict()
|
||||||
# create axes
|
# create axes
|
||||||
self.axes = self.figure.add_subplot(111)
|
self.axes = self.figure.add_subplot(111)
|
||||||
|
Loading…
Reference in New Issue
Block a user