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

This commit is contained in:
Marcel Paffrath 2015-09-28 12:22:09 +02:00
commit 48c889129a
9 changed files with 323 additions and 219 deletions

View File

@ -386,8 +386,8 @@ class MainWindow(QMainWindow):
else:
raise DatastructureError('not specified')
return self.fnames
except DatastructureError, e:
print e
except DatastructureError as e:
print(e)
props = PropertiesDlg(self)
if props.exec_() == QDialog.Accepted:
return self.getWFFnames()
@ -410,7 +410,7 @@ class MainWindow(QMainWindow):
def saveData(self):
def getSavePath(e):
print 'warning: {0}'.format(e)
print('warning: {0}'.format(e))
directory = os.path.join(self.getRoot(), self.getEventFileName())
file_filter = "QuakeML file (*.xml);;VELEST observation file format (*.cnv);;NonLinLoc observation file (*.obs)"
fname = QFileDialog.getSaveFileName(self, 'Save event data ...',
@ -513,7 +513,7 @@ class MainWindow(QMainWindow):
def plotWaveformData(self):
zne_text = {'Z': 'vertical', 'N': 'north-south', 'E': 'east-west'}
comp = self.getComponent()
title = 'overview: {0} components'.format(zne_text[comp])
title = 'section: {0} components'.format(zne_text[comp])
wfst = self.getData().getWFData().select(component=comp)
self.getPlotWidget().plotWFData(wfdata=wfst, title=title)
self.draw()
@ -574,8 +574,8 @@ class MainWindow(QMainWindow):
def getFilterOptions(self):
try:
return self.filteroptions[self.getSeismicPhase()]
except AttributeError, e:
print e
except AttributeError as e:
print(e)
return FilterOptions(None, None, None)
def getFilters(self):
@ -592,12 +592,12 @@ class MainWindow(QMainWindow):
settings = QSettings()
if settings.value("filterdefaults",
None) is None and not self.getFilters():
for key, value in FILTERDEFAULTS.iteritems():
for key, value in FILTERDEFAULTS.items():
self.setFilterOptions(FilterOptions(**value), key)
elif settings.value("filterdefaults", None) is not None:
for key, value in settings.value("filterdefaults"):
self.setFilterOptions(FilterOptions(**value), key)
except Exception, e:
except Exception as e:
self.updateStatus('Error ...')
emsg = QErrorMessage(self)
emsg.showMessage('Error: {0}'.format(e))
@ -636,7 +636,11 @@ class MainWindow(QMainWindow):
if pickDlg.exec_():
self.setDirty(True)
self.updateStatus('picks accepted ({0})'.format(station))
self.addPicks(station, pickDlg.getPicks())
replot = self.addPicks(station, pickDlg.getPicks())
if replot:
self.plotWaveformData()
self.drawPicks()
else:
self.drawPicks(station)
else:
self.updateStatus('picks discarded ({0})'.format(station))
@ -667,6 +671,7 @@ class MainWindow(QMainWindow):
def addPicks(self, station, picks):
stat_picks = self.getPicksOnStation(station)
rval = False
if not stat_picks:
stat_picks = picks
else:
@ -684,11 +689,13 @@ class MainWindow(QMainWindow):
ret = msgBox.exec_()
if ret == QMessageBox.Save:
stat_picks = picks
rval = True
elif ret == QMessageBox.Cancel:
pass
else:
raise Exception('FATAL: Should never occur!')
self.getPicks()[station] = stat_picks
return rval
def updatePicks(self):
evt = self.getData().getEvtData()

View File

@ -3,6 +3,7 @@
<file>icons/pylot.ico</file>
<file>icons/pylot.png</file>
<file>icons/printer.png</file>
<file>icons/delete.png</file>
<file>icons/key_E.png</file>
<file>icons/key_N.png</file>
<file>icons/key_P.png</file>

BIN
icons/delete.png Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.0 KiB

File diff suppressed because one or more lines are too long

View File

@ -25,7 +25,8 @@ class Magnitude(object):
:type: float
:param: pwin, pick window [To To+pwin] to get maximum
peak-to-peak amplitude
peak-to-peak amplitude (WApp) or to calculate
source spectrum (DCfc)
:type: float
:param: iplot, no. of figure window for plotting interims results
@ -40,6 +41,7 @@ class Magnitude(object):
self.setpwin(pwin)
self.setiplot(iplot)
self.calcwapp()
self.calcsourcespec()
def getwfstream(self):
@ -69,17 +71,22 @@ class Magnitude(object):
def getwapp(self):
return self.wapp
def getw0(self):
return self.w0
def getfc(self):
return self.fc
def calcwapp(self):
self.wapp = None
def calcsourcespec(self):
self.sourcespek = None
class WApp(Magnitude):
'''
Method to derive peak-to-peak amplitude as seen on a Wood-Anderson-
seismograph. Has to be derived from corrected traces!
seismograph. Has to be derived from instrument corrected traces!
'''
def calcwapp(self):
@ -110,6 +117,7 @@ class WApp(Magnitude):
iwin = getsignalwin(th, self.getTo(), self.getpwin())
self.wapp = np.max(sqH[iwin])
print ("Determined Wood-Anderson peak-to-peak amplitude: %f mm") % self.wapp
if self.getiplot() > 1:
stream.plot()
f = plt.figure(2)
@ -128,10 +136,50 @@ class WApp(Magnitude):
class DCfc(Magnitude):
'''
Method to calculate the source spectrum and to derive from that the plateau
(the so-called DC-value) and the corner frequency assuming Aki's omega-square
source model. Has to be derived from corrected traces!
(so-called DC-value) and the corner frequency assuming Aki's omega-square
source model. Has to be derived from instrument corrected displacement traces!
'''
def calcsourcespec(self):
print ("Calculating source spectrum ....")
self.w0 = None # DC-value
self.fc = None # corner frequency
stream = self.getwfstream()
tr = stream[0]
# get time array
t = np.arange(0, len(tr) * tr.stats.delta, tr.stats.delta)
iwin = getsignalwin(t, self.getTo(), self.getpwin())
xdat = tr.data[iwin]
# fft
fny = tr.stats.sampling_rate / 2
l = len(xdat) / tr.stats.sampling_rate
n = tr.stats.sampling_rate * l # number of fft bins after Bath
# find next power of 2 of data length
m = pow(2, np.ceil(np.log(len(xdat)) / np.log(2)))
N = int(np.power(m, 2))
y = tr.stats.delta * np.fft.fft(xdat, N)
Y = abs(y[: N/2])
L = (N - 1) / tr.stats.sampling_rate
f = np.arange(0, fny, 1/L)
if self.getiplot() > 1:
f1 = plt.figure(1)
plt.subplot(2,1,1)
plt.plot(t, np.multiply(tr, 1000), 'k') # show displacement in mm
plt.plot(t[iwin], np.multiply(xdat, 1000), 'g') # show displacement in mm
plt.title('Seismogram and P pulse, station %s' % tr.stats.station)
plt.xlabel('Time since %s' % tr.stats.starttime)
plt.ylabel('Displacement [mm]')
plt.subplot(2,1,2)
plt.semilogy(f, Y.real)
plt.title('Source Spectrum from P Pulse')
plt.xlabel('Frequency [Hz]')
plt.ylabel('Amplitude [m/Hz]')
plt.show()
raw_input()
plt.close(f1)

View File

@ -147,7 +147,7 @@ class AICPicker(AutoPicking):
def calcPick(self):
print 'AICPicker: Get initial onset time (pick) from AIC-CF ...'
print('AICPicker: Get initial onset time (pick) from AIC-CF ...')
self.Pick = None
self.slope = None
@ -163,7 +163,7 @@ class AICPicker(AutoPicking):
ismooth = int(round(self.Tsmooth / self.dt))
aicsmooth = np.zeros(len(aic))
if len(aic) < ismooth:
print 'AICPicker: Tsmooth larger than CF!'
print('AICPicker: Tsmooth larger than CF!')
return
else:
for i in range(1, len(aic)):
@ -211,8 +211,8 @@ class AICPicker(AutoPicking):
# get signal window
isignal = getsignalwin(self.Tcf, self.Pick, self.TSNR[2])
# calculate SNR from CF
self.SNR = max(abs(aic[isignal] - np.mean(aic[isignal]))) / max(abs(aic[inoise] \
- np.mean(aic[inoise])))
self.SNR = max(abs(aic[isignal] - np.mean(aic[isignal]))) / \
max(abs(aic[inoise] - np.mean(aic[inoise])))
# calculate slope from CF after initial pick
# get slope window
tslope = self.TSNR[3] #slope determination window
@ -222,8 +222,8 @@ class AICPicker(AutoPicking):
# 'cause slope should be calculated up to first local minimum only!
imax = np.argmax(self.Data[0].data[islope])
if imax == 0:
print 'AICPicker: Maximum for slope determination right at the beginning of the window!'
print 'Choose longer slope determination window!'
print('AICPicker: Maximum for slope determination right at the beginning of the window!')
print('Choose longer slope determination window!')
if self.iplot > 1:
p = plt.figure(self.iplot)
x = self.Data[0].data
@ -244,7 +244,7 @@ class AICPicker(AutoPicking):
P = np.polyfit(xslope, dataslope, 1)
datafit = np.polyval(P, xslope)
if datafit[0] >= datafit[len(datafit) - 1]:
print 'AICPicker: Negative slope, bad onset skipped!'
print('AICPicker: Negative slope, bad onset skipped!')
return
self.slope = 1 / tslope * (datafit[len(dataslope) - 1] - datafit[0])
@ -273,9 +273,9 @@ class AICPicker(AutoPicking):
p13, = plt.plot(self.Tcf[isignal], self.Data[0].data[isignal], 'r')
p14, = plt.plot(self.Tcf[islope], dataslope, 'g--')
p15, = plt.plot(self.Tcf[islope], datafit, 'g', linewidth=2)
plt.legend([p11, p12, p13, p14, p15], ['Data', 'Noise Window', 'Signal Window', 'Slope Window', 'Slope'], \
plt.legend([p11, p12, p13, p14, p15], ['Data', 'Noise Window', 'Signal Window', 'Slope Window', 'Slope'],
loc='best')
plt.title('Station %s, SNR=%7.2f, Slope= %12.2f counts/s' % (self.Data[0].stats.station, \
plt.title('Station %s, SNR=%7.2f, Slope= %12.2f counts/s' % (self.Data[0].stats.station,
self.SNR, self.slope))
plt.xlabel('Time [s] since %s' % self.Data[0].stats.starttime)
plt.ylabel('Counts')
@ -286,7 +286,7 @@ class AICPicker(AutoPicking):
plt.close(p)
if self.Pick == None:
print 'AICPicker: Could not find minimum, picking window too short?'
print('AICPicker: Could not find minimum, picking window too short?')
class PragPicker(AutoPicking):
@ -297,7 +297,7 @@ class PragPicker(AutoPicking):
def calcPick(self):
if self.getpick1() is not None:
print 'PragPicker: Get most likely pick from HOS- or AR-CF using pragmatic picking algorithm ...'
print('PragPicker: Get most likely pick from HOS- or AR-CF using pragmatic picking algorithm ...')
self.Pick = None
self.SNR = None
@ -307,7 +307,7 @@ class PragPicker(AutoPicking):
ismooth = int(round(self.Tsmooth / self.dt))
cfsmooth = np.zeros(len(self.cf))
if len(self.cf) < ismooth:
print 'PragPicker: Tsmooth larger than CF!'
print('PragPicker: Tsmooth larger than CF!')
return
else:
for i in range(1, len(self.cf)):
@ -330,11 +330,11 @@ class PragPicker(AutoPicking):
#check trend of CF, i.e. differences of CF and adjust aus regarding this trend
#prominent trend: decrease aus
#flat: use given aus
cfdiff = np.diff(cfipick);
cfdiff = np.diff(cfipick)
i0diff = np.where(cfdiff > 0)
cfdiff = cfdiff[i0diff]
minaus = min(cfdiff * (1 + self.aus));
aus1 = max([minaus, self.aus]);
minaus = min(cfdiff * (1 + self.aus))
aus1 = max([minaus, self.aus])
#at first we look to the right until the end of the pick window is reached
flagpick_r = 0
@ -374,7 +374,7 @@ class PragPicker(AutoPicking):
self.Pick = pick_l
pickflag = 1
else:
print 'PragPicker: Could not find reliable onset!'
print('PragPicker: Could not find reliable onset!')
self.Pick = None
pickflag = 0
@ -393,6 +393,6 @@ class PragPicker(AutoPicking):
plt.close(p)
else:
print 'PragPicker: No initial onset time given! Check input!'
print('PragPicker: No initial onset time given! Check input!')
self.Pick = None
return

View File

@ -11,12 +11,13 @@ function conglomerate utils.
import matplotlib.pyplot as plt
import numpy as np
from scipy import integrate
from pylot.core.pick.Picker import AICPicker, PragPicker
from pylot.core.pick.CharFuns import HOScf, AICcf, ARZcf, ARHcf, AR3Ccf
from pylot.core.pick.utils import checksignallength, checkZ4S, earllatepicker,\
getSNR, fmpicker, checkPonsets, wadaticheck
getSNR, fmpicker, checkPonsets, wadaticheck, crossings_nonzero_all
from pylot.core.read.data import Data
from pylot.core.analysis.magnitude import WApp
from pylot.core.analysis.magnitude import WApp, DCfc
def autopickevent(data, param):
stations = []
@ -309,6 +310,26 @@ def autopickstation(wfstream, pickparam):
else:
FM = 'N'
##############################################################
# get DC value (w0) and corner frequency (fc) of source spectrum
# from P pulse
# restitute streams
# initialize Data object
data = Data()
[corzdat, restflag] = data.restituteWFData(invdir, zdat)
if restflag == 1:
# integrate to displacement
corintzdat = integrate.cumtrapz(corzdat[0], None, corzdat[0].stats.delta)
# class needs stream object => build it
z_copy = zdat.copy()
z_copy[0].data = corintzdat
# calculate source spectrum and get w0 and fc
calcwin = 1 / bpz2[0] # largest detectable period == window length
# around P pulse for calculating source spectrum
specpara = DCfc(z_copy, mpickP, calcwin, iplot)
w0 = specpara.getw0()
fc = specpara.getfc()
print 'autopickstation: P-weight: %d, SNR: %f, SNR[dB]: %f, ' \
'Polarity: %s' % (Pweight, SNRP, SNRPdB, FM)
Sflag = 1

View File

@ -45,7 +45,7 @@ class AutoPickParameter(object):
self.__filename = fnin
parFileCont = {}
# read from parsed arguments alternatively
for key, val in kwargs.iteritems():
for key, val in kwargs.items():
parFileCont[key] = val
if self.__filename is not None:
@ -57,7 +57,7 @@ class AutoPickParameter(object):
for line in lines:
parspl = line.split('\t')[:2]
parFileCont[parspl[0].strip()] = parspl[1]
except Exception, e:
except Exception as e:
self._printParameterError(e)
inputFile.seek(0)
lines = inputFile.readlines()
@ -65,7 +65,7 @@ class AutoPickParameter(object):
if not line.startswith(('#', '%', '\n', ' ')):
parspl = line.split('#')[:2]
parFileCont[parspl[1].strip()] = parspl[0].strip()
for key, value in parFileCont.iteritems():
for key, value in parFileCont.items():
try:
val = int(value)
except:
@ -121,7 +121,7 @@ class AutoPickParameter(object):
return len(self.__parameter.keys())
def iteritems(self):
for key, value in self.__parameter.iteritems():
for key, value in self.__parameter.items():
yield key, value
def hasParam(self, parameter):
@ -134,22 +134,22 @@ class AutoPickParameter(object):
for param in args:
try:
return self.__getitem__(param)
except KeyError, e:
except KeyError as e:
self._printParameterError(e)
except TypeError:
try:
return self.__getitem__(args)
except KeyError, e:
except KeyError as e:
self._printParameterError(e)
def setParam(self, **kwargs):
for param, value in kwargs.iteritems():
for param, value in kwargs.items():
self.__setitem__(param, value)
print self
print(self)
@staticmethod
def _printParameterError(errmsg):
print 'ParameterError:\n non-existent parameter %s' % errmsg
print('ParameterError:\n non-existent parameter %s' % errmsg)
def export2File(self, fnout):
fid_out = open(fnout, 'w')

View File

@ -187,7 +187,7 @@ class PickDlg(QDialog):
try:
data = parent.getData().getWFData().copy()
self.data = data.select(station=station)
except AttributeError, e:
except AttributeError as e:
errmsg = 'You either have to put in a data or an appropriate ' \
'parent (PyLoT MainWindow) object: {0}'.format(e)
raise Exception(errmsg)
@ -239,6 +239,8 @@ class PickDlg(QDialog):
zoom_icon.addPixmap(QPixmap(':/icons/zoom_in.png'))
home_icon = QIcon()
home_icon.addPixmap(QPixmap(':/icons/zoom_0.png'))
del_icon = QIcon()
del_icon.addPixmap(QPixmap(':/icons/delete.png'))
# create actions
self.filterAction = createAction(parent=self, text='Filter',
@ -251,9 +253,12 @@ class PickDlg(QDialog):
slot=self.zoom, icon=zoom_icon,
tip='Zoom into waveform',
checkable=True)
self.resetAction = createAction(parent=self, text='Home',
self.resetZoomAction = createAction(parent=self, text='Home',
slot=self.resetZoom, icon=home_icon,
tip='Reset zoom to original limits')
self.resetPicksAction = createAction(parent=self, text='Delete Picks',
slot=self.delPicks, icon=del_icon,
tip='Delete current picks.')
# create other widget elements
self.selectPhase = QComboBox()
@ -269,7 +274,9 @@ class PickDlg(QDialog):
_dialtoolbar.addWidget(self.selectPhase)
_dialtoolbar.addAction(self.zoomAction)
_dialtoolbar.addSeparator()
_dialtoolbar.addAction(self.resetAction)
_dialtoolbar.addAction(self.resetZoomAction)
_dialtoolbar.addSeparator()
_dialtoolbar.addAction(self.resetPicksAction)
# layout the innermost widget
_innerlayout = QVBoxLayout()
@ -371,7 +378,7 @@ class PickDlg(QDialog):
traceIDs = []
for channel in channels:
channel = channel.upper()
for traceID, channelID in plotDict.iteritems():
for traceID, channelID in plotDict.items():
if channelID[1].upper().endswith(channel):
traceIDs.append(traceID)
return traceIDs
@ -422,6 +429,13 @@ class PickDlg(QDialog):
def getPicks(self):
return self.picks
def resetPicks(self):
self.picks = {}
def delPicks(self):
self.resetPicks()
self.resetPlot()
def setIniPick(self, gui_event):
trace_number = round(gui_event.ydata)
@ -672,8 +686,21 @@ class PickDlg(QDialog):
zoomx=self.getXLims(),
zoomy=self.getYLims())
self.setPlotLabels()
self.drawPicks()
self.draw()
def resetPlot(self):
self.updateCurrentLimits()
data = self.getWFData().copy()
title = self.getPlotWidget().getAxes().get_title()
self.getPlotWidget().plotWFData(wfdata=data, title=title,
zoomx=self.getXLims(),
zoomy=self.getYLims())
self.setPlotLabels()
self.drawPicks()
self.draw()
def setPlotLabels(self):
# get channel labels
@ -711,7 +738,7 @@ class PickDlg(QDialog):
else:
# deal with something that should never happen
scale_factor = 1
print gui_event.button
print(gui_event.button)
new_xlim = gui_event.xdata - \
scale_factor * (gui_event.xdata - self.getXLims())
@ -742,7 +769,7 @@ class PickDlg(QDialog):
def apply(self):
picks = self.getPicks()
for pick in picks:
print pick, picks[pick]
print(pick, picks[pick])
def accept(self):
self.apply()