Merge branch 'develop'
This commit is contained in:
commit
15799feee7
1733
QtPyLoT.py
1733
QtPyLoT.py
File diff suppressed because it is too large
Load Diff
119
autoPyLoT.py
119
autoPyLoT.py
@ -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
|
||||
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,6 +260,11 @@ 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)
|
||||
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)
|
||||
@ -240,18 +286,19 @@ def autoPyLoT(inputfile, fnames=None, savepath=None):
|
||||
print("autoPyLoT: No more bad onsets found, stop iterative picking!")
|
||||
nlloccounter = maxnumit
|
||||
evt = read_events(nllocfile)[0]
|
||||
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, \
|
||||
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()
|
||||
@ -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.")
|
||||
|
||||
|
@ -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>
|
||||
|
BIN
icons/autopicksicon_small.png
Normal file
BIN
icons/autopicksicon_small.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 27 KiB |
BIN
icons/manupicksicon_small.png
Normal file
BIN
icons/manupicksicon_small.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 22 KiB |
8190
icons_rc.py
8190
icons_rc.py
File diff suppressed because it is too large
Load Diff
@ -1 +1 @@
|
||||
3932-dirty
|
||||
5412-dirty
|
||||
|
@ -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
|
||||
|
@ -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")
|
||||
|
362
pylot/core/io/default_parameters.py
Normal file
362
pylot/core/io/default_parameters.py
Normal 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']
|
||||
}
|
@ -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):
|
||||
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 setParam(self, **kwargs):
|
||||
for param, value in kwargs.items():
|
||||
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)
|
||||
# print(self)
|
||||
|
||||
def setParam(self, **kwargs):
|
||||
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):
|
||||
|
@ -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']
|
||||
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
|
||||
|
@ -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)
|
||||
|
||||
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,14 +344,26 @@ 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,
|
||||
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
|
||||
@ -342,6 +385,13 @@ def autopickstation(wfstream, pickparam, verbose=False):
|
||||
# get first motion of P onset
|
||||
# certain quality required
|
||||
if Pweight <= minfmweight and SNRP >= minFMSNR:
|
||||
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,20 +550,44 @@ 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,
|
||||
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,
|
||||
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:
|
||||
@ -603,39 +681,39 @@ 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 '
|
||||
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,
|
||||
@ -643,22 +721,21 @@ def autopickstation(wfstream, pickparam, verbose=False):
|
||||
SNRPdB,
|
||||
FM))
|
||||
else:
|
||||
plt.legend([p1, p2], ['Data', 'CF1'])
|
||||
plt.title('%s, P Weight=%d, SNR=None, '
|
||||
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
|
||||
|
@ -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!')
|
||||
|
@ -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
|
||||
@ -410,6 +417,8 @@ def getnoisewin(t, t1, tnoise, tgap):
|
||||
# get noise window
|
||||
inoise, = np.where((t <= max([t1 - tgap, 0])) \
|
||||
& (t >= max([t1 - tnoise - tgap, 0])))
|
||||
if np.size(inoise) < 1:
|
||||
inoise, = np.where((t>=t[0]) & (t<=t1))
|
||||
if np.size(inoise) < 1:
|
||||
print ("getnoisewin: Empty array inoise, check noise window!")
|
||||
|
||||
@ -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
|
||||
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]]],
|
||||
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)
|
||||
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,
|
||||
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])
|
||||
plt.title('CheckZ4S, Station %s' % zdat[0].stats.station)
|
||||
plt.show()
|
||||
raw_input()
|
||||
ax.set_title('CheckZ4S, Station %s' % zdat[0].stats.station)
|
||||
ax.legend()
|
||||
|
||||
return returnflag
|
||||
|
||||
|
@ -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]
|
||||
|
@ -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()))
|
||||
|
||||
|
365
pylot/core/util/map_projection.py
Normal file
365
pylot/core/util/map_projection.py
Normal 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()
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
Loading…
Reference in New Issue
Block a user