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

1817
QtPyLoT.py

File diff suppressed because it is too large Load Diff

View File

@ -8,7 +8,6 @@ import glob
import os
import datetime
from obspy import read_events
import pylot.core.loc.hyposat as hyposat
import pylot.core.loc.hypo71 as hypo71
import pylot.core.loc.velest as velest
@ -29,7 +28,7 @@ from pylot.core.util.version import get_git_version as _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
algorithms by Kueperkoch et al. 2010/2012.
@ -55,15 +54,43 @@ def autoPyLoT(inputfile, fnames=None, savepath=None):
***********************************'''.format(version=_getVersionString())
print(splash)
# reading parameter file
parameter = AutoPickParameter(inputfile)
locflag = 1
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()
evt = None
# getting information on data structure
# reading parameter file
if parameter.hasParam('datastructure'):
# getting information on data structure
datastructure = DATASTRUCTURE[parameter.get('datastructure')]()
dsfields = {'root': parameter.get('rootpath'),
'dpath': parameter.get('datapath'),
@ -79,8 +106,7 @@ def autoPyLoT(inputfile, fnames=None, savepath=None):
datastructure.setExpandFields(exf)
# check if default location routine NLLoc is available
if parameter.hasParam('nllocbin'):
locflag = 1
if parameter['nllocbin'] and locflag:
# get NLLoc-root path
nllocroot = parameter.get('nllocroot')
# 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')))
else:
# autoPyLoT was initialized from GUI
events = fnames
events = []
events.append(eventid)
evID = os.path.split(eventid)[-1]
locflag = 2
for event in events:
if fnames == 'None':
@ -135,27 +164,39 @@ def autoPyLoT(inputfile, fnames=None, savepath=None):
parameter.setParam(eventID=eventID)
else:
data.setWFData(fnames)
event = savepath
now = datetime.datetime.now()
evID = '%d%02d%02d%02d%02d' % (now.year,
now.month,
now.day,
now.hour,
now.minute)
parameter.setParam(eventID=evID)
event = events[0]
#now = datetime.datetime.now()
#evID = '%d%02d%02d%02d%02d' % (now.year,
# now.month,
# now.day,
# now.hour,
# now.minute)
parameter.setParam(eventID=eventid)
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)
metadata = read_metadata(parameter.get('invdir'))
print("Restitute data ...")
corr_dat = restitute_data(wfdat.copy(), *metadata)
print('Working on event %s' % event)
print(data)
print('Working on event %s. Stations: %s' % (event, station))
print(wfdat)
##########################################################
# !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
if locflag == 1:
if locflag > 0:
# write phases to NLLoc-phase file
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'),
parameter.get('Qp'),
parameter.get('rho'), True, \
parameter.get('iplot'))
iplot)
# update pick with moment property values (w0, fc, Mo)
for station, props in moment_mag.moment_props.items():
picks[station]['P'].update(props)
evt = moment_mag.updated_event()
local_mag = RichterMagnitude(corr_dat, evt,
parameter.get('sstop'), True,\
parameter.get('iplot'))
iplot)
for station, amplitude in local_mag.amplitudes.items():
picks[station]['S']['Ao'] = amplitude.generic_amplitude
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!")
break
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
nll.export(picks, phasefile, parameter)
# 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!")
nlloccounter = maxnumit
evt = read_events(nllocfile)[0]
# calculating seismic moment Mo and moment magnitude Mw
moment_mag = MomentMagnitude(corr_dat, evt, parameter.get('vp'),
parameter.get('Qp'),
parameter.get('rho'), True, \
parameter.get('iplot'))
# update pick with moment property values (w0, fc, Mo)
for station, props in moment_mag.moment_props.items():
picks[station]['P'].update(props)
evt = moment_mag.updated_event()
local_mag = RichterMagnitude(corr_dat, evt,
parameter.get('sstop'), True, \
parameter.get('iplot'))
for station, amplitude in local_mag.amplitudes.items():
picks[station]['S']['Ao'] = amplitude.generic_amplitude
evt = local_mag.updated_event()
net_mw = moment_mag.net_magnitude()
print("Network moment magnitude: %4.1f" % net_mw.mag)
if locflag < 2:
# calculating seismic moment Mo and moment magnitude Mw
moment_mag = MomentMagnitude(corr_dat, evt, parameter.get('vp'),
parameter.get('Qp'),
parameter.get('rho'), True, \
iplot)
# update pick with moment property values (w0, fc, Mo)
for station, props in moment_mag.moment_props.items():
picks[station]['P'].update(props)
evt = moment_mag.updated_event()
local_mag = RichterMagnitude(corr_dat, evt,
parameter.get('sstop'), True, \
iplot)
for station, amplitude in local_mag.amplitudes.items():
picks[station]['S']['Ao'] = amplitude.generic_amplitude
evt = local_mag.updated_event()
net_mw = moment_mag.net_magnitude()
print("Network moment magnitude: %4.1f" % net_mw.mag)
else:
print("autoPyLoT: No NLLoc-location file available! Stop iteration!")
locflag = 9
@ -303,14 +350,22 @@ def autoPyLoT(inputfile, fnames=None, savepath=None):
The Python picking and Location Tool\n
************************************'''.format(version=_getVersionString())
print(endsp)
return picks
if __name__ == "__main__":
# parse arguments
parser = argparse.ArgumentParser(
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,
action='store',
help='''full path to the file containing the input
@ -318,13 +373,21 @@ if __name__ == "__main__":
parser.add_argument('-f', '-F', '--fnames', type=str,
action='store',
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,
action='store',
help='''optional, save path for autoPyLoT output''')
parser.add_argument('-v', '-V', '--version', action='version',
version='autoPyLoT ' + __version__,
help='show version information and exit')
#parser.add_argument('-v', '-V', '--version', action='version',
# version='autoPyLoT ' + __version__,
# help='show version information and exit')
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>
<qresource>
<file>icons/Library-icon.png</file>
<file>icons/pylot.ico</file>
<file>icons/pylot.png</file>
<file>icons/manupicsicon.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/locactionicon.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))
# check for plot flag (for debugging only)
fig = None
if self.plot_flag > 1:
st.plot()
f = plt.figure(2)
plt.plot(th, sqH)
plt.plot(th[iwin], sqH[iwin], 'g')
plt.plot([t0, t0], [0, max(sqH)], 'r', linewidth=2)
plt.title(
fig = plt.figure()
ax = fig.add_subplot(111)
ax.plot(th, sqH)
ax.plot(th[iwin], sqH[iwin], 'g')
ax.plot([t0, t0], [0, max(sqH)], 'r', linewidth=2)
ax.title(
'Station %s, RMS Horizontal Traces, WA-peak-to-peak=%4.1f mm' \
% (st[0].stats.station, wapp))
plt.xlabel('Time [s]')
plt.ylabel('Displacement [mm]')
plt.show()
raw_input()
plt.close(f)
ax.set_xlabel('Time [s]')
ax.set_ylabel('Displacement [mm]')
return wapp
return wapp, fig
def calc(self):
for a in self.arrivals:
@ -234,7 +233,7 @@ class RichterMagnitude(Magnitude):
continue
delta = degrees2kilometers(a.distance)
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.unit = 'm'
amplitude.category = 'point'
@ -581,9 +580,6 @@ def calcsourcespec(wfstream, onset, vp, delta, azimuth, incidence,
plt.xlabel('Frequency [Hz]')
plt.ylabel('Amplitude [m/Hz]')
plt.grid()
plt.show()
raw_input()
plt.close(f1)
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))
if iplot > 1:
plt.figure(iplot)
plt.figure()#iplot)
plt.loglog(f, S, 'k')
plt.loglog([f[0], fc], [w0, 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.ylabel('Amplitude [m/Hz]')
plt.grid()
plt.figure(iplot + 1)
plt.figure()#iplot + 1)
plt.subplot(311)
plt.plot(f[il:ir], STD, '*')
plt.title('Common Standard Deviations')
@ -707,8 +703,5 @@ def fitSourceModel(f, S, fc0, iplot, verbosity=False):
plt.plot(f[il:ir], stdfc, '*')
plt.title('Standard Deviations of Corner Frequencies')
plt.xlabel('Corner Frequencies [Hz]')
plt.show()
raw_input()
plt.close()
return w0, fc

View File

@ -5,6 +5,7 @@ import copy
import os
from obspy import read_events
from obspy.core import read, Stream, UTCDateTime
from obspy.io.sac import SacIOError
from obspy.core.event import Event
from pylot.core.io.phases import readPILOTEvent, picks_from_picksdict, \
picksdict_from_pilot, merge_picks
@ -230,6 +231,8 @@ class Data(object):
self.wfdata += read(fname, format='GSE2')
except Exception as e:
warnmsg += '{0}\n{1}\n'.format(fname, e)
except SacIOError as se:
warnmsg += '{0}\n{1}\n'.format(fname, se)
if warnmsg:
warnmsg = 'WARNING: unable to read\n' + warnmsg
print(warnmsg)
@ -294,7 +297,6 @@ class Data(object):
:raise OverwriteError: raises an OverwriteError if the picks list is
not empty. The GUI will then ask for a decision.
"""
#firstonset = find_firstonset(picks)
# check for automatic picks
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 -*-
from pylot.core.util.errors import ParameterError
import default_parameters
class AutoPickParameter(object):
'''
@ -44,48 +44,15 @@ class AutoPickParameter(object):
contain all parameters.
'''
self.__init_default_paras()
self.__init_subsettings()
self.__filename = fnin
parFileCont = {}
self._verbosity = verbosity
self._parFileCont = {}
# io from parsed arguments alternatively
for key, val in kwargs.items():
parFileCont[key] = val
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
self._parFileCont[key] = val
self.from_file()
if fnout:
self.export2File(fnout)
@ -100,16 +67,28 @@ class AutoPickParameter(object):
string += 'Empty parameter dictionary.'
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
def __repr__(self):
return "AutoPickParameter('%s')" % self.__filename
# Boolean test
def __nonzero__(self):
return self.__parameter
return bool(self.__parameter)
def __getitem__(self, key):
return self.__parameter[key]
try:
return self.__parameter[key]
except:
return None
def __setitem__(self, key, value):
self.__parameter[key] = value
@ -147,21 +126,157 @@ class AutoPickParameter(object):
self._printParameterError(e)
raise ParameterError(e)
def get_defaults(self):
return self.__defaults
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 param, value in kwargs.items():
self.__setitem__(param, value)
# print(self)
for key in kwargs:
self.__setitem__(key, kwargs[key])
@staticmethod
def _printParameterError(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):
fid_out = open(fnout, 'w')
lines = []
for key, value in self.iteritems():
lines.append('{key}\t{value}'.format(key=key, value=value))
fid_out.writelines(lines)
# for key, value in self.iteritems():
# lines.append('{key}\t{value}\n'.format(key=key, value=value))
# 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):

View File

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

View File

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

View File

@ -34,7 +34,7 @@ class AutoPicker(object):
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
:type: `~pylot.core.pick.CharFuns.CharacteristicFunction` object
@ -72,6 +72,7 @@ class AutoPicker(object):
self.setaus(aus)
self.setTsmooth(Tsmooth)
self.setpick1(Pick1)
self.fig = fig
self.calcPick()
def __str__(self):
@ -172,21 +173,14 @@ class AICPicker(AutoPicker):
aicsmooth[i] = aicsmooth[i - 1] + (aic[i] - aic[ii1]) / ismooth
else:
aicsmooth[i] = np.mean(aic[1: i])
# remove offset
# remove offset in AIC function
offset = abs(min(aic) - min(aicsmooth))
aicsmooth = aicsmooth - offset
# get maximum of 1st derivative of AIC-CF (more stable!) as starting point
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))
icfmax = np.argmax(diffcf)
# get maximum of HOS/AR-CF as startimg point for searching
# minimum in AIC function
icfmax = np.argmax(self.Data[0].data)
# 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))
for i in range(icfmax - 1, max([icfmax - lpickwindow, 2]), -1):
if aicsmooth[i - 1] >= aicsmooth[i]:
@ -195,6 +189,14 @@ class AICPicker(AutoPicker):
# if no minimum could be found:
# search in 1st derivative of AIC-CF
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):
if diffcf[i - 1] >= diffcf[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('Choose longer slope determination window!')
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
p1, = plt.plot(self.Tcf, x / max(x), 'k')
p2, = plt.plot(self.Tcf, aicsmooth / max(aicsmooth), 'r')
plt.legend([p1, p2], ['(HOS-/AR-) Data', 'Smoothed AIC-CF'])
plt.xlabel('Time [s] since %s' % self.Data[0].stats.starttime)
plt.yticks([])
plt.title(self.Data[0].stats.station)
plt.show()
raw_input()
plt.close(p)
ax.plot(self.Tcf, x / max(x), 'k', legend='(HOS-/AR-) Data')
ax.plot(self.Tcf, aicsmooth / max(aicsmooth), 'r', legend='Smoothed AIC-CF')
ax.legend()
ax.set_xlabel('Time [s] since %s' % self.Data[0].stats.starttime)
ax.set_yticks([])
ax.set_title(self.Data[0].stats.station)
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
xslope = np.arange(0, len(dataslope), 1)
P = np.polyfit(xslope, dataslope, 1)
@ -253,42 +261,46 @@ class AICPicker(AutoPicker):
self.slope = None
if self.iplot > 1:
p = plt.figure(self.iplot)
x = self.Data[0].data
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'])
if not self.fig:
fig = plt.figure()#self.iplot)
else:
plt.legend([p1, p2], ['(HOS-/AR-) Data', 'Smoothed AIC-CF'])
plt.xlabel('Time [s] since %s' % self.Data[0].stats.starttime)
plt.yticks([])
plt.title(self.Data[0].stats.station)
fig = self.fig
ax1 = fig.add_subplot(211)
x = self.Data[0].data
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:
ax1.plot([self.Pick, self.Pick], [-0.1, 0.5], 'b', linewidth=2, label='AIC-Pick')
ax1.set_xlabel('Time [s] since %s' % self.Data[0].stats.starttime)
ax1.set_yticks([])
ax1.legend()
if self.Pick is not None:
plt.figure(self.iplot + 1)
p11, = plt.plot(self.Tcf, x, 'k')
p12, = plt.plot(self.Tcf[inoise], self.Data[0].data[inoise])
p13, = plt.plot(self.Tcf[isignal], self.Data[0].data[isignal], 'r')
p14, = plt.plot(self.Tcf[islope], dataslope, 'g--')
p15, = plt.plot(self.Tcf[islope], datafit, 'g', linewidth=2)
plt.legend([p11, p12, p13, p14, p15],
['Data', 'Noise Window', 'Signal Window', 'Slope Window', 'Slope'],
loc='best')
plt.title('Station %s, SNR=%7.2f, Slope= %12.2f counts/s' % (self.Data[0].stats.station,
self.SNR, self.slope))
plt.xlabel('Time [s] since %s' % self.Data[0].stats.starttime)
plt.ylabel('Counts')
plt.yticks([])
ax2 = fig.add_subplot(2,1,2, sharex=ax1)
ax2.plot(self.Tcf, x, 'k', label='Data')
ax1.axvspan(self.Tcf[inoise[0]],self.Tcf[inoise[-1]], color='y', alpha=0.2, lw=0, label='Noise Window')
ax1.axvspan(self.Tcf[isignal[0]],self.Tcf[isignal[-1]], color='b', alpha=0.2, lw=0, label='Signal Window')
ax1.axvspan(self.Tcf[iislope[0]],self.Tcf[iislope[-1]], color='g', alpha=0.2, lw=0, label='Slope Window')
plt.show()
raw_input()
plt.close(p)
ax2.axvspan(self.Tcf[inoise[0]],self.Tcf[inoise[-1]], color='y', alpha=0.2, lw=0, label='Noise Window')
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')
ax2.plot(self.Tcf[iislope], datafit, 'g', linewidth=2, label='Slope')
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:
print('AICPicker: Could not find minimum, picking window too short?')
return
class PragPicker(AutoPicker):
'''
@ -380,18 +392,20 @@ class PragPicker(AutoPicker):
pickflag = 0
if self.getiplot() > 1:
p = plt.figure(self.getiplot())
p1, = plt.plot(Tcfpick, cfipick, 'k')
p2, = plt.plot(Tcfpick, cfsmoothipick, 'r')
if not self.fig:
fig = plt.figure()#self.getiplot())
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:
p3, = plt.plot([self.Pick, self.Pick], [min(cfipick), max(cfipick)], 'b', linewidth=2)
plt.legend([p1, p2, p3], ['CF', 'Smoothed CF', 'Pick'])
plt.xlabel('Time [s] since %s' % self.Data[0].stats.starttime)
plt.yticks([])
plt.title(self.Data[0].stats.station)
plt.show()
raw_input()
plt.close(p)
ax.plot([self.Pick, self.Pick], [min(cfipick), max(cfipick)], 'b', linewidth=2, label='Pick')
ax.set_xlabel('Time [s] since %s' % self.Data[0].stats.starttime)
ax.set_yticks([])
ax.set_title(self.Data[0].stats.station)
ax.legend()
return
else:
print('PragPicker: No initial onset time given! Check input!')

View File

@ -9,13 +9,12 @@
"""
import warnings
import matplotlib.pyplot as plt
import numpy as np
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)
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)
if verbosity == 2:
print('earllatepicker:')
print('nfac:', nfac)
print('Init pick:', Pick1)
print('TSNR (T_noise, T_gap, T_signal):', TSNR)
LPick = None
EPick = None
PickError = None
if stealth_mode is False:
if verbosity:
print('earllatepicker: Get earliest and latest possible 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])
# calculate noise level
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
ilup, = np.where(x[isignal] > nlevel)
ildown, = np.where(x[isignal] < -nlevel)
if not ilup.size and not ildown.size:
if stealth_mode is False:
if verbosity:
print ("earllatepicker: Signal lower than noise level!\n"
"Skip this trace!")
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
while np.isnan(EPick):
if count > 0:
if stealth_mode is False:
if verbosity:
print("\nearllatepicker: Doubled signal window size %s time(s) "
"because of NaN for earliest pick." % count)
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:
pis = np.concatenate((pis, isignalDoubleWin))
else:
if stealth_mode is False:
if verbosity:
print("Could not double signal window. Index out of bounds.")
break
count += 1
@ -105,38 +117,34 @@ def earllatepicker(X, nfac, TSNR, Pick1, iplot=None, stealth_mode=False):
PickError = symmetrize_error(diffti_te, diffti_tl)
if iplot > 1:
p = plt.figure(iplot)
p1, = plt.plot(t, x, 'k')
p2, = plt.plot(t[inoise], x[inoise])
p3, = plt.plot(t[isignal], x[isignal], 'r')
p4, = plt.plot([t[0], t[int(len(t)) - 1]], [nlevel, nlevel], '--k')
p5, = plt.plot(t[isignal[zc]], np.zeros(len(zc)), '*g',
markersize=14)
plt.legend([p1, p2, p3, p4, p5],
['Data', 'Noise Window', 'Signal Window', 'Noise Level',
'Zero Crossings'],
loc='best')
plt.plot([t[0], t[int(len(t)) - 1]], [-nlevel, -nlevel], '--k')
plt.plot([Pick1, Pick1], [max(x), -max(x)], 'b', linewidth=2)
plt.plot([LPick, LPick], [max(x) / 2, -max(x) / 2], '--k')
plt.plot([EPick, EPick], [max(x) / 2, -max(x) / 2], '--k')
plt.plot([Pick1 + PickError, Pick1 + PickError],
if not fig:
fig = plt.figure()#iplot)
ax = fig.add_subplot(111)
ax.plot(t, x, 'k', label='Data')
ax.axvspan(t[inoise[0]], t[inoise[-1]], color='y', alpha=0.2, lw=0, label='Noise Window')
ax.axvspan(t[isignal[0]], t[isignal[-1]], color='b', alpha=0.2, lw=0, label='Signal Window')
ax.plot([t[0], t[int(len(t)) - 1]], [nlevel, nlevel], '--k', label='Noise Level')
ax.plot(t[isignal[zc]], np.zeros(len(zc)), '*g',
markersize=14, label='Zero Crossings')
ax.plot([t[0], t[int(len(t)) - 1]], [-nlevel, -nlevel], '--k')
ax.plot([Pick1, Pick1], [max(x), -max(x)], 'b', linewidth=2, label='mpp')
ax.plot([LPick, LPick], [max(x) / 2, -max(x) / 2], '--k', label='lpp')
ax.plot([EPick, EPick], [max(x) / 2, -max(x) / 2], '--k', label='epp')
ax.plot([Pick1 + PickError, Pick1 + PickError],
[max(x) / 2, -max(x) / 2], 'r--', label='spe')
ax.plot([Pick1 - PickError, Pick1 - PickError],
[max(x) / 2, -max(x) / 2], 'r--')
plt.plot([Pick1 - PickError, Pick1 - PickError],
[max(x) / 2, -max(x) / 2], 'r--')
plt.xlabel('Time [s] since %s' % X[0].stats.starttime)
plt.yticks([])
plt.title(
ax.set_xlabel('Time [s] since %s' % X[0].stats.starttime)
ax.set_yticks([])
ax.set_title(
'Earliest-/Latest Possible/Most Likely Pick & Symmetric Pick Error, %s' %
X[0].stats.station)
plt.show()
raw_input()
plt.close(p)
ax.legend()
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.
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)
if iplot > 1:
plt.figure(iplot)
plt.subplot(2, 1, 1)
plt.plot(t, xraw, 'k')
p1, = plt.plot([Pick, Pick], [max(xraw), -max(xraw)], 'b', linewidth=2)
if not fig:
fig = plt.figure()#iplot)
ax1 = fig.add_subplot(211)
ax1.plot(t, xraw, 'k')
ax1.plot([Pick, Pick], [max(xraw), -max(xraw)], 'b', linewidth=2, label='Pick')
if P1 is not None:
p2, = plt.plot(t[islope1], xraw[islope1])
p3, = plt.plot(zc1, np.zeros(len(zc1)), '*g', markersize=14)
p4, = plt.plot(t[islope1], datafit1, '--g', linewidth=2)
plt.legend([p1, p2, p3, p4],
['Pick', 'Slope Window', 'Zero Crossings', 'Slope'],
loc='best')
plt.text(Pick + 0.02, max(xraw) / 2, '%s' % FM, fontsize=14)
ax = plt.gca()
plt.yticks([])
plt.title('First-Motion Determination, %s, Unfiltered Data' % Xraw[
ax1.plot(t[islope1], xraw[islope1], label='Slope Window')
ax1.plot(zc1, np.zeros(len(zc1)), '*g', markersize=14, label='Zero Crossings')
ax1.plot(t[islope1], datafit1, '--g', linewidth=2)
ax1.legend()
ax1.text(Pick + 0.02, max(xraw) / 2, '%s' % FM, fontsize=14)
ax1.set_yticks([])
ax1.set_title('First-Motion Determination, %s, Unfiltered Data' % Xraw[
0].stats.station)
plt.subplot(2, 1, 2)
plt.title('First-Motion Determination, Filtered Data')
plt.plot(t, xfilt, 'k')
p1, = plt.plot([Pick, Pick], [max(xfilt), -max(xfilt)], 'b',
ax2=fig.add_subplot(2,1,2, sharex=ax1)
ax2.set_title('First-Motion Determination, Filtered Data')
ax2.plot(t, xfilt, 'k')
ax2.plot([Pick, Pick], [max(xfilt), -max(xfilt)], 'b',
linewidth=2)
if P2 is not None:
p2, = plt.plot(t[islope2], xfilt[islope2])
p3, = plt.plot(zc2, np.zeros(len(zc2)), '*g', markersize=14)
p4, = plt.plot(t[islope2], datafit2, '--g', linewidth=2)
plt.text(Pick + 0.02, max(xraw) / 2, '%s' % FM, fontsize=14)
ax = plt.gca()
plt.xlabel('Time [s] since %s' % Xraw[0].stats.starttime)
plt.yticks([])
plt.show()
raw_input()
plt.close(iplot)
ax2.plot(t[islope2], xfilt[islope2])
ax2.plot(zc2, np.zeros(len(zc2)), '*g', markersize=14)
ax2.plot(t[islope2], datafit2, '--g', linewidth=2)
ax2.text(Pick + 0.02, max(xraw) / 2, '%s' % FM, fontsize=14)
ax2.set_xlabel('Time [s] since %s' % Xraw[0].stats.starttime)
ax2.set_yticks([])
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)
SNR = None
SNRdb = None
noiselevel = None
x = X[tracenum].data
npts = X[tracenum].stats.npts
sr = X[tracenum].stats.sampling_rate
@ -367,19 +373,20 @@ def getSNR(X, TSNR, t1, tracenum=0):
isignal = getsignalwin(t, t1, TSNR[2])
if np.size(inoise) < 1:
print ("getSNR: Empty array inoise, check noise window!")
return
elif np.size(isignal) < 1:
print ("getSNR: Empty array isignal, check signal window!")
return
return SNR, SNRdB, noiselevel
# demean over entire waveform
x = x - np.mean(x[inoise])
# calculate ratios
# noiselevel = np.sqrt(np.mean(np.square(x[inoise])))
# signallevel = np.sqrt(np.mean(np.square(x[isignal])))
noiselevel = np.sqrt(np.mean(np.square(x[inoise])))
#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()
SNR = signallevel / noiselevel
@ -411,7 +418,9 @@ def getnoisewin(t, t1, tnoise, tgap):
inoise, = np.where((t <= max([t1 - tgap, 0])) \
& (t >= max([t1 - tnoise - tgap, 0])))
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
@ -440,7 +449,7 @@ def getsignalwin(t, t1, tsignal):
return isignal
def getResolutionWindow(snr):
def getResolutionWindow(snr, extent):
"""
Number -> Float
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
see also Diehl et al. 2009
:parameter: extent, can be 'local', 'regional', 'global'
>>> getResolutionWindow(0.5)
7.5
>>> getResolutionWindow(1.8)
@ -463,16 +474,22 @@ def getResolutionWindow(snr):
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:
time_resolution = res_wins['VLRW']
time_resolution = res_wins[extent]['VLRW']
elif snr < 2.:
time_resolution = res_wins['LRW']
time_resolution = res_wins[extent]['LRW']
elif snr < 3.:
time_resolution = res_wins['MRW']
time_resolution = res_wins[extent]['MRW']
elif snr >3.:
time_resolution = res_wins[extent]['HRW']
else:
time_resolution = res_wins['HRW']
time_resolution = res_wins[extent]['VLRW']
return time_resolution / 2
@ -489,18 +506,21 @@ def select_for_phase(st, phase):
:type phase: str
:return:
'''
from pylot.core.util.defaults import COMPNAME_MAP
from pylot.core.util.defaults import SetChannelComponents
sel_st = Stream()
compclass = SetChannelComponents()
if phase.upper() == 'P':
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=alter_comp)
elif phase.upper() == 'S':
comps = 'NE'
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=alter_comp)
else:
@ -605,8 +625,8 @@ def wadaticheck(pickdic, dttolerance, iplot):
wfitflag = 1
# plot results
if iplot > 1:
plt.figure(iplot)
if iplot > 0:
plt.figure()#iplot)
f1, = plt.plot(Ppicks, SPtimes, 'ro')
if wfitflag == 0:
f2, = plt.plot(Ppicks, wdfit, 'k')
@ -621,14 +641,11 @@ def wadaticheck(pickdic, dttolerance, iplot):
plt.ylabel('S-P Times [s]')
plt.xlabel('P Times [s]')
plt.show()
raw_input()
plt.close(iplot)
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.
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
if iplot == 2:
plt.figure(iplot)
p1, = plt.plot(t, rms, 'k')
p2, = plt.plot(t[inoise], rms[inoise], 'c')
p3, = plt.plot(t[isignal], rms[isignal], 'r')
p4, = plt.plot([t[isignal[0]], t[isignal[len(isignal) - 1]]],
[minsiglevel, minsiglevel], 'g', linewidth=2)
p5, = plt.plot([pick, pick], [min(rms), max(rms)], 'b', linewidth=2)
plt.legend([p1, p2, p3, p4, p5], ['RMS Data', 'RMS Noise Window',
'RMS Signal Window', 'Minimum Signal Level',
'Onset'], loc='best')
plt.xlabel('Time [s] since %s' % X[0].stats.starttime)
plt.ylabel('Counts')
plt.title('Check for Signal Length, Station %s' % X[0].stats.station)
plt.yticks([])
plt.show()
raw_input()
plt.close(iplot)
if not fig:
fig = plt.figure()#iplot)
ax = fig.add_subplot(111)
ax.plot(t, rms, 'k', label='RMS Data')
ax.axvspan(t[inoise[0]], t[inoise[-1]], color='y', alpha=0.2, lw=0, label='Noise Window')
ax.axvspan(t[isignal[0]], t[isignal[-1]], color='b', alpha=0.2, lw=0, label='Signal Window')
ax.plot([t[isignal[0]], t[isignal[len(isignal) - 1]]],
[minsiglevel, minsiglevel], 'g', linewidth=2, label='Minimum Signal Level')
ax.plot([pick, pick], [min(rms), max(rms)], 'b', linewidth=2, label='Onset')
ax.legend()
ax.set_xlabel('Time [s] since %s' % X[0].stats.starttime)
ax.set_ylabel('Counts')
ax.set_title('Check for Signal Length, Station %s' % X[0].stats.station)
ax.set_yticks([])
return returnflag
@ -756,11 +770,12 @@ def checkPonsets(pickdic, dttolerance, iplot):
[xjack, PHI_pseudo, PHI_sub] = jackknife(Ppicks, 'VAR', 1)
# get pseudo variances smaller than average variances
# (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
badjk = np.where(PHI_pseudo > 2 * xjack)
badjk = np.where(PHI_pseudo > 5 * xjack)
badjkstations = np.array(stations)[badjk]
print ("checkPonsets: %d pick(s) did not pass jackknife test!" % len(badjkstations))
print(badjkstations)
# calculate median from these picks
pmedian = np.median(np.array(Ppicks)[ij])
@ -795,21 +810,22 @@ def checkPonsets(pickdic, dttolerance, iplot):
checkedonsets = pickdic
if iplot > 1:
p1, = plt.plot(np.arange(0, len(Ppicks)), Ppicks, 'r+', markersize=14)
p2, = plt.plot(igood, np.array(Ppicks)[igood], 'g*', markersize=14)
if iplot > 0:
p1, = plt.plot(np.arange(0, len(Ppicks)), Ppicks, 'ro', 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',
linewidth=2)
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.ylabel('Onset Time [s] from 1.1.1970')
plt.legend([p1, p2, p3], ['Skipped P Picks', 'Good P Picks', 'Median'],
loc='best')
plt.title('Check P Onsets')
plt.show()
raw_input()
plt.title('Jackknifing and Median Tests on P Onsets')
return checkedonsets
@ -878,7 +894,7 @@ def jackknife(X, phi, h):
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
energy content of horizontal traces to detect spuriously
@ -943,8 +959,18 @@ def checkZ4S(X, pick, zfac, checkwin, iplot):
isignal = getsignalwin(tz, pick, checkwin)
# calculate energy levels
zcodalevel = max(absz[isignal])
encodalevel = max(absen[isignal])
try:
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
minsiglevel = encodalevel * zfac
@ -962,22 +988,23 @@ def checkZ4S(X, pick, zfac, checkwin, iplot):
edat[0].stats.delta)
tn = np.arange(0, ndat[0].stats.npts / ndat[0].stats.sampling_rate,
ndat[0].stats.delta)
plt.plot(tz, z / max(z), 'k')
plt.plot(tz[isignal], z[isignal] / max(z), 'r')
plt.plot(te, edat[0].data / max(edat[0].data) + 1, 'k')
plt.plot(te[isignal], edat[0].data[isignal] / max(edat[0].data) + 1, 'r')
plt.plot(tn, ndat[0].data / max(ndat[0].data) + 2, 'k')
plt.plot(tn[isignal], ndat[0].data[isignal] / max(ndat[0].data) + 2, 'r')
plt.plot([tz[isignal[0]], tz[isignal[len(isignal) - 1]]],
[minsiglevel / max(z), minsiglevel / max(z)], 'g',
linewidth=2)
plt.xlabel('Time [s] since %s' % zdat[0].stats.starttime)
plt.ylabel('Normalized Counts')
plt.yticks([0, 1, 2], [zdat[0].stats.channel, edat[0].stats.channel,
ndat[0].stats.channel])
plt.title('CheckZ4S, Station %s' % zdat[0].stats.station)
plt.show()
raw_input()
if not fig:
fig = plt.figure()
ax = fig.add_subplot(111)
ax.plot(tz, z / max(z), 'k')
ax.axvspan(tz[isignal[0]], tz[isignal[-1]], color='b', alpha=0.2,
lw=0, label='Signal Window')
ax.plot(te, edat[0].data / max(edat[0].data) + 1, 'k')
ax.plot(tn, ndat[0].data / max(ndat[0].data) + 2, 'k')
ax.plot([tz[isignal[0]], tz[isignal[len(isignal) - 1]]],
[minsiglevel / max(z), minsiglevel / max(z)], 'g',
linewidth=2, label='Minimum Signal Level')
ax.set_xlabel('Time [s] since %s' % zdat[0].stats.starttime)
ax.set_ylabel('Normalized Counts')
ax.set_yticks([0, 1, 2], [zdat[0].stats.channel, edat[0].stats.channel,
ndat[0].stats.channel])
ax.set_title('CheckZ4S, Station %s' % zdat[0].stats.station)
ax.legend()
return returnflag

View File

@ -169,7 +169,8 @@ def read_metadata(path_to_inventory):
dlfile = list()
invfile = 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):
ext = os.path.splitext(path_to_inventory)[1].split('.')[1]
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)
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 -*-
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):
message = Signal(str)
finished = Signal()
def __init__(self, parent, func, infile, fnames, savepath):
def __init__(self, parent, func, infile, fnames, eventid, savepath):
super(AutoPickThread, self).__init__()
self.setParent(parent)
self.func = func
self.infile = infile
self.fnames = fnames
self.eventid = eventid
self.savepath = savepath
def run(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")
@ -35,3 +37,60 @@ class AutoPickThread(QThread):
def flush(self):
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 pwd
import re
import warnings
import subprocess
from obspy import UTCDateTime, read
from pylot.core.io.inputs import AutoPickParameter
@ -381,9 +382,11 @@ def prepTimeAxis(stime, trace):
print('shorten time axes by one datum')
time_ax = np.arange(stime, etime - tincr, tincr)
if len(time_ax) != nsamp:
raise ValueError('{0} samples of data \n '
'{1} length of time vector \n'
'delta: {2}'.format(nsamp, len(time_ax), tincr))
print('Station {0}, {1} samples of data \n '
'{2} length of time vector \n'
'delta: {3}'.format(trace.stats.station,
nsamp, len(time_ax), tincr))
time_ax = None
return time_ax

File diff suppressed because it is too large Load Diff