Merge branch 'develop' of ariadne.geophysik.ruhr-uni-bochum.de:/data/git/pylot into develop

This commit is contained in:
Marcel Paffrath 2016-06-13 14:35:47 +02:00
commit d02bb369ec
3 changed files with 244 additions and 36 deletions

View File

@ -42,6 +42,7 @@ from obspy import UTCDateTime
from pylot.core.io.data import Data
from pylot.core.io.inputs import FilterOptions, AutoPickParameter
from pylot.core.pick.autopick import autopickevent
from pylot.core.pick.compare import Comparison
from pylot.core.io.phases import picksdict_from_picks
from pylot.core.loc.nll import locate as locateNll
from pylot.core.util.defaults import FILTERDEFAULTS, COMPNAME_MAP, \
@ -53,7 +54,8 @@ from pylot.core.util.utils import fnConstructor, getLogin, \
getGlobalTimes
from pylot.core.io.location import create_creation_info, create_event
from pylot.core.util.widgets import FilterOptionsDialog, NewEventDlg, \
WaveformWidget, PropertiesDlg, HelpForm, createAction, PickDlg, getDataType
WaveformWidget, PropertiesDlg, HelpForm, createAction, PickDlg, \
getDataType, ComparisonDialog
from pylot.core.util.structure import DATASTRUCTURE
from pylot.core.util.thread import AutoPickThread
from pylot.core.util.version import get_git_version as _getVersionString
@ -578,7 +580,9 @@ class MainWindow(QMainWindow):
def comparePicks(self):
if self.check4Comparison():
compare_dlg = ComparisonDialog(self)
co = Comparison(auto=self.getPicks('auto'), manu=self.getPicks())
compare_dlg = ComparisonDialog(co, self)
compare_dlg.exec_()
def getPlotWidget(self):
return self.DataPlot
@ -749,7 +753,7 @@ class MainWindow(QMainWindow):
wfID = self.getWFID(gui_event)
if not wfID: return
if wfID is None: return
station = self.getStationName(wfID)
self.updateStatus('picking on station {0}'.format(station))

View File

@ -29,10 +29,12 @@ class Comparison(object):
names = list()
self._pdfs = dict()
for name, fn in kwargs.items():
if not isinstance(PDFDictionary, fn):
self._pdfs[name] = PDFDictionary.from_quakeml(fn)
else:
if isinstance(fn, PDFDictionary):
self._pdfs[name] = fn
elif isinstance(fn, dict):
self._pdfs[name] = PDFDictionary(fn)
else:
self._pdfs[name] = PDFDictionary.from_quakeml(fn)
names.append(name)
if len(names) > 2:
raise ValueError('Comparison is only defined for two '
@ -138,29 +140,28 @@ class Comparison(object):
plt.show()
def get_expectation_array(self, phase):
def get_all(self, phasename):
pdf_dict = self.comparison
exp_array = list()
for station, phases in pdf_dict.items():
rlist = list()
for phases in pdf_dict.values():
try:
exp_array.append(phases[phase].expectation())
except KeyError as e:
print('{err_msg}; station = {station}, phase = {phase}'.format(
err_msg=str(e), station=station, phase=phase))
rlist.append(phases[phasename])
except KeyError:
continue
return exp_array
return rlist
def get_array(self, phase, method_name):
import operator
method = operator.methodcaller(method_name)
pdf_list = self.get_all(phase)
rarray = map(method, pdf_list)
return np.array(rarray)
def get_expectation_array(self, phase):
return self.get_array(phase, 'expectation')
def get_std_array(self, phase):
pdf_dict = self.comparison
std_array = list()
for station, phases in pdf_dict.items():
try:
std_array.append(phases[phase].standard_deviation())
except KeyError as e:
print('{err_msg}; station = {station}, phase = {phase}'.format(
err_msg=str(e), station=station, phase=phase))
continue
return std_array
return self.get_array(phase, 'standard_deviation')
def hist_expectation(self, phases='all', bins=20, normed=False):
phases.strip()
@ -222,6 +223,9 @@ class PDFDictionary(object):
else:
return True
def __getitem__(self, item):
return self.pdf_data[item]
@property
def pdf_data(self):
return self._pdfdata
@ -268,6 +272,8 @@ class PDFDictionary(object):
for station, phases in pdf_picks.items():
for phase, values in phases.items():
if phase not in 'PS':
continue
phases[phase] = ProbabilityDensityFunction.from_pick(
values['epp'],
values['mpp'],

View File

@ -17,17 +17,18 @@ except ImportError:
from matplotlib.backends.backend_qt4agg import FigureCanvasQTAgg as FigureCanvas
from matplotlib.backends.backend_qt4agg import NavigationToolbar2QT
from matplotlib.widgets import MultiCursor
from PySide.QtGui import QAction, QApplication, QComboBox, QDateTimeEdit, \
QDialog, QDialogButtonBox, QDoubleSpinBox, QGroupBox, QGridLayout, \
QIcon, QKeySequence, QLabel, QLineEdit, QMessageBox, QPixmap, QSpinBox, \
QTabWidget, QToolBar, QVBoxLayout, QWidget, QPushButton, QFileDialog, \
QInputDialog
from PySide.QtGui import QAction, QApplication, QCheckBox, QComboBox, \
QDateTimeEdit, QDialog, QDialogButtonBox, QDoubleSpinBox, QGroupBox, \
QGridLayout, QIcon, QKeySequence, QLabel, QLineEdit, QMessageBox, \
QPixmap, QSpinBox, QTabWidget, QToolBar, QVBoxLayout, QWidget, \
QPushButton, QFileDialog, QInputDialog
from PySide.QtCore import QSettings, Qt, QUrl, Signal, Slot
from PySide.QtWebKit import QWebView
from obspy import Stream, UTCDateTime
from pylot.core.io.inputs import FilterOptions
from pylot.core.pick.utils import getSNR, earllatepicker, getnoisewin, \
getResolutionWindow
from pylot.core.pick.compare import Comparison
from pylot.core.util.defaults import OUTPUTFORMATS, FILTERDEFAULTS, LOCTOOLS, \
COMPPOSITION_MAP
from pylot.core.util.utils import prepTimeAxis, getGlobalTimes, scaleWFData, \
@ -64,21 +65,70 @@ def createAction(parent, text, slot=None, shortcut=None, icon=None,
action.setCheckable(True)
return action
class ComparsionDialog(QDialog):
class ComparisonDialog(QDialog):
def __init__(self, c, parent=None):
self._data = c
self._stats = c.keys()
self._canvas = PlotWidget(parent)
super(ComparsionDialog, self).__init__(parent)
self
self._stats = c.stations
self._canvas = PlotWidget(self)
self._widgets = dict(stationsComboBox=None,
phasesComboBox=None,
histCheckBox=None)
self._phases = 'PS'
self._plotprops = dict(station=self.stations[0], phase=self.phases[0])
super(ComparisonDialog, self).__init__(parent)
self.setupUI()
self.plotcomparison()
def setupUI(self):
pass
_outerlayout = QVBoxLayout(self)
_innerlayout = QVBoxLayout(self)
_stats_combobox = QComboBox(self)
_stats_combobox.setObjectName('stationsComboBox')
_stats_combobox.setEditable(True)
_stats_combobox.setInsertPolicy(QComboBox.NoInsert)
_stats_combobox.addItems(self.stations)
_stats_combobox.editTextChanged.connect(self.prepareplot)
self.widgets = _stats_combobox
_phases_combobox = QComboBox(self)
_phases_combobox.setObjectName('phasesComboBox')
_phases_combobox.addItems(['P', 'S'])
_phases_combobox.currentIndexChanged.connect(self.prepareplot)
self.widgets = _phases_combobox
_hist_checkbox = QCheckBox('Show histograms', self)
_hist_checkbox.setObjectName('histCheckBox')
_hist_checkbox.stateChanged.connect(self.plothist)
self.widgets = _hist_checkbox
_toolbar = QToolBar(self)
_toolbar.addWidget(_stats_combobox)
_toolbar.addWidget(_phases_combobox)
_toolbar.addWidget(_hist_checkbox)
_buttonbox = QDialogButtonBox(QDialogButtonBox.Close)
_innerlayout.addWidget(self.canvas)
_innerlayout.addWidget(_buttonbox)
_outerlayout.addWidget(_toolbar)
_outerlayout.addLayout(_innerlayout)
_buttonbox.rejected.connect(self.reject)
# finally layout the entire dialog
self.setLayout(_outerlayout)
@property
def canvas(self):
return self._canvas
@canvas.setter
def canvas(self, canvas_obj):
self._canvas = canvas_obj
@property
def stations(self):
return self._stats
@ -87,15 +137,163 @@ class ComparsionDialog(QDialog):
def stations(self, stations):
self._stats = stations
@property
def phases(self):
return self._phases
@phases.setter
def phases(self, value):
self._phases = value
@property
def plotprops(self):
return self._plotprops
@plotprops.setter
def plotprops(self, values):
try:
key, value = values
if key not in self.plotprops.keys():
raise KeyError("'key' {0} not found in "
"ComparisonDialog.plotprops keys.".format(key))
except ValueError:
raise ValueError("Pass an iterable with two items")
else:
self._plotprops[key] = value
@property
def data(self):
return self._data
@data.setter
def data(self, data):
self.stations = data.keys()
assert not isinstance(data, Comparison)
self.stations = data.stations
self._data = data
@property
def widgets(self):
return self._widgets
@widgets.setter
def widgets(self, widget):
name = widget.objectName()
if name in self.widgets.keys():
self._widgets[name] = widget
def hasvalue(self, sender):
text = sender.currentText()
index = sender.findText(text.upper())
return index
def prepareplot(self):
try:
_widget = self.sender()
name = _widget.objectName()
text = _widget.currentText().upper()
index = self.hasvalue(_widget)
if name == 'stationsComboBox' and index is not -1:
_widget.setCurrentIndex(index)
self.plotprops = ('station', text)
elif name == 'phasesComboBox':
self.plotprops = ('phase', text)
except ValueError:
raise ValueError('No sender widget given!')
finally:
self.plotcomparison()
def plotcomparison(self):
from matplotlib import gridspec
_axes = self.canvas.figure.add_subplot(111)
_gs = gridspec.GridSpec(3, 2)
_axes = self.canvas.figure.add_subplot(_gs[0:2, :])
_ax1 = self.canvas.figure.add_subplot(_gs[2, 0])
_ax2 = self.canvas.figure.add_subplot(_gs[2, 1])
_axes.cla()
station = self.plotprops['station']
phase = self.plotprops['phase']
pdf = self.data.comparison[station][phase]
x, y, std, exp = pdf.axis, pdf.data, pdf.standard_deviation(), \
pdf.expectation()
_axes.plot(x, y)
_axes.set_title(phase)
_axes.set_ylabel('propability density [-]')
_axes.set_xlabel('time difference [s]')
annotation = "{phase} difference on {station}\n" \
"expectation: {exp}\n" \
"std: {std}".format(station=station, phase=phase,
std=std, exp=exp)
_anno = _axes.annotate(annotation, xy=(.05, .5), xycoords='axes '
'fraction')
bbox_props = dict(boxstyle='round', facecolor='lightgrey', alpha=.7)
_anno.set_bbox(bbox_props)
pdf_a = self.data.get('auto')[station][phase]
pdf_m = self.data.get('manu')[station][phase]
xauto, yauto, stdauto, expauto = pdf_a.axis, pdf_a.data, \
pdf_a.standard_deviation(), \
pdf_a.expectation()
xmanu, ymanu, stdmanu, expmanu = pdf_m.axis, pdf_m.data, \
pdf_m.standard_deviation(), \
pdf_m.expectation()
_ax1.plot(xauto, yauto)
_ax2.plot(xmanu, ymanu)
_gs.update(wspace=0.5, hspace=0.5)
self.canvas.draw()
def plothist(self):
name = self.sender().objectName()
if self.widgets[name].isChecked():
for wname, widget in self.widgets.items():
if wname != name:
self.widgets[wname].setEnabled(False)
self.canvas.figure.clf()
_axPstd, _axPexp = self.canvas.figure.add_subplot(221), self.canvas.figure.add_subplot(223)
_axSstd, _axSexp = self.canvas.figure.add_subplot(222), self.canvas.figure.add_subplot(224)
axes_dict = dict(P=dict(std=_axPstd, exp=_axPexp),
S=dict(std=_axSstd, exp=_axSexp))
bbox_props = dict(boxstyle='round', facecolor='lightgrey', alpha=.7)
for phase in self.phases:
std = self.data.get_std_array(phase)
std = std[np.isfinite(std)]
stdxlims = [0., 1.2 * max(std)]
exp = self.data.get_expectation_array(phase)
exp = exp[np.isfinite(exp)]
eps_exp = 0.05 * (max(exp) - min(exp))
expxlims = [min(exp) - eps_exp, max(exp) + eps_exp]
axes_dict[phase]['std'].hist(std, range=stdxlims, bins=20, normed=False)
axes_dict[phase]['exp'].hist(exp, range=expxlims, bins=20,
normed=False)
std_annotation = "Distribution curve for {phase} differences'\n" \
"standard deviations (all stations)\n" \
"number of samples: {nsamples}".format(phase=phase, nsamples=len(std))
_anno_std = axes_dict[phase]['std'].annotate(std_annotation, xy=(.05, .8), xycoords='axes fraction')
_anno_std.set_bbox(bbox_props)
exp_annotation = "Distribution curve for {phase} differences'\n" \
"expectations (all stations)\n" \
"number of samples: {nsamples}".format(phase=phase, nsamples=len(exp))
_anno_exp = axes_dict[phase]['exp'].annotate(exp_annotation, xy=(.05, .8), xycoords='axes fraction')
_anno_exp.set_bbox(bbox_props)
axes_dict[phase]['exp'].set_xlabel('expectation [s]')
axes_dict[phase]['std'].set_xlabel('standard deviation [s]')
for ax in axes_dict['P'].values():
ax.set_ylabel('frequency [-]')
self.canvas.draw()
else:
for wname, widget in self.widgets.items():
if wname != name:
self.widgets[wname].setEnabled(True)
self.canvas.figure.clf()
self.plotcomparison()
class PlotWidget(FigureCanvas):
def __init__(self, parent=None, xlabel='x', ylabel='y', title='Title'):