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

Conflicts:
	pylot/core/util/utils.py
This commit is contained in:
Sebastian Wehling-Benatelli 2016-08-12 19:57:11 +02:00
commit 7921d12c80
15 changed files with 429 additions and 140 deletions

View File

@ -9,7 +9,7 @@ matplotlib.rcParams['backend.qt4']='PySide'
from PySide import QtCore, QtGui from PySide import QtCore, QtGui
from pylot.core.active import activeSeismoPick, surveyUtils, fmtomoUtils, seismicArrayPreparation from pylot.core.active import activeSeismoPick, surveyUtils, fmtomoUtils, seismicArrayPreparation
from pylot.core.active.gui.asp3d_layout import * from pylot.core.active.gui.asp3d_layout import *
from pylot.core.active.gui.windows import Gen_SeisArray, Gen_Survey_from_SA, Gen_Survey_from_SR, Call_autopicker, Call_FMTOMO, Call_VTK_dialog from pylot.core.active.gui.windows import Gen_SeisArray, Gen_Survey_from_SA, Gen_Survey_from_SR, Call_autopicker, Call_FMTOMO, Call_VTK_dialog, Postprocessing
from pylot.core.active.gui.windows import openFile, saveFile, browseDir, getMaxCPU from pylot.core.active.gui.windows import openFile, saveFile, browseDir, getMaxCPU
from matplotlib.backends.backend_qt4agg import FigureCanvasQTAgg as FigureCanvas from matplotlib.backends.backend_qt4agg import FigureCanvasQTAgg as FigureCanvas
@ -43,6 +43,7 @@ class gui_control(object):
self.autopicker = None self.autopicker = None
self.fmtomo = None self.fmtomo = None
self.vtktools = None self.vtktools = None
self.postprocessing = None
def setInitStates(self): def setInitStates(self):
self.setPickState(False) self.setPickState(False)
@ -362,8 +363,9 @@ class gui_control(object):
if not self.checkSurveyState(): if not self.checkSurveyState():
self.printDialogMessage('No Survey defined.') self.printDialogMessage('No Survey defined.')
return return
self.survey.plotAllPicks() self.postprocessing = Postprocessing(self.mainwindow, self.survey)
self.refreshPickedWidgets() # wait until finished #self.survey.plotAllPicks()
#self.refreshPickedWidgets() # wait until finished
def load_survey(self): def load_survey(self):

View File

@ -1,6 +1,7 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
import os import os
import sys import sys
import math
import numpy as np import numpy as np
from pylot.core.active import seismicshot from pylot.core.active import seismicshot
from pylot.core.active.surveyUtils import cleanUp from pylot.core.active.surveyUtils import cleanUp
@ -672,10 +673,29 @@ class Survey(object):
''' '''
import matplotlib.pyplot as plt import matplotlib.pyplot as plt
import math
plt.interactive(True) plt.interactive(True)
from pylot.core.active.surveyPlotTools import regions from pylot.core.active.surveyPlotTools import regions
dist, pick, snrlog, pickerror, spe = self.preparePlotAllPicks(plotRemoved)
color = {'log10SNR': snrlog,
'pickerror': pickerror,
'spe': spe}
self.color = color
if refreshPlot is False:
ax, cbar, sc = self.createPlot(dist, pick, color[colorByVal],
label='%s' % colorByVal)
region = regions(ax, cbar, self)
ax.legend()
return (ax, region)
if refreshPlot is True:
ax, cbar, sc = self.createPlot(dist, pick, color[colorByVal],
label='%s' % colorByVal, ax=ax,
cbar=cbar)
ax.legend()
return ax
def preparePlotAllPicks(self, plotRemoved = False):
dist = [] dist = []
pick = [] pick = []
snrlog = [] snrlog = []
@ -693,29 +713,15 @@ class Survey(object):
pickerror.append(shot.getPickError(traceID)) pickerror.append(shot.getPickError(traceID))
spe.append(shot.getSymmetricPickError(traceID)) spe.append(shot.getSymmetricPickError(traceID))
color = {'log10SNR': snrlog, return dist, pick, snrlog, pickerror, spe
'pickerror': pickerror,
'spe': spe}
self.color = color
if refreshPlot is False:
ax, cbar = self.createPlot(dist, pick, color[colorByVal],
label='%s' % colorByVal)
region = regions(ax, cbar, self)
ax.legend()
return (ax, region)
if refreshPlot is True:
ax, cbar = self.createPlot(dist, pick, color[colorByVal],
label='%s' % colorByVal, ax=ax,
cbar=cbar)
ax.legend()
return ax
def createPlot(self, dist, pick, inkByVal, label, ax=None, cbar=None): def createPlot(self, dist, pick, inkByVal, label, ax=None, cbar=None):
''' '''
Used by plotAllPicks. Used by plotAllPicks.
''' '''
import matplotlib.pyplot as plt import matplotlib.pyplot as plt
plt.interactive(True) #plt.interactive(True)
cm = plt.cm.jet cm = plt.cm.jet
if ax is None: if ax is None:
print('Generating new plot...') print('Generating new plot...')
@ -723,7 +729,7 @@ class Survey(object):
ax = fig.add_subplot(111) ax = fig.add_subplot(111)
sc = ax.scatter(dist, pick, cmap=cm, c=inkByVal, s=5, sc = ax.scatter(dist, pick, cmap=cm, c=inkByVal, s=5,
edgecolors='none', label=label) edgecolors='none', label=label)
cbar = plt.colorbar(sc, fraction=0.05) cbar = fig.colorbar(sc, fraction=0.05)
cbar.set_label(label) cbar.set_label(label)
ax.set_xlabel('Distance [m]') ax.set_xlabel('Distance [m]')
ax.set_ylabel('Time [s]') ax.set_ylabel('Time [s]')
@ -732,13 +738,15 @@ class Survey(object):
else: else:
sc = ax.scatter(dist, pick, cmap=cm, c=inkByVal, s=5, sc = ax.scatter(dist, pick, cmap=cm, c=inkByVal, s=5,
edgecolors='none', label=label) edgecolors='none', label=label)
cbar = plt.colorbar(sc, cax=cbar.ax) if cbar is not None:
cbar.ax.clear()
cbar = ax.figure.colorbar(sc, cax=cbar.ax)
cbar.set_label(label) cbar.set_label(label)
ax.set_xlabel('Distance [m]') ax.set_xlabel('Distance [m]')
ax.set_ylabel('Time [s]') ax.set_ylabel('Time [s]')
ax.text(0.5, 0.95, 'Plot of all picks', transform=ax.transAxes, ax.text(0.5, 0.95, 'Plot of all picks', transform=ax.transAxes,
horizontalalignment='center') horizontalalignment='center')
return (ax, cbar) return ax, cbar, sc
def _update_progress(self, shotname, tend, progress): def _update_progress(self, shotname, tend, progress):
sys.stdout.write( sys.stdout.write(

View File

@ -2,7 +2,7 @@
# Form implementation generated from reading ui file 'asp3d_layout.ui' # Form implementation generated from reading ui file 'asp3d_layout.ui'
# #
# Created: Thu Aug 4 13:55:47 2016 # Created: Wed Aug 10 14:11:07 2016
# by: pyside-uic 0.2.15 running on PySide 1.2.2 # by: pyside-uic 0.2.15 running on PySide 1.2.2
# #
# WARNING! All changes made in this file will be lost! # WARNING! All changes made in this file will be lost!

View File

@ -2,7 +2,7 @@
# Form implementation generated from reading ui file 'fmtomo_parameters_layout.ui' # Form implementation generated from reading ui file 'fmtomo_parameters_layout.ui'
# #
# Created: Thu Aug 4 13:55:47 2016 # Created: Wed Aug 10 14:11:07 2016
# by: pyside-uic 0.2.15 running on PySide 1.2.2 # by: pyside-uic 0.2.15 running on PySide 1.2.2
# #
# WARNING! All changes made in this file will be lost! # WARNING! All changes made in this file will be lost!

View File

@ -2,7 +2,7 @@
# Form implementation generated from reading ui file 'generate_seisarray_layout.ui' # Form implementation generated from reading ui file 'generate_seisarray_layout.ui'
# #
# Created: Thu Aug 4 13:55:47 2016 # Created: Wed Aug 10 14:11:07 2016
# by: pyside-uic 0.2.15 running on PySide 1.2.2 # by: pyside-uic 0.2.15 running on PySide 1.2.2
# #
# WARNING! All changes made in this file will be lost! # WARNING! All changes made in this file will be lost!

View File

@ -2,7 +2,7 @@
# Form implementation generated from reading ui file 'generate_survey_layout.ui' # Form implementation generated from reading ui file 'generate_survey_layout.ui'
# #
# Created: Thu Aug 4 13:55:47 2016 # Created: Wed Aug 10 14:11:07 2016
# by: pyside-uic 0.2.15 running on PySide 1.2.2 # by: pyside-uic 0.2.15 running on PySide 1.2.2
# #
# WARNING! All changes made in this file will be lost! # WARNING! All changes made in this file will be lost!

View File

@ -2,7 +2,7 @@
# Form implementation generated from reading ui file 'generate_survey_layout_minimal.ui' # Form implementation generated from reading ui file 'generate_survey_layout_minimal.ui'
# #
# Created: Thu Aug 4 13:55:47 2016 # Created: Wed Aug 10 14:11:07 2016
# by: pyside-uic 0.2.15 running on PySide 1.2.2 # by: pyside-uic 0.2.15 running on PySide 1.2.2
# #
# WARNING! All changes made in this file will be lost! # WARNING! All changes made in this file will be lost!

View File

@ -2,7 +2,7 @@
# Form implementation generated from reading ui file 'picking_parameters_layout.ui' # Form implementation generated from reading ui file 'picking_parameters_layout.ui'
# #
# Created: Thu Aug 4 13:55:47 2016 # Created: Wed Aug 10 14:11:07 2016
# by: pyside-uic 0.2.15 running on PySide 1.2.2 # by: pyside-uic 0.2.15 running on PySide 1.2.2
# #
# WARNING! All changes made in this file will be lost! # WARNING! All changes made in this file will be lost!

View File

@ -2,7 +2,7 @@
# Form implementation generated from reading ui file 'postprocessing_layout.ui' # Form implementation generated from reading ui file 'postprocessing_layout.ui'
# #
# Created: Tue Aug 9 10:36:58 2016 # Created: Wed Aug 10 14:11:08 2016
# by: pyside-uic 0.2.15 running on PySide 1.2.2 # by: pyside-uic 0.2.15 running on PySide 1.2.2
# #
# WARNING! All changes made in this file will be lost! # WARNING! All changes made in this file will be lost!
@ -12,34 +12,13 @@ from PySide import QtCore, QtGui
class Ui_postprocessing(object): class Ui_postprocessing(object):
def setupUi(self, postprocessing): def setupUi(self, postprocessing):
postprocessing.setObjectName("postprocessing") postprocessing.setObjectName("postprocessing")
postprocessing.resize(640, 479) postprocessing.resize(663, 617)
self.verticalLayout_2 = QtGui.QVBoxLayout(postprocessing) self.verticalLayout = QtGui.QVBoxLayout(postprocessing)
self.verticalLayout_2.setObjectName("verticalLayout_2")
self.verticalLayout = QtGui.QVBoxLayout()
self.verticalLayout.setObjectName("verticalLayout") self.verticalLayout.setObjectName("verticalLayout")
self.gridLayout = QtGui.QGridLayout() self.horizontalLayout_2 = QtGui.QHBoxLayout()
self.gridLayout.setObjectName("gridLayout") self.horizontalLayout_2.setObjectName("horizontalLayout_2")
self.horizontalLayout = QtGui.QHBoxLayout() self.verticalLayout_3 = QtGui.QVBoxLayout()
self.horizontalLayout.setObjectName("horizontalLayout") self.verticalLayout_3.setObjectName("verticalLayout_3")
self.pushButton_rect = QtGui.QPushButton(postprocessing)
sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Minimum)
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(self.pushButton_rect.sizePolicy().hasHeightForWidth())
self.pushButton_rect.setSizePolicy(sizePolicy)
self.pushButton_rect.setMaximumSize(QtCore.QSize(16777215, 30))
self.pushButton_rect.setObjectName("pushButton_rect")
self.horizontalLayout.addWidget(self.pushButton_rect)
self.pushButton_poly = QtGui.QPushButton(postprocessing)
sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Minimum)
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(self.pushButton_poly.sizePolicy().hasHeightForWidth())
self.pushButton_poly.setSizePolicy(sizePolicy)
self.pushButton_poly.setMaximumSize(QtCore.QSize(16777215, 30))
self.pushButton_poly.setObjectName("pushButton_poly")
self.horizontalLayout.addWidget(self.pushButton_poly)
self.gridLayout.addLayout(self.horizontalLayout, 1, 0, 1, 1)
self.label = QtGui.QLabel(postprocessing) self.label = QtGui.QLabel(postprocessing)
sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Preferred, QtGui.QSizePolicy.Minimum) sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Preferred, QtGui.QSizePolicy.Minimum)
sizePolicy.setHorizontalStretch(0) sizePolicy.setHorizontalStretch(0)
@ -49,7 +28,42 @@ class Ui_postprocessing(object):
self.label.setMinimumSize(QtCore.QSize(0, 20)) self.label.setMinimumSize(QtCore.QSize(0, 20))
self.label.setMaximumSize(QtCore.QSize(16777215, 30)) self.label.setMaximumSize(QtCore.QSize(16777215, 30))
self.label.setObjectName("label") self.label.setObjectName("label")
self.gridLayout.addWidget(self.label, 0, 0, 1, 1) self.verticalLayout_3.addWidget(self.label)
self.horizontalLayout_4 = QtGui.QHBoxLayout()
self.horizontalLayout_4.setObjectName("horizontalLayout_4")
self.pushButton_rect = QtGui.QPushButton(postprocessing)
sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Minimum)
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(self.pushButton_rect.sizePolicy().hasHeightForWidth())
self.pushButton_rect.setSizePolicy(sizePolicy)
self.pushButton_rect.setMaximumSize(QtCore.QSize(16777215, 30))
self.pushButton_rect.setObjectName("pushButton_rect")
self.horizontalLayout_4.addWidget(self.pushButton_rect)
self.pushButton_poly = QtGui.QPushButton(postprocessing)
sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Minimum)
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(self.pushButton_poly.sizePolicy().hasHeightForWidth())
self.pushButton_poly.setSizePolicy(sizePolicy)
self.pushButton_poly.setMaximumSize(QtCore.QSize(16777215, 30))
self.pushButton_poly.setObjectName("pushButton_poly")
self.horizontalLayout_4.addWidget(self.pushButton_poly)
self.pushButton_plot = QtGui.QPushButton(postprocessing)
self.pushButton_plot.setCheckable(False)
self.pushButton_plot.setDefault(False)
self.pushButton_plot.setFlat(False)
self.pushButton_plot.setObjectName("pushButton_plot")
self.horizontalLayout_4.addWidget(self.pushButton_plot)
self.verticalLayout_3.addLayout(self.horizontalLayout_4)
self.horizontalLayout_2.addLayout(self.verticalLayout_3)
self.line = QtGui.QFrame(postprocessing)
self.line.setFrameShape(QtGui.QFrame.VLine)
self.line.setFrameShadow(QtGui.QFrame.Sunken)
self.line.setObjectName("line")
self.horizontalLayout_2.addWidget(self.line)
self.verticalLayout_2 = QtGui.QVBoxLayout()
self.verticalLayout_2.setObjectName("verticalLayout_2")
self.label_2 = QtGui.QLabel(postprocessing) self.label_2 = QtGui.QLabel(postprocessing)
sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Preferred, QtGui.QSizePolicy.Minimum) sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Preferred, QtGui.QSizePolicy.Minimum)
sizePolicy.setHorizontalStretch(0) sizePolicy.setHorizontalStretch(0)
@ -59,9 +73,9 @@ class Ui_postprocessing(object):
self.label_2.setMinimumSize(QtCore.QSize(0, 20)) self.label_2.setMinimumSize(QtCore.QSize(0, 20))
self.label_2.setMaximumSize(QtCore.QSize(16777215, 30)) self.label_2.setMaximumSize(QtCore.QSize(16777215, 30))
self.label_2.setObjectName("label_2") self.label_2.setObjectName("label_2")
self.gridLayout.addWidget(self.label_2, 0, 1, 1, 1) self.verticalLayout_2.addWidget(self.label_2)
self.horizontalLayout_3 = QtGui.QHBoxLayout() self.horizontalLayout_5 = QtGui.QHBoxLayout()
self.horizontalLayout_3.setObjectName("horizontalLayout_3") self.horizontalLayout_5.setObjectName("horizontalLayout_5")
self.pushButton_snr = QtGui.QPushButton(postprocessing) self.pushButton_snr = QtGui.QPushButton(postprocessing)
sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Minimum) sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Minimum)
sizePolicy.setHorizontalStretch(0) sizePolicy.setHorizontalStretch(0)
@ -70,7 +84,7 @@ class Ui_postprocessing(object):
self.pushButton_snr.setSizePolicy(sizePolicy) self.pushButton_snr.setSizePolicy(sizePolicy)
self.pushButton_snr.setMaximumSize(QtCore.QSize(16777215, 30)) self.pushButton_snr.setMaximumSize(QtCore.QSize(16777215, 30))
self.pushButton_snr.setObjectName("pushButton_snr") self.pushButton_snr.setObjectName("pushButton_snr")
self.horizontalLayout_3.addWidget(self.pushButton_snr) self.horizontalLayout_5.addWidget(self.pushButton_snr)
self.pushButton_pe = QtGui.QPushButton(postprocessing) self.pushButton_pe = QtGui.QPushButton(postprocessing)
sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Minimum) sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Minimum)
sizePolicy.setHorizontalStretch(0) sizePolicy.setHorizontalStretch(0)
@ -79,7 +93,7 @@ class Ui_postprocessing(object):
self.pushButton_pe.setSizePolicy(sizePolicy) self.pushButton_pe.setSizePolicy(sizePolicy)
self.pushButton_pe.setMaximumSize(QtCore.QSize(16777215, 30)) self.pushButton_pe.setMaximumSize(QtCore.QSize(16777215, 30))
self.pushButton_pe.setObjectName("pushButton_pe") self.pushButton_pe.setObjectName("pushButton_pe")
self.horizontalLayout_3.addWidget(self.pushButton_pe) self.horizontalLayout_5.addWidget(self.pushButton_pe)
self.pushButton_spe = QtGui.QPushButton(postprocessing) self.pushButton_spe = QtGui.QPushButton(postprocessing)
sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Minimum) sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Minimum)
sizePolicy.setHorizontalStretch(0) sizePolicy.setHorizontalStretch(0)
@ -88,29 +102,23 @@ class Ui_postprocessing(object):
self.pushButton_spe.setSizePolicy(sizePolicy) self.pushButton_spe.setSizePolicy(sizePolicy)
self.pushButton_spe.setMaximumSize(QtCore.QSize(16777215, 30)) self.pushButton_spe.setMaximumSize(QtCore.QSize(16777215, 30))
self.pushButton_spe.setObjectName("pushButton_spe") self.pushButton_spe.setObjectName("pushButton_spe")
self.horizontalLayout_3.addWidget(self.pushButton_spe) self.horizontalLayout_5.addWidget(self.pushButton_spe)
self.gridLayout.addLayout(self.horizontalLayout_3, 1, 1, 1, 1) self.verticalLayout_2.addLayout(self.horizontalLayout_5)
self.verticalLayout.addLayout(self.gridLayout) self.horizontalLayout_2.addLayout(self.verticalLayout_2)
self.horizontalLayout_plot = QtGui.QHBoxLayout() self.verticalLayout.addLayout(self.horizontalLayout_2)
self.horizontalLayout_plot.setObjectName("horizontalLayout_plot") self.verticalLayout_plot = QtGui.QVBoxLayout()
self.verticalLayout.addLayout(self.horizontalLayout_plot) self.verticalLayout_plot.setObjectName("verticalLayout_plot")
self.verticalLayout_2.addLayout(self.verticalLayout) self.verticalLayout.addLayout(self.verticalLayout_plot)
self.buttonBox = QtGui.QDialogButtonBox(postprocessing)
self.buttonBox.setOrientation(QtCore.Qt.Horizontal)
self.buttonBox.setStandardButtons(QtGui.QDialogButtonBox.Ok)
self.buttonBox.setObjectName("buttonBox")
self.verticalLayout_2.addWidget(self.buttonBox)
self.retranslateUi(postprocessing) self.retranslateUi(postprocessing)
QtCore.QObject.connect(self.buttonBox, QtCore.SIGNAL("accepted()"), postprocessing.accept)
QtCore.QObject.connect(self.buttonBox, QtCore.SIGNAL("rejected()"), postprocessing.reject)
QtCore.QMetaObject.connectSlotsByName(postprocessing) QtCore.QMetaObject.connectSlotsByName(postprocessing)
def retranslateUi(self, postprocessing): def retranslateUi(self, postprocessing):
postprocessing.setWindowTitle(QtGui.QApplication.translate("postprocessing", "Postprocessing", None, QtGui.QApplication.UnicodeUTF8)) postprocessing.setWindowTitle(QtGui.QApplication.translate("postprocessing", "Postprocessing", None, QtGui.QApplication.UnicodeUTF8))
self.label.setText(QtGui.QApplication.translate("postprocessing", "Selection", None, QtGui.QApplication.UnicodeUTF8))
self.pushButton_rect.setText(QtGui.QApplication.translate("postprocessing", "Rectangle", None, QtGui.QApplication.UnicodeUTF8)) self.pushButton_rect.setText(QtGui.QApplication.translate("postprocessing", "Rectangle", None, QtGui.QApplication.UnicodeUTF8))
self.pushButton_poly.setText(QtGui.QApplication.translate("postprocessing", "Polygon", None, QtGui.QApplication.UnicodeUTF8)) self.pushButton_poly.setText(QtGui.QApplication.translate("postprocessing", "Polygon", None, QtGui.QApplication.UnicodeUTF8))
self.label.setText(QtGui.QApplication.translate("postprocessing", "Selection", None, QtGui.QApplication.UnicodeUTF8)) self.pushButton_plot.setText(QtGui.QApplication.translate("postprocessing", "Plot", None, QtGui.QApplication.UnicodeUTF8))
self.label_2.setText(QtGui.QApplication.translate("postprocessing", "Color by", None, QtGui.QApplication.UnicodeUTF8)) self.label_2.setText(QtGui.QApplication.translate("postprocessing", "Color by", None, QtGui.QApplication.UnicodeUTF8))
self.pushButton_snr.setText(QtGui.QApplication.translate("postprocessing", "SNR", None, QtGui.QApplication.UnicodeUTF8)) self.pushButton_snr.setText(QtGui.QApplication.translate("postprocessing", "SNR", None, QtGui.QApplication.UnicodeUTF8))
self.pushButton_pe.setText(QtGui.QApplication.translate("postprocessing", "PE", None, QtGui.QApplication.UnicodeUTF8)) self.pushButton_pe.setText(QtGui.QApplication.translate("postprocessing", "PE", None, QtGui.QApplication.UnicodeUTF8))

View File

@ -2,7 +2,7 @@
# Form implementation generated from reading ui file 'vtk_tools_layout.ui' # Form implementation generated from reading ui file 'vtk_tools_layout.ui'
# #
# Created: Thu Aug 4 13:55:47 2016 # Created: Wed Aug 10 14:11:07 2016
# by: pyside-uic 0.2.15 running on PySide 1.2.2 # by: pyside-uic 0.2.15 running on PySide 1.2.2
# #
# WARNING! All changes made in this file will be lost! # WARNING! All changes made in this file will be lost!

View File

@ -1,6 +1,9 @@
#!/usr/bin/env python #!/usr/bin/env python
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
import os import os
import numpy as np
import matplotlib
import matplotlib.pyplot as plt
from PySide import QtCore, QtGui from PySide import QtCore, QtGui
from pylot.core.active import surveyUtils, activeSeismoPick, seismicArrayPreparation, fmtomoUtils from pylot.core.active import surveyUtils, activeSeismoPick, seismicArrayPreparation, fmtomoUtils
from generate_survey_layout import Ui_generate_survey from generate_survey_layout import Ui_generate_survey
@ -8,11 +11,11 @@ from generate_survey_layout_minimal import Ui_generate_survey_minimal
from generate_seisarray_layout import Ui_generate_seisarray from generate_seisarray_layout import Ui_generate_seisarray
from picking_parameters_layout import Ui_picking_parameters from picking_parameters_layout import Ui_picking_parameters
from fmtomo_parameters_layout import Ui_fmtomo_parameters from fmtomo_parameters_layout import Ui_fmtomo_parameters
from pylot.core.active.gui.vtk_tools_layout import Ui_vtk_tools from vtk_tools_layout import Ui_vtk_tools
from postprocessing_layout import Ui_postprocessing
from pylot.core.active.surveyPlotTools import regions
import numpy as np
import matplotlib
matplotlib.use('Qt4Agg') matplotlib.use('Qt4Agg')
matplotlib.rcParams['backend.qt4']='PySide' matplotlib.rcParams['backend.qt4']='PySide'
@ -597,3 +600,88 @@ class Call_VTK_dialog(object):
def newFileVTK(self): def newFileVTK(self):
self.ui.lineEdit_vgout.setText(saveFile()) self.ui.lineEdit_vgout.setText(saveFile())
class Postprocessing(object):
def __init__(self, mainwindow, survey):
self.mainwindow = mainwindow
self.survey = survey
self.init_widget()
self.start_widget()
def init_widget(self):
qwidget = QtGui.QWidget()#
ui = Ui_postprocessing()
ui.setupUi(qwidget)
self.ui = ui
self.qwidget = qwidget
self.initPlot()
self.newPlot()
self.connectButtons()
self.region = regions(self.ax, self.cbar, self.survey, qt_interface = True)
def start_widget(self):
self.qwidget.show()
def initPlot(self):
self.figure = Figure()
self.canvas = FigureCanvas(self.figure)
self.ui.verticalLayout_plot.addWidget(self.canvas)
self.toolbar = NavigationToolbar(self.canvas, self.mainwindow)
self.ui.verticalLayout_plot.addWidget(self.toolbar)
def newPlot(self):
ax = self.figure.add_subplot(111)
dists, picks, snrlog, pe, spe = self.survey.preparePlotAllPicks(plotRemoved = False)
self.dists = dists
self.picks = picks
self.inkDict = {'snrlog': snrlog,
'pe': pe,
'spe': spe}
ax, cbar, sc = self.survey.createPlot(dists, picks, snrlog, 'log10(SNR)', ax = ax, cbar = None)
self.cbar = self.figure.colorbar(sc, ax = ax, fraction=0.05)
self.ax = ax
self.draw()
def refreshPlot(self, inkByVal = 'snrlog'):
self.ax.clear()
ax = self.ax
ax, cbar, sc = self.survey.createPlot(self.dists, self.picks, self.inkDict[inkByVal],
inkByVal, ax = ax, cbar = self.cbar)
#self.cbar = self.figure.colorbar(sc, fraction=0.05)
self.draw()
def update_survey(self, survey):
self.survey = survey
def get_survey(self):
return self.survey
def draw(self):
self.canvas.draw()
def connectButtons(self):
QtCore.QObject.connect(self.ui.pushButton_rect, QtCore.SIGNAL("clicked()"), self.chooseRect)
QtCore.QObject.connect(self.ui.pushButton_poly, QtCore.SIGNAL("clicked()"), self.choosePoly)
QtCore.QObject.connect(self.ui.pushButton_plot, QtCore.SIGNAL("clicked()"), self.plotPicks)
QtCore.QObject.connect(self.ui.pushButton_snr, QtCore.SIGNAL("clicked()"), self.refrSNR)
QtCore.QObject.connect(self.ui.pushButton_pe, QtCore.SIGNAL("clicked()"), self.refrPE)
QtCore.QObject.connect(self.ui.pushButton_spe, QtCore.SIGNAL("clicked()"), self.refrSPE)
def chooseRect(self):
self.region.chooseRectangles()
def choosePoly(self):
self.region.choosePolygon()
def plotPicks(self):
self.region.plotTracesInActiveRegions()
def refrSNR(self):
self.refreshPlot('snrlog')
def refrPE(self):
self.refreshPlot('pe')
def refrSPE(self):
self.refreshPlot('spe')

View File

@ -29,7 +29,7 @@ class regions(object):
''' '''
def __init__(self, ax, cbar, survey): def __init__(self, ax, cbar, survey, qt_interface = False):
self.ax = ax self.ax = ax
self.cbar = cbar self.cbar = cbar
self.cbv = 'log10SNR' self.cbv = 'log10SNR'
@ -45,11 +45,12 @@ class regions(object):
self._y1 = [] self._y1 = []
self._polyx = [] self._polyx = []
self._polyy = [] self._polyy = []
self.buttons = {}
self._allpicks = None self._allpicks = None
self.shots_found = {} self.shots_found = {}
self.shots_for_deletion = {} self.shots_for_deletion = {}
self._generateList() self._generateList()
if not qt_interface:
self.buttons = {}
self._addButtons() self._addButtons()
self.addTextfield() self.addTextfield()
self.drawFigure() self.drawFigure()
@ -525,4 +526,5 @@ class regions(object):
if resetAxes == True: if resetAxes == True:
self.ax.set_xlim(self._xlim) self.ax.set_xlim(self._xlim)
self.ax.set_ylim(self._ylim) self.ax.set_ylim(self._ylim)
plt.draw() self.ax.figure.canvas.draw()

View File

@ -339,16 +339,30 @@ class PDFDictionary(object):
class PDFstatistics(object): class PDFstatistics(object):
''' """
To do: This object can be used to get various statistic values from probabillity density functions.
plots for std, quantiles, Takes a path as argument.
''' """
def __init__(self, directory): def __init__(self, directory):
"""Initiates some values needed when dealing with pdfs later"""
self.directory = directory self.directory = directory
self.evtlist = list() self.evtlist = list()
self.return_phase = None self.return_phase = None
def readTheta(self, arname, dir, fnpattern): def readTheta(self, arname, dir, fnpattern):
"""
Loads an array from file into object instance.
:param arname: Name of Array beeing created.
:type arname: string
:param dir: Directory where file is to be found.
:type dir: string
:param fnpattern: file name pattern for reading multiple files into one array.
:type fnpattern: string
:return: a list with all args* from the files.
"""
exec('self.' + arname +' = []') exec('self.' + arname +' = []')
filelist = glob.glob1(dir, fnpattern) filelist = glob.glob1(dir, fnpattern)
for file in filelist: for file in filelist:
@ -359,8 +373,14 @@ class PDFstatistics(object):
exec('self.' + arname + ' += list') exec('self.' + arname + ' += list')
fid.close() fid.close()
def makeFileList(self, fn_pattern='*.xml'): def makeFileList(self, fn_pattern='*.xml'):
evtlist = list() """
Takes a file pattern and searches for that recursively in the set path for the object.
:param fn_pattern: A pattern that can identify all datafiles. Default Value = '*.xml'
:type fn_pattern: string
:return: creates a list of events saved in the PDFstatistics object.
"""
evtlist = glob.glob1((os.path.join(self.directory)), fn_pattern) evtlist = glob.glob1((os.path.join(self.directory)), fn_pattern)
if not evtlist: if not evtlist:
for root, _, files in os.walk(self.directory): for root, _, files in os.walk(self.directory):
@ -369,7 +389,9 @@ class PDFstatistics(object):
evtlist.append(os.path.join(root, file)) evtlist.append(os.path.join(root, file))
self.evtlist = evtlist self.evtlist = evtlist
def __iter__(self): def __iter__(self):
"""Iterating over the PDFstatistics object yields every single pdf from the list of events"""
assert isinstance(self.return_phase, str), 'phase has to be set before being able to iterate over items...' assert isinstance(self.return_phase, str), 'phase has to be set before being able to iterate over items...'
for evt in self.evtlist: for evt in self.evtlist:
self.getPDFDict(self.directory, evt) self.getPDFDict(self.directory, evt)
@ -379,13 +401,30 @@ class PDFstatistics(object):
except KeyError: except KeyError:
continue continue
def set_return_phase(self, type): def set_return_phase(self, type):
"""
Sets the phase typ of event data that is returned on iteration over the object.
:param type: can be either p (p-phase) or s (s-phase).
:type type: string
:return: -
"""
if type.upper() not in 'PS': if type.upper() not in 'PS':
raise ValueError("phase type must be either 'P' or 'S'!") raise ValueError("phase type must be either 'P' or 'S'!")
else: else:
self.return_phase = type.upper() self.return_phase = type.upper()
def getQD(self,value): def getQD(self,value):
"""
Takes a probability value and and returns the distance
between two complementary quantiles.
For example: getQD(0.3) yields Quantile(1-0.3) - Quantile(0.3)
:param value: 0 < value < 0.5
:type value: float
:return: returns a list of all quantile distances for all pdfs in
the list of events.
"""
QDlist = [] QDlist = []
for pdf in self: for pdf in self:
QD = pdf.quantile_distance(value) QD = pdf.quantile_distance(value)
@ -394,6 +433,16 @@ class PDFstatistics(object):
def getQDQ(self,value): def getQDQ(self,value):
"""
Takes a probability value and and returns the fraction of
two quantile distances.
For example:
getQDQ(x) = getQD(0.5-x)/getQD(x)
(Quantile(1-0.5-x) - Quantile(x)) / (Quantile(1-x) - Quantile(x))
:param value: 0 < value < 0.25
:return: returns a list of all quantile fractions for all pdfs in
the list of events.
"""
QDQlist = [] QDQlist = []
for pdf in self: for pdf in self:
QDQ = pdf.qtile_dist_quot(value) QDQ = pdf.qtile_dist_quot(value)
@ -402,6 +451,12 @@ class PDFstatistics(object):
def getSTD(self): def getSTD(self):
"""
Iterates over PDFstatistics object and returns the standard
deviation of all pdfs in the list of events.
:return: saves an instance of self.p_stdarray or
self.s_stdarray, depending on set phase.
"""
std = [] std = []
for pdf in self: for pdf in self:
try: try:
@ -413,6 +468,10 @@ class PDFstatistics(object):
def set_stdarray(self, array): def set_stdarray(self, array):
"""
Helper function for self.getSTD(). This function
should not be called directly.
"""
if self.return_phase == 'P': if self.return_phase == 'P':
self.p_stdarray = array self.p_stdarray = array
elif self.return_phase == 'S': elif self.return_phase == 'S':
@ -423,6 +482,22 @@ class PDFstatistics(object):
def getBinList(self,l_boundary,u_boundary,nbins = 100): def getBinList(self,l_boundary,u_boundary,nbins = 100):
"""
Helper function for self.histplot(). Takes in two boundaries and
a number of bins and creates a list of bins which can be passed
to self.histplot().
:param l_boundary: Any number.
:type l_boundary: float
:param u_boundary: Any number that is greater than l_boundary.
:type u_boundary: float
:param nbins: Any positive integer.
:type nbins: int
:return: A list of equidistant bins.
"""
if u_boundary <= l_boundary:
raise ValueError('Upper boundary must be greather than lower!')
elif nbins <= 0:
raise ValueError('Number of bins is not valid.')
binlist = [] binlist = []
for i in range(nbins): for i in range(nbins):
binlist.append(l_boundary + i*(u_boundary-l_boundary)/nbins) binlist.append(l_boundary + i*(u_boundary-l_boundary)/nbins)
@ -430,24 +505,57 @@ class PDFstatistics(object):
def histplot(self, array, binlist, xlab = 'Values', def histplot(self, array, binlist, xlab = 'Values',
ylab = 'Frequency', title = None, label=None): ylab = 'Frequency', title = None, fnout = None):
"""
Method to quickly show some distribution of data. Takes array like data,
and a list of bins. Editing detail and inserting a legend is not possible.
:param array: List of values.
:type array: Array like
:param binlist: List of bins.
:type binlist: list
:param xlab: A label for the x-axes.
:type xlab: str
:param ylab: A label for the y-axes.
:type ylab: str
:param title: A title for the Plot.
:type title: str
:param fnout: A path to save the plot instead of showing.
Has to contain filename and type. Like: 'path/to/file.png'
:type fnout. str
:return: -
"""
import matplotlib.pyplot as plt import matplotlib.pyplot as plt
plt.hist(array,bins = binlist) plt.hist(array,bins = binlist)
plt.xlabel('Values') plt.xlabel(xlab)
plt.ylabel('Frequency') plt.ylabel(ylab)
if title: if title:
title_str = 'Quantile distance quotient distribution' plt.title(title)
if label: if fnout:
title_str += ' (' + label + ')' plt.savefig(fnout)
plt.title(title_str) else:
plt.show() plt.show()
def getPDFDict(self, month, evt): def getPDFDict(self, month, evt):
"""
Helper function for __iter__(). Should not be called directly.
"""
self.pdfdict = PDFDictionary.from_quakeml(os.path.join(self.directory,month,evt)) self.pdfdict = PDFDictionary.from_quakeml(os.path.join(self.directory,month,evt))
def getStatistics(self): def getStatistics(self):
"""
On call function will get mean, median and standard deviation values
from self.p_stdarray and self.s_stdarray. Both must be
instances before calling this function.
:return: Creates instances of self.p_mean, self.p_std_std and self.p_median
for both phases (simultaneously) for the PDFstatistics object.
"""
if not self.p_stdarray or not self.s_stdarray:
raise NotImplementedError('Arrays are not properly set yet!')
elif type(self.p_stdarray) != type(np.zeros(1)) or type(self.s_stdarray) != type(np.zeros(1)):
raise TypeError('Array is not a proper numpy array.')
self.p_mean = self.p_stdarray.mean() self.p_mean = self.p_stdarray.mean()
self.p_std_std = self.p_stdarray.std() self.p_std_std = self.p_stdarray.std()
self.p_median = np.median(self.p_stdarray) self.p_median = np.median(self.p_stdarray)
@ -456,12 +564,22 @@ class PDFstatistics(object):
self.s_median = np.median(self.s_stdarray) self.s_median = np.median(self.s_stdarray)
def writeThetaToFile(self,array,out_dir,filename = None): def writeThetaToFile(self,array,out_dir):
fid = open(os.path.join(out_dir,filename), 'w') """
Method to write array like data to file. Useful since acquiring can take
serious amount of time when dealing with large databases.
:param array: List of values.
:type array: list
:param out_dir: Path to save file to including file name.
:type out_dir: str
:return: Saves a file at given output directory.
"""
fid = open(os.path.join(out_dir), 'w')
for val in array: for val in array:
fid.write(str(val)+'\n') fid.write(str(val)+'\n')
fid.close() fid.close()
def main(): def main():
root_dir ='/home/sebastianp/Codetesting/xmls/' root_dir ='/home/sebastianp/Codetesting/xmls/'
Insheim = PDFstatistics(root_dir) Insheim = PDFstatistics(root_dir)

View File

@ -363,13 +363,15 @@ class ProbabilityDensityFunction(object):
return m return m
def quantile_distance(self, prob_value): def quantile_distance(self, prob_value):
if 0 >= prob_value or prob_value >= 0.5:
raise ValueError('Value out of range.')
ql = self.quantile(prob_value) ql = self.quantile(prob_value)
qu = self.quantile(1 - prob_value) qu = self.quantile(1 - prob_value)
return qu - ql return qu - ql
def qtile_dist_quot(self,x): def qtile_dist_quot(self,x):
if x <= 0 or x >= 0.5: if x <= 0 or x >= 0.25:
raise ValueError('Value out of range.') raise ValueError('Value out of range.')
return self.quantile_distance(0.5-x)/self.quantile_distance(x) return self.quantile_distance(0.5-x)/self.quantile_distance(x)

View File

@ -82,8 +82,8 @@ def clims(lim1, lim2):
def demeanTrace(trace, window): def demeanTrace(trace, window):
""" """
returns the DATA where each trace is demean by the average value within takes a trace object and returns the same trace object but with data
WINDOW demeaned within a certain time window
:param trace: waveform trace object :param trace: waveform trace object
:type trace: `~obspy.core.stream.Trace` :type trace: `~obspy.core.stream.Trace`
:param window: :param window:
@ -100,9 +100,9 @@ def findComboBoxIndex(combo_box, val):
Function findComboBoxIndex takes a QComboBox object and a string and Function findComboBoxIndex takes a QComboBox object and a string and
returns either 0 or the index throughout all QComboBox items. returns either 0 or the index throughout all QComboBox items.
:param combo_box: Combo box object. :param combo_box: Combo box object.
:type combo_box: QComboBox :type combo_box: `~QComboBox`
:param val: Name of a combo box to search for. :param val: Name of a combo box to search for.
:type val: :type val: basestring
:return: index value of item with name val or 0 :return: index value of item with name val or 0
""" """
return combo_box.findText(val) if combo_box.findText(val) is not -1 else 0 return combo_box.findText(val) if combo_box.findText(val) is not -1 else 0
@ -110,21 +110,35 @@ def findComboBoxIndex(combo_box, val):
def find_nearest(array, value): def find_nearest(array, value):
''' '''
Function find_nearest takes an array and a value and returns the function find_nearest takes an array and a value and returns the
index of the nearest value found in the array. index of the nearest value found in the array
:param array: :param array: array containing values
:param value: :type array: `~numpy.ndarray`
:return: :param value: number searched for
:return: index of the array item being nearest to the value
>>> a = np.array([ 1.80339578, -0.72546654, 0.95769195, -0.98320759, 0.85922623])
>>> find_nearest(a, 1.3)
2
>>> find_nearest(a, 0)
1
>>> find_nearest(a, 2)
0
>>> find_nearest(a, -1)
3
>>> a = np.array([ 1.1, -0.7, 0.9, -0.9, 0.8])
>>> find_nearest(a, 0.849)
4
''' '''
return (np.abs(array - value)).argmin() return (np.abs(array - value)).argmin()
def fnConstructor(s): def fnConstructor(s):
''' '''
takes a string and returns a valid filename (especially on windows machines)
:param s: :param s: desired filename
:type s: :type s: str
:return: :return: valid filename
''' '''
if type(s) is str: if type(s) is str:
s = s.split(':')[-1] s = s.split(':')[-1]
@ -142,7 +156,21 @@ def fnConstructor(s):
def four_digits(year): def four_digits(year):
if year + 2000 < UTCDateTime.utcnow().year: """
takes a two digit year integer and returns the correct four digit equivalent
from the last 100 years
:param year: two digit year
:type year: int
:return: four digit year correspondant
>>> four_digits(20)
1920
>>> four_digits(16)
2016
>>> four_digits(00)
2000
"""
if year + 2000 <= UTCDateTime.utcnow().year:
year += 2000 year += 2000
else: else:
year += 1900 year += 1900
@ -151,10 +179,11 @@ def four_digits(year):
def getGlobalTimes(stream): def getGlobalTimes(stream):
''' '''
takes a stream object and returns the latest end and the earliest start
:param stream: time of all contained trace objects
:type stream :param stream: seismological data stream
:return: :type stream: `~obspy.core.stream.Stream`
:return: minimum start time and maximum end time
''' '''
min_start = UTCDateTime() min_start = UTCDateTime()
max_end = None max_end = None
@ -168,6 +197,8 @@ def getGlobalTimes(stream):
def getHash(time): def getHash(time):
''' '''
takes a time object and returns the corresponding SHA1 hash of the
formatted date string
:param time: time object for which a hash should be calculated :param time: time object for which a hash should be calculated
:type time: :class: `~obspy.core.utcdatetime.UTCDateTime` object :type time: :class: `~obspy.core.utcdatetime.UTCDateTime` object
:return: str :return: str
@ -179,27 +210,27 @@ def getHash(time):
def getLogin(): def getLogin():
''' '''
returns the actual user's login id returns the actual user's login ID
:return: User ID :return: login ID
''' '''
return pwd.getpwuid(os.getuid())[0] return pwd.getpwuid(os.getuid())[0]
def getOwner(fn): def getOwner(fn):
''' '''
takes filename and returns the User ID of the owner of the file takes a filename and return the login ID of the actual owner of the file
:param fn: filename :param fn: filename of the file tested
:type fn: str :type fn: str
:return: User ID :return: login ID of the file's owner
''' '''
return pwd.getpwuid(os.stat(fn).st_uid).pw_name return pwd.getpwuid(os.stat(fn).st_uid).pw_name
def getPatternLine(fn, pattern): def getPatternLine(fn, pattern):
""" """
Takes a file name and a pattern string to search for in the file and takes a file name and a pattern string to search for in the file and
returns the first line which contains the pattern string otherwise None. returns the first line which contains the pattern string otherwise 'None'
:param fn: filename :param fn: file name
:type fn: str :type fn: str
:param pattern: pattern string to search for :param pattern: pattern string to search for
:type pattern: str :type pattern: str
@ -221,22 +252,52 @@ def getPatternLine(fn, pattern):
def isSorted(iterable): def isSorted(iterable):
''' '''
takes a python variable and returns True if the iterable is sorted and False otherwise takes an iterable and returns 'True' if the items are in order otherwise
:param iterable: a python variable 'False'
:param iterable: an iterable object
:type iterable: :type iterable:
:return: :return: Boolean
>>> isSorted(1)
Traceback (most recent call last):
...
AssertionError: object is not iterable; object: 1
>>> isSorted([1,2,3,4])
True
>>> isSorted('abcd')
True
>>> isSorted('bcad')
False
>>> isSorted([2,3,1,4])
False
''' '''
assert isIterable(iterable), 'object is not iterable; object: {' \
'0}'.format(iterable)
if type(iterable) is str:
iterable = [s for s in iterable]
return sorted(iterable) == iterable return sorted(iterable) == iterable
def isIterable(obj):
"""
takes a python object and returns 'True' is the object is iterable and
'False' otherwise
:param obj: a python object
:return: True of False
"""
try:
iterator = iter(obj)
except TypeError as te:
return False
return True
def prepTimeAxis(stime, trace): def prepTimeAxis(stime, trace):
''' '''
takes a starttime 'stime' and a trace object 'trace' and return a vector containing as much time stamps as data values in the trace object are available takes a starttime and a trace object and returns a valid time axis for
:param stime: plotting
:type stime: :param stime: start time of the actual seismogram as UTCDateTime
:param trace: :param trace: seismic trace object
:type trace: :return: valid numpy array with time stamps for plotting
:return: time axis
''' '''
nsamp = trace.stats.npts nsamp = trace.stats.npts
srate = trace.stats.sampling_rate srate = trace.stats.sampling_rate