[add] check second maximum of HOS/AR-CF

Use the second maximum if it is larger than first maximum * minfactor. This helps when two onsets are close together (eg. S and SKS at 90°) and the second onset is stronger.
This commit is contained in:
Darius Arnold 2017-08-26 02:12:31 +02:00
parent cd83c99034
commit 2db6fde709
4 changed files with 73 additions and 13 deletions

View File

@ -273,6 +273,26 @@ defaults = {'rootpath': {'type': str,
'value': 1.5, 'value': 1.5,
'namestring': 'Noise factor S'}, 'namestring': 'Noise factor S'},
'checkwindowP': {'type': float,
'tooltip': 'time window before HOS/AR-maximum to check for smaller maxima [s]',
'value': 10.0,
'namestring': 'Check Window P'},
'minfactorP': {'type': float,
'tooltip': 'Second maximum must be at least minfactor * first maximum [-]',
'value': 0.7,
'namestring': 'Minimum Factor P'},
'checkwindowS': {'type': float,
'tooltip': 'time window before AR-maximum to check for smaller maxima [s]',
'value': 10.0,
'namestring': 'Check Window S'},
'minfactorS': {'type': float,
'tooltip': 'Second maximum must be at least minfactor * first maximum [-]',
'value': 0.7,
'namestring': 'Minimum Factor S'},
'minfmweight': {'type': int, 'minfmweight': {'type': int,
'tooltip': 'minimum required P weight for first-motion determination', 'tooltip': 'minimum required P weight for first-motion determination',
'value': 1, 'value': 1,
@ -450,7 +470,9 @@ settings_special_pick = {
'aictsmooth', 'aictsmooth',
'tsmoothP', 'tsmoothP',
'ausP', 'ausP',
'nfacP'], 'nfacP',
'checkwindowP',
'minfactorP'],
'h': [ 'h': [
'algoS', 'algoS',
'tdet1h', 'tdet1h',
@ -464,7 +486,9 @@ settings_special_pick = {
'aictsmoothS', 'aictsmoothS',
'tsmoothS', 'tsmoothS',
'ausS', 'ausS',
'nfacS'], 'nfacS',
'checkwindowS',
'minfactorS'],
'fm': [ 'fm': [
'minfmweight', 'minfmweight',
'minFMSNR', 'minFMSNR',

View File

@ -175,6 +175,10 @@ def autopickstation(wfstream, pickparam, verbose=False,
# parameter to check for spuriously picked S onset # parameter to check for spuriously picked S onset
zfac = pickparam.get('zfac') zfac = pickparam.get('zfac')
# path to inventory-, dataless- or resp-files # path to inventory-, dataless- or resp-files
checkwindowP = pickparam.get('checkwindowP')
minfactorP = pickparam.get('minfactorP')
checkwindowS = pickparam.get('checkwindowS')
minfactorS = pickparam.get('minfactorS')
# initialize output # initialize output
Pweight = 4 # weight for P onset Pweight = 4 # weight for P onset
@ -322,7 +326,8 @@ def autopickstation(wfstream, pickparam, verbose=False,
fig = fig_dict[key] fig = fig_dict[key]
else: else:
fig = None fig = None
aicpick = AICPicker(aiccf, tsnrz, pickwinP, iplot, None, tsmoothP, fig=fig) aicpick = AICPicker(aiccf, tsnrz, pickwinP, checkwindow=checkwindowP, minfactor=minfactorP,
iplot=iplot, Tsmooth=tsmoothP, fig=fig)
# add pstart and pstop to aic plot # add pstart and pstop to aic plot
if fig: if fig:
for ax in fig.axes: for ax in fig.axes:
@ -442,8 +447,8 @@ def autopickstation(wfstream, pickparam, verbose=False,
fig = fig_dict['refPpick'] fig = fig_dict['refPpick']
else: else:
fig = None fig = None
refPpick = PragPicker(cf2, tsnrz, pickwinP, iplot, ausP, tsmoothP, refPpick = PragPicker(cf2, tsnrz, pickwinP, iplot=iplot, aus=ausP, Tsmooth=tsmoothP,
aicpick.getpick(), fig) Pick1 = aicpick.getpick(), fig=fig)
mpickP = refPpick.getpick() mpickP = refPpick.getpick()
############################################################# #############################################################
if mpickP is not None: if mpickP is not None:
@ -624,8 +629,9 @@ def autopickstation(wfstream, pickparam, verbose=False,
fig = fig_dict['aicARHfig'] fig = fig_dict['aicARHfig']
else: else:
fig = None fig = None
aicarhpick = AICPicker(haiccf, tsnrh, pickwinS, iplot, None, aicarhpick = AICPicker(haiccf, tsnrh, pickwinS, checkwindow=checkwindowS,
aictsmoothS, fig=fig) minfactor=minfactorS, iplot=iplot, Tsmooth=aictsmoothS,
fig=fig)
############################################################### ###############################################################
# go on with processing if AIC onset passes quality control # go on with processing if AIC onset passes quality control
slope = aicarhpick.getSlope() slope = aicarhpick.getSlope()
@ -686,8 +692,8 @@ def autopickstation(wfstream, pickparam, verbose=False,
fig = fig_dict['refSpick'] fig = fig_dict['refSpick']
else: else:
fig = None fig = None
refSpick = PragPicker(arhcf2, tsnrh, pickwinS, iplot, ausS, refSpick = PragPicker(arhcf2, tsnrh, pickwinS, iplot=iplot, aus=ausS,
tsmoothS, aicarhpick.getpick(), fig) Tsmooth=tsmoothS, Pick1=aicarhpick.getpick(), fig=fig)
mpickS = refSpick.getpick() mpickS = refSpick.getpick()
############################################################# #############################################################
if mpickS is not None: if mpickS is not None:

View File

@ -24,7 +24,7 @@ import warnings
import matplotlib.pyplot as plt import matplotlib.pyplot as plt
import numpy as np import numpy as np
from pylot.core.pick.charfuns import CharacteristicFunction from pylot.core.pick.charfuns import CharacteristicFunction
from pylot.core.pick.utils import getnoisewin, getsignalwin from pylot.core.pick.utils import getnoisewin, getsignalwin, get_maximum_index
class AutoPicker(object): class AutoPicker(object):
@ -35,7 +35,7 @@ class AutoPicker(object):
warnings.simplefilter('ignore') warnings.simplefilter('ignore')
def __init__(self, cf, TSNR, PickWindow, iplot=0, aus=None, Tsmooth=None, Pick1=None, fig=None): def __init__(self, cf, TSNR, PickWindow, checkwindow=None, minfactor=None, iplot=0, aus=None, Tsmooth=None, Pick1=None, fig=None):
''' '''
:param: cf, characteristic function, on which the picking algorithm is applied :param: cf, characteristic function, on which the picking algorithm is applied
:type: `~pylot.core.pick.CharFuns.CharacteristicFunction` object :type: `~pylot.core.pick.CharFuns.CharacteristicFunction` object
@ -74,6 +74,8 @@ class AutoPicker(object):
self.setTsmooth(Tsmooth) self.setTsmooth(Tsmooth)
self.setpick1(Pick1) self.setpick1(Pick1)
self.fig = fig self.fig = fig
self.setCheckWindow(checkwindow)
self.minfactor = minfactor
self.calcPick() self.calcPick()
def __str__(self): def __str__(self):
@ -89,6 +91,10 @@ class AutoPicker(object):
aus=self.getaus(), aus=self.getaus(),
Tsmooth=self.getTsmooth(), Tsmooth=self.getTsmooth(),
Pick1=self.getpick1()) Pick1=self.getpick1())
def setCheckWindow(self, checkwindow):
'''convert checkwindow to samples'''
if checkwindow:
self.checkwindow = int(checkwindow / self.Data[0].stats.delta)
def getTSNR(self): def getTSNR(self):
return self.TSNR return self.TSNR
@ -187,8 +193,8 @@ class AICPicker(AutoPicker):
offset = abs(min(aic) - min(aicsmooth)) offset = abs(min(aic) - min(aicsmooth))
aicsmooth = aicsmooth - offset aicsmooth = aicsmooth - offset
# get maximum of HOS/AR-CF as startimg point for searching # get maximum of HOS/AR-CF as startimg point for searching
# minimum in AIC function # minimum in AIC function
icfmax = np.argmax(self.Data[0].data) icfmax = get_maximum_index(self.Data[0].data, self.checkwindow, self.minfactor)
# find minimum in AIC-CF front of maximum of HOS/AR-CF # find minimum in AIC-CF front of maximum of HOS/AR-CF
lpickwindow = int(round(self.PickWindow / self.dt)) lpickwindow = int(round(self.PickWindow / self.dt))

View File

@ -13,6 +13,7 @@ import warnings
import matplotlib.pyplot as plt import matplotlib.pyplot as plt
import numpy as np import numpy as np
from obspy.core import Stream, UTCDateTime from obspy.core import Stream, UTCDateTime
from scipy.signal import argrelextrema
def earllatepicker(X, nfac, TSNR, Pick1, iplot=0, verbosity=1, fig=None): def earllatepicker(X, nfac, TSNR, Pick1, iplot=0, verbosity=1, fig=None):
@ -1171,6 +1172,29 @@ def removePicksAbove(pickDic, minWeight):
newdic[eventKey][station].update({phasename: phaseinfo}) newdic[eventKey][station].update({phasename: phaseinfo})
return newdic return newdic
def get_maximum_index(data, checkwindow, minfactor):
'''get maximum of CF as starting point, then check for highest local maximum
in front of it.
return second maximum if its larger than first maximum * minfactor, else
return first maximum'''
icfmax1 = np.argmax(data)
imax_local = argrelextrema(data[icfmax1 - checkwindow:icfmax1], np.greater) # indices of local maxima
if (len(imax_local[0]) > 0):
imax_local = imax_local[0] + icfmax1 - checkwindow
local_maxima = (imax_local, data[imax_local])
icfmax2 = local_maxima[0][np.where(local_maxima[1] == max(local_maxima[1]))][0]
if data[icfmax2] > data[icfmax1] * minfactor:
print("Found valid local maximum in front of first maximum")
return icfmax2
else:
print("First maximum is the largest: {}>{}".format(data[icfmax1],
data[icfmax2]))
return icfmax1
else:
print("No local maxima found in check window")
return icfmax1
if __name__ == '__main__': if __name__ == '__main__':
import doctest import doctest