438 lines
14 KiB
Python
438 lines
14 KiB
Python
# -*- coding: utf-8 -*-
|
|
"""
|
|
Created on Wed Mar 19 11:27:35 2014
|
|
|
|
@author: sebastianw
|
|
"""
|
|
|
|
import datetime
|
|
import matplotlib
|
|
|
|
matplotlib.use('Qt4Agg')
|
|
matplotlib.rcParams['backend.qt4'] = 'PySide'
|
|
|
|
from matplotlib.figure import Figure
|
|
from matplotlib.backends.backend_qt4agg import FigureCanvasQTAgg as FigureCanvas
|
|
from PySide.QtGui import (QAction,
|
|
QApplication,
|
|
QComboBox,
|
|
QDateTimeEdit,
|
|
QDialog,
|
|
QDialogButtonBox,
|
|
QDoubleSpinBox,
|
|
QGroupBox,
|
|
QGridLayout,
|
|
QHBoxLayout,
|
|
QIcon,
|
|
QKeySequence,
|
|
QLabel,
|
|
QLineEdit,
|
|
QMessageBox,
|
|
QSpinBox,
|
|
QTabWidget,
|
|
QToolBar,
|
|
QVBoxLayout,
|
|
QWidget)
|
|
from PySide.QtCore import (QSettings,
|
|
Qt,
|
|
QUrl,
|
|
SIGNAL,
|
|
SLOT)
|
|
from PySide.QtWebKit import QWebView
|
|
from pylot.core.read import FilterOptions
|
|
from pylot.core.util.defaults import OUTPUTFORMATS
|
|
|
|
|
|
class MPLWidget(FigureCanvas):
|
|
|
|
def __init__(self, parent=None, xlabel='x', ylabel='y', title='Title'):
|
|
super(MPLWidget, self).__init__(Figure())
|
|
|
|
self.setParent(parent)
|
|
self.figure = Figure()
|
|
self.canvas = FigureCanvas(self.figure)
|
|
self.axes = self.figure.add_subplot(111)
|
|
|
|
self.axes.set_xlabel(xlabel)
|
|
self.axes.set_ylabel(ylabel)
|
|
self.axes.set_title(title)
|
|
|
|
|
|
class PickDlg(QDialog):
|
|
|
|
def __init__(self, station=None, parent=None):
|
|
super(PickDlg, self).__init__(parent)
|
|
|
|
pass
|
|
|
|
|
|
class PropertiesDlg(QDialog):
|
|
|
|
def __init__(self, parent=None):
|
|
super(PropertiesDlg, self).__init__(parent)
|
|
|
|
appName = QApplication.applicationName()
|
|
|
|
self.setWindowTitle("{0} Properties".format(appName))
|
|
|
|
self.tabWidget = QTabWidget()
|
|
self.tabWidget.addTab(InputsTab(self), "Inputs")
|
|
self.tabWidget.addTab(OutputsTab(self), "Outputs")
|
|
self.tabWidget.addTab(PhasesTab(self), "Phases")
|
|
self.tabWidget.addTab(GraphicsTab(self), "Graphics")
|
|
self.buttonBox = QDialogButtonBox(QDialogButtonBox.Ok |
|
|
QDialogButtonBox.Apply |
|
|
QDialogButtonBox.Close)
|
|
|
|
layout = QVBoxLayout()
|
|
layout.addWidget(self.tabWidget)
|
|
layout.addWidget(self.buttonBox)
|
|
self.setLayout(layout)
|
|
|
|
self.connect(self.buttonBox, SIGNAL("accepted()"), self,
|
|
SLOT("accept()"))
|
|
self.connect(self.buttonBox.button(QDialogButtonBox.Apply),
|
|
SIGNAL("clicked()"), self.apply)
|
|
self.connect(self.buttonBox, SIGNAL("rejected()"),
|
|
self, SLOT("reject()"))
|
|
|
|
def accept(self, *args, **kwargs):
|
|
self.apply()
|
|
self.destroy()
|
|
|
|
def reject(self, *args, **kwargs):
|
|
self.destroy()
|
|
|
|
def apply(self):
|
|
for widint in range(self.tabWidget.count()):
|
|
curwid = self.tabWidget.widget(widint)
|
|
values = curwid.getValues()
|
|
if values is not None: self.setValues(values)
|
|
|
|
def setValues(self, tabValues):
|
|
settings = QSettings()
|
|
for setting, value in tabValues.iteritems():
|
|
settings.setValue(setting, value)
|
|
settings.sync()
|
|
|
|
|
|
class PropTab(QWidget):
|
|
|
|
def __init__(self, parent=None):
|
|
super(PropTab, self).__init__(parent)
|
|
|
|
def getValues(self):
|
|
return None
|
|
|
|
|
|
class InputsTab(PropTab):
|
|
|
|
def __init__(self, parent):
|
|
super(InputsTab, self).__init__(parent)
|
|
|
|
settings = QSettings()
|
|
fulluser = settings.value("user/FullName")
|
|
login = settings.value("user/Login")
|
|
|
|
fullNameLabel = QLabel("Full name for user '{0}': ".format(login))
|
|
|
|
# get the full name of the actual user
|
|
self.fullNameEdit = QLineEdit()
|
|
self.fullNameEdit.setText(fulluser)
|
|
|
|
# information about data structure
|
|
dataroot = settings.value("data/dataRoot")
|
|
dataDirLabel = QLabel("data root directory: ")
|
|
self.dataDirEdit = QLineEdit()
|
|
self.dataDirEdit.setText(dataroot)
|
|
self.dataDirEdit.selectAll()
|
|
structureLabel = QLabel("data structure: ")
|
|
self.structureSelect = QComboBox()
|
|
|
|
from pylot.core.util.structure import DATASTRUCTURE
|
|
|
|
datastruct = DATASTRUCTURE.keys()
|
|
self.structureSelect.addItems(datastruct)
|
|
self.updateWidget(DATASTRUCTURE)
|
|
|
|
layout = QGridLayout()
|
|
layout.addWidget(dataDirLabel, 0, 0)
|
|
layout.addWidget(self.dataDirEdit, 0, 1)
|
|
layout.addWidget(fullNameLabel, 1, 0)
|
|
layout.addWidget(self.fullNameEdit, 1, 1)
|
|
|
|
self.setLayout(layout)
|
|
|
|
def getValues(self):
|
|
values = {}
|
|
values["data/dataRoot"] = self.dataDirEdit.text()
|
|
values["user/FullName"] = self.fullNameEdit.text()
|
|
return values
|
|
|
|
def updateWidget(self, structure):
|
|
key = self.structureSelect.currentText()
|
|
structure = structure[key]
|
|
structure().getFields().keys()
|
|
|
|
|
|
|
|
|
|
class OutputsTab(PropTab):
|
|
|
|
def __init__(self, parent=None):
|
|
super(OutputsTab, self).__init__(parent)
|
|
|
|
settings = QSettings()
|
|
curval = settings.value("output/Format", None)
|
|
|
|
eventOutputLabel = QLabel("event ouput format")
|
|
self.eventOutputComboBox = QComboBox()
|
|
eventoutputformats = OUTPUTFORMATS.keys()
|
|
self.eventOutputComboBox.addItems(eventoutputformats)
|
|
|
|
if curval is None:
|
|
ind = 0
|
|
else:
|
|
ind = self.eventOutputComboBox.findText(curval)
|
|
|
|
self.eventOutputComboBox.setCurrentIndex(ind)
|
|
layout = QGridLayout()
|
|
layout.addWidget(eventOutputLabel, 0, 0)
|
|
layout.addWidget(self.eventOutputComboBox, 0, 1)
|
|
|
|
self.setLayout(layout)
|
|
|
|
def getValues(self):
|
|
values = {}
|
|
values["output/Format"] = self.eventOutputComboBox.currentText()
|
|
return values
|
|
|
|
class PhasesTab(PropTab):
|
|
|
|
def __init__(self, parent=None):
|
|
super(PhasesTab, self).__init__(parent)
|
|
|
|
pass
|
|
|
|
|
|
class GraphicsTab(PropTab):
|
|
|
|
def __init__(self, parent=None):
|
|
super(GraphicsTab, self).__init__(parent)
|
|
|
|
pass
|
|
|
|
|
|
class NewEventDlg(QDialog):
|
|
def __init__(self, parent=None, titleString="Create a new event"):
|
|
"""
|
|
QDialog object utilized to create a new event manually.
|
|
"""
|
|
super(NewEventDlg, self).__init__()
|
|
|
|
self.setupUI()
|
|
|
|
now = datetime.datetime.now()
|
|
self.eventTimeEdit.setDateTime(now)
|
|
# event dates in the future are forbidden
|
|
self.eventTimeEdit.setMaximumDateTime(now)
|
|
|
|
self.latEdit.setText("51.0000")
|
|
self.lonEdit.setText("7.0000")
|
|
self.depEdit.setText("10.0")
|
|
|
|
self.buttonBox.accepted.connect(self.accept)
|
|
self.buttonBox.rejected.connect(self.reject)
|
|
|
|
def getValues(self):
|
|
if self.accepted():
|
|
return {'origintime' : self.eventTimeEdit.dateTime().toPyDateTime(),
|
|
'latitude' : self.latEdit.text(),
|
|
'longitude' : self.lonEdit.text(),
|
|
'depth' : self.depEdit.text()}
|
|
|
|
def setupUI(self):
|
|
|
|
# create widget objects
|
|
timeLabel = QLabel()
|
|
timeLabel.setText("Select time: ")
|
|
self.eventTimeEdit = QDateTimeEdit()
|
|
latLabel = QLabel()
|
|
latLabel.setText("Latitude: ")
|
|
self.latEdit = QLineEdit()
|
|
lonLabel = QLabel()
|
|
lonLabel.setText("Longitude: ")
|
|
self.lonEdit = QLineEdit()
|
|
depLabel = QLabel()
|
|
depLabel.setText("Depth: ")
|
|
self.depEdit = QLineEdit()
|
|
|
|
self.buttonBox = QDialogButtonBox(QDialogButtonBox.Ok |
|
|
QDialogButtonBox.Cancel)
|
|
|
|
grid = QGridLayout()
|
|
grid.addWidget(timeLabel, 0, 0)
|
|
grid.addWidget(self.eventTimeEdit, 0, 1)
|
|
grid.addWidget(latLabel, 1, 0)
|
|
grid.addWidget(self.latEdit, 1, 1)
|
|
grid.addWidget(lonLabel, 2, 0)
|
|
grid.addWidget(self.lonEdit, 2, 1)
|
|
grid.addWidget(depLabel, 3, 0)
|
|
grid.addWidget(self.depEdit, 3, 1)
|
|
grid.addWidget(self.buttonBox, 4, 1)
|
|
|
|
self.setLayout(grid)
|
|
|
|
class FilterOptionsDialog(QDialog):
|
|
|
|
def __init__(self, parent=None, titleString="Filter options",
|
|
filterOptions=None):
|
|
"""
|
|
PyLoT widget FilterOptionsDialog is a QDialog object. It is an UI to
|
|
adjust parameters for filtering seismic data.
|
|
"""
|
|
super(FilterOptionsDialog, self).__init__()
|
|
|
|
if filterOptions is not None and parent.getSeismicPhase() != "P":
|
|
self.filterOptions = filterOptions
|
|
else:
|
|
self.filterOptions = FilterOptions()
|
|
|
|
self.freqminLabel = QLabel()
|
|
self.freqminLabel.setText("minimum:")
|
|
self.freqminSpinBox = QDoubleSpinBox()
|
|
self.freqminSpinBox.setRange(5e-7, 1e6)
|
|
self.freqminSpinBox.setDecimals(2)
|
|
self.freqminSpinBox.setSuffix(' Hz')
|
|
self.freqminSpinBox.setValue(self.getFilterOptions().getFreq[0])
|
|
self.freqmaxLabel = QLabel()
|
|
self.freqmaxLabel.setText("maximum:")
|
|
self.freqmaxSpinBox = QDoubleSpinBox()
|
|
self.freqmaxSpinBox.setRange(5e-7, 1e6)
|
|
self.freqmaxSpinBox.setDecimals(2)
|
|
self.freqmaxSpinBox.setSuffix(' Hz')
|
|
if self.filterOptions.filterType in ['bandpass', 'bandstop']:
|
|
self.freqmaxSpinBox.setValue(self.getFilterOptions().getFreq[1])
|
|
|
|
typeOptions = ["bandpass", "bandstop", "lowpass", "highpass"]
|
|
|
|
self.orderLabel = QLabel()
|
|
self.orderLabel.setText("Order:")
|
|
self.orderSpinBox = QSpinBox()
|
|
self.orderSpinBox.setRange(2, 10)
|
|
self.selectTypeLabel = QLabel()
|
|
self.selectTypeLabel.setText("Select filter type:")
|
|
self.selectTypeCombo = QComboBox()
|
|
self.selectTypeCombo.addItems(typeOptions)
|
|
self.selectTypeLayout = QVBoxLayout()
|
|
self.selectTypeLayout.addWidget(self.orderLabel)
|
|
self.selectTypeLayout.addWidget(self.orderSpinBox)
|
|
self.selectTypeLayout.addWidget(self.selectTypeLabel)
|
|
self.selectTypeLayout.addWidget(self.selectTypeCombo)
|
|
|
|
self.freqGroupBox = QGroupBox("Frequency range")
|
|
self.freqGroupLayout = QGridLayout()
|
|
self.freqGroupLayout.addWidget(self.freqminLabel, 0, 0)
|
|
self.freqGroupLayout.addWidget(self.freqminSpinBox, 0, 1)
|
|
self.freqGroupLayout.addWidget(self.freqmaxLabel, 1, 0)
|
|
self.freqGroupLayout.addWidget(self.freqmaxSpinBox, 1, 1)
|
|
self.freqGroupBox.setLayout(self.freqGroupLayout)
|
|
|
|
self.buttonBox = QDialogButtonBox(QDialogButtonBox.Ok|
|
|
QDialogButtonBox.Cancel)
|
|
|
|
grid = QGridLayout()
|
|
grid.addWidget(self.freqGroupBox, 0, 2, 1, 2)
|
|
grid.addLayout(self.selectTypeLayout, 1, 2, 1, 2)
|
|
grid.addWidget(self.buttonBox, 2, 2, 1, 2)
|
|
|
|
self.setLayout(grid)
|
|
|
|
self.freqminSpinBox.valueChanged.connect(self.updateUi)
|
|
self.freqmaxSpinBox.valueChanged.connect(self.updateUi)
|
|
self.orderSpinBox.valueChanged.connect(self.updateUi)
|
|
self.selectTypeCombo.currentIndexChanged.connect(self.updateUi)
|
|
self.buttonBox.accepted.connect(self.accept)
|
|
self.buttonBox.rejected.connect(self.reject)
|
|
|
|
def updateUi(self):
|
|
if self.selectTypeCombo.currentText() not in ['bandpass', 'bandstop']:
|
|
self.freqminLabel.setText("cutoff:")
|
|
self.freqmaxLabel.setEnabled(False)
|
|
self.freqmaxSpinBox.setEnabled(False)
|
|
self.freqmaxSpinBox.setValue(self.freqminSpinBox.value())
|
|
else:
|
|
self.freqminLabel.setText("minimum:")
|
|
self.freqmaxLabel.setEnabled(True)
|
|
self.freqmaxSpinBox.setEnabled(True)
|
|
|
|
self.filterOptions.filterType = self.selectTypeCombo.currentText()
|
|
freq = []
|
|
freq.append(self.freqminSpinBox.value())
|
|
if self.filterOptions.filterType in ['bandpass', 'bandstop']:
|
|
if self.freqminSpinBox.value() > self.freqmaxSpinBox.value():
|
|
QMessageBox.warning(self, "Value error",
|
|
"Maximum frequency must be at least the "
|
|
"same value as minimum frequency (notch)!")
|
|
self.freqmaxSpinBox.setValue(self.freqminSpinBox.value())
|
|
self.freqmaxSpinBox.selectAll()
|
|
self.freqmaxSpinBox.setFocus()
|
|
return
|
|
freq.append(self.freqmaxSpinBox.value())
|
|
self.filterOptions.freq = freq
|
|
self.filterOptions.order = self.orderSpinBox.value()
|
|
|
|
def getFilterOptions(self):
|
|
return self.filterOptions
|
|
|
|
def accept(self):
|
|
self.updateUi()
|
|
QDialog.accept(self)
|
|
|
|
|
|
class LoadDataDlg(QDialog):
|
|
|
|
def __init__(self, parent=None):
|
|
super(LoadDataDlg, self).__init__(parent)
|
|
|
|
pass
|
|
|
|
|
|
class HelpForm(QDialog):
|
|
|
|
def __init__(self, page=QUrl('https://ariadne.geophysik.rub.de/trac/PyLoT'), parent=None):
|
|
super(HelpForm, self).__init__(parent)
|
|
self.setAttribute(Qt.WA_DeleteOnClose)
|
|
self.setAttribute(Qt.WA_GroupLeader)
|
|
|
|
backAction = QAction(QIcon(":/back.png"), "&Back", self)
|
|
backAction.setShortcut(QKeySequence.Back)
|
|
homeAction = QAction(QIcon(":/home.png"), "&Home", self)
|
|
homeAction.setShortcut("Home")
|
|
self.pageLabel = QLabel()
|
|
|
|
toolBar = QToolBar()
|
|
toolBar.addAction(backAction)
|
|
toolBar.addAction(homeAction)
|
|
toolBar.addWidget(self.pageLabel)
|
|
self.webBrowser = QWebView()
|
|
self.webBrowser.load(page)
|
|
|
|
layout = QVBoxLayout()
|
|
layout.addWidget(toolBar)
|
|
layout.addWidget(self.webBrowser, 1)
|
|
self.setLayout(layout)
|
|
|
|
self.connect(backAction, SIGNAL("triggered()"),
|
|
self.webBrowser, SLOT("backward()"))
|
|
self.connect(homeAction, SIGNAL("triggered()"),
|
|
self.webBrowser, SLOT("home()"))
|
|
self.connect(self.webBrowser, SIGNAL("sourceChanged(QUrl)"),
|
|
self.updatePageTitle)
|
|
|
|
self.resize(400, 600)
|
|
self.setWindowTitle("{0} Help".format(QApplication.applicationName()))
|
|
|
|
def updatePageTitle(self):
|
|
self.pageLabel.setText(self.webBrowser.documentTitle())
|