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 pylot.core.active import activeSeismoPick, surveyUtils, fmtomoUtils, seismicArrayPreparation
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 matplotlib.backends.backend_qt4agg import FigureCanvasQTAgg as FigureCanvas
@ -43,6 +43,7 @@ class gui_control(object):
self.autopicker = None
self.fmtomo = None
self.vtktools = None
self.postprocessing = None
def setInitStates(self):
self.setPickState(False)
@ -362,8 +363,9 @@ class gui_control(object):
if not self.checkSurveyState():
self.printDialogMessage('No Survey defined.')
return
self.survey.plotAllPicks()
self.refreshPickedWidgets() # wait until finished
self.postprocessing = Postprocessing(self.mainwindow, self.survey)
#self.survey.plotAllPicks()
#self.refreshPickedWidgets() # wait until finished
def load_survey(self):

View File

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

View File

@ -2,7 +2,7 @@
# 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
#
# 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'
#
# 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
#
# 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'
#
# 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
#
# 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'
#
# 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
#
# 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'
#
# 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
#
# 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'
#
# 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
#
# 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'
#
# 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
#
# WARNING! All changes made in this file will be lost!
@ -12,34 +12,13 @@ from PySide import QtCore, QtGui
class Ui_postprocessing(object):
def setupUi(self, postprocessing):
postprocessing.setObjectName("postprocessing")
postprocessing.resize(640, 479)
self.verticalLayout_2 = QtGui.QVBoxLayout(postprocessing)
self.verticalLayout_2.setObjectName("verticalLayout_2")
self.verticalLayout = QtGui.QVBoxLayout()
postprocessing.resize(663, 617)
self.verticalLayout = QtGui.QVBoxLayout(postprocessing)
self.verticalLayout.setObjectName("verticalLayout")
self.gridLayout = QtGui.QGridLayout()
self.gridLayout.setObjectName("gridLayout")
self.horizontalLayout = QtGui.QHBoxLayout()
self.horizontalLayout.setObjectName("horizontalLayout")
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.horizontalLayout_2 = QtGui.QHBoxLayout()
self.horizontalLayout_2.setObjectName("horizontalLayout_2")
self.verticalLayout_3 = QtGui.QVBoxLayout()
self.verticalLayout_3.setObjectName("verticalLayout_3")
self.label = QtGui.QLabel(postprocessing)
sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Preferred, QtGui.QSizePolicy.Minimum)
sizePolicy.setHorizontalStretch(0)
@ -49,7 +28,42 @@ class Ui_postprocessing(object):
self.label.setMinimumSize(QtCore.QSize(0, 20))
self.label.setMaximumSize(QtCore.QSize(16777215, 30))
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)
sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Preferred, QtGui.QSizePolicy.Minimum)
sizePolicy.setHorizontalStretch(0)
@ -59,9 +73,9 @@ class Ui_postprocessing(object):
self.label_2.setMinimumSize(QtCore.QSize(0, 20))
self.label_2.setMaximumSize(QtCore.QSize(16777215, 30))
self.label_2.setObjectName("label_2")
self.gridLayout.addWidget(self.label_2, 0, 1, 1, 1)
self.horizontalLayout_3 = QtGui.QHBoxLayout()
self.horizontalLayout_3.setObjectName("horizontalLayout_3")
self.verticalLayout_2.addWidget(self.label_2)
self.horizontalLayout_5 = QtGui.QHBoxLayout()
self.horizontalLayout_5.setObjectName("horizontalLayout_5")
self.pushButton_snr = QtGui.QPushButton(postprocessing)
sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Minimum)
sizePolicy.setHorizontalStretch(0)
@ -70,7 +84,7 @@ class Ui_postprocessing(object):
self.pushButton_snr.setSizePolicy(sizePolicy)
self.pushButton_snr.setMaximumSize(QtCore.QSize(16777215, 30))
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)
sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Minimum)
sizePolicy.setHorizontalStretch(0)
@ -79,7 +93,7 @@ class Ui_postprocessing(object):
self.pushButton_pe.setSizePolicy(sizePolicy)
self.pushButton_pe.setMaximumSize(QtCore.QSize(16777215, 30))
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)
sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Minimum)
sizePolicy.setHorizontalStretch(0)
@ -88,29 +102,23 @@ class Ui_postprocessing(object):
self.pushButton_spe.setSizePolicy(sizePolicy)
self.pushButton_spe.setMaximumSize(QtCore.QSize(16777215, 30))
self.pushButton_spe.setObjectName("pushButton_spe")
self.horizontalLayout_3.addWidget(self.pushButton_spe)
self.gridLayout.addLayout(self.horizontalLayout_3, 1, 1, 1, 1)
self.verticalLayout.addLayout(self.gridLayout)
self.horizontalLayout_plot = QtGui.QHBoxLayout()
self.horizontalLayout_plot.setObjectName("horizontalLayout_plot")
self.verticalLayout.addLayout(self.horizontalLayout_plot)
self.verticalLayout_2.addLayout(self.verticalLayout)
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.horizontalLayout_5.addWidget(self.pushButton_spe)
self.verticalLayout_2.addLayout(self.horizontalLayout_5)
self.horizontalLayout_2.addLayout(self.verticalLayout_2)
self.verticalLayout.addLayout(self.horizontalLayout_2)
self.verticalLayout_plot = QtGui.QVBoxLayout()
self.verticalLayout_plot.setObjectName("verticalLayout_plot")
self.verticalLayout.addLayout(self.verticalLayout_plot)
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)
def retranslateUi(self, postprocessing):
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_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.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))

View File

@ -2,7 +2,7 @@
# 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
#
# WARNING! All changes made in this file will be lost!

View File

@ -1,6 +1,9 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import os
import numpy as np
import matplotlib
import matplotlib.pyplot as plt
from PySide import QtCore, QtGui
from pylot.core.active import surveyUtils, activeSeismoPick, seismicArrayPreparation, fmtomoUtils
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 picking_parameters_layout import Ui_picking_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.rcParams['backend.qt4']='PySide'
@ -597,3 +600,88 @@ class Call_VTK_dialog(object):
def newFileVTK(self):
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.cbar = cbar
self.cbv = 'log10SNR'
@ -45,11 +45,12 @@ class regions(object):
self._y1 = []
self._polyx = []
self._polyy = []
self.buttons = {}
self._allpicks = None
self.shots_found = {}
self.shots_for_deletion = {}
self._generateList()
if not qt_interface:
self.buttons = {}
self._addButtons()
self.addTextfield()
self.drawFigure()
@ -525,4 +526,5 @@ class regions(object):
if resetAxes == True:
self.ax.set_xlim(self._xlim)
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):
'''
To do:
plots for std, quantiles,
'''
"""
This object can be used to get various statistic values from probabillity density functions.
Takes a path as argument.
"""
def __init__(self, directory):
"""Initiates some values needed when dealing with pdfs later"""
self.directory = directory
self.evtlist = list()
self.return_phase = None
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 +' = []')
filelist = glob.glob1(dir, fnpattern)
for file in filelist:
@ -359,8 +373,14 @@ class PDFstatistics(object):
exec('self.' + arname + ' += list')
fid.close()
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)
if not evtlist:
for root, _, files in os.walk(self.directory):
@ -369,7 +389,9 @@ class PDFstatistics(object):
evtlist.append(os.path.join(root, file))
self.evtlist = evtlist
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...'
for evt in self.evtlist:
self.getPDFDict(self.directory, evt)
@ -379,13 +401,30 @@ class PDFstatistics(object):
except KeyError:
continue
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':
raise ValueError("phase type must be either 'P' or 'S'!")
else:
self.return_phase = type.upper()
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 = []
for pdf in self:
QD = pdf.quantile_distance(value)
@ -394,6 +433,16 @@ class PDFstatistics(object):
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 = []
for pdf in self:
QDQ = pdf.qtile_dist_quot(value)
@ -402,6 +451,12 @@ class PDFstatistics(object):
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 = []
for pdf in self:
try:
@ -413,6 +468,10 @@ class PDFstatistics(object):
def set_stdarray(self, array):
"""
Helper function for self.getSTD(). This function
should not be called directly.
"""
if self.return_phase == 'P':
self.p_stdarray = array
elif self.return_phase == 'S':
@ -423,6 +482,22 @@ class PDFstatistics(object):
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 = []
for i in range(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',
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
plt.hist(array,bins = binlist)
plt.xlabel('Values')
plt.ylabel('Frequency')
plt.xlabel(xlab)
plt.ylabel(ylab)
if title:
title_str = 'Quantile distance quotient distribution'
if label:
title_str += ' (' + label + ')'
plt.title(title_str)
plt.title(title)
if fnout:
plt.savefig(fnout)
else:
plt.show()
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))
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_std_std = self.p_stdarray.std()
self.p_median = np.median(self.p_stdarray)
@ -456,12 +564,22 @@ class PDFstatistics(object):
self.s_median = np.median(self.s_stdarray)
def writeThetaToFile(self,array,out_dir,filename = None):
fid = open(os.path.join(out_dir,filename), 'w')
def writeThetaToFile(self,array,out_dir):
"""
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:
fid.write(str(val)+'\n')
fid.close()
def main():
root_dir ='/home/sebastianp/Codetesting/xmls/'
Insheim = PDFstatistics(root_dir)

View File

@ -363,13 +363,15 @@ class ProbabilityDensityFunction(object):
return m
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)
qu = self.quantile(1 - prob_value)
return qu - ql
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.')
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):
"""
returns the DATA where each trace is demean by the average value within
WINDOW
takes a trace object and returns the same trace object but with data
demeaned within a certain time window
:param trace: waveform trace object
:type trace: `~obspy.core.stream.Trace`
:param window:
@ -100,9 +100,9 @@ def findComboBoxIndex(combo_box, val):
Function findComboBoxIndex takes a QComboBox object and a string and
returns either 0 or the index throughout all QComboBox items.
:param combo_box: Combo box object.
:type combo_box: QComboBox
:type combo_box: `~QComboBox`
: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 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):
'''
Function find_nearest takes an array and a value and returns the
index of the nearest value found in the array.
:param array:
:param value:
:return:
function find_nearest takes an array and a value and returns the
index of the nearest value found in the array
:param array: array containing values
:type array: `~numpy.ndarray`
: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()
def fnConstructor(s):
'''
:param s:
:type s:
:return:
takes a string and returns a valid filename (especially on windows machines)
:param s: desired filename
:type s: str
:return: valid filename
'''
if type(s) is str:
s = s.split(':')[-1]
@ -142,7 +156,21 @@ def fnConstructor(s):
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
else:
year += 1900
@ -151,10 +179,11 @@ def four_digits(year):
def getGlobalTimes(stream):
'''
:param stream:
:type stream
:return:
takes a stream object and returns the latest end and the earliest start
time of all contained trace objects
:param stream: seismological data stream
:type stream: `~obspy.core.stream.Stream`
:return: minimum start time and maximum end time
'''
min_start = UTCDateTime()
max_end = None
@ -168,6 +197,8 @@ def getGlobalTimes(stream):
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
:type time: :class: `~obspy.core.utcdatetime.UTCDateTime` object
:return: str
@ -179,27 +210,27 @@ def getHash(time):
def getLogin():
'''
returns the actual user's login id
:return: User ID
returns the actual user's login ID
:return: login ID
'''
return pwd.getpwuid(os.getuid())[0]
def getOwner(fn):
'''
takes filename and returns the User ID of the owner of the file
:param fn: filename
takes a filename and return the login ID of the actual owner of the file
:param fn: filename of the file tested
:type fn: str
:return: User ID
:return: login ID of the file's owner
'''
return pwd.getpwuid(os.stat(fn).st_uid).pw_name
def getPatternLine(fn, pattern):
"""
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.
:param fn: filename
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'
:param fn: file name
:type fn: str
:param pattern: pattern string to search for
:type pattern: str
@ -221,22 +252,52 @@ def getPatternLine(fn, pattern):
def isSorted(iterable):
'''
takes a python variable and returns True if the iterable is sorted and False otherwise
:param iterable: a python variable
takes an iterable and returns 'True' if the items are in order otherwise
'False'
:param iterable: an iterable object
: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
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):
'''
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
:param stime:
:type stime:
:param trace:
:type trace:
:return: time axis
takes a starttime and a trace object and returns a valid time axis for
plotting
:param stime: start time of the actual seismogram as UTCDateTime
:param trace: seismic trace object
:return: valid numpy array with time stamps for plotting
'''
nsamp = trace.stats.npts
srate = trace.stats.sampling_rate