resolved conflicts
This commit is contained in:
commit
7588ad3c5b
11
QtPyLoT.py
11
QtPyLoT.py
@ -434,13 +434,16 @@ class MainWindow(QMainWindow):
|
|||||||
except OverwriteError:
|
except OverwriteError:
|
||||||
msgBox = QMessageBox()
|
msgBox = QMessageBox()
|
||||||
msgBox.setText("Picks have been modified!")
|
msgBox.setText("Picks have been modified!")
|
||||||
msgBox.setInformativeText("Do you want to overwrite the picks and save?")
|
msgBox.setInformativeText("Do you want to save the changes and overwrite the picks?")
|
||||||
msgBox.setStandardButtons(QMessageBox.Save | QMessageBox.Discard |
|
msgBox.setDetailedText(self.getData().getPicksStr())
|
||||||
QMessageBox.Cancel)
|
msgBox.setStandardButtons(QMessageBox.Save | QMessageBox.Cancel)
|
||||||
msgBox.setDefaultButton(QMessageBox.Save)
|
msgBox.setDefaultButton(QMessageBox.Save)
|
||||||
ret = msgBox.exec_()
|
ret = msgBox.exec_()
|
||||||
if ret == QMessageBox.Save:
|
if ret == QMessageBox.Save:
|
||||||
print('Overwrite and Save')
|
self.getData().resetPicks()
|
||||||
|
self.saveData()
|
||||||
|
elif ret == QMessageBox.Cancel:
|
||||||
|
return False
|
||||||
try:
|
try:
|
||||||
self.getData().exportEvent(fbasename, exform)
|
self.getData().exportEvent(fbasename, exform)
|
||||||
except FormatError as e:
|
except FormatError as e:
|
||||||
|
@ -70,8 +70,6 @@ def autoPyLoT(inputfile):
|
|||||||
|
|
||||||
# get path to inventory or dataless-seed file with station meta data
|
# get path to inventory or dataless-seed file with station meta data
|
||||||
invdir = parameter.getParam('invdir')
|
invdir = parameter.getParam('invdir')
|
||||||
# get corner frequencies for pre-filtering traces
|
|
||||||
prefilt = parameter.getParam('prefilt')
|
|
||||||
|
|
||||||
# multiple event processing
|
# multiple event processing
|
||||||
# read each event in database
|
# read each event in database
|
||||||
@ -83,8 +81,6 @@ def autoPyLoT(inputfile):
|
|||||||
print data
|
print data
|
||||||
|
|
||||||
wfdat = data.getWFData() # all available streams
|
wfdat = data.getWFData() # all available streams
|
||||||
# restitute waveform data getting responses from inventory-file
|
|
||||||
wfdat = data.restituteWFData(invdir, prefilt)
|
|
||||||
##########################################################
|
##########################################################
|
||||||
# !automated picking starts here!
|
# !automated picking starts here!
|
||||||
picks = autopickevent(wfdat, parameter)
|
picks = autopickevent(wfdat, parameter)
|
||||||
@ -100,8 +96,6 @@ def autoPyLoT(inputfile):
|
|||||||
print data
|
print data
|
||||||
|
|
||||||
wfdat = data.getWFData() # all available streams
|
wfdat = data.getWFData() # all available streams
|
||||||
# restitute waveform data getting responses from inventory-file
|
|
||||||
wfdat = data.restituteWFData(invdir, prefilt)
|
|
||||||
##########################################################
|
##########################################################
|
||||||
# !automated picking starts here!
|
# !automated picking starts here!
|
||||||
picks = autopickevent(wfdat, parameter)
|
picks = autopickevent(wfdat, parameter)
|
||||||
|
124
pylot/core/analysis/magnitude.py
Normal file
124
pylot/core/analysis/magnitude.py
Normal file
@ -0,0 +1,124 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
"""
|
||||||
|
Created August/September 2015.
|
||||||
|
|
||||||
|
:author: Ludger Küperkoch / MAGS2 EP3 working group
|
||||||
|
"""
|
||||||
|
|
||||||
|
import matplotlib.pyplot as plt
|
||||||
|
import numpy as np
|
||||||
|
from obspy.core import Stream
|
||||||
|
from pylot.core.pick.utils import getsignalwin
|
||||||
|
|
||||||
|
class Magnitude(object):
|
||||||
|
'''
|
||||||
|
Superclass for calculating Wood-Anderson peak-to-peak
|
||||||
|
amplitudes, local magnitudes and moment magnitudes.
|
||||||
|
'''
|
||||||
|
|
||||||
|
def __init__(self, wfstream, To, pwin, iplot):
|
||||||
|
'''
|
||||||
|
:param: wfstream
|
||||||
|
:type: `~obspy.core.stream.Stream
|
||||||
|
|
||||||
|
:param: To, onset time, P- or S phase
|
||||||
|
:type: float
|
||||||
|
|
||||||
|
:param: pwin, pick window [To To+pwin] to get maximum
|
||||||
|
peak-to-peak amplitude
|
||||||
|
:type: float
|
||||||
|
|
||||||
|
:param: iplot, no. of figure window for plotting interims results
|
||||||
|
:type: integer
|
||||||
|
|
||||||
|
'''
|
||||||
|
|
||||||
|
assert isinstance(wfstream, Stream), "%s is not a stream object" % str(wfstream)
|
||||||
|
|
||||||
|
self.setwfstream(wfstream)
|
||||||
|
self.setTo(To)
|
||||||
|
self.setpwin(pwin)
|
||||||
|
self.setiplot(iplot)
|
||||||
|
self.calcwapp()
|
||||||
|
|
||||||
|
|
||||||
|
def getwfstream(self):
|
||||||
|
return self.wfstream
|
||||||
|
|
||||||
|
def setwfstream(self, wfstream):
|
||||||
|
self.wfstream = wfstream
|
||||||
|
|
||||||
|
def getTo(self):
|
||||||
|
return self.To
|
||||||
|
|
||||||
|
def setTo(self, To):
|
||||||
|
self.To = To
|
||||||
|
|
||||||
|
def getpwin(self):
|
||||||
|
return self.pwin
|
||||||
|
|
||||||
|
def setpwin(self, pwin):
|
||||||
|
self.pwin = pwin
|
||||||
|
|
||||||
|
def getiplot(self):
|
||||||
|
return self.iplot
|
||||||
|
|
||||||
|
def setiplot(self, iplot):
|
||||||
|
self.iplot = iplot
|
||||||
|
|
||||||
|
def getwapp(self):
|
||||||
|
return self.wapp
|
||||||
|
|
||||||
|
def calcwapp(self):
|
||||||
|
self.wapp = 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!
|
||||||
|
'''
|
||||||
|
|
||||||
|
def calcwapp(self):
|
||||||
|
print "Getting Wood-Anderson peak-to-peak amplitude ..."
|
||||||
|
print "Simulating Wood-Anderson seismograph ..."
|
||||||
|
|
||||||
|
self.wapp = None
|
||||||
|
stream = self.getwfstream()
|
||||||
|
|
||||||
|
# poles, zeros and sensitivity of WA seismograph
|
||||||
|
# (see Uhrhammer & Collins, 1990, BSSA, pp. 702-716)
|
||||||
|
paz_wa = {
|
||||||
|
'poles': [5.6089 - 5.4978j, -5.6089 - 5.4978j],
|
||||||
|
'zeros': [0j, 0j],
|
||||||
|
'gain': 2080,
|
||||||
|
'sensitivity': 1}
|
||||||
|
|
||||||
|
stream.simulate(paz_remove=None, paz_simulate=paz_wa)
|
||||||
|
|
||||||
|
trH1 = stream[0].data
|
||||||
|
trH2 = stream[1].data
|
||||||
|
ilen = min([len(trH1), len(trH2)])
|
||||||
|
# get RMS of both horizontal components
|
||||||
|
sqH = np.sqrt(np.power(trH1[0:ilen], 2) + np.power(trH2[0:ilen], 2))
|
||||||
|
# get time array
|
||||||
|
th = np.arange(0, len(sqH) * stream[0].stats.delta, stream[0].stats.delta)
|
||||||
|
# get maximum peak within pick window
|
||||||
|
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)
|
||||||
|
plt.plot(th, sqH)
|
||||||
|
plt.plot(th[iwin], sqH[iwin], 'g')
|
||||||
|
plt.plot([self.getTo(), self.getTo()], [0, max(sqH)], 'r', linewidth=2)
|
||||||
|
plt.title('Station %s, RMS Horizontal Traces, WA-peak-to-peak=%4.1f mm' \
|
||||||
|
% (stream[0].stats.station, self.wapp))
|
||||||
|
plt.xlabel('Time [s]')
|
||||||
|
plt.ylabel('Displacement [mm]')
|
||||||
|
plt.show()
|
||||||
|
raw_input()
|
||||||
|
plt.close(f)
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -15,6 +15,8 @@ from pylot.core.pick.Picker import AICPicker, PragPicker
|
|||||||
from pylot.core.pick.CharFuns import HOScf, AICcf, ARZcf, ARHcf, AR3Ccf
|
from pylot.core.pick.CharFuns import HOScf, AICcf, ARZcf, ARHcf, AR3Ccf
|
||||||
from pylot.core.pick.utils import checksignallength, checkZ4S, earllatepicker,\
|
from pylot.core.pick.utils import checksignallength, checkZ4S, earllatepicker,\
|
||||||
getSNR, fmpicker, checkPonsets, wadaticheck
|
getSNR, fmpicker, checkPonsets, wadaticheck
|
||||||
|
from pylot.core.read.data import Data
|
||||||
|
from pylot.core.analysis.magnitude import WApp
|
||||||
|
|
||||||
def autopickevent(data, param):
|
def autopickevent(data, param):
|
||||||
stations = []
|
stations = []
|
||||||
@ -109,6 +111,8 @@ def autopickstation(wfstream, pickparam):
|
|||||||
nfacsl = pickparam.getParam('noisefactor')
|
nfacsl = pickparam.getParam('noisefactor')
|
||||||
# parameter to check for spuriously picked S onset
|
# parameter to check for spuriously picked S onset
|
||||||
zfac = pickparam.getParam('zfac')
|
zfac = pickparam.getParam('zfac')
|
||||||
|
# path to inventory-, dataless- or resp-files
|
||||||
|
invdir = pickparam.getParam('invdir')
|
||||||
|
|
||||||
# initialize output
|
# initialize output
|
||||||
Pweight = 4 # weight for P onset
|
Pweight = 4 # weight for P onset
|
||||||
@ -132,6 +136,7 @@ def autopickstation(wfstream, pickparam):
|
|||||||
Pflag = 0
|
Pflag = 0
|
||||||
Sflag = 0
|
Sflag = 0
|
||||||
Pmarker = []
|
Pmarker = []
|
||||||
|
Ao = None
|
||||||
|
|
||||||
# split components
|
# split components
|
||||||
zdat = wfstream.select(component="Z")
|
zdat = wfstream.select(component="Z")
|
||||||
@ -501,6 +506,21 @@ def autopickstation(wfstream, pickparam):
|
|||||||
|
|
||||||
print 'autopickstation: S-weight: %d, SNR: %f, SNR[dB]: %f' % (
|
print 'autopickstation: S-weight: %d, SNR: %f, SNR[dB]: %f' % (
|
||||||
Sweight, SNRS, SNRSdB)
|
Sweight, SNRS, SNRSdB)
|
||||||
|
##################################################################
|
||||||
|
if Sweight < 4:
|
||||||
|
# get Wood-Anderson peak-to-peak amplitude
|
||||||
|
print "################################################"
|
||||||
|
# initialize Data object
|
||||||
|
data = Data()
|
||||||
|
# re-create stream object including both horizontal components
|
||||||
|
hdat = edat.copy()
|
||||||
|
hdat += ndat
|
||||||
|
h_copy = hdat.copy()
|
||||||
|
cordat = data.restituteWFData(invdir, h_copy)
|
||||||
|
# calculate WA-peak-to-peak amplitude
|
||||||
|
# using subclass WApp of superclass Magnitude
|
||||||
|
wapp = WApp(cordat, mpickS, mpickP + sstop, iplot)
|
||||||
|
Ao = wapp.getwapp()
|
||||||
|
|
||||||
else:
|
else:
|
||||||
print 'Bad initial (AIC) S-pick, skipping this onset!'
|
print 'Bad initial (AIC) S-pick, skipping this onset!'
|
||||||
@ -509,6 +529,21 @@ def autopickstation(wfstream, pickparam):
|
|||||||
print '(min. AIC-SNR=', minAICSSNR, ', min. AIC-Slope=', \
|
print '(min. AIC-SNR=', minAICSSNR, ', min. AIC-Slope=', \
|
||||||
minAICSslope, 'counts/s)'
|
minAICSslope, 'counts/s)'
|
||||||
|
|
||||||
|
############################################################
|
||||||
|
# get Wood-Anderson peak-to-peak amplitude
|
||||||
|
print "################################################"
|
||||||
|
# initialize Data object
|
||||||
|
data = Data()
|
||||||
|
# re-create stream object including both horizontal components
|
||||||
|
hdat = edat.copy()
|
||||||
|
hdat += ndat
|
||||||
|
h_copy = hdat.copy()
|
||||||
|
cordat = data.restituteWFData(invdir, h_copy)
|
||||||
|
# calculate WA-peak-to-peak amplitude
|
||||||
|
# using subclass WApp of superclass Magnitude
|
||||||
|
wapp = WApp(cordat, mpickP, mpickP + sstop, iplot)
|
||||||
|
Ao = wapp.getwapp()
|
||||||
|
|
||||||
else:
|
else:
|
||||||
print 'autopickstation: No horizontal component data available or ' \
|
print 'autopickstation: No horizontal component data available or ' \
|
||||||
'bad P onset, skipping S picking!'
|
'bad P onset, skipping S picking!'
|
||||||
@ -693,5 +728,7 @@ def autopickstation(wfstream, pickparam):
|
|||||||
phasepick = {'lpp': lpickS, 'epp': epickS, 'mpp': mpickS, 'spe': Serror, \
|
phasepick = {'lpp': lpickS, 'epp': epickS, 'mpp': mpickS, 'spe': Serror, \
|
||||||
'snr': SNRS, 'snrdb': SNRSdB, 'weight': Sweight, 'fm': None}
|
'snr': SNRS, 'snrdb': SNRSdB, 'weight': Sweight, 'fm': None}
|
||||||
picks[phase] = phasepick
|
picks[phase] = phasepick
|
||||||
|
# add Wood-Anderson amplitude
|
||||||
|
picks[phase]['Ao'] = Ao
|
||||||
|
|
||||||
return picks
|
return picks
|
||||||
|
@ -52,6 +52,13 @@ class Data(object):
|
|||||||
def __str__(self):
|
def __str__(self):
|
||||||
return str(self.wfdata)
|
return str(self.wfdata)
|
||||||
|
|
||||||
|
def getPicksStr(self):
|
||||||
|
picks_str = ''
|
||||||
|
for pick in self.getEvtData().picks:
|
||||||
|
picks_str += str(pick) + '\n'
|
||||||
|
return picks_str
|
||||||
|
|
||||||
|
|
||||||
def getParent(self):
|
def getParent(self):
|
||||||
"""
|
"""
|
||||||
|
|
||||||
@ -222,7 +229,8 @@ class Data(object):
|
|||||||
:return:
|
:return:
|
||||||
"""
|
"""
|
||||||
if streams is None:
|
if streams is None:
|
||||||
st = self.getWFData()
|
st_raw = self.getWFData()
|
||||||
|
st = st_raw.copy()
|
||||||
else:
|
else:
|
||||||
st = streams
|
st = streams
|
||||||
|
|
||||||
@ -360,9 +368,11 @@ class Data(object):
|
|||||||
|
|
||||||
def applyPicks(picks):
|
def applyPicks(picks):
|
||||||
"""
|
"""
|
||||||
|
Creates ObsPy pick objects and append it to the picks list from the
|
||||||
|
PyLoT dictionary contain all picks.
|
||||||
:param picks:
|
:param picks:
|
||||||
:raise OverwriteError:
|
:raise OverwriteError: raises an OverwriteError if the picks list is
|
||||||
|
not empty. The GUI will then ask for a decision.
|
||||||
"""
|
"""
|
||||||
firstonset = None
|
firstonset = None
|
||||||
if self.getEvtData().picks:
|
if self.getEvtData().picks:
|
||||||
|
Loading…
Reference in New Issue
Block a user