Merge branch 'develop'

This commit is contained in:
Marcel Paffrath 2017-06-14 10:20:41 +02:00
commit 15799feee7
22 changed files with 12449 additions and 1097 deletions

1831
QtPyLoT.py

File diff suppressed because it is too large Load Diff

View File

@ -8,7 +8,6 @@ import glob
import os import os
import datetime import datetime
from obspy import read_events from obspy import read_events
import pylot.core.loc.hyposat as hyposat import pylot.core.loc.hyposat as hyposat
import pylot.core.loc.hypo71 as hypo71 import pylot.core.loc.hypo71 as hypo71
import pylot.core.loc.velest as velest import pylot.core.loc.velest as velest
@ -29,7 +28,7 @@ from pylot.core.util.version import get_git_version as _getVersionString
__version__ = _getVersionString() __version__ = _getVersionString()
def autoPyLoT(inputfile, fnames=None, savepath=None): def autoPyLoT(input_dict=None, parameter=None, inputfile=None, fnames=None, eventid=None, savepath=None, station='all', iplot=0):
""" """
Determine phase onsets automatically utilizing the automatic picking Determine phase onsets automatically utilizing the automatic picking
algorithms by Kueperkoch et al. 2010/2012. algorithms by Kueperkoch et al. 2010/2012.
@ -55,15 +54,43 @@ def autoPyLoT(inputfile, fnames=None, savepath=None):
***********************************'''.format(version=_getVersionString()) ***********************************'''.format(version=_getVersionString())
print(splash) print(splash)
# reading parameter file locflag = 1
parameter = AutoPickParameter(inputfile) if input_dict and isinstance(input_dict, dict):
if input_dict.has_key('parameter'):
parameter = input_dict['parameter']
if input_dict.has_key('fig_dict'):
fig_dict = input_dict['fig_dict']
if input_dict.has_key('station'):
station = input_dict['station']
if input_dict.has_key('fnames'):
fnames = input_dict['fnames']
if input_dict.has_key('iplot'):
iplot = input_dict['iplot']
if input_dict.has_key('locflag'):
locflag = input_dict['locflag']
if not parameter:
if inputfile:
parameter = AutoPickParameter(inputfile)
iplot = parameter['iplot']
else:
print('No parameters set and no input file given. Choose either of both.')
return
else:
if not type(parameter) == AutoPickParameter:
print('Wrong input type for parameter: {}'.format(type(parameter)))
return
if inputfile:
print('Parameters set and input file given. Choose either of both.')
return
data = Data() data = Data()
evt = None evt = None
# getting information on data structure
# reading parameter file
if parameter.hasParam('datastructure'): if parameter.hasParam('datastructure'):
# getting information on data structure
datastructure = DATASTRUCTURE[parameter.get('datastructure')]() datastructure = DATASTRUCTURE[parameter.get('datastructure')]()
dsfields = {'root': parameter.get('rootpath'), dsfields = {'root': parameter.get('rootpath'),
'dpath': parameter.get('datapath'), 'dpath': parameter.get('datapath'),
@ -79,8 +106,7 @@ def autoPyLoT(inputfile, fnames=None, savepath=None):
datastructure.setExpandFields(exf) datastructure.setExpandFields(exf)
# check if default location routine NLLoc is available # check if default location routine NLLoc is available
if parameter.hasParam('nllocbin'): if parameter['nllocbin'] and locflag:
locflag = 1
# get NLLoc-root path # get NLLoc-root path
nllocroot = parameter.get('nllocroot') nllocroot = parameter.get('nllocroot')
# get path to NLLoc executable # get path to NLLoc executable
@ -114,7 +140,10 @@ def autoPyLoT(inputfile, fnames=None, savepath=None):
events = glob.glob(os.path.join(datapath, parameter.get('eventID'))) events = glob.glob(os.path.join(datapath, parameter.get('eventID')))
else: else:
# autoPyLoT was initialized from GUI # autoPyLoT was initialized from GUI
events = fnames events = []
events.append(eventid)
evID = os.path.split(eventid)[-1]
locflag = 2
for event in events: for event in events:
if fnames == 'None': if fnames == 'None':
@ -135,27 +164,39 @@ def autoPyLoT(inputfile, fnames=None, savepath=None):
parameter.setParam(eventID=eventID) parameter.setParam(eventID=eventID)
else: else:
data.setWFData(fnames) data.setWFData(fnames)
event = savepath
now = datetime.datetime.now() event = events[0]
evID = '%d%02d%02d%02d%02d' % (now.year, #now = datetime.datetime.now()
now.month, #evID = '%d%02d%02d%02d%02d' % (now.year,
now.day, # now.month,
now.hour, # now.day,
now.minute) # now.hour,
parameter.setParam(eventID=evID) # now.minute)
parameter.setParam(eventID=eventid)
wfdat = data.getWFData() # all available streams wfdat = data.getWFData() # all available streams
if not station == 'all':
wfdat = wfdat.select(station=station)
if not wfdat:
print('Could not find station {}. STOP!'.format(station))
return
wfdat = remove_underscores(wfdat) wfdat = remove_underscores(wfdat)
metadata = read_metadata(parameter.get('invdir')) metadata = read_metadata(parameter.get('invdir'))
print("Restitute data ...")
corr_dat = restitute_data(wfdat.copy(), *metadata) corr_dat = restitute_data(wfdat.copy(), *metadata)
print('Working on event %s' % event) print('Working on event %s. Stations: %s' % (event, station))
print(data) print(wfdat)
########################################################## ##########################################################
# !automated picking starts here! # !automated picking starts here!
picks = autopickevent(wfdat, parameter) if input_dict:
if input_dict.has_key('fig_dict'):
fig_dict = input_dict['fig_dict']
picks = autopickevent(wfdat, parameter, iplot=iplot, fig_dict=fig_dict)
else:
picks = autopickevent(wfdat, parameter, iplot=iplot)
########################################################## ##########################################################
# locating # locating
if locflag == 1: if locflag > 0:
# write phases to NLLoc-phase file # write phases to NLLoc-phase file
nll.export(picks, phasefile, parameter) nll.export(picks, phasefile, parameter)
@ -192,14 +233,14 @@ def autoPyLoT(inputfile, fnames=None, savepath=None):
moment_mag = MomentMagnitude(corr_dat, evt, parameter.get('vp'), moment_mag = MomentMagnitude(corr_dat, evt, parameter.get('vp'),
parameter.get('Qp'), parameter.get('Qp'),
parameter.get('rho'), True, \ parameter.get('rho'), True, \
parameter.get('iplot')) iplot)
# update pick with moment property values (w0, fc, Mo) # update pick with moment property values (w0, fc, Mo)
for station, props in moment_mag.moment_props.items(): for station, props in moment_mag.moment_props.items():
picks[station]['P'].update(props) picks[station]['P'].update(props)
evt = moment_mag.updated_event() evt = moment_mag.updated_event()
local_mag = RichterMagnitude(corr_dat, evt, local_mag = RichterMagnitude(corr_dat, evt,
parameter.get('sstop'), True,\ parameter.get('sstop'), True,\
parameter.get('iplot')) iplot)
for station, amplitude in local_mag.amplitudes.items(): for station, amplitude in local_mag.amplitudes.items():
picks[station]['S']['Ao'] = amplitude.generic_amplitude picks[station]['S']['Ao'] = amplitude.generic_amplitude
evt = local_mag.updated_event() evt = local_mag.updated_event()
@ -219,7 +260,12 @@ def autoPyLoT(inputfile, fnames=None, savepath=None):
print("autoPyLoT: Number of maximum iterations reached, stop iterative picking!") print("autoPyLoT: Number of maximum iterations reached, stop iterative picking!")
break break
print("autoPyLoT: Starting with iteration No. %d ..." % nlloccounter) print("autoPyLoT: Starting with iteration No. %d ..." % nlloccounter)
picks = iteratepicker(wfdat, nllocfile, picks, badpicks, parameter) if input_dict:
if input_dict.has_key('fig_dict'):
fig_dict = input_dict['fig_dict']
picks = iteratepicker(wfdat, nllocfile, picks, badpicks, parameter, fig_dict=fig_dict)
else:
picks = iteratepicker(wfdat, nllocfile, picks, badpicks, parameter)
# write phases to NLLoc-phase file # write phases to NLLoc-phase file
nll.export(picks, phasefile, parameter) nll.export(picks, phasefile, parameter)
# remove actual NLLoc-location file to keep only the last # remove actual NLLoc-location file to keep only the last
@ -240,23 +286,24 @@ def autoPyLoT(inputfile, fnames=None, savepath=None):
print("autoPyLoT: No more bad onsets found, stop iterative picking!") print("autoPyLoT: No more bad onsets found, stop iterative picking!")
nlloccounter = maxnumit nlloccounter = maxnumit
evt = read_events(nllocfile)[0] evt = read_events(nllocfile)[0]
# calculating seismic moment Mo and moment magnitude Mw if locflag < 2:
moment_mag = MomentMagnitude(corr_dat, evt, parameter.get('vp'), # calculating seismic moment Mo and moment magnitude Mw
parameter.get('Qp'), moment_mag = MomentMagnitude(corr_dat, evt, parameter.get('vp'),
parameter.get('rho'), True, \ parameter.get('Qp'),
parameter.get('iplot')) parameter.get('rho'), True, \
# update pick with moment property values (w0, fc, Mo) iplot)
for station, props in moment_mag.moment_props.items(): # update pick with moment property values (w0, fc, Mo)
picks[station]['P'].update(props) for station, props in moment_mag.moment_props.items():
evt = moment_mag.updated_event() picks[station]['P'].update(props)
local_mag = RichterMagnitude(corr_dat, evt, evt = moment_mag.updated_event()
parameter.get('sstop'), True, \ local_mag = RichterMagnitude(corr_dat, evt,
parameter.get('iplot')) parameter.get('sstop'), True, \
for station, amplitude in local_mag.amplitudes.items(): iplot)
picks[station]['S']['Ao'] = amplitude.generic_amplitude for station, amplitude in local_mag.amplitudes.items():
evt = local_mag.updated_event() picks[station]['S']['Ao'] = amplitude.generic_amplitude
net_mw = moment_mag.net_magnitude() evt = local_mag.updated_event()
print("Network moment magnitude: %4.1f" % net_mw.mag) net_mw = moment_mag.net_magnitude()
print("Network moment magnitude: %4.1f" % net_mw.mag)
else: else:
print("autoPyLoT: No NLLoc-location file available! Stop iteration!") print("autoPyLoT: No NLLoc-location file available! Stop iteration!")
locflag = 9 locflag = 9
@ -303,14 +350,22 @@ def autoPyLoT(inputfile, fnames=None, savepath=None):
The Python picking and Location Tool\n The Python picking and Location Tool\n
************************************'''.format(version=_getVersionString()) ************************************'''.format(version=_getVersionString())
print(endsp) print(endsp)
return picks
if __name__ == "__main__": if __name__ == "__main__":
# parse arguments # parse arguments
parser = argparse.ArgumentParser( parser = argparse.ArgumentParser(
description='''autoPyLoT automatically picks phase onset times using higher order statistics, description='''autoPyLoT automatically picks phase onset times using higher order statistics,
autoregressive prediction and AIC''') autoregressive prediction and AIC followed by locating the seismic events using
NLLoc''')
#parser.add_argument('-d', '-D', '--input_dict', type=str,
# action='store',
# help='''optional, dictionary containing processing parameters''')
#parser.add_argument('-p', '-P', '--parameter', type=str,
# action='store',
# help='''parameter file, default=None''')
parser.add_argument('-i', '-I', '--inputfile', type=str, parser.add_argument('-i', '-I', '--inputfile', type=str,
action='store', action='store',
help='''full path to the file containing the input help='''full path to the file containing the input
@ -318,13 +373,21 @@ if __name__ == "__main__":
parser.add_argument('-f', '-F', '--fnames', type=str, parser.add_argument('-f', '-F', '--fnames', type=str,
action='store', action='store',
help='''optional, list of data file names''') help='''optional, list of data file names''')
parser.add_argument('-e', '-E', '--eventid', type=str,
action='store',
help='''optional, event path incl. event ID''')
parser.add_argument('-s', '-S', '--spath', type=str, parser.add_argument('-s', '-S', '--spath', type=str,
action='store', action='store',
help='''optional, save path for autoPyLoT output''') help='''optional, save path for autoPyLoT output''')
parser.add_argument('-v', '-V', '--version', action='version', #parser.add_argument('-v', '-V', '--version', action='version',
version='autoPyLoT ' + __version__, # version='autoPyLoT ' + __version__,
help='show version information and exit') # help='show version information and exit')
cla = parser.parse_args() cla = parser.parse_args()
autoPyLoT(str(cla.inputfile), str(cla.fnames), str(cla.spath)) try:
picks, mainFig = autoPyLoT(inputfile=str(cla.inputfile), fnames=str(cla.fnames),
eventid=str(cla.eventid), savepath=str(cla.spath))
except ValueError:
print("autoPyLoT was running in production mode.")

View File

@ -1,9 +1,13 @@
<RCC> <RCC>
<qresource> <qresource>
<file>icons/Library-icon.png</file>
<file>icons/pylot.ico</file> <file>icons/pylot.ico</file>
<file>icons/pylot.png</file> <file>icons/pylot.png</file>
<file>icons/manupicsicon.png</file> <file>icons/manupicsicon.png</file>
<file>icons/autopicsicon.png</file> <file>icons/autopicsicon.png</file>
<file>icons/autopylot_button.png</file>
<file>icons/manupicksicon_small.png</file>
<file>icons/autopicksicon_small.png</file>
<file>icons/autopick_button.png</file> <file>icons/autopick_button.png</file>
<file>icons/locactionicon.png</file> <file>icons/locactionicon.png</file>
<file>icons/compare_button.png</file> <file>icons/compare_button.png</file>

Binary file not shown.

After

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

File diff suppressed because it is too large Load Diff

View File

@ -1 +1 @@
3932-dirty 5412-dirty

View File

@ -201,22 +201,21 @@ class RichterMagnitude(Magnitude):
"mm".format(st[0].stats.station, wapp)) "mm".format(st[0].stats.station, wapp))
# check for plot flag (for debugging only) # check for plot flag (for debugging only)
fig = None
if self.plot_flag > 1: if self.plot_flag > 1:
st.plot() st.plot()
f = plt.figure(2) fig = plt.figure()
plt.plot(th, sqH) ax = fig.add_subplot(111)
plt.plot(th[iwin], sqH[iwin], 'g') ax.plot(th, sqH)
plt.plot([t0, t0], [0, max(sqH)], 'r', linewidth=2) ax.plot(th[iwin], sqH[iwin], 'g')
plt.title( ax.plot([t0, t0], [0, max(sqH)], 'r', linewidth=2)
ax.title(
'Station %s, RMS Horizontal Traces, WA-peak-to-peak=%4.1f mm' \ 'Station %s, RMS Horizontal Traces, WA-peak-to-peak=%4.1f mm' \
% (st[0].stats.station, wapp)) % (st[0].stats.station, wapp))
plt.xlabel('Time [s]') ax.set_xlabel('Time [s]')
plt.ylabel('Displacement [mm]') ax.set_ylabel('Displacement [mm]')
plt.show()
raw_input()
plt.close(f)
return wapp return wapp, fig
def calc(self): def calc(self):
for a in self.arrivals: for a in self.arrivals:
@ -234,7 +233,7 @@ class RichterMagnitude(Magnitude):
continue continue
delta = degrees2kilometers(a.distance) delta = degrees2kilometers(a.distance)
onset = pick.time onset = pick.time
a0 = self.peak_to_peak(wf, onset) a0, self.p2p_fig = self.peak_to_peak(wf, onset)
amplitude = ope.Amplitude(generic_amplitude=a0 * 1e-3) amplitude = ope.Amplitude(generic_amplitude=a0 * 1e-3)
amplitude.unit = 'm' amplitude.unit = 'm'
amplitude.category = 'point' amplitude.category = 'point'
@ -581,9 +580,6 @@ def calcsourcespec(wfstream, onset, vp, delta, azimuth, incidence,
plt.xlabel('Frequency [Hz]') plt.xlabel('Frequency [Hz]')
plt.ylabel('Amplitude [m/Hz]') plt.ylabel('Amplitude [m/Hz]')
plt.grid() plt.grid()
plt.show()
raw_input()
plt.close(f1)
return w0, fc return w0, fc
@ -685,7 +681,7 @@ def fitSourceModel(f, S, fc0, iplot, verbosity=False):
"fitSourceModel: best fc: {0} Hz, best w0: {1} m/Hz".format(fc, w0)) "fitSourceModel: best fc: {0} Hz, best w0: {1} m/Hz".format(fc, w0))
if iplot > 1: if iplot > 1:
plt.figure(iplot) plt.figure()#iplot)
plt.loglog(f, S, 'k') plt.loglog(f, S, 'k')
plt.loglog([f[0], fc], [w0, w0], 'g') plt.loglog([f[0], fc], [w0, w0], 'g')
plt.loglog([fc, fc], [w0 / 100, w0], 'g') plt.loglog([fc, fc], [w0 / 100, w0], 'g')
@ -694,7 +690,7 @@ def fitSourceModel(f, S, fc0, iplot, verbosity=False):
plt.xlabel('Frequency [Hz]') plt.xlabel('Frequency [Hz]')
plt.ylabel('Amplitude [m/Hz]') plt.ylabel('Amplitude [m/Hz]')
plt.grid() plt.grid()
plt.figure(iplot + 1) plt.figure()#iplot + 1)
plt.subplot(311) plt.subplot(311)
plt.plot(f[il:ir], STD, '*') plt.plot(f[il:ir], STD, '*')
plt.title('Common Standard Deviations') plt.title('Common Standard Deviations')
@ -707,8 +703,5 @@ def fitSourceModel(f, S, fc0, iplot, verbosity=False):
plt.plot(f[il:ir], stdfc, '*') plt.plot(f[il:ir], stdfc, '*')
plt.title('Standard Deviations of Corner Frequencies') plt.title('Standard Deviations of Corner Frequencies')
plt.xlabel('Corner Frequencies [Hz]') plt.xlabel('Corner Frequencies [Hz]')
plt.show()
raw_input()
plt.close()
return w0, fc return w0, fc

View File

@ -5,6 +5,7 @@ import copy
import os import os
from obspy import read_events from obspy import read_events
from obspy.core import read, Stream, UTCDateTime from obspy.core import read, Stream, UTCDateTime
from obspy.io.sac import SacIOError
from obspy.core.event import Event from obspy.core.event import Event
from pylot.core.io.phases import readPILOTEvent, picks_from_picksdict, \ from pylot.core.io.phases import readPILOTEvent, picks_from_picksdict, \
picksdict_from_pilot, merge_picks picksdict_from_pilot, merge_picks
@ -230,6 +231,8 @@ class Data(object):
self.wfdata += read(fname, format='GSE2') self.wfdata += read(fname, format='GSE2')
except Exception as e: except Exception as e:
warnmsg += '{0}\n{1}\n'.format(fname, e) warnmsg += '{0}\n{1}\n'.format(fname, e)
except SacIOError as se:
warnmsg += '{0}\n{1}\n'.format(fname, se)
if warnmsg: if warnmsg:
warnmsg = 'WARNING: unable to read\n' + warnmsg warnmsg = 'WARNING: unable to read\n' + warnmsg
print(warnmsg) print(warnmsg)
@ -294,7 +297,6 @@ class Data(object):
:raise OverwriteError: raises an OverwriteError if the picks list is :raise OverwriteError: raises an OverwriteError if the picks list is
not empty. The GUI will then ask for a decision. not empty. The GUI will then ask for a decision.
""" """
#firstonset = find_firstonset(picks) #firstonset = find_firstonset(picks)
# check for automatic picks # check for automatic picks
print("Writing phases to ObsPy-quakeml file") print("Writing phases to ObsPy-quakeml file")

View File

@ -0,0 +1,362 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
defaults = {'rootpath': {'type': str,
'tooltip': 'project path',
'value': ''},
'datapath': {'type': str,
'tooltip': 'data path',
'value': ''},
'database': {'type': str,
'tooltip': 'name of data base',
'value': ''},
'eventID': {'type': str,
'tooltip': 'event ID for single event processing',
'value': ''},
'extent': {'type': str,
'tooltip': 'extent of array ("local", "regional" or "global")',
'value': 'local'},
'invdir': {'type': str,
'tooltip': 'full path to inventory or dataless-seed file',
'value': ''},
'datastructure': {'type': str,
'tooltip': 'choose data structure',
'value': 'PILOT'},
'apverbose': {'type': bool,
'tooltip': "choose 'True' or 'False' for terminal output",
'value': True},
'nllocbin': {'type': str,
'tooltip': 'path to NLLoc executable',
'value': ''},
'nllocroot': {'type': str,
'tooltip': 'root of NLLoc-processing directory',
'value': ''},
'phasefile': {'type': str,
'tooltip': 'name of autoPyLoT-output phase file for NLLoc',
'value': 'AUTOPHASES.obs'},
'ctrfile': {'type': str,
'tooltip': 'name of autoPyLoT-output control file for NLLoc',
'value': 'Insheim_min1d2015_auto.in'},
'ttpatter': {'type': str,
'tooltip': 'pattern of NLLoc ttimes from grid',
'value': 'ttime'},
'outpatter': {'type': str,
'tooltip': 'pattern of NLLoc-output file',
'value': 'AUTOLOC_nlloc'},
'vp': {'type': float,
'tooltip': 'average P-wave velocity',
'value': 3530.},
'rho': {'type': float,
'tooltip': 'average rock density [kg/m^3]',
'value': 2500.},
'Qp': {'type': (float, float),
'tooltip': 'quality factor for P waves (Qp*f^a); list(Qp, a)',
'value': (300., 0.8)},
'pstart': {'type': float,
'tooltip': 'start time [s] for calculating CF for P-picking',
'value': 15.0},
'pstop': {'type': float,
'tooltip': 'end time [s] for calculating CF for P-picking',
'value': 60.0},
'sstart': {'type': float,
'tooltip': 'start time [s] relative to P-onset for calculating CF for S-picking',
'value': -1.0},
'sstop': {'type': float,
'tooltip': 'end time [s] after P-onset for calculating CF for S-picking',
'value': 10.0},
'bpz1': {'type': (float, float),
'tooltip': 'lower/upper corner freq. of first band pass filter Z-comp. [Hz]',
'value': (2, 20)},
'bpz2': {'type': (float, float),
'tooltip': 'lower/upper corner freq. of second band pass filter Z-comp. [Hz]',
'value': (2, 30)},
'bph1': {'type': (float, float),
'tooltip': 'lower/upper corner freq. of first band pass filter H-comp. [Hz]',
'value': (2, 15)},
'bph2': {'type': (float, float),
'tooltip': 'lower/upper corner freq. of second band pass filter z-comp. [Hz]',
'value': (2, 20)},
'algoP': {'type': str,
'tooltip': 'choose algorithm for P-onset determination (HOS, ARZ, or AR3)',
'value': 'HOS'},
'tlta': {'type': float,
'tooltip': 'for HOS-/AR-AIC-picker, length of LTA window [s]',
'value': 7.0},
'hosorder': {'type': int,
'tooltip': 'for HOS-picker, order of Higher Order Statistics',
'value': 4},
'Parorder': {'type': int,
'tooltip': 'for AR-picker, order of AR process of Z-component',
'value': 2},
'tdet1z': {'type': float,
'tooltip': 'for AR-picker, length of AR determination window [s] for Z-component, 1st pick',
'value': 1.2},
'tpred1z': {'type': float,
'tooltip': 'for AR-picker, length of AR prediction window [s] for Z-component, 1st pick',
'value': 0.4},
'tdet2z': {'type': float,
'tooltip': 'for AR-picker, length of AR determination window [s] for Z-component, 2nd pick',
'value': 0.6},
'tpred2z': {'type': float,
'tooltip': 'for AR-picker, length of AR prediction window [s] for Z-component, 2nd pick',
'value': 0.2},
'addnoise': {'type': float,
'tooltip': 'add noise to seismogram for stable AR prediction',
'value': 0.001},
'tsnrz': {'type': (float, float, float, float),
'tooltip': 'for HOS/AR, window lengths for SNR-and slope estimation [tnoise, tsafetey, tsignal, tslope] [s]',
'value': (3, 0.1, 0.5, 1.0)},
'pickwinP': {'type': float,
'tooltip': 'for initial AIC pick, length of P-pick window [s]',
'value': 3.0},
'Precalcwin': {'type': float,
'tooltip': 'for HOS/AR, window length [s] for recalculation of CF (relative to 1st pick)',
'value': 6.0},
'aictsmooth': {'type': float,
'tooltip': 'for HOS/AR, take average of samples for smoothing of AIC-function [s]',
'value': 0.2},
'tsmoothP': {'type': float,
'tooltip': 'for HOS/AR, take average of samples for smoothing CF [s]',
'value': 0.1},
'ausP': {'type': float,
'tooltip': 'for HOS/AR, artificial uplift of samples (aus) of CF (P)',
'value': 0.001},
'nfacP': {'type': float,
'tooltip': 'for HOS/AR, noise factor for noise level determination (P)',
'value': 1.3},
'algoS': {'type': str,
'tooltip': 'choose algorithm for S-onset determination (ARH or AR3)',
'value': 'ARH'},
'tdet1h': {'type': float,
'tooltip': 'for HOS/AR, length of AR-determination window [s], H-components, 1st pick',
'value': 0.8},
'tpred1h': {'type': float,
'tooltip': 'for HOS/AR, length of AR-prediction window [s], H-components, 1st pick',
'value': 0.4},
'tdet2h': {'type': float,
'tooltip': 'for HOS/AR, length of AR-determinaton window [s], H-components, 2nd pick',
'value': 0.6},
'tpred2h': {'type': float,
'tooltip': 'for HOS/AR, length of AR-prediction window [s], H-components, 2nd pick',
'value': 0.3},
'Sarorder': {'type': int,
'tooltip': 'for AR-picker, order of AR process of H-components',
'value': 4},
'Srecalcwin': {'type': float,
'tooltip': 'for AR-picker, window length [s] for recalculation of CF (2nd pick) (H)',
'value': 5.0},
'pickwinS': {'type': float,
'tooltip': 'for initial AIC pick, length of S-pick window [s]',
'value': 3.0},
'tsnrh': {'type': (float, float, float, float),
'tooltip': 'for ARH/AR3, window lengths for SNR-and slope estimation [tnoise, tsafetey, tsignal, tslope] [s]',
'value': (2, 0.2, 1.5, 0.5)},
'aictsmoothS': {'type': float,
'tooltip': 'for AIC-picker, take average of samples for smoothing of AIC-function [s]',
'value': 0.5},
'tsmoothS': {'type': float,
'tooltip': 'for AR-picker, take average of samples for smoothing CF [s] (S)',
'value': 0.7},
'ausS': {'type': float,
'tooltip': 'for HOS/AR, artificial uplift of samples (aus) of CF (S)',
'value': 0.9},
'nfacS': {'type': float,
'tooltip': 'for AR-picker, noise factor for noise level determination (S)',
'value': 1.5},
'minfmweight': {'type': int,
'tooltip': 'minimum required P weight for first-motion determination',
'value': 1},
'minFMSNR': {'type': float,
'tooltip': 'miniumum required SNR for first-motion determination',
'value': 2.},
'fmpickwin': {'type': float,
'tooltip': 'pick window around P onset for calculating zero crossings',
'value': 0.2},
'timeerrorsP': {'type': (float, float, float, float),
'tooltip': 'discrete time errors [s] corresponding to picking weights [0 1 2 3] for P',
'value': (0.01, 0.02, 0.04, 0.08)},
'timeerrorsS': {'type': (float, float, float, float),
'tooltip': 'discrete time errors [s] corresponding to picking weights [0 1 2 3] for S',
'value': (0.04, 0.08, 0.16, 0.32)},
'minAICPslope': {'type': float,
'tooltip': 'below this slope [counts/s] the initial P pick is rejected',
'value': 0.8},
'minAICPSNR': {'type': float,
'tooltip': 'below this SNR the initial P pick is rejected',
'value': 1.1},
'minAICSslope': {'type': float,
'tooltip': 'below this slope [counts/s] the initial S pick is rejected',
'value': 1.},
'minAICSSNR': {'type': float,
'tooltip': 'below this SNR the initial S pick is rejected',
'value': 1.5},
'minsiglength': {'type': float,
'tooltip': 'length of signal part for which amplitudes must exceed noiselevel [s]',
'value': 1.},
'noisefactor': {'type': float,
'tooltip': 'noiselevel*noisefactor=threshold',
'value': 1.0},
'minpercent': {'type': float,
'tooltip': 'required percentage of amplitudes exceeding threshold',
'value': 10.},
'zfac': {'type': float,
'tooltip': 'P-amplitude must exceed at least zfac times RMS-S amplitude',
'value': 1.5},
'mdttolerance': {'type': float,
'tooltip': 'maximum allowed deviation of P picks from median [s]',
'value': 6.0},
'wdttolerance': {'type': float,
'tooltip': 'maximum allowed deviation from Wadati-diagram',
'value': 1.0}
}
settings_main={
'dirs':[
'rootpath',
'datapath',
'database',
'eventID',
'invdir',
'datastructure',
'apverbose'],
'nlloc':[
'nllocbin',
'nllocroot',
'phasefile',
'ctrfile',
'ttpatter',
'outpatter'],
'smoment':[
'vp',
'rho',
'Qp'],
'pick':[
'extent',
'pstart',
'pstop',
'sstart',
'sstop',
'bpz1',
'bpz2',
'bph1',
'bph2']
}
settings_special_pick={
'z':[
'algoP',
'tlta',
'hosorder',
'Parorder',
'tdet1z',
'tpred1z',
'tdet2z',
'tpred2z',
'addnoise',
'tsnrz',
'pickwinP',
'Precalcwin',
'aictsmooth',
'tsmoothP',
'ausP',
'nfacP'],
'h':[
'algoS',
'tdet1h',
'tpred1h',
'tdet2h',
'tpred2h',
'Sarorder',
'Srecalcwin',
'pickwinS',
'tsnrh',
'aictsmoothS',
'tsmoothS',
'ausS',
'nfacS'],
'fm':[
'minfmweight',
'minFMSNR',
'fmpickwin'],
'quality':[
'timeerrorsP',
'timeerrorsS',
'minAICPslope',
'minAICPSNR',
'minAICSslope',
'minAICSSNR',
'minsiglength',
'noisefactor',
'minpercent',
'zfac',
'mdttolerance',
'wdttolerance']
}

View File

@ -2,7 +2,7 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
from pylot.core.util.errors import ParameterError from pylot.core.util.errors import ParameterError
import default_parameters
class AutoPickParameter(object): class AutoPickParameter(object):
''' '''
@ -44,48 +44,15 @@ class AutoPickParameter(object):
contain all parameters. contain all parameters.
''' '''
self.__init_default_paras()
self.__init_subsettings()
self.__filename = fnin self.__filename = fnin
parFileCont = {} self._verbosity = verbosity
self._parFileCont = {}
# io from parsed arguments alternatively # io from parsed arguments alternatively
for key, val in kwargs.items(): for key, val in kwargs.items():
parFileCont[key] = val self._parFileCont[key] = val
self.from_file()
if self.__filename is not None:
inputFile = open(self.__filename, 'r')
else:
return
try:
lines = inputFile.readlines()
for line in lines:
parspl = line.split('\t')[:2]
parFileCont[parspl[0].strip()] = parspl[1]
except IndexError as e:
if verbosity > 0:
self._printParameterError(e)
inputFile.seek(0)
lines = inputFile.readlines()
for line in lines:
if not line.startswith(('#', '%', '\n', ' ')):
parspl = line.split('#')[:2]
parFileCont[parspl[1].strip()] = parspl[0].strip()
for key, value in parFileCont.items():
try:
val = int(value)
except:
try:
val = float(value)
except:
if len(value.split(' ')) > 1:
vallist = value.strip().split(' ')
val = []
for val0 in vallist:
val0 = float(val0)
val.append(val0)
else:
val = str(value.strip())
parFileCont[key] = val
self.__parameter = parFileCont
if fnout: if fnout:
self.export2File(fnout) self.export2File(fnout)
@ -100,16 +67,28 @@ class AutoPickParameter(object):
string += 'Empty parameter dictionary.' string += 'Empty parameter dictionary.'
return string return string
# Set default values of parameter names
def __init_default_paras(self):
parameters=default_parameters.defaults
self.__defaults = parameters
def __init_subsettings(self):
self._settings_main=default_parameters.settings_main
self._settings_special_pick=default_parameters.settings_special_pick
# String representation of the object # String representation of the object
def __repr__(self): def __repr__(self):
return "AutoPickParameter('%s')" % self.__filename return "AutoPickParameter('%s')" % self.__filename
# Boolean test # Boolean test
def __nonzero__(self): def __nonzero__(self):
return self.__parameter return bool(self.__parameter)
def __getitem__(self, key): def __getitem__(self, key):
return self.__parameter[key] try:
return self.__parameter[key]
except:
return None
def __setitem__(self, key, value): def __setitem__(self, key, value):
self.__parameter[key] = value self.__parameter[key] = value
@ -147,21 +126,157 @@ class AutoPickParameter(object):
self._printParameterError(e) self._printParameterError(e)
raise ParameterError(e) raise ParameterError(e)
def setParam(self, **kwargs): def get_defaults(self):
for param, value in kwargs.items(): return self.__defaults
self.__setitem__(param, value)
# print(self)
def get_main_para_names(self):
return self._settings_main
def get_special_para_names(self):
return self._settings_special_pick
def get_all_para_names(self):
all_names=[]
all_names += self.get_main_para_names()['dirs']
all_names += self.get_main_para_names()['nlloc']
all_names += self.get_main_para_names()['smoment']
all_names += self.get_main_para_names()['pick']
all_names += self.get_special_para_names()['z']
all_names += self.get_special_para_names()['h']
all_names += self.get_special_para_names()['fm']
all_names += self.get_special_para_names()['quality']
return all_names
def checkValue(self, param, value):
is_type = type(value)
expect_type = self.get_defaults()[param]['type']
if not is_type == expect_type and not is_type == tuple:
message = 'Type check failed for param: {}, is type: {}, expected type:{}'
message = message.format(param, is_type, expect_type)
print(Warning(message))
def setParamKV(self, param, value):
self.__setitem__(param, value)
def setParam(self, **kwargs):
for key in kwargs:
self.__setitem__(key, kwargs[key])
@staticmethod @staticmethod
def _printParameterError(errmsg): def _printParameterError(errmsg):
print('ParameterError:\n non-existent parameter %s' % errmsg) print('ParameterError:\n non-existent parameter %s' % errmsg)
def reset_defaults(self):
defaults = self.get_defaults()
for param in defaults:
self.setParamKV(param, defaults[param]['value'])
def from_file(self, fnin=None):
if not fnin:
if self.__filename is not None:
fnin = self.__filename
else:
return
if isinstance(fnin, (list, tuple)):
fnin = fnin[0]
inputFile = open(fnin, 'r')
try:
lines = inputFile.readlines()
for line in lines:
parspl = line.split('\t')[:2]
self._parFileCont[parspl[0].strip()] = parspl[1]
except IndexError as e:
if self._verbosity > 0:
self._printParameterError(e)
inputFile.seek(0)
lines = inputFile.readlines()
for line in lines:
if not line.startswith(('#', '%', '\n', ' ')):
parspl = line.split('#')[:2]
self._parFileCont[parspl[1].strip()] = parspl[0].strip()
for key, value in self._parFileCont.items():
try:
val = int(value)
except:
try:
val = float(value)
except:
if len(value.split(' ')) > 1:
vallist = value.strip().split(' ')
val = []
for val0 in vallist:
val0 = float(val0)
val.append(val0)
else:
val = str(value.strip())
self._parFileCont[key] = val
self.__parameter = self._parFileCont
def export2File(self, fnout): def export2File(self, fnout):
fid_out = open(fnout, 'w') fid_out = open(fnout, 'w')
lines = [] lines = []
for key, value in self.iteritems(): # for key, value in self.iteritems():
lines.append('{key}\t{value}'.format(key=key, value=value)) # lines.append('{key}\t{value}\n'.format(key=key, value=value))
fid_out.writelines(lines) # fid_out.writelines(lines)
header = ('%This is a parameter input file for PyLoT/autoPyLoT.\n'+
'%All main and special settings regarding data handling\n'+
'%and picking are to be set here!\n'+
'%Parameters are optimized for local data sets!\n')
seperator = '%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n'
fid_out.write(header)
self.write_section(fid_out, self.get_main_para_names()['dirs'],
'main settings', seperator)
self.write_section(fid_out, self.get_main_para_names()['nlloc'],
'NLLoc settings', seperator)
self.write_section(fid_out, self.get_main_para_names()['smoment'],
'parameters for seismic moment estimation', seperator)
self.write_section(fid_out, self.get_main_para_names()['pick'],
'common settings picker', seperator)
fid_out.write(('#special settings for calculating CF#\n'+
'%!!Edit the following only if you know what you are doing!!%\n'))
self.write_section(fid_out, self.get_special_para_names()['z'],
'Z-component', None)
self.write_section(fid_out, self.get_special_para_names()['h'],
'H-components', None)
self.write_section(fid_out, self.get_special_para_names()['fm'],
'first-motion picker', None)
self.write_section(fid_out, self.get_special_para_names()['quality'],
'quality assessment', None)
def write_section(self, fid, names, title, seperator):
if seperator:
fid.write(seperator)
fid.write('#{}#\n'.format(title))
l_val = 50
l_name = 15
l_ttip = 100
for name in names:
value = self[name]
if type(value) == list or type(value) == tuple:
value_tmp = ''
for vl in value:
value_tmp+= '{} '.format(vl)
value = value_tmp
tooltip = self.get_defaults()[name]['tooltip']
if not len(str(value)) > l_val:
value = '{:<{}} '.format(str(value), l_val)
else:
value = '{} '.format(str(value))
name += '#'
if not len(name) > l_name:
name = '#{:<{}} '.format(name, l_name)
else:
name = '#{} '.format(name)
if not len(tooltip) > l_ttip:
ttip = '%{:<{}}\n'.format(tooltip, l_ttip)
else:
ttip = '%{}\n'.format(tooltip)
line = value+name+ttip
fid.write(line)
class FilterOptions(object): class FilterOptions(object):

View File

@ -217,4 +217,4 @@ def create_resourceID(timetohash, restype, authority_id=None, hrstr=None):
resID = ope.ResourceIdentifier(restype + '/' + hrstr) resID = ope.ResourceIdentifier(restype + '/' + hrstr)
if authority_id is not None: if authority_id is not None:
resID.convertIDToQuakeMLURI(authority_id=authority_id) resID.convertIDToQuakeMLURI(authority_id=authority_id)
return resID return resID

View File

@ -194,6 +194,7 @@ def picksdict_from_picks(evt):
for pick in evt.picks: for pick in evt.picks:
phase = {} phase = {}
station = pick.waveform_id.station_code station = pick.waveform_id.station_code
channel = pick.waveform_id.channel_code
try: try:
onsets = picks[station] onsets = picks[station]
except KeyError as e: except KeyError as e:
@ -213,6 +214,7 @@ def picksdict_from_picks(evt):
phase['epp'] = epp phase['epp'] = epp
phase['lpp'] = lpp phase['lpp'] = lpp
phase['spe'] = spe phase['spe'] = spe
phase['channel'] = channel
try: try:
picker = str(pick.method_id) picker = str(pick.method_id)
if picker.startswith('smi:local/'): if picker.startswith('smi:local/'):
@ -232,8 +234,11 @@ def picks_from_picksdict(picks, creation_info=None):
if not isinstance(phase, dict): if not isinstance(phase, dict):
continue continue
onset = phase['mpp'] onset = phase['mpp']
ccode = phase['channel'] try:
ncode = phase['network'] ccode = phase['channel']
ncode = phase['network']
except:
continue
pick = ope.Pick() pick = ope.Pick()
if creation_info: if creation_info:
pick.creation_info = creation_info pick.creation_info = creation_info
@ -353,7 +358,7 @@ def reassess_pilot_event(root_dir, db_dir, event_id, out_dir=None, fn_param=None
default.get('tsnrz' if phase == 'P' else 'tsnrh'), default.get('tsnrz' if phase == 'P' else 'tsnrh'),
Pick1=rel_pick, Pick1=rel_pick,
iplot=None, iplot=None,
stealth_mode=True) verbosity=0)
if epp is None or lpp is None: if epp is None or lpp is None:
continue continue
epp = stime + epp epp = stime + epp
@ -830,8 +835,9 @@ def merge_picks(event, picks):
err = pick.time_errors err = pick.time_errors
phase = pick.phase_hint phase = pick.phase_hint
station = pick.waveform_id.station_code station = pick.waveform_id.station_code
method = pick.method_id
for p in event.picks: for p in event.picks:
if p.waveform_id.station_code == station and p.phase_hint == phase: if p.waveform_id.station_code == station and p.phase_hint == phase:
p.time, p.time_errors = time, err p.time, p.time_errors, p.method_id = time, err, method
del time, err, phase, station del time, err, phase, station, method
return event return event

View File

@ -21,7 +21,7 @@ from pylot.core.util.utils import getPatternLine, gen_Pool
from pylot.core.io.data import Data from pylot.core.io.data import Data
def autopickevent(data, param): def autopickevent(data, param, iplot=0, fig_dict=None):
stations = [] stations = []
all_onsets = {} all_onsets = {}
input_tuples = [] input_tuples = []
@ -30,7 +30,6 @@ def autopickevent(data, param):
# parameter input file (usually autoPyLoT.in). # parameter input file (usually autoPyLoT.in).
wdttolerance = param.get('wdttolerance') wdttolerance = param.get('wdttolerance')
mdttolerance = param.get('mdttolerance') mdttolerance = param.get('mdttolerance')
iplot = param.get('iplot')
apverbose = param.get('apverbose') apverbose = param.get('apverbose')
for n in range(len(data)): for n in range(len(data)):
station = data[n].stats.station station = data[n].stats.station
@ -41,9 +40,16 @@ def autopickevent(data, param):
for station in stations: for station in stations:
topick = data.select(station=station) topick = data.select(station=station)
#all_onsets[station] = autopickstation(topick, param, verbose=apverbose)
input_tuples.append((topick, param, apverbose)) if not iplot:
input_tuples.append((topick, param, apverbose))
if iplot>0:
all_onsets[station] = autopickstation(topick, param, verbose=apverbose, iplot=iplot, fig_dict=fig_dict)
if iplot>0:
print('iPlot Flag active: NO MULTIPROCESSING possible.')
return all_onsets
pool = gen_Pool() pool = gen_Pool()
result = pool.map(call_autopickstation, input_tuples) result = pool.map(call_autopickstation, input_tuples)
pool.close() pool.close()
@ -52,7 +58,9 @@ def autopickevent(data, param):
station = pick['station'] station = pick['station']
pick.pop('station') pick.pop('station')
all_onsets[station] = pick all_onsets[station] = pick
return all_onsets
# quality control # quality control
# median check and jackknife on P-onset times # median check and jackknife on P-onset times
jk_checked_onsets = checkPonsets(all_onsets, mdttolerance, iplot) jk_checked_onsets = checkPonsets(all_onsets, mdttolerance, iplot)
@ -62,10 +70,11 @@ def autopickevent(data, param):
def call_autopickstation(input_tuple): def call_autopickstation(input_tuple):
wfstream, pickparam, verbose = input_tuple wfstream, pickparam, verbose = input_tuple
return autopickstation(wfstream, pickparam, verbose) #multiprocessing not possible with interactive plotting
return autopickstation(wfstream, pickparam, verbose, iplot=0)
def autopickstation(wfstream, pickparam, verbose=False): def autopickstation(wfstream, pickparam, verbose=False, iplot=0, fig_dict=None):
""" """
:param wfstream: `~obspy.core.stream.Stream` containing waveform :param wfstream: `~obspy.core.stream.Stream` containing waveform
:type wfstream: obspy.core.stream.Stream :type wfstream: obspy.core.stream.Stream
@ -82,8 +91,9 @@ def autopickstation(wfstream, pickparam, verbose=False):
# read your autoPyLoT.in for details! # read your autoPyLoT.in for details!
# special parameters for P picking # special parameters for P picking
iplot = iplot
algoP = pickparam.get('algoP') algoP = pickparam.get('algoP')
iplot = pickparam.get('iplot')
pstart = pickparam.get('pstart') pstart = pickparam.get('pstart')
pstop = pickparam.get('pstop') pstop = pickparam.get('pstop')
thosmw = pickparam.get('tlta') thosmw = pickparam.get('tlta')
@ -222,7 +232,12 @@ def autopickstation(wfstream, pickparam, verbose=False):
############################################################## ##############################################################
# get prelimenary onset time from AIC-HOS-CF using subclass AICPicker # get prelimenary onset time from AIC-HOS-CF using subclass AICPicker
# of class AutoPicking # of class AutoPicking
aicpick = AICPicker(aiccf, tsnrz, pickwinP, iplot, None, tsmoothP) key = 'aicFig'
if fig_dict:
fig = fig_dict[key]
else:
fig = None
aicpick = AICPicker(aiccf, tsnrz, pickwinP, iplot, None, tsmoothP, fig=fig)
############################################################## ##############################################################
if aicpick.getpick() is not None: if aicpick.getpick() is not None:
# check signal length to detect spuriously picked noise peaks # check signal length to detect spuriously picked noise peaks
@ -236,9 +251,15 @@ def autopickstation(wfstream, pickparam, verbose=False):
'Decreasing minsiglengh from {0} to ' \ 'Decreasing minsiglengh from {0} to ' \
'{1}'.format(minsiglength, minsiglength / 2) '{1}'.format(minsiglength, minsiglength / 2)
if verbose: print(msg) if verbose: print(msg)
key = 'slength'
if fig_dict:
fig = fig_dict[key]
else:
fig = None
Pflag = checksignallength(zne, aicpick.getpick(), tsnrz, Pflag = checksignallength(zne, aicpick.getpick(), tsnrz,
minsiglength / 2, minsiglength / 2,
nfacsl, minpercent, iplot) nfacsl, minpercent, iplot,
fig)
else: else:
# filter and taper horizontal traces # filter and taper horizontal traces
trH1_filt = edat.copy() trH1_filt = edat.copy()
@ -253,9 +274,14 @@ def autopickstation(wfstream, pickparam, verbose=False):
trH2_filt.taper(max_percentage=0.05, type='hann') trH2_filt.taper(max_percentage=0.05, type='hann')
zne += trH1_filt zne += trH1_filt
zne += trH2_filt zne += trH2_filt
if fig_dict:
fig = fig_dict['slength']
else:
fig = None
Pflag = checksignallength(zne, aicpick.getpick(), tsnrz, Pflag = checksignallength(zne, aicpick.getpick(), tsnrz,
minsiglength, minsiglength,
nfacsl, minpercent, iplot) nfacsl, minpercent, iplot,
fig)
if Pflag == 1: if Pflag == 1:
# check for spuriously picked S onset # check for spuriously picked S onset
@ -265,8 +291,13 @@ def autopickstation(wfstream, pickparam, verbose=False):
'Skipping control function checkZ4S.' 'Skipping control function checkZ4S.'
if verbose: print(msg) if verbose: print(msg)
else: else:
if iplot>1:
if fig_dict:
fig = fig_dict['checkZ4s']
else:
fig = None
Pflag = checkZ4S(zne, aicpick.getpick(), zfac, Pflag = checkZ4S(zne, aicpick.getpick(), zfac,
tsnrz[3], iplot) tsnrz[3], iplot, fig)
if Pflag == 0: if Pflag == 0:
Pmarker = 'SinsteadP' Pmarker = 'SinsteadP'
Pweight = 9 Pweight = 9
@ -313,15 +344,27 @@ def autopickstation(wfstream, pickparam, verbose=False):
'correctly: maybe the algorithm name ({algoP}) is ' \ 'correctly: maybe the algorithm name ({algoP}) is ' \
'corrupted'.format( 'corrupted'.format(
algoP=algoP) algoP=algoP)
if fig_dict:
fig = fig_dict['refPpick']
else:
fig = None
refPpick = PragPicker(cf2, tsnrz, pickwinP, iplot, ausP, tsmoothP, refPpick = PragPicker(cf2, tsnrz, pickwinP, iplot, ausP, tsmoothP,
aicpick.getpick()) aicpick.getpick(), fig)
mpickP = refPpick.getpick() mpickP = refPpick.getpick()
############################################################# #############################################################
if mpickP is not None: if mpickP is not None:
# quality assessment # quality assessment
# get earliest/latest possible pick and symmetrized uncertainty # get earliest/latest possible pick and symmetrized uncertainty
[epickP, lpickP, Perror] = earllatepicker(z_copy, nfacP, tsnrz, if iplot:
mpickP, iplot) if fig_dict:
fig = fig_dict['el_Ppick']
else:
fig = None
epickP, lpickP, Perror = earllatepicker(z_copy, nfacP, tsnrz,
mpickP, iplot, fig=fig)
else:
epickP, lpickP, Perror = earllatepicker(z_copy, nfacP, tsnrz,
mpickP, iplot)
# get SNR # get SNR
[SNRP, SNRPdB, Pnoiselevel] = getSNR(z_copy, tsnrz, mpickP) [SNRP, SNRPdB, Pnoiselevel] = getSNR(z_copy, tsnrz, mpickP)
@ -342,7 +385,14 @@ def autopickstation(wfstream, pickparam, verbose=False):
# get first motion of P onset # get first motion of P onset
# certain quality required # certain quality required
if Pweight <= minfmweight and SNRP >= minFMSNR: if Pweight <= minfmweight and SNRP >= minFMSNR:
FM = fmpicker(zdat, z_copy, fmpickwin, mpickP, iplot) if iplot:
if fig_dict:
fig = fig_dict['fm_picker']
else:
fig = None
FM = fmpicker(zdat, z_copy, fmpickwin, mpickP, iplot, fig)
else:
FM = fmpicker(zdat, z_copy, fmpickwin, mpickP, iplot)
else: else:
FM = 'N' FM = 'N'
@ -441,8 +491,12 @@ def autopickstation(wfstream, pickparam, verbose=False):
############################################################## ##############################################################
# get prelimenary onset time from AIC-HOS-CF using subclass AICPicker # get prelimenary onset time from AIC-HOS-CF using subclass AICPicker
# of class AutoPicking # of class AutoPicking
if fig_dict:
fig = fig_dict['aicARHfig']
else:
fig = None
aicarhpick = AICPicker(haiccf, tsnrh, pickwinS, iplot, None, aicarhpick = AICPicker(haiccf, tsnrh, pickwinS, iplot, None,
aictsmoothS) aictsmoothS, fig=fig)
############################################################### ###############################################################
# go on with processing if AIC onset passes quality control # go on with processing if AIC onset passes quality control
if (aicarhpick.getSlope() >= minAICSslope and if (aicarhpick.getSlope() >= minAICSslope and
@ -496,22 +550,46 @@ def autopickstation(wfstream, pickparam, verbose=False):
addnoise) # instance of ARHcf addnoise) # instance of ARHcf
# get refined onset time from CF2 using class Picker # get refined onset time from CF2 using class Picker
if fig_dict:
fig = fig_dict['refSpick']
else:
fig = None
refSpick = PragPicker(arhcf2, tsnrh, pickwinS, iplot, ausS, refSpick = PragPicker(arhcf2, tsnrh, pickwinS, iplot, ausS,
tsmoothS, aicarhpick.getpick()) tsmoothS, aicarhpick.getpick(), fig)
mpickS = refSpick.getpick() mpickS = refSpick.getpick()
############################################################# #############################################################
if mpickS is not None: if mpickS is not None:
# quality assessment # quality assessment
# get earliest/latest possible pick and symmetrized uncertainty # get earliest/latest possible pick and symmetrized uncertainty
h_copy[0].data = trH1_filt.data h_copy[0].data = trH1_filt.data
[epickS1, lpickS1, Serror1] = earllatepicker(h_copy, nfacS, if iplot:
tsnrh, if fig_dict:
mpickS, iplot) fig = fig_dict['el_S1pick']
else:
fig = None
epickS1, lpickS1, Serror1 = earllatepicker(h_copy, nfacS,
tsnrh,
mpickS, iplot,
fig=fig)
else:
epickS1, lpickS1, Serror1 = earllatepicker(h_copy, nfacS,
tsnrh,
mpickS, iplot)
h_copy[0].data = trH2_filt.data h_copy[0].data = trH2_filt.data
[epickS2, lpickS2, Serror2] = earllatepicker(h_copy, nfacS, if iplot:
tsnrh, if fig_dict:
mpickS, iplot) fig = fig_dict['el_S2pick']
else:
fig = None
epickS2, lpickS2, Serror2 = earllatepicker(h_copy, nfacS,
tsnrh,
mpickS, iplot,
fig=fig)
else:
epickS2, lpickS2, Serror2 = earllatepicker(h_copy, nfacS,
tsnrh,
mpickS, iplot)
if epickS1 is not None and epickS2 is not None: if epickS1 is not None and epickS2 is not None:
if algoS == 'ARH': if algoS == 'ARH':
# get earliest pick of both earliest possible picks # get earliest pick of both earliest possible picks
@ -603,62 +681,61 @@ def autopickstation(wfstream, pickparam, verbose=False):
############################################################## ##############################################################
if iplot > 0: if iplot > 0:
# plot vertical trace # plot vertical trace
plt.figure() if not fig_dict:
plt.subplot(3, 1, 1) fig = plt.figure()
else:
fig = fig_dict['mainFig']
ax1 = fig.add_subplot(311)
tdata = np.arange(0, zdat[0].stats.npts / tr_filt.stats.sampling_rate, tdata = np.arange(0, zdat[0].stats.npts / tr_filt.stats.sampling_rate,
tr_filt.stats.delta) tr_filt.stats.delta)
# check equal length of arrays, sometimes they are different!? # check equal length of arrays, sometimes they are different!?
wfldiff = len(tr_filt.data) - len(tdata) wfldiff = len(tr_filt.data) - len(tdata)
if wfldiff < 0: if wfldiff < 0:
tdata = tdata[0:len(tdata) - abs(wfldiff)] tdata = tdata[0:len(tdata) - abs(wfldiff)]
p1, = plt.plot(tdata, tr_filt.data / max(tr_filt.data), 'k') ax1.plot(tdata, tr_filt.data / max(tr_filt.data), 'k', label='Data')
if Pweight < 4: if Pweight < 4:
p2, = plt.plot(cf1.getTimeArray(), cf1.getCF() / max(cf1.getCF()), ax1.plot(cf1.getTimeArray(), cf1.getCF() / max(cf1.getCF()),
'b') 'b', label='CF1')
if aicPflag == 1: if aicPflag == 1:
p3, = plt.plot(cf2.getTimeArray(), ax1.plot(cf2.getTimeArray(),
cf2.getCF() / max(cf2.getCF()), 'm') cf2.getCF() / max(cf2.getCF()), 'm', label='CF2')
p4, = plt.plot([aicpick.getpick(), aicpick.getpick()], [-1, 1], ax1.plot([aicpick.getpick(), aicpick.getpick()], [-1, 1],
'r') 'r', label='Initial P Onset')
plt.plot([aicpick.getpick() - 0.5, aicpick.getpick() + 0.5], ax1.plot([aicpick.getpick() - 0.5, aicpick.getpick() + 0.5],
[1, 1], 'r') [1, 1], 'r')
plt.plot([aicpick.getpick() - 0.5, aicpick.getpick() + 0.5], ax1.plot([aicpick.getpick() - 0.5, aicpick.getpick() + 0.5],
[-1, -1], 'r') [-1, -1], 'r')
p5, = plt.plot([refPpick.getpick(), refPpick.getpick()], ax1.plot([refPpick.getpick(), refPpick.getpick()],
[-1.3, 1.3], 'r', linewidth=2) [-1.3, 1.3], 'r', linewidth=2, label='Final P Pick')
plt.plot([refPpick.getpick() - 0.5, refPpick.getpick() + 0.5], ax1.plot([refPpick.getpick() - 0.5, refPpick.getpick() + 0.5],
[1.3, 1.3], 'r', linewidth=2) [1.3, 1.3], 'r', linewidth=2)
plt.plot([refPpick.getpick() - 0.5, refPpick.getpick() + 0.5], ax1.plot([refPpick.getpick() - 0.5, refPpick.getpick() + 0.5],
[-1.3, -1.3], 'r', linewidth=2) [-1.3, -1.3], 'r', linewidth=2)
plt.plot([lpickP, lpickP], [-1.1, 1.1], 'r--') ax1.plot([lpickP, lpickP], [-1.1, 1.1], 'r--', label='lpp')
plt.plot([epickP, epickP], [-1.1, 1.1], 'r--') ax1.plot([epickP, epickP], [-1.1, 1.1], 'r--', label='epp')
plt.legend([p1, p2, p3, p4, p5], ax1.set_title('%s, %s, P Weight=%d, SNR=%7.2f, SNR[dB]=%7.2f '
['Data', 'CF1', 'CF2', 'Initial P Onset', 'Polarity: %s' % (tr_filt.stats.station,
'Final P Pick']) tr_filt.stats.channel,
plt.title('%s, %s, P Weight=%d, SNR=%7.2f, SNR[dB]=%7.2f ' Pweight,
'Polarity: %s' % (tr_filt.stats.station, SNRP,
tr_filt.stats.channel, SNRPdB,
Pweight, FM))
SNRP,
SNRPdB,
FM))
else: else:
plt.legend([p1, p2], ['Data', 'CF1']) ax1.set_title('%s, P Weight=%d, SNR=None, '
plt.title('%s, P Weight=%d, SNR=None, ' 'SNRdB=None' % (tr_filt.stats.channel, Pweight))
'SNRdB=None' % (tr_filt.stats.channel, Pweight))
else: else:
plt.title('%s, %s, P Weight=%d' % (tr_filt.stats.station, ax1.set_title('%s, %s, P Weight=%d' % (tr_filt.stats.station,
tr_filt.stats.channel, tr_filt.stats.channel,
Pweight)) Pweight))
ax1.legend()
plt.yticks([]) ax1.set_yticks([])
plt.ylim([-1.5, 1.5]) ax1.set_ylim([-1.5, 1.5])
plt.ylabel('Normalized Counts') ax1.set_ylabel('Normalized Counts')
plt.suptitle(tr_filt.stats.starttime) #fig.suptitle(tr_filt.stats.starttime)
if len(edat[0]) > 1 and len(ndat[0]) > 1 and Sflag == 1: if len(edat[0]) > 1 and len(ndat[0]) > 1 and Sflag == 1:
# plot horizontal traces # plot horizontal traces
plt.subplot(3, 1, 2) ax2 = fig.add_subplot(3,1,2,sharex=ax1)
th1data = np.arange(0, th1data = np.arange(0,
trH1_filt.stats.npts / trH1_filt.stats.npts /
trH1_filt.stats.sampling_rate, trH1_filt.stats.sampling_rate,
@ -667,50 +744,47 @@ def autopickstation(wfstream, pickparam, verbose=False):
wfldiff = len(trH1_filt.data) - len(th1data) wfldiff = len(trH1_filt.data) - len(th1data)
if wfldiff < 0: if wfldiff < 0:
th1data = th1data[0:len(th1data) - abs(wfldiff)] th1data = th1data[0:len(th1data) - abs(wfldiff)]
p21, = plt.plot(th1data, trH1_filt.data / max(trH1_filt.data), 'k') ax2.plot(th1data, trH1_filt.data / max(trH1_filt.data), 'k', label='Data')
if Pweight < 4: if Pweight < 4:
p22, = plt.plot(arhcf1.getTimeArray(), ax2.plot(arhcf1.getTimeArray(),
arhcf1.getCF() / max(arhcf1.getCF()), 'b') arhcf1.getCF() / max(arhcf1.getCF()), 'b', label='CF1')
if aicSflag == 1: if aicSflag == 1:
p23, = plt.plot(arhcf2.getTimeArray(), ax2.plot(arhcf2.getTimeArray(),
arhcf2.getCF() / max(arhcf2.getCF()), 'm') arhcf2.getCF() / max(arhcf2.getCF()), 'm', label='CF2')
p24, = plt.plot( ax2.plot(
[aicarhpick.getpick(), aicarhpick.getpick()], [aicarhpick.getpick(), aicarhpick.getpick()],
[-1, 1], 'g') [-1, 1], 'g', label='Initial S Onset')
plt.plot( ax2.plot(
[aicarhpick.getpick() - 0.5, [aicarhpick.getpick() - 0.5,
aicarhpick.getpick() + 0.5], aicarhpick.getpick() + 0.5],
[1, 1], 'g') [1, 1], 'g')
plt.plot( ax2.plot(
[aicarhpick.getpick() - 0.5, [aicarhpick.getpick() - 0.5,
aicarhpick.getpick() + 0.5], aicarhpick.getpick() + 0.5],
[-1, -1], 'g') [-1, -1], 'g')
p25, = plt.plot([refSpick.getpick(), refSpick.getpick()], ax2.plot([refSpick.getpick(), refSpick.getpick()],
[-1.3, 1.3], 'g', linewidth=2) [-1.3, 1.3], 'g', linewidth=2, label='Final S Pick')
plt.plot( ax2.plot(
[refSpick.getpick() - 0.5, refSpick.getpick() + 0.5], [refSpick.getpick() - 0.5, refSpick.getpick() + 0.5],
[1.3, 1.3], 'g', linewidth=2) [1.3, 1.3], 'g', linewidth=2)
plt.plot( ax2.plot(
[refSpick.getpick() - 0.5, refSpick.getpick() + 0.5], [refSpick.getpick() - 0.5, refSpick.getpick() + 0.5],
[-1.3, -1.3], 'g', linewidth=2) [-1.3, -1.3], 'g', linewidth=2)
plt.plot([lpickS, lpickS], [-1.1, 1.1], 'g--') ax2.plot([lpickS, lpickS], [-1.1, 1.1], 'g--', label='lpp')
plt.plot([epickS, epickS], [-1.1, 1.1], 'g--') ax2.plot([epickS, epickS], [-1.1, 1.1], 'g--', label='epp')
plt.legend([p21, p22, p23, p24, p25], ax2.set_title('%s, S Weight=%d, SNR=%7.2f, SNR[dB]=%7.2f' % (
['Data', 'CF1', 'CF2', 'Initial S Onset',
'Final S Pick'])
plt.title('%s, S Weight=%d, SNR=%7.2f, SNR[dB]=%7.2f' % (
trH1_filt.stats.channel, trH1_filt.stats.channel,
Sweight, SNRS, SNRSdB)) Sweight, SNRS, SNRSdB))
else: else:
plt.legend([p21, p22], ['Data', 'CF1']) ax2.set_title('%s, S Weight=%d, SNR=None, SNRdB=None' % (
plt.title('%s, S Weight=%d, SNR=None, SNRdB=None' % (
trH1_filt.stats.channel, Sweight)) trH1_filt.stats.channel, Sweight))
plt.yticks([]) ax2.legend()
plt.ylim([-1.5, 1.5]) ax2.set_yticks([])
plt.ylabel('Normalized Counts') ax2.set_ylim([-1.5, 1.5])
plt.suptitle(trH1_filt.stats.starttime) ax2.set_ylabel('Normalized Counts')
#fig.suptitle(trH1_filt.stats.starttime)
plt.subplot(3, 1, 3) ax3 = fig.add_subplot(3,1,3, sharex=ax1)
th2data = np.arange(0, th2data = np.arange(0,
trH2_filt.stats.npts / trH2_filt.stats.npts /
trH2_filt.stats.sampling_rate, trH2_filt.stats.sampling_rate,
@ -719,47 +793,40 @@ def autopickstation(wfstream, pickparam, verbose=False):
wfldiff = len(trH2_filt.data) - len(th2data) wfldiff = len(trH2_filt.data) - len(th2data)
if wfldiff < 0: if wfldiff < 0:
th2data = th2data[0:len(th2data) - abs(wfldiff)] th2data = th2data[0:len(th2data) - abs(wfldiff)]
plt.plot(th2data, trH2_filt.data / max(trH2_filt.data), 'k') ax3.plot(th2data, trH2_filt.data / max(trH2_filt.data), 'k', label='Data')
if Pweight < 4: if Pweight < 4:
p22, = plt.plot(arhcf1.getTimeArray(), p22, = ax3.plot(arhcf1.getTimeArray(),
arhcf1.getCF() / max(arhcf1.getCF()), 'b') arhcf1.getCF() / max(arhcf1.getCF()), 'b', label='CF1')
if aicSflag == 1: if aicSflag == 1:
p23, = plt.plot(arhcf2.getTimeArray(), ax3.plot(arhcf2.getTimeArray(),
arhcf2.getCF() / max(arhcf2.getCF()), 'm') arhcf2.getCF() / max(arhcf2.getCF()), 'm', label='CF2')
p24, = plt.plot( ax3.plot(
[aicarhpick.getpick(), aicarhpick.getpick()], [aicarhpick.getpick(), aicarhpick.getpick()],
[-1, 1], 'g') [-1, 1], 'g', label='Initial S Onset')
plt.plot( ax3.plot(
[aicarhpick.getpick() - 0.5, [aicarhpick.getpick() - 0.5,
aicarhpick.getpick() + 0.5], aicarhpick.getpick() + 0.5],
[1, 1], 'g') [1, 1], 'g')
plt.plot( ax3.plot(
[aicarhpick.getpick() - 0.5, [aicarhpick.getpick() - 0.5,
aicarhpick.getpick() + 0.5], aicarhpick.getpick() + 0.5],
[-1, -1], 'g') [-1, -1], 'g')
p25, = plt.plot([refSpick.getpick(), refSpick.getpick()], ax3.plot([refSpick.getpick(), refSpick.getpick()],
[-1.3, 1.3], 'g', linewidth=2) [-1.3, 1.3], 'g', linewidth=2, label='Final S Pick')
plt.plot( ax3.plot(
[refSpick.getpick() - 0.5, refSpick.getpick() + 0.5], [refSpick.getpick() - 0.5, refSpick.getpick() + 0.5],
[1.3, 1.3], 'g', linewidth=2) [1.3, 1.3], 'g', linewidth=2)
plt.plot( ax3.plot(
[refSpick.getpick() - 0.5, refSpick.getpick() + 0.5], [refSpick.getpick() - 0.5, refSpick.getpick() + 0.5],
[-1.3, -1.3], 'g', linewidth=2) [-1.3, -1.3], 'g', linewidth=2)
plt.plot([lpickS, lpickS], [-1.1, 1.1], 'g--') ax3.plot([lpickS, lpickS], [-1.1, 1.1], 'g--', label='lpp')
plt.plot([epickS, epickS], [-1.1, 1.1], 'g--') ax3.plot([epickS, epickS], [-1.1, 1.1], 'g--', label='epp')
plt.legend([p21, p22, p23, p24, p25], ax3.legend()
['Data', 'CF1', 'CF2', 'Initial S Onset', ax3.set_yticks([])
'Final S Pick']) ax3.set_ylim([-1.5, 1.5])
else: ax3.set_xlabel('Time [s] after %s' % tr_filt.stats.starttime)
plt.legend([p21, p22], ['Data', 'CF1']) ax3.set_ylabel('Normalized Counts')
plt.yticks([]) ax3.set_title(trH2_filt.stats.channel)
plt.ylim([-1.5, 1.5])
plt.xlabel('Time [s] after %s' % tr_filt.stats.starttime)
plt.ylabel('Normalized Counts')
plt.title(trH2_filt.stats.channel)
plt.show()
raw_input()
plt.close()
########################################################################## ##########################################################################
# calculate "real" onset times # calculate "real" onset times
if lpickP is not None and lpickP == mpickP: if lpickP is not None and lpickP == mpickP:
@ -809,7 +876,7 @@ def autopickstation(wfstream, pickparam, verbose=False):
return picks return picks
def iteratepicker(wf, NLLocfile, picks, badpicks, pickparameter): def iteratepicker(wf, NLLocfile, picks, badpicks, pickparameter, fig_dict=None):
''' '''
Repicking of bad onsets. Uses theoretical onset times from NLLoc-location file. Repicking of bad onsets. Uses theoretical onset times from NLLoc-location file.
@ -884,7 +951,7 @@ def iteratepicker(wf, NLLocfile, picks, badpicks, pickparameter):
print("zfac: %f => %f" % (zfac_old, pickparameter.get('zfac'))) print("zfac: %f => %f" % (zfac_old, pickparameter.get('zfac')))
# repick station # repick station
newpicks = autopickstation(wf2pick, pickparameter) newpicks = autopickstation(wf2pick, pickparameter, fig_dict=fig_dict)
# replace old dictionary with new one # replace old dictionary with new one
picks[badpicks[i][0]] = newpicks picks[badpicks[i][0]] = newpicks

View File

@ -34,7 +34,7 @@ class AutoPicker(object):
warnings.simplefilter('ignore') warnings.simplefilter('ignore')
def __init__(self, cf, TSNR, PickWindow, iplot=None, aus=None, Tsmooth=None, Pick1=None): def __init__(self, cf, TSNR, PickWindow, iplot=None, 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
@ -72,6 +72,7 @@ class AutoPicker(object):
self.setaus(aus) self.setaus(aus)
self.setTsmooth(Tsmooth) self.setTsmooth(Tsmooth)
self.setpick1(Pick1) self.setpick1(Pick1)
self.fig = fig
self.calcPick() self.calcPick()
def __str__(self): def __str__(self):
@ -172,21 +173,14 @@ class AICPicker(AutoPicker):
aicsmooth[i] = aicsmooth[i - 1] + (aic[i] - aic[ii1]) / ismooth aicsmooth[i] = aicsmooth[i - 1] + (aic[i] - aic[ii1]) / ismooth
else: else:
aicsmooth[i] = np.mean(aic[1: i]) aicsmooth[i] = np.mean(aic[1: i])
# remove offset # remove offset in AIC function
offset = abs(min(aic) - min(aicsmooth)) offset = abs(min(aic) - min(aicsmooth))
aicsmooth = aicsmooth - offset aicsmooth = aicsmooth - offset
# get maximum of 1st derivative of AIC-CF (more stable!) as starting point # get maximum of HOS/AR-CF as startimg point for searching
diffcf = np.diff(aicsmooth) # minimum in AIC function
# find NaN's icfmax = np.argmax(self.Data[0].data)
nn = np.isnan(diffcf)
if len(nn) > 1:
diffcf[nn] = 0
# taper CF to get rid off side maxima
tap = np.hanning(len(diffcf))
diffcf = tap * diffcf * max(abs(aicsmooth))
icfmax = np.argmax(diffcf)
# find minimum in AIC-CF front of maximum # 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))
for i in range(icfmax - 1, max([icfmax - lpickwindow, 2]), -1): for i in range(icfmax - 1, max([icfmax - lpickwindow, 2]), -1):
if aicsmooth[i - 1] >= aicsmooth[i]: if aicsmooth[i - 1] >= aicsmooth[i]:
@ -195,6 +189,14 @@ class AICPicker(AutoPicker):
# if no minimum could be found: # if no minimum could be found:
# search in 1st derivative of AIC-CF # search in 1st derivative of AIC-CF
if self.Pick is None: if self.Pick is None:
diffcf = np.diff(aicsmooth)
# find NaN's
nn = np.isnan(diffcf)
if len(nn) > 1:
diffcf[nn] = 0
# taper CF to get rid off side maxima
tap = np.hanning(len(diffcf))
diffcf = tap * diffcf * max(abs(aicsmooth))
for i in range(icfmax - 1, max([icfmax - lpickwindow, 2]), -1): for i in range(icfmax - 1, max([icfmax - lpickwindow, 2]), -1):
if diffcf[i - 1] >= diffcf[i]: if diffcf[i - 1] >= diffcf[i]:
self.Pick = self.Tcf[i] self.Pick = self.Tcf[i]
@ -225,20 +227,26 @@ class AICPicker(AutoPicker):
print('AICPicker: Maximum for slope determination right at the beginning of the window!') print('AICPicker: Maximum for slope determination right at the beginning of the window!')
print('Choose longer slope determination window!') print('Choose longer slope determination window!')
if self.iplot > 1: if self.iplot > 1:
p = plt.figure(self.iplot) if not self.fig:
fig = plt.figure() #self.iplot) ### WHY? MP MP
else:
fig = self.fig
ax = fig.add_subplot(111)
x = self.Data[0].data x = self.Data[0].data
p1, = plt.plot(self.Tcf, x / max(x), 'k') ax.plot(self.Tcf, x / max(x), 'k', legend='(HOS-/AR-) Data')
p2, = plt.plot(self.Tcf, aicsmooth / max(aicsmooth), 'r') ax.plot(self.Tcf, aicsmooth / max(aicsmooth), 'r', legend='Smoothed AIC-CF')
plt.legend([p1, p2], ['(HOS-/AR-) Data', 'Smoothed AIC-CF']) ax.legend()
plt.xlabel('Time [s] since %s' % self.Data[0].stats.starttime) ax.set_xlabel('Time [s] since %s' % self.Data[0].stats.starttime)
plt.yticks([]) ax.set_yticks([])
plt.title(self.Data[0].stats.station) ax.set_title(self.Data[0].stats.station)
plt.show()
raw_input()
plt.close(p)
return return
islope = islope[0][0:imax]
dataslope = self.Data[0].data[islope] iislope = islope[0][0:imax]
if len(iislope) <= 3:
# calculate slope from initial onset to maximum of AIC function
imax = np.argmax(aicsmooth[islope])
iislope = islope[0][0:imax]
dataslope = self.Data[0].data[iislope]
# calculate slope as polynomal fit of order 1 # calculate slope as polynomal fit of order 1
xslope = np.arange(0, len(dataslope), 1) xslope = np.arange(0, len(dataslope), 1)
P = np.polyfit(xslope, dataslope, 1) P = np.polyfit(xslope, dataslope, 1)
@ -253,41 +261,45 @@ class AICPicker(AutoPicker):
self.slope = None self.slope = None
if self.iplot > 1: if self.iplot > 1:
p = plt.figure(self.iplot) if not self.fig:
x = self.Data[0].data fig = plt.figure()#self.iplot)
p1, = plt.plot(self.Tcf, x / max(x), 'k')
p2, = plt.plot(self.Tcf, aicsmooth / max(aicsmooth), 'r')
if self.Pick is not None:
p3, = plt.plot([self.Pick, self.Pick], [-0.1, 0.5], 'b', linewidth=2)
plt.legend([p1, p2, p3], ['(HOS-/AR-) Data', 'Smoothed AIC-CF', 'AIC-Pick'])
else: else:
plt.legend([p1, p2], ['(HOS-/AR-) Data', 'Smoothed AIC-CF']) fig = self.fig
plt.xlabel('Time [s] since %s' % self.Data[0].stats.starttime) ax1 = fig.add_subplot(211)
plt.yticks([]) x = self.Data[0].data
plt.title(self.Data[0].stats.station) ax1.plot(self.Tcf, x / max(x), 'k', label='(HOS-/AR-) Data')
ax1.plot(self.Tcf, aicsmooth / max(aicsmooth), 'r', label='Smoothed AIC-CF')
if self.Pick is not None: if self.Pick is not None:
plt.figure(self.iplot + 1) ax1.plot([self.Pick, self.Pick], [-0.1, 0.5], 'b', linewidth=2, label='AIC-Pick')
p11, = plt.plot(self.Tcf, x, 'k') ax1.set_xlabel('Time [s] since %s' % self.Data[0].stats.starttime)
p12, = plt.plot(self.Tcf[inoise], self.Data[0].data[inoise]) ax1.set_yticks([])
p13, = plt.plot(self.Tcf[isignal], self.Data[0].data[isignal], 'r') ax1.legend()
p14, = plt.plot(self.Tcf[islope], dataslope, 'g--')
p15, = plt.plot(self.Tcf[islope], datafit, 'g', linewidth=2) if self.Pick is not None:
plt.legend([p11, p12, p13, p14, p15], ax2 = fig.add_subplot(2,1,2, sharex=ax1)
['Data', 'Noise Window', 'Signal Window', 'Slope Window', 'Slope'], ax2.plot(self.Tcf, x, 'k', label='Data')
loc='best') ax1.axvspan(self.Tcf[inoise[0]],self.Tcf[inoise[-1]], color='y', alpha=0.2, lw=0, label='Noise Window')
plt.title('Station %s, SNR=%7.2f, Slope= %12.2f counts/s' % (self.Data[0].stats.station, ax1.axvspan(self.Tcf[isignal[0]],self.Tcf[isignal[-1]], color='b', alpha=0.2, lw=0, label='Signal Window')
self.SNR, self.slope)) ax1.axvspan(self.Tcf[iislope[0]],self.Tcf[iislope[-1]], color='g', alpha=0.2, lw=0, label='Slope Window')
plt.xlabel('Time [s] since %s' % self.Data[0].stats.starttime)
plt.ylabel('Counts') ax2.axvspan(self.Tcf[inoise[0]],self.Tcf[inoise[-1]], color='y', alpha=0.2, lw=0, label='Noise Window')
plt.yticks([]) ax2.axvspan(self.Tcf[isignal[0]],self.Tcf[isignal[-1]], color='b', alpha=0.2, lw=0, label='Signal Window')
ax2.axvspan(self.Tcf[iislope[0]],self.Tcf[iislope[-1]], color='g', alpha=0.2, lw=0, label='Slope Window')
plt.show() ax2.plot(self.Tcf[iislope], datafit, 'g', linewidth=2, label='Slope')
raw_input()
plt.close(p) ax1.set_title('Station %s, SNR=%7.2f, Slope= %12.2f counts/s' % (self.Data[0].stats.station,
self.SNR, self.slope))
ax2.set_xlabel('Time [s] since %s' % self.Data[0].stats.starttime)
ax2.set_ylabel('Counts')
ax2.set_yticks([])
ax2.legend()
else:
ax1.set_title(self.Data[0].stats.station)
if self.Pick == None: if self.Pick == None:
print('AICPicker: Could not find minimum, picking window too short?') print('AICPicker: Could not find minimum, picking window too short?')
return
class PragPicker(AutoPicker): class PragPicker(AutoPicker):
@ -296,7 +308,7 @@ class PragPicker(AutoPicker):
''' '''
def calcPick(self): def calcPick(self):
if self.getpick1() is not None: 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 ...')
@ -380,18 +392,20 @@ class PragPicker(AutoPicker):
pickflag = 0 pickflag = 0
if self.getiplot() > 1: if self.getiplot() > 1:
p = plt.figure(self.getiplot()) if not self.fig:
p1, = plt.plot(Tcfpick, cfipick, 'k') fig = plt.figure()#self.getiplot())
p2, = plt.plot(Tcfpick, cfsmoothipick, 'r') else:
fig = self.fig
ax = fig.add_subplot(111)
ax.plot(Tcfpick, cfipick, 'k', label='CF')
ax.plot(Tcfpick, cfsmoothipick, 'r', label='Smoothed CF')
if pickflag > 0: if pickflag > 0:
p3, = plt.plot([self.Pick, self.Pick], [min(cfipick), max(cfipick)], 'b', linewidth=2) ax.plot([self.Pick, self.Pick], [min(cfipick), max(cfipick)], 'b', linewidth=2, label='Pick')
plt.legend([p1, p2, p3], ['CF', 'Smoothed CF', 'Pick']) ax.set_xlabel('Time [s] since %s' % self.Data[0].stats.starttime)
plt.xlabel('Time [s] since %s' % self.Data[0].stats.starttime) ax.set_yticks([])
plt.yticks([]) ax.set_title(self.Data[0].stats.station)
plt.title(self.Data[0].stats.station) ax.legend()
plt.show() return
raw_input()
plt.close(p)
else: else:
print('PragPicker: No initial onset time given! Check input!') print('PragPicker: No initial onset time given! Check input!')

View File

@ -9,13 +9,12 @@
""" """
import warnings 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
def earllatepicker(X, nfac, TSNR, Pick1, iplot=None, stealth_mode=False): def earllatepicker(X, nfac, TSNR, Pick1, iplot=None, verbosity=1, fig=None):
''' '''
Function to derive earliest and latest possible pick after Diehl & Kissling (2009) Function to derive earliest and latest possible pick after Diehl & Kissling (2009)
as reasonable uncertainties. Latest possible pick is based on noise level, as reasonable uncertainties. Latest possible pick is based on noise level,
@ -41,10 +40,16 @@ def earllatepicker(X, nfac, TSNR, Pick1, iplot=None, stealth_mode=False):
assert isinstance(X, Stream), "%s is not a stream object" % str(X) assert isinstance(X, Stream), "%s is not a stream object" % str(X)
if verbosity == 2:
print('earllatepicker:')
print('nfac:', nfac)
print('Init pick:', Pick1)
print('TSNR (T_noise, T_gap, T_signal):', TSNR)
LPick = None LPick = None
EPick = None EPick = None
PickError = None PickError = None
if stealth_mode is False: if verbosity:
print('earllatepicker: Get earliest and latest possible pick' print('earllatepicker: Get earliest and latest possible pick'
' relative to most likely pick ...') ' relative to most likely pick ...')
@ -58,11 +63,18 @@ def earllatepicker(X, nfac, TSNR, Pick1, iplot=None, stealth_mode=False):
x = x - np.mean(x[inoise]) x = x - np.mean(x[inoise])
# calculate noise level # calculate noise level
nlevel = np.sqrt(np.mean(np.square(x[inoise]))) * nfac nlevel = np.sqrt(np.mean(np.square(x[inoise]))) * nfac
if verbosity == 2:
print('x:', x)
print('t:', t)
print('x_inoise:', x[inoise])
print('x_isignal:', x[isignal])
print('nlevel:', nlevel)
# get time where signal exceeds nlevel # get time where signal exceeds nlevel
ilup, = np.where(x[isignal] > nlevel) ilup, = np.where(x[isignal] > nlevel)
ildown, = np.where(x[isignal] < -nlevel) ildown, = np.where(x[isignal] < -nlevel)
if not ilup.size and not ildown.size: if not ilup.size and not ildown.size:
if stealth_mode is False: if verbosity:
print ("earllatepicker: Signal lower than noise level!\n" print ("earllatepicker: Signal lower than noise level!\n"
"Skip this trace!") "Skip this trace!")
return LPick, EPick, PickError return LPick, EPick, PickError
@ -79,7 +91,7 @@ def earllatepicker(X, nfac, TSNR, Pick1, iplot=None, stealth_mode=False):
# if EPick stays NaN the signal window size will be doubled # if EPick stays NaN the signal window size will be doubled
while np.isnan(EPick): while np.isnan(EPick):
if count > 0: if count > 0:
if stealth_mode is False: if verbosity:
print("\nearllatepicker: Doubled signal window size %s time(s) " print("\nearllatepicker: Doubled signal window size %s time(s) "
"because of NaN for earliest pick." % count) "because of NaN for earliest pick." % count)
isigDoubleWinStart = pis[-1] + 1 isigDoubleWinStart = pis[-1] + 1
@ -88,7 +100,7 @@ def earllatepicker(X, nfac, TSNR, Pick1, iplot=None, stealth_mode=False):
if (isigDoubleWinStart + len(pis)) < X[0].data.size: if (isigDoubleWinStart + len(pis)) < X[0].data.size:
pis = np.concatenate((pis, isignalDoubleWin)) pis = np.concatenate((pis, isignalDoubleWin))
else: else:
if stealth_mode is False: if verbosity:
print("Could not double signal window. Index out of bounds.") print("Could not double signal window. Index out of bounds.")
break break
count += 1 count += 1
@ -105,38 +117,34 @@ def earllatepicker(X, nfac, TSNR, Pick1, iplot=None, stealth_mode=False):
PickError = symmetrize_error(diffti_te, diffti_tl) PickError = symmetrize_error(diffti_te, diffti_tl)
if iplot > 1: if iplot > 1:
p = plt.figure(iplot) if not fig:
p1, = plt.plot(t, x, 'k') fig = plt.figure()#iplot)
p2, = plt.plot(t[inoise], x[inoise]) ax = fig.add_subplot(111)
p3, = plt.plot(t[isignal], x[isignal], 'r') ax.plot(t, x, 'k', label='Data')
p4, = plt.plot([t[0], t[int(len(t)) - 1]], [nlevel, nlevel], '--k') ax.axvspan(t[inoise[0]], t[inoise[-1]], color='y', alpha=0.2, lw=0, label='Noise Window')
p5, = plt.plot(t[isignal[zc]], np.zeros(len(zc)), '*g', ax.axvspan(t[isignal[0]], t[isignal[-1]], color='b', alpha=0.2, lw=0, label='Signal Window')
markersize=14) ax.plot([t[0], t[int(len(t)) - 1]], [nlevel, nlevel], '--k', label='Noise Level')
plt.legend([p1, p2, p3, p4, p5], ax.plot(t[isignal[zc]], np.zeros(len(zc)), '*g',
['Data', 'Noise Window', 'Signal Window', 'Noise Level', markersize=14, label='Zero Crossings')
'Zero Crossings'], ax.plot([t[0], t[int(len(t)) - 1]], [-nlevel, -nlevel], '--k')
loc='best') ax.plot([Pick1, Pick1], [max(x), -max(x)], 'b', linewidth=2, label='mpp')
plt.plot([t[0], t[int(len(t)) - 1]], [-nlevel, -nlevel], '--k') ax.plot([LPick, LPick], [max(x) / 2, -max(x) / 2], '--k', label='lpp')
plt.plot([Pick1, Pick1], [max(x), -max(x)], 'b', linewidth=2) ax.plot([EPick, EPick], [max(x) / 2, -max(x) / 2], '--k', label='epp')
plt.plot([LPick, LPick], [max(x) / 2, -max(x) / 2], '--k') ax.plot([Pick1 + PickError, Pick1 + PickError],
plt.plot([EPick, EPick], [max(x) / 2, -max(x) / 2], '--k') [max(x) / 2, -max(x) / 2], 'r--', label='spe')
plt.plot([Pick1 + PickError, Pick1 + PickError], ax.plot([Pick1 - PickError, Pick1 - PickError],
[max(x) / 2, -max(x) / 2], 'r--') [max(x) / 2, -max(x) / 2], 'r--')
plt.plot([Pick1 - PickError, Pick1 - PickError], ax.set_xlabel('Time [s] since %s' % X[0].stats.starttime)
[max(x) / 2, -max(x) / 2], 'r--') ax.set_yticks([])
plt.xlabel('Time [s] since %s' % X[0].stats.starttime) ax.set_title(
plt.yticks([])
plt.title(
'Earliest-/Latest Possible/Most Likely Pick & Symmetric Pick Error, %s' % 'Earliest-/Latest Possible/Most Likely Pick & Symmetric Pick Error, %s' %
X[0].stats.station) X[0].stats.station)
plt.show() ax.legend()
raw_input()
plt.close(p)
return EPick, LPick, PickError return EPick, LPick, PickError
def fmpicker(Xraw, Xfilt, pickwin, Pick, iplot=None): def fmpicker(Xraw, Xfilt, pickwin, Pick, iplot=None, fig=None):
''' '''
Function to derive first motion (polarity) of given phase onset Pick. Function to derive first motion (polarity) of given phase onset Pick.
Calculation is based on zero crossings determined within time window pickwin Calculation is based on zero crossings determined within time window pickwin
@ -281,39 +289,33 @@ def fmpicker(Xraw, Xfilt, pickwin, Pick, iplot=None):
print ("fmpicker: Found polarity %s" % FM) print ("fmpicker: Found polarity %s" % FM)
if iplot > 1: if iplot > 1:
plt.figure(iplot) if not fig:
plt.subplot(2, 1, 1) fig = plt.figure()#iplot)
plt.plot(t, xraw, 'k') ax1 = fig.add_subplot(211)
p1, = plt.plot([Pick, Pick], [max(xraw), -max(xraw)], 'b', linewidth=2) ax1.plot(t, xraw, 'k')
ax1.plot([Pick, Pick], [max(xraw), -max(xraw)], 'b', linewidth=2, label='Pick')
if P1 is not None: if P1 is not None:
p2, = plt.plot(t[islope1], xraw[islope1]) ax1.plot(t[islope1], xraw[islope1], label='Slope Window')
p3, = plt.plot(zc1, np.zeros(len(zc1)), '*g', markersize=14) ax1.plot(zc1, np.zeros(len(zc1)), '*g', markersize=14, label='Zero Crossings')
p4, = plt.plot(t[islope1], datafit1, '--g', linewidth=2) ax1.plot(t[islope1], datafit1, '--g', linewidth=2)
plt.legend([p1, p2, p3, p4], ax1.legend()
['Pick', 'Slope Window', 'Zero Crossings', 'Slope'], ax1.text(Pick + 0.02, max(xraw) / 2, '%s' % FM, fontsize=14)
loc='best') ax1.set_yticks([])
plt.text(Pick + 0.02, max(xraw) / 2, '%s' % FM, fontsize=14) ax1.set_title('First-Motion Determination, %s, Unfiltered Data' % Xraw[
ax = plt.gca()
plt.yticks([])
plt.title('First-Motion Determination, %s, Unfiltered Data' % Xraw[
0].stats.station) 0].stats.station)
plt.subplot(2, 1, 2) ax2=fig.add_subplot(2,1,2, sharex=ax1)
plt.title('First-Motion Determination, Filtered Data') ax2.set_title('First-Motion Determination, Filtered Data')
plt.plot(t, xfilt, 'k') ax2.plot(t, xfilt, 'k')
p1, = plt.plot([Pick, Pick], [max(xfilt), -max(xfilt)], 'b', ax2.plot([Pick, Pick], [max(xfilt), -max(xfilt)], 'b',
linewidth=2) linewidth=2)
if P2 is not None: if P2 is not None:
p2, = plt.plot(t[islope2], xfilt[islope2]) ax2.plot(t[islope2], xfilt[islope2])
p3, = plt.plot(zc2, np.zeros(len(zc2)), '*g', markersize=14) ax2.plot(zc2, np.zeros(len(zc2)), '*g', markersize=14)
p4, = plt.plot(t[islope2], datafit2, '--g', linewidth=2) ax2.plot(t[islope2], datafit2, '--g', linewidth=2)
plt.text(Pick + 0.02, max(xraw) / 2, '%s' % FM, fontsize=14) ax2.text(Pick + 0.02, max(xraw) / 2, '%s' % FM, fontsize=14)
ax = plt.gca() ax2.set_xlabel('Time [s] since %s' % Xraw[0].stats.starttime)
plt.xlabel('Time [s] since %s' % Xraw[0].stats.starttime) ax2.set_yticks([])
plt.yticks([])
plt.show()
raw_input()
plt.close(iplot)
return FM return FM
@ -354,6 +356,10 @@ def getSNR(X, TSNR, t1, tracenum=0):
assert isinstance(X, Stream), "%s is not a stream object" % str(X) assert isinstance(X, Stream), "%s is not a stream object" % str(X)
SNR = None
SNRdb = None
noiselevel = None
x = X[tracenum].data x = X[tracenum].data
npts = X[tracenum].stats.npts npts = X[tracenum].stats.npts
sr = X[tracenum].stats.sampling_rate sr = X[tracenum].stats.sampling_rate
@ -367,19 +373,20 @@ def getSNR(X, TSNR, t1, tracenum=0):
isignal = getsignalwin(t, t1, TSNR[2]) isignal = getsignalwin(t, t1, TSNR[2])
if np.size(inoise) < 1: if np.size(inoise) < 1:
print ("getSNR: Empty array inoise, check noise window!") print ("getSNR: Empty array inoise, check noise window!")
return return SNR, SNRdB, noiselevel
elif np.size(isignal) < 1:
print ("getSNR: Empty array isignal, check signal window!")
return
# demean over entire waveform # demean over entire waveform
x = x - np.mean(x[inoise]) x = x - np.mean(x[inoise])
# calculate ratios # calculate ratios
# noiselevel = np.sqrt(np.mean(np.square(x[inoise]))) noiselevel = np.sqrt(np.mean(np.square(x[inoise])))
# signallevel = np.sqrt(np.mean(np.square(x[isignal]))) #signallevel = np.sqrt(np.mean(np.square(x[isignal])))
noiselevel = np.abs(x[inoise]).max() if np.size(isignal) < 1:
print ("getSNR: Empty array isignal, check signal window!")
return SNR, SNRdB, noiselevel
#noiselevel = np.abs(x[inoise]).max()
signallevel = np.abs(x[isignal]).max() signallevel = np.abs(x[isignal]).max()
SNR = signallevel / noiselevel SNR = signallevel / noiselevel
@ -411,7 +418,9 @@ def getnoisewin(t, t1, tnoise, tgap):
inoise, = np.where((t <= max([t1 - tgap, 0])) \ inoise, = np.where((t <= max([t1 - tgap, 0])) \
& (t >= max([t1 - tnoise - tgap, 0]))) & (t >= max([t1 - tnoise - tgap, 0])))
if np.size(inoise) < 1: if np.size(inoise) < 1:
print ("getnoisewin: Empty array inoise, check noise window!") inoise, = np.where((t>=t[0]) & (t<=t1))
if np.size(inoise) < 1:
print ("getnoisewin: Empty array inoise, check noise window!")
return inoise return inoise
@ -440,7 +449,7 @@ def getsignalwin(t, t1, tsignal):
return isignal return isignal
def getResolutionWindow(snr): def getResolutionWindow(snr, extent):
""" """
Number -> Float Number -> Float
produce the half of the time resolution window width from given SNR produce the half of the time resolution window width from given SNR
@ -451,6 +460,8 @@ def getResolutionWindow(snr):
1.5 > SNR -> 15 sec VLRW 1.5 > SNR -> 15 sec VLRW
see also Diehl et al. 2009 see also Diehl et al. 2009
:parameter: extent, can be 'local', 'regional', 'global'
>>> getResolutionWindow(0.5) >>> getResolutionWindow(0.5)
7.5 7.5
>>> getResolutionWindow(1.8) >>> getResolutionWindow(1.8)
@ -462,18 +473,24 @@ def getResolutionWindow(snr):
>>> getResolutionWindow(2) >>> getResolutionWindow(2)
2.5 2.5
""" """
res_wins = {'HRW': 2., 'MRW': 5., 'LRW': 10., 'VLRW': 15.} res_wins = {
'regional': {'HRW': 2., 'MRW': 5., 'LRW': 10., 'VLRW': 15.},
'local': {'HRW': 2., 'MRW': 5., 'LRW': 10., 'VLRW': 15.},
'global': {'HRW': 40., 'MRW': 100., 'LRW': 200., 'VLRW': 300.}
}
if snr < 1.5: if snr < 1.5:
time_resolution = res_wins['VLRW'] time_resolution = res_wins[extent]['VLRW']
elif snr < 2.: elif snr < 2.:
time_resolution = res_wins['LRW'] time_resolution = res_wins[extent]['LRW']
elif snr < 3.: elif snr < 3.:
time_resolution = res_wins['MRW'] time_resolution = res_wins[extent]['MRW']
elif snr >3.:
time_resolution = res_wins[extent]['HRW']
else: else:
time_resolution = res_wins['HRW'] time_resolution = res_wins[extent]['VLRW']
return time_resolution / 2 return time_resolution / 2
@ -489,18 +506,21 @@ def select_for_phase(st, phase):
:type phase: str :type phase: str
:return: :return:
''' '''
from pylot.core.util.defaults import COMPNAME_MAP from pylot.core.util.defaults import SetChannelComponents
sel_st = Stream() sel_st = Stream()
compclass = SetChannelComponents()
if phase.upper() == 'P': if phase.upper() == 'P':
comp = 'Z' comp = 'Z'
alter_comp = COMPNAME_MAP[comp] alter_comp = compclass.getCompPosition(comp)
alter_comp = str(alter_comp[0])
sel_st += st.select(component=comp) sel_st += st.select(component=comp)
sel_st += st.select(component=alter_comp) sel_st += st.select(component=alter_comp)
elif phase.upper() == 'S': elif phase.upper() == 'S':
comps = 'NE' comps = 'NE'
for comp in comps: for comp in comps:
alter_comp = COMPNAME_MAP[comp] alter_comp = compclass.getCompPosition(comp)
alter_comp = str(alter_comp[0])
sel_st += st.select(component=comp) sel_st += st.select(component=comp)
sel_st += st.select(component=alter_comp) sel_st += st.select(component=alter_comp)
else: else:
@ -605,8 +625,8 @@ def wadaticheck(pickdic, dttolerance, iplot):
wfitflag = 1 wfitflag = 1
# plot results # plot results
if iplot > 1: if iplot > 0:
plt.figure(iplot) plt.figure()#iplot)
f1, = plt.plot(Ppicks, SPtimes, 'ro') f1, = plt.plot(Ppicks, SPtimes, 'ro')
if wfitflag == 0: if wfitflag == 0:
f2, = plt.plot(Ppicks, wdfit, 'k') f2, = plt.plot(Ppicks, wdfit, 'k')
@ -621,14 +641,11 @@ def wadaticheck(pickdic, dttolerance, iplot):
plt.ylabel('S-P Times [s]') plt.ylabel('S-P Times [s]')
plt.xlabel('P Times [s]') plt.xlabel('P Times [s]')
plt.show()
raw_input()
plt.close(iplot)
return checkedonsets return checkedonsets
def checksignallength(X, pick, TSNR, minsiglength, nfac, minpercent, iplot): def checksignallength(X, pick, TSNR, minsiglength, nfac, minpercent, iplot=0, fig=None):
''' '''
Function to detect spuriously picked noise peaks. Function to detect spuriously picked noise peaks.
Uses RMS trace of all 3 components (if available) to determine, Uses RMS trace of all 3 components (if available) to determine,
@ -700,23 +717,20 @@ def checksignallength(X, pick, TSNR, minsiglength, nfac, minpercent, iplot):
returnflag = 0 returnflag = 0
if iplot == 2: if iplot == 2:
plt.figure(iplot) if not fig:
p1, = plt.plot(t, rms, 'k') fig = plt.figure()#iplot)
p2, = plt.plot(t[inoise], rms[inoise], 'c') ax = fig.add_subplot(111)
p3, = plt.plot(t[isignal], rms[isignal], 'r') ax.plot(t, rms, 'k', label='RMS Data')
p4, = plt.plot([t[isignal[0]], t[isignal[len(isignal) - 1]]], ax.axvspan(t[inoise[0]], t[inoise[-1]], color='y', alpha=0.2, lw=0, label='Noise Window')
[minsiglevel, minsiglevel], 'g', linewidth=2) ax.axvspan(t[isignal[0]], t[isignal[-1]], color='b', alpha=0.2, lw=0, label='Signal Window')
p5, = plt.plot([pick, pick], [min(rms), max(rms)], 'b', linewidth=2) ax.plot([t[isignal[0]], t[isignal[len(isignal) - 1]]],
plt.legend([p1, p2, p3, p4, p5], ['RMS Data', 'RMS Noise Window', [minsiglevel, minsiglevel], 'g', linewidth=2, label='Minimum Signal Level')
'RMS Signal Window', 'Minimum Signal Level', ax.plot([pick, pick], [min(rms), max(rms)], 'b', linewidth=2, label='Onset')
'Onset'], loc='best') ax.legend()
plt.xlabel('Time [s] since %s' % X[0].stats.starttime) ax.set_xlabel('Time [s] since %s' % X[0].stats.starttime)
plt.ylabel('Counts') ax.set_ylabel('Counts')
plt.title('Check for Signal Length, Station %s' % X[0].stats.station) ax.set_title('Check for Signal Length, Station %s' % X[0].stats.station)
plt.yticks([]) ax.set_yticks([])
plt.show()
raw_input()
plt.close(iplot)
return returnflag return returnflag
@ -756,11 +770,12 @@ def checkPonsets(pickdic, dttolerance, iplot):
[xjack, PHI_pseudo, PHI_sub] = jackknife(Ppicks, 'VAR', 1) [xjack, PHI_pseudo, PHI_sub] = jackknife(Ppicks, 'VAR', 1)
# get pseudo variances smaller than average variances # get pseudo variances smaller than average variances
# (times safety factor), these picks passed jackknife test # (times safety factor), these picks passed jackknife test
ij = np.where(PHI_pseudo <= 2 * xjack) ij = np.where(PHI_pseudo <= 5 * xjack)
# these picks did not pass jackknife test # these picks did not pass jackknife test
badjk = np.where(PHI_pseudo > 2 * xjack) badjk = np.where(PHI_pseudo > 5 * xjack)
badjkstations = np.array(stations)[badjk] badjkstations = np.array(stations)[badjk]
print ("checkPonsets: %d pick(s) did not pass jackknife test!" % len(badjkstations)) print ("checkPonsets: %d pick(s) did not pass jackknife test!" % len(badjkstations))
print(badjkstations)
# calculate median from these picks # calculate median from these picks
pmedian = np.median(np.array(Ppicks)[ij]) pmedian = np.median(np.array(Ppicks)[ij])
@ -795,21 +810,22 @@ def checkPonsets(pickdic, dttolerance, iplot):
checkedonsets = pickdic checkedonsets = pickdic
if iplot > 1: if iplot > 0:
p1, = plt.plot(np.arange(0, len(Ppicks)), Ppicks, 'r+', markersize=14) p1, = plt.plot(np.arange(0, len(Ppicks)), Ppicks, 'ro', markersize=14)
p2, = plt.plot(igood, np.array(Ppicks)[igood], 'g*', markersize=14) if len(badstations) < 1 and len(badjkstations) < 1:
p2, = plt.plot(np.arange(0, len(Ppicks)), Ppicks, 'go', markersize=14)
else:
p2, = plt.plot(igood, np.array(Ppicks)[igood], 'go', markersize=14)
p3, = plt.plot([0, len(Ppicks) - 1], [pmedian, pmedian], 'g', p3, = plt.plot([0, len(Ppicks) - 1], [pmedian, pmedian], 'g',
linewidth=2) linewidth=2)
for i in range(0, len(Ppicks)): for i in range(0, len(Ppicks)):
plt.text(i, Ppicks[i] + 0.2, stations[i]) plt.text(i, Ppicks[i] + 0.01, '{0}'.format(stations[i]))
plt.xlabel('Number of P Picks') plt.xlabel('Number of P Picks')
plt.ylabel('Onset Time [s] from 1.1.1970') plt.ylabel('Onset Time [s] from 1.1.1970')
plt.legend([p1, p2, p3], ['Skipped P Picks', 'Good P Picks', 'Median'], plt.legend([p1, p2, p3], ['Skipped P Picks', 'Good P Picks', 'Median'],
loc='best') loc='best')
plt.title('Check P Onsets') plt.title('Jackknifing and Median Tests on P Onsets')
plt.show()
raw_input()
return checkedonsets return checkedonsets
@ -878,7 +894,7 @@ def jackknife(X, phi, h):
return PHI_jack, PHI_pseudo, PHI_sub return PHI_jack, PHI_pseudo, PHI_sub
def checkZ4S(X, pick, zfac, checkwin, iplot): def checkZ4S(X, pick, zfac, checkwin, iplot, fig=None):
''' '''
Function to compare energy content of vertical trace with Function to compare energy content of vertical trace with
energy content of horizontal traces to detect spuriously energy content of horizontal traces to detect spuriously
@ -943,8 +959,18 @@ def checkZ4S(X, pick, zfac, checkwin, iplot):
isignal = getsignalwin(tz, pick, checkwin) isignal = getsignalwin(tz, pick, checkwin)
# calculate energy levels # calculate energy levels
zcodalevel = max(absz[isignal]) try:
encodalevel = max(absen[isignal]) zcodalevel = max(absz[isignal])
except:
ii = np.where(isignal <= len(absz))
isignal = isignal[ii]
zcodalevel = max(absz[isignal - 1])
try:
encodalevel = max(absen[isignal])
except:
ii = np.where(isignal <= len(absen))
isignal = isignal[ii]
encodalevel = max(absen[isignal - 1])
# calculate threshold # calculate threshold
minsiglevel = encodalevel * zfac minsiglevel = encodalevel * zfac
@ -962,22 +988,23 @@ def checkZ4S(X, pick, zfac, checkwin, iplot):
edat[0].stats.delta) edat[0].stats.delta)
tn = np.arange(0, ndat[0].stats.npts / ndat[0].stats.sampling_rate, tn = np.arange(0, ndat[0].stats.npts / ndat[0].stats.sampling_rate,
ndat[0].stats.delta) ndat[0].stats.delta)
plt.plot(tz, z / max(z), 'k') if not fig:
plt.plot(tz[isignal], z[isignal] / max(z), 'r') fig = plt.figure()
plt.plot(te, edat[0].data / max(edat[0].data) + 1, 'k') ax = fig.add_subplot(111)
plt.plot(te[isignal], edat[0].data[isignal] / max(edat[0].data) + 1, 'r') ax.plot(tz, z / max(z), 'k')
plt.plot(tn, ndat[0].data / max(ndat[0].data) + 2, 'k') ax.axvspan(tz[isignal[0]], tz[isignal[-1]], color='b', alpha=0.2,
plt.plot(tn[isignal], ndat[0].data[isignal] / max(ndat[0].data) + 2, 'r') lw=0, label='Signal Window')
plt.plot([tz[isignal[0]], tz[isignal[len(isignal) - 1]]], ax.plot(te, edat[0].data / max(edat[0].data) + 1, 'k')
[minsiglevel / max(z), minsiglevel / max(z)], 'g', ax.plot(tn, ndat[0].data / max(ndat[0].data) + 2, 'k')
linewidth=2) ax.plot([tz[isignal[0]], tz[isignal[len(isignal) - 1]]],
plt.xlabel('Time [s] since %s' % zdat[0].stats.starttime) [minsiglevel / max(z), minsiglevel / max(z)], 'g',
plt.ylabel('Normalized Counts') linewidth=2, label='Minimum Signal Level')
plt.yticks([0, 1, 2], [zdat[0].stats.channel, edat[0].stats.channel, ax.set_xlabel('Time [s] since %s' % zdat[0].stats.starttime)
ndat[0].stats.channel]) ax.set_ylabel('Normalized Counts')
plt.title('CheckZ4S, Station %s' % zdat[0].stats.station) ax.set_yticks([0, 1, 2], [zdat[0].stats.channel, edat[0].stats.channel,
plt.show() ndat[0].stats.channel])
raw_input() ax.set_title('CheckZ4S, Station %s' % zdat[0].stats.station)
ax.legend()
return returnflag return returnflag

View File

@ -169,7 +169,8 @@ def read_metadata(path_to_inventory):
dlfile = list() dlfile = list()
invfile = list() invfile = list()
respfile = list() respfile = list()
inv = dict(dless=dlfile, xml=invfile, resp=respfile) # possible file extensions specified here:
inv = dict(dless=dlfile, xml=invfile, resp=respfile, dseed=dlfile)
if os.path.isfile(path_to_inventory): if os.path.isfile(path_to_inventory):
ext = os.path.splitext(path_to_inventory)[1].split('.')[1] ext = os.path.splitext(path_to_inventory)[1].split('.')[1]
inv[ext] += [path_to_inventory] inv[ext] += [path_to_inventory]

View File

@ -55,9 +55,56 @@ OUTPUTFORMATS = {'.xml': 'QUAKEML',
LOCTOOLS = dict(nll=nll, hyposat=hyposat, velest=velest, hypo71=hypo71, hypodd=hypodd) LOCTOOLS = dict(nll=nll, hyposat=hyposat, velest=velest, hypo71=hypo71, hypodd=hypodd)
COMPPOSITION_MAP = dict(Z=2, N=1, E=0)
COMPPOSITION_MAP['1'] = 1
COMPPOSITION_MAP['2'] = 0
COMPPOSITION_MAP['3'] = 2
COMPNAME_MAP = dict(Z='3', N='1', E='2') class SetChannelComponents(object):
def __init__(self):
self.setDefaultCompPosition()
def setDefaultCompPosition(self):
# default component order
self.compPosition_Map = dict(Z=2, N=1, E=0)
self.compName_Map = {'3': 'Z',
'1': 'N',
'2': 'E'}
def _getCurrentPosition(self, component):
for key, value in self.compName_Map.items():
if value == component:
return key, value
errMsg = 'getCurrentPosition: Could not find former position of component {}.'.format(component)
raise ValueError(errMsg)
def _switch(self, component, component_alter):
# Without switching, multiple definitions of the same alter_comp are possible
old_alter_comp, _ = self._getCurrentPosition(component)
old_comp = self.compName_Map[component_alter]
if not old_alter_comp == component_alter and not old_comp == component:
self.compName_Map[old_alter_comp] = old_comp
print('switch: Automatically switched component {} to {}'.format(old_alter_comp, old_comp))
def setCompPosition(self, component_alter, component, switch=True):
component_alter = str(component_alter)
if not component_alter in self.compName_Map.keys():
errMsg='setCompPosition: Unrecognized alternative component {}. Expecting one of {}.'
raise ValueError(errMsg.format(component_alter, self.compName_Map.keys()))
if not component in self.compPosition_Map.keys():
errMsg='setCompPosition: Unrecognized target component {}. Expecting one of {}.'
raise ValueError(errMsg.format(component, self.compPosition_Map.keys()))
print('setCompPosition: set component {} to {}'.format(component_alter, component))
if switch:
self._switch(component, component_alter)
self.compName_Map[component_alter] = component
def getCompPosition(self, component):
return self._getCurrentPosition(component)[0]
def getPlotPosition(self, component):
component = str(component)
if component in self.compPosition_Map.keys():
return self.compPosition_Map[component]
elif component in self.compName_Map.keys():
return self.compPosition_Map[self.compName_Map[component]]
else:
errMsg='getCompPosition: Unrecognized component {}. Expecting one of {} or {}.'
raise ValueError(errMsg.format(component, self.compPosition_Map.keys(), self.compName_Map.keys()))

View File

@ -0,0 +1,365 @@
from mpl_toolkits.basemap import Basemap
import matplotlib.pyplot as plt
import numpy as np
import obspy
from matplotlib import cm
from scipy.interpolate import griddata
from matplotlib.backends.backend_qt4agg import NavigationToolbar2QT as NavigationToolbar
from PySide import QtCore, QtGui
from pylot.core.util.widgets import PickDlg
plt.interactive(False)
class map_projection(QtGui.QWidget):
def __init__(self, parent, figure=None):
'''
:param: picked, can be False, auto, manual
:value: str
'''
QtGui.QWidget.__init__(self)
self._parent = parent
self.parser = parent.metadata[1]
self.picks = None
self.picks_dict = None
self.figure = figure
self.init_graphics()
self.init_stations()
self.init_basemap(resolution='l')
self.init_map()
#self.show()
def init_map(self):
self.init_lat_lon_dimensions()
self.init_lat_lon_grid()
self.init_x_y_dimensions()
self.connectSignals()
self.draw_everything()
def onpick(self, event):
ind = event.ind
button = event.mouseevent.button
if ind == [] or not button == 1:
return
data = self._parent.get_data().getWFData()
for index in ind:
station=str(self.station_names[index].split('.')[-1])
try:
pickDlg = PickDlg(self, parameter=self._parent._inputs,
data=data.select(station=station),
station=station,
picks=self._parent.get_current_event().getPick(station),
autopicks=self._parent.get_current_event().getAutopick(station))
except Exception as e:
message = 'Could not generate Plot for station {st}.\n {er}'.format(st=station, er=e)
self._warn(message)
print(message, e)
return
pyl_mw = self._parent
try:
if pickDlg.exec_():
pyl_mw.setDirty(True)
pyl_mw.update_status('picks accepted ({0})'.format(station))
replot = pyl_mw.get_current_event().setPick(station, pickDlg.getPicks())
self._refresh_drawings()
if replot:
pyl_mw.plotWaveformData()
pyl_mw.drawPicks()
pyl_mw.draw()
else:
pyl_mw.drawPicks(station)
pyl_mw.draw()
else:
pyl_mw.update_status('picks discarded ({0})'.format(station))
except Exception as e:
message = 'Could not save picks for station {st}.\n{er}'.format(st=station, er=e)
self._warn(message)
print(message, e)
def connectSignals(self):
self.comboBox_phase.currentIndexChanged.connect(self._refresh_drawings)
self.zoom_id = self.basemap.ax.figure.canvas.mpl_connect('scroll_event', self.zoom)
def init_graphics(self):
if not self.figure:
if not hasattr(self._parent, 'am_figure'):
self.figure = plt.figure()
self.toolbar = NavigationToolbar(self.figure.canvas, self)
else:
self.figure = self._parent.am_figure
self.toolbar = self._parent.am_toolbar
self.main_ax = self.figure.add_subplot(111)
self.canvas = self.figure.canvas
self.main_box = QtGui.QVBoxLayout()
self.setLayout(self.main_box)
self.top_row = QtGui.QHBoxLayout()
self.main_box.addLayout(self.top_row)
self.comboBox_phase = QtGui.QComboBox()
self.comboBox_phase.insertItem(0, 'P')
self.comboBox_phase.insertItem(1, 'S')
self.comboBox_am = QtGui.QComboBox()
self.comboBox_am.insertItem(0, 'auto')
self.comboBox_am.insertItem(1, 'manual')
self.top_row.addWidget(QtGui.QLabel('Select a phase: '))
self.top_row.addWidget(self.comboBox_phase)
self.top_row.setStretch(1,1) #set stretch of item 1 to 1
self.main_box.addWidget(self.canvas)
self.main_box.addWidget(self.toolbar)
def init_stations(self):
def get_station_names_lat_lon(parser):
station_names=[]
lat=[]
lon=[]
for station in parser.stations:
station_name=station[0].station_call_letters
network=station[0].network_code
if not station_name in station_names:
station_names.append(network+'.'+station_name)
lat.append(station[0].latitude)
lon.append(station[0].longitude)
return station_names, lat, lon
station_names, lat, lon = get_station_names_lat_lon(self.parser)
self.station_names = station_names
self.lat = lat
self.lon = lon
def init_picks(self):
phase = self.comboBox_phase.currentText()
def get_picks(station_names):
picks=[]
for station in station_names:
try:
station=station.split('.')[-1]
picks.append(self.picks_dict[station][phase]['mpp'])
except:
picks.append(np.nan)
return picks
def get_picks_rel(picks):
picks_rel=[]
picks_utc = []
for pick in picks:
if type(pick) is obspy.core.utcdatetime.UTCDateTime:
picks_utc.append(pick)
minp = min(picks_utc)
for pick in picks:
if type(pick) is obspy.core.utcdatetime.UTCDateTime:
pick -= minp
picks_rel.append(pick)
return picks_rel
self.picks = get_picks(self.station_names)
self.picks_rel = get_picks_rel(self.picks)
def init_picks_active(self):
def remove_nan_picks(picks):
picks_no_nan=[]
for pick in picks:
if not np.isnan(pick):
picks_no_nan.append(pick)
return picks_no_nan
self.picks_no_nan = remove_nan_picks(self.picks_rel)
def init_stations_active(self):
def remove_nan_lat_lon(picks, lat, lon):
lat_no_nan=[]
lon_no_nan=[]
for index, pick in enumerate(picks):
if not np.isnan(pick):
lat_no_nan.append(lat[index])
lon_no_nan.append(lon[index])
return lat_no_nan, lon_no_nan
self.lat_no_nan, self.lon_no_nan = remove_nan_lat_lon(self.picks_rel, self.lat, self.lon)
def init_lat_lon_dimensions(self):
def get_lon_lat_dim(lon, lat):
londim = max(lon) - min(lon)
latdim = max(lat) - min(lat)
return londim, latdim
self.londim, self.latdim = get_lon_lat_dim(self.lon, self.lat)
def init_x_y_dimensions(self):
def get_x_y_dim(x, y):
xdim = max(x) - min(x)
ydim = max(y) - min(y)
return xdim, ydim
self.x, self.y = self.basemap(self.lon, self.lat)
self.xdim, self.ydim = get_x_y_dim(self.x, self.y)
def init_basemap(self, resolution='l'):
#basemap = Basemap(projection=projection, resolution = resolution, ax=self.main_ax)
basemap = Basemap(projection='lcc', resolution = resolution, ax=self.main_ax,
width=5e6, height=2e6,
lat_0=(min(self.lat)+max(self.lat))/2.,
lon_0=(min(self.lon)+max(self.lon))/2.)
#basemap.fillcontinents(color=None, lake_color='aqua',zorder=1)
basemap.drawmapboundary(zorder=2)#fill_color='darkblue')
basemap.shadedrelief(zorder=3)
basemap.drawcountries(zorder=4)
basemap.drawstates(zorder=5)
basemap.drawcoastlines(zorder=6)
self.basemap = basemap
self.figure.tight_layout()
def init_lat_lon_grid(self):
def get_lat_lon_axis(lat, lon):
steplat = (max(lat)-min(lat))/250
steplon = (max(lon)-min(lon))/250
lataxis = np.arange(min(lat), max(lat), steplat)
lonaxis = np.arange(min(lon), max(lon), steplon)
return lataxis, lonaxis
def get_lat_lon_grid(lataxis, lonaxis):
longrid, latgrid = np.meshgrid(lonaxis, lataxis)
return latgrid, longrid
self.lataxis, self.lonaxis = get_lat_lon_axis(self.lat, self.lon)
self.latgrid, self.longrid = get_lat_lon_grid(self.lataxis, self.lonaxis)
def init_picksgrid(self):
self.picksgrid_no_nan = griddata((self.lat_no_nan, self.lon_no_nan),
self.picks_no_nan, (self.latgrid, self.longrid), method='linear') ##################
def draw_contour_filled(self, nlevel='50'):
levels = np.linspace(min(self.picks_no_nan), max(self.picks_no_nan), nlevel)
self.contourf = self.basemap.contourf(self.longrid, self.latgrid, self.picksgrid_no_nan,
levels, latlon=True, zorder=9, alpha=0.5)
def scatter_all_stations(self):
self.sc = self.basemap.scatter(self.lon, self.lat, s=50, facecolor='none', latlon=True,
zorder=10, picker=True, edgecolor='m', label='Not Picked')
self.cid = self.canvas.mpl_connect('pick_event', self.onpick)
def scatter_picked_stations(self):
lon = self.lon_no_nan
lat = self.lat_no_nan
#workaround because of an issue with latlon transformation of arrays with len <3
if len(lon) <= 2 and len(lat) <= 2:
self.sc_picked = self.basemap.scatter(lon[0], lat[0], s=50, facecolor='white',
c=self.picks_no_nan[0], latlon=True, zorder=11, label='Picked')
if len(lon) == 2 and len(lat) == 2:
self.sc_picked = self.basemap.scatter(lon[1], lat[1], s=50, facecolor='white',
c=self.picks_no_nan[1], latlon=True, zorder=11)
else:
self.sc_picked = self.basemap.scatter(lon, lat, s=50, facecolor='white',
c=self.picks_no_nan, latlon=True, zorder=11, label='Picked')
def annotate_ax(self):
self.annotations=[]
for index, name in enumerate(self.station_names):
self.annotations.append(self.main_ax.annotate(' %s' % name, xy=(self.x[index], self.y[index]),
fontsize='x-small', color='white', zorder=12))
self.legend=self.main_ax.legend()
def add_cbar(self, label):
cbar = self.main_ax.figure.colorbar(self.sc_picked, fraction=0.025)
cbar.set_label(label)
return cbar
def refresh_drawings(self, picks=None):
self.picks_dict = picks
self.remove_drawings()
self.draw_everything()
def _refresh_drawings(self):
self.remove_drawings()
self.draw_everything()
def draw_everything(self):
if self.picks_dict:
self.init_picks()
self.init_picks_active()
self.init_stations_active()
if len(self.picks_no_nan) >= 3:
self.init_picksgrid()
self.draw_contour_filled()
self.scatter_all_stations()
if self.picks_dict:
self.scatter_picked_stations()
self.cbar = self.add_cbar(label='Time relative to first onset [s]')
self.comboBox_phase.setEnabled(True)
else:
self.comboBox_phase.setEnabled(False)
self.annotate_ax()
self.canvas.draw()
def remove_drawings(self):
if hasattr(self, 'sc_picked'):
self.sc_picked.remove()
del(self.sc_picked)
if hasattr(self, 'cbar'):
self.cbar.remove()
del(self.cbar)
if hasattr(self, 'contourf'):
self.remove_contourf()
del(self.contourf)
if hasattr(self, 'cid'):
self.canvas.mpl_disconnect(self.cid)
del(self.cid)
try:
self.sc.remove()
except Exception as e:
print('Warning: could not remove station scatter plot.\nReason: {}'.format(e))
try:
self.legend.remove()
except Exception as e:
print('Warning: could not remove legend. Reason: {}'.format(e))
self.canvas.draw()
def remove_contourf(self):
for item in self.contourf.collections:
item.remove()
def remove_annotations(self):
for annotation in self.annotations:
annotation.remove()
def zoom(self, event):
map = self.basemap
xlim = map.ax.get_xlim()
ylim = map.ax.get_ylim()
x, y = event.xdata, event.ydata
zoom = {'up': 1./2.,
'down': 2.}
if not event.xdata or not event.ydata:
return
if event.button in zoom:
factor = zoom[event.button]
xdiff = (xlim[1]-xlim[0])*factor
xl = x - 0.5 * xdiff
xr = x + 0.5 * xdiff
ydiff = (ylim[1]-ylim[0])*factor
yb = y - 0.5 * ydiff
yt = y + 0.5 * ydiff
if xl < map.xmin or yb < map.ymin or xr > map.xmax or yt > map.ymax:
xl, xr = map.xmin, map.xmax
yb, yt = map.ymin, map.ymax
map.ax.set_xlim(xl, xr)
map.ax.set_ylim(yb, yt)
map.ax.figure.canvas.draw()
def _warn(self, message):
self.qmb = QtGui.QMessageBox(QtGui.QMessageBox.Icon.Warning,
'Warning', message)
self.qmb.show()

View File

@ -1,24 +1,26 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
import sys import sys
from PySide.QtCore import QThread, Signal from PySide.QtCore import QThread, Signal, Qt
from PySide.QtGui import QDialog, QProgressBar, QLabel, QHBoxLayout
class AutoPickThread(QThread): class AutoPickThread(QThread):
message = Signal(str) message = Signal(str)
finished = Signal() finished = Signal()
def __init__(self, parent, func, infile, fnames, savepath): def __init__(self, parent, func, infile, fnames, eventid, savepath):
super(AutoPickThread, self).__init__() super(AutoPickThread, self).__init__()
self.setParent(parent) self.setParent(parent)
self.func = func self.func = func
self.infile = infile self.infile = infile
self.fnames = fnames self.fnames = fnames
self.eventid = eventid
self.savepath = savepath self.savepath = savepath
def run(self): def run(self):
sys.stdout = self sys.stdout = self
picks = self.func(self.infile, self.fnames, self.savepath) picks = self.func(None, None, self.infile, self.fnames, self.eventid, self.savepath)
print("Autopicking finished!\n") print("Autopicking finished!\n")
@ -35,3 +37,60 @@ class AutoPickThread(QThread):
def flush(self): def flush(self):
pass pass
class Thread(QThread):
message = Signal(str)
def __init__(self, parent, func, arg=None, progressText=None, pb_widget=None, redirect_stdout=False):
QThread.__init__(self, parent)
self.func = func
self.arg = arg
self.progressText = progressText
self.pb_widget = pb_widget
self.redirect_stdout = redirect_stdout
self.finished.connect(self.hideProgressbar)
self.showProgressbar()
def run(self):
if self.redirect_stdout:
sys.stdout = self
try:
if self.arg:
self.data = self.func(self.arg)
else:
self.data = self.func()
self._executed = True
except Exception as e:
self._executed = False
self._executedError = e
print(e)
sys.stdout = sys.__stdout__
def __del__(self):
self.wait()
def showProgressbar(self):
if self.progressText:
if not self.pb_widget:
self.pb_widget = QDialog(self.parent())
self.pb_widget.setWindowFlags(Qt.SplashScreen)
self.pb_widget.setModal(True)
hl = QHBoxLayout()
pb = QProgressBar()
pb.setRange(0, 0)
hl.addWidget(pb)
hl.addWidget(QLabel(self.progressText))
self.pb_widget.setLayout(hl)
self.pb_widget.show()
def hideProgressbar(self):
if self.pb_widget:
self.pb_widget.hide()
def write(self, text):
self.message.emit(text)
def flush(self):
pass

View File

@ -7,6 +7,7 @@ from scipy.interpolate import splrep, splev
import os import os
import pwd import pwd
import re import re
import warnings
import subprocess import subprocess
from obspy import UTCDateTime, read from obspy import UTCDateTime, read
from pylot.core.io.inputs import AutoPickParameter from pylot.core.io.inputs import AutoPickParameter
@ -381,9 +382,11 @@ def prepTimeAxis(stime, trace):
print('shorten time axes by one datum') print('shorten time axes by one datum')
time_ax = np.arange(stime, etime - tincr, tincr) time_ax = np.arange(stime, etime - tincr, tincr)
if len(time_ax) != nsamp: if len(time_ax) != nsamp:
raise ValueError('{0} samples of data \n ' print('Station {0}, {1} samples of data \n '
'{1} length of time vector \n' '{2} length of time vector \n'
'delta: {2}'.format(nsamp, len(time_ax), tincr)) 'delta: {3}'.format(trace.stats.station,
nsamp, len(time_ax), tincr))
time_ax = None
return time_ax return time_ax

File diff suppressed because it is too large Load Diff