Merge branch 'develop'
1995
QtPyLoT.py → PyLoT.py
Executable file → Normal file
186
README.md
@ -1,90 +1,96 @@
|
||||
# PyLoT
|
||||
|
||||
version: 0.1a
|
||||
|
||||
The Python picking and Localisation Tool
|
||||
|
||||
This python library contains a graphical user interfaces for picking
|
||||
seismic phases. This software needs [ObsPy][ObsPy]
|
||||
and the PySide Qt4 bindings for python to be installed first.
|
||||
|
||||
PILOT has originally been developed in Mathworks' MatLab. In order to
|
||||
distribute PILOT without facing portability problems, it has been decided
|
||||
to redevelop the software package in Python. The great work of the ObsPy
|
||||
group allows easy handling of a bunch of seismic data and PyLoT will
|
||||
benefit a lot compared to the former MatLab version.
|
||||
|
||||
The development of PyLoT is part of the joint research project MAGS2.
|
||||
|
||||
## Installation
|
||||
|
||||
At the moment there is no automatic installation procedure available for PyLoT.
|
||||
Best way to install is to clone the repository and add the path to your Python path.
|
||||
|
||||
#### Prerequisites:
|
||||
|
||||
In order to run PyLoT you need to install:
|
||||
|
||||
- python
|
||||
- scipy
|
||||
- numpy
|
||||
- matplotlib
|
||||
- obspy
|
||||
- pyside
|
||||
|
||||
#### Some handwork:
|
||||
|
||||
PyLoT needs a properties folder on your system to work. It should be situated in your home directory:
|
||||
|
||||
mkdir ~/.pylot
|
||||
|
||||
In the next step you have to copy some files to this directory:
|
||||
|
||||
cp path-to-pylot/inputs/pylot.in ~/.pylot/
|
||||
|
||||
for local distance seismicity
|
||||
|
||||
cp path-to-pylot/inputs/autoPyLoT_local.in ~/.pylot/autoPyLoT.in
|
||||
|
||||
for regional distance seismicity
|
||||
|
||||
cp path-to-pylot/inputs/autoPyLoT_regional.in ~/.pylot/autoPyLoT.in
|
||||
|
||||
and some extra information on filtering, error estimates (just needed for reading old PILOT data) and the Richter magnitude scaling relation
|
||||
|
||||
cp path-to-pylot/inputs/filter.in path-to-pylot/inputs/PILOT_TimeErrors.in path-to-pylot/inputs/richter_scaling.data ~/.pylot/
|
||||
|
||||
You may need to do some modifications to these files. Especially folder names should be reviewed.
|
||||
|
||||
PyLoT has been tested on Mac OSX (10.11) and Debian Linux 8.
|
||||
|
||||
|
||||
## Release notes
|
||||
|
||||
#### Features:
|
||||
|
||||
- consistent manual phase picking through predefined SNR dependant zoom level
|
||||
- uniform uncertainty estimation from waveform's properties for automatic and manual picks
|
||||
- pdf representation and comparison of picks taking the uncertainty intrinsically into account
|
||||
- Richter and moment magnitude estimation
|
||||
- location determination with external installation of [NonLinLoc](http://alomax.free.fr/nlloc/index.html)
|
||||
|
||||
#### Known issues:
|
||||
|
||||
- Magnitude estimation from manual PyLoT takes some time (instrument correction)
|
||||
|
||||
We hope to solve these with the next release.
|
||||
|
||||
## Staff
|
||||
|
||||
Original author(s): L. Kueperkoch, S. Wehling-Benatelli, M. Bischoff (PILOT)
|
||||
|
||||
Developer(s): S. Wehling-Benatelli, L. Kueperkoch, K. Olbert, M. Bischoff,
|
||||
C. Wollin, M. Rische, M. Paffrath
|
||||
|
||||
Others: A. Bruestle, T. Meier, W. Friederich
|
||||
|
||||
|
||||
[ObsPy]: http://github.com/obspy/obspy/wiki
|
||||
|
||||
October 2016
|
||||
# PyLoT
|
||||
|
||||
version: 0.2
|
||||
|
||||
The Python picking and Localisation Tool
|
||||
|
||||
This python library contains a graphical user interfaces for picking
|
||||
seismic phases. This software needs [ObsPy][ObsPy]
|
||||
and the PySide Qt4 bindings for python to be installed first.
|
||||
|
||||
PILOT has originally been developed in Mathworks' MatLab. In order to
|
||||
distribute PILOT without facing portability problems, it has been decided
|
||||
to redevelop the software package in Python. The great work of the ObsPy
|
||||
group allows easy handling of a bunch of seismic data and PyLoT will
|
||||
benefit a lot compared to the former MatLab version.
|
||||
|
||||
The development of PyLoT is part of the joint research project MAGS2 and AlpArray.
|
||||
|
||||
## Installation
|
||||
|
||||
At the moment there is no automatic installation procedure available for PyLoT.
|
||||
Best way to install is to clone the repository and add the path to your Python path.
|
||||
|
||||
#### Prerequisites:
|
||||
|
||||
In order to run PyLoT you need to install:
|
||||
|
||||
- python 2 or 3
|
||||
- scipy
|
||||
- numpy
|
||||
- matplotlib
|
||||
- obspy
|
||||
- pyside
|
||||
|
||||
#### Some handwork:
|
||||
|
||||
PyLoT needs a properties folder on your system to work. It should be situated in your home directory
|
||||
(on Windows usually C:/Users/*username*):
|
||||
|
||||
mkdir ~/.pylot
|
||||
|
||||
In the next step you have to copy some files to this directory:
|
||||
|
||||
*for local distance seismicity*
|
||||
|
||||
cp path-to-pylot/inputs/pylot_local.in ~/.pylot/pylot.in
|
||||
|
||||
*for regional distance seismicity*
|
||||
|
||||
cp path-to-pylot/inputs/pylot_regional.in ~/.pylot/pylot.in
|
||||
|
||||
*for global distance seismicity*
|
||||
|
||||
cp path-to-pylot/inputs/pylot_global.in ~/.pylot/pylot.in
|
||||
|
||||
and some extra information on error estimates (just needed for reading old PILOT data) and the Richter magnitude scaling relation
|
||||
|
||||
cp path-to-pylot/inputs/PILOT_TimeErrors.in path-to-pylot/inputs/richter_scaling.data ~/.pylot/
|
||||
|
||||
You may need to do some modifications to these files. Especially folder names should be reviewed.
|
||||
|
||||
PyLoT has been tested on Mac OSX (10.11), Debian Linux 8 and on Windows 10.
|
||||
|
||||
|
||||
## Release notes
|
||||
|
||||
#### Features:
|
||||
|
||||
- event organisation in project files and waveform visualisation
|
||||
- consistent manual phase picking through predefined SNR dependant zoom level
|
||||
- consistent automatic phase picking routines using Higher Order Statistics, AIC and Autoregression
|
||||
- interactive tuning of auto-pick parameters
|
||||
- uniform uncertainty estimation from waveform's properties for automatic and manual picks
|
||||
- pdf representation and comparison of picks taking the uncertainty intrinsically into account
|
||||
- Richter and moment magnitude estimation
|
||||
- location determination with external installation of [NonLinLoc](http://alomax.free.fr/nlloc/index.html)
|
||||
|
||||
#### Known issues:
|
||||
|
||||
- Sometimes an error might occur when using Qt
|
||||
|
||||
We hope to solve these with the next release.
|
||||
|
||||
## Staff
|
||||
|
||||
Original author(s): L. Kueperkoch, S. Wehling-Benatelli, M. Bischoff (PILOT)
|
||||
|
||||
Developer(s): S. Wehling-Benatelli, L. Kueperkoch, K. Olbert, M. Bischoff,
|
||||
C. Wollin, M. Rische, M. Paffrath
|
||||
|
||||
Others: A. Bruestle, T. Meier, W. Friederich
|
||||
|
||||
|
||||
[ObsPy]: http://github.com/obspy/obspy/wiki
|
||||
|
||||
September 2017
|
||||
|
279
autoPyLoT.py
@ -4,31 +4,37 @@
|
||||
from __future__ import print_function
|
||||
|
||||
import argparse
|
||||
import datetime
|
||||
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
|
||||
import pylot.core.loc.hypodd as hypodd
|
||||
|
||||
import pylot.core.loc.focmec as focmec
|
||||
import pylot.core.loc.hash as hash
|
||||
import pylot.core.loc.hypo71 as hypo71
|
||||
import pylot.core.loc.hypodd as hypodd
|
||||
import pylot.core.loc.hyposat as hyposat
|
||||
import pylot.core.loc.nll as nll
|
||||
#from PySide.QtGui import QWidget, QInputDialog
|
||||
import pylot.core.loc.velest as velest
|
||||
from obspy import read_events
|
||||
from obspy.core.event import ResourceIdentifier
|
||||
# from PySide.QtGui import QWidget, QInputDialog
|
||||
from pylot.core.analysis.magnitude import MomentMagnitude, LocalMagnitude
|
||||
from pylot.core.io.data import Data
|
||||
from pylot.core.io.inputs import PylotParameter
|
||||
from pylot.core.pick.autopick import autopickevent, iteratepicker
|
||||
from pylot.core.util.dataprocessing import restitute_data, read_metadata, \
|
||||
remove_underscores
|
||||
from pylot.core.util.dataprocessing import restitute_data, read_metadata
|
||||
from pylot.core.util.defaults import SEPARATOR
|
||||
from pylot.core.util.event import Event
|
||||
from pylot.core.util.structure import DATASTRUCTURE
|
||||
from pylot.core.util.utils import real_None, remove_underscores, trim_station_components, check4gaps, check4doubled, \
|
||||
check4rotated
|
||||
from pylot.core.util.version import get_git_version as _getVersionString
|
||||
|
||||
__version__ = _getVersionString()
|
||||
|
||||
|
||||
def autoPyLoT(input_dict=None, parameter=None, inputfile=None, fnames=None, eventid=None, savepath=None, station='all', iplot=0):
|
||||
def autoPyLoT(input_dict=None, parameter=None, inputfile=None, fnames=None, eventid=None, savepath=None,
|
||||
savexml=True, station='all', iplot=0, ncores=0):
|
||||
"""
|
||||
Determine phase onsets automatically utilizing the automatic picking
|
||||
algorithms by Kueperkoch et al. 2010/2012.
|
||||
@ -42,40 +48,68 @@ def autoPyLoT(input_dict=None, parameter=None, inputfile=None, fnames=None, even
|
||||
.. rubric:: Example
|
||||
|
||||
"""
|
||||
|
||||
if ncores == 1:
|
||||
sp_info = 'autoPyLoT is running serial on 1 cores.'
|
||||
else:
|
||||
if ncores == 0:
|
||||
ncores_readable = 'all available'
|
||||
else:
|
||||
ncores_readable = ncores
|
||||
sp_info = 'autoPyLoT is running in parallel on {} cores.'.format(ncores_readable)
|
||||
|
||||
splash = '''************************************\n
|
||||
*********autoPyLoT starting*********\n
|
||||
The Python picking and Location Tool\n
|
||||
Version {version} 2015\n
|
||||
Version {version} 2017\n
|
||||
\n
|
||||
Authors:\n
|
||||
S. Wehling-Benatelli (Ruhr-Universitaet Bochum)\n
|
||||
L. Kueperkoch (BESTEC GmbH, Landau i. d. Pfalz)\n
|
||||
K. Olbert (Christian-Albrechts Universitaet zu Kiel)\n
|
||||
***********************************'''.format(version=_getVersionString())
|
||||
M. Paffrath (Ruhr-Universitaet Bochum)\n
|
||||
S. Wehling-Benatelli (Ruhr-Universitaet Bochum)\n
|
||||
|
||||
{sp}
|
||||
***********************************'''.format(version=_getVersionString(),
|
||||
sp=sp_info)
|
||||
print(splash)
|
||||
|
||||
|
||||
parameter = real_None(parameter)
|
||||
inputfile = real_None(inputfile)
|
||||
eventid = real_None(eventid)
|
||||
|
||||
fig_dict = None
|
||||
fig_dict_wadatijack = None
|
||||
|
||||
locflag = 1
|
||||
if input_dict and isinstance(input_dict, dict):
|
||||
if input_dict.has_key('parameter'):
|
||||
if 'parameter' in input_dict:
|
||||
parameter = input_dict['parameter']
|
||||
if input_dict.has_key('fig_dict'):
|
||||
if 'fig_dict' in input_dict:
|
||||
fig_dict = input_dict['fig_dict']
|
||||
if input_dict.has_key('station'):
|
||||
if 'fig_dict_wadatijack' in input_dict:
|
||||
fig_dict_wadatijack = input_dict['fig_dict_wadatijack']
|
||||
if 'station' in input_dict:
|
||||
station = input_dict['station']
|
||||
if input_dict.has_key('fnames'):
|
||||
if 'fnames' in input_dict:
|
||||
fnames = input_dict['fnames']
|
||||
if input_dict.has_key('iplot'):
|
||||
if 'eventid' in input_dict:
|
||||
eventid = input_dict['eventid']
|
||||
if 'iplot' in input_dict:
|
||||
iplot = input_dict['iplot']
|
||||
if input_dict.has_key('locflag'):
|
||||
if 'locflag' in input_dict:
|
||||
locflag = input_dict['locflag']
|
||||
if 'savexml' in input_dict:
|
||||
savexml = input_dict['savexml']
|
||||
|
||||
if not parameter:
|
||||
if inputfile:
|
||||
parameter = PylotParameter(inputfile)
|
||||
iplot = parameter['iplot']
|
||||
#iplot = parameter['iplot']
|
||||
else:
|
||||
print('No parameters set and no input file given. Choose either of both.')
|
||||
return
|
||||
infile = os.path.join(os.path.expanduser('~'), '.pylot', 'pylot.in')
|
||||
print('Using default input file {}'.format(infile))
|
||||
parameter = PylotParameter(infile)
|
||||
else:
|
||||
if not type(parameter) == PylotParameter:
|
||||
print('Wrong input type for parameter: {}'.format(type(parameter)))
|
||||
@ -83,8 +117,6 @@ def autoPyLoT(input_dict=None, parameter=None, inputfile=None, fnames=None, even
|
||||
if inputfile:
|
||||
print('Parameters set and input file given. Choose either of both.')
|
||||
return
|
||||
|
||||
data = Data()
|
||||
|
||||
evt = None
|
||||
|
||||
@ -97,7 +129,7 @@ def autoPyLoT(input_dict=None, parameter=None, inputfile=None, fnames=None, even
|
||||
'dbase': parameter.get('database')}
|
||||
|
||||
exf = ['root', 'dpath', 'dbase']
|
||||
|
||||
|
||||
if parameter['eventID'] is not '*' and fnames == 'None':
|
||||
dsfields['eventID'] = parameter['eventID']
|
||||
exf.append('eventID')
|
||||
@ -106,7 +138,7 @@ def autoPyLoT(input_dict=None, parameter=None, inputfile=None, fnames=None, even
|
||||
datastructure.setExpandFields(exf)
|
||||
|
||||
# check if default location routine NLLoc is available
|
||||
if parameter['nllocbin'] and locflag:
|
||||
if real_None(parameter['nllocbin']) and locflag:
|
||||
# get NLLoc-root path
|
||||
nllocroot = parameter.get('nllocroot')
|
||||
# get path to NLLoc executable
|
||||
@ -137,9 +169,14 @@ def autoPyLoT(input_dict=None, parameter=None, inputfile=None, fnames=None, even
|
||||
# multiple event processing
|
||||
# read each event in database
|
||||
events = [events for events in glob.glob(os.path.join(datapath, '*')) if os.path.isdir(events)]
|
||||
elif fnames == 'None' and parameter['eventID'] is not '*':
|
||||
elif fnames == 'None' and parameter['eventID'] is not '*' and not type(parameter['eventID']) == list:
|
||||
# single event processing
|
||||
events = glob.glob(os.path.join(datapath, parameter['eventID']))
|
||||
elif fnames == 'None' and type(parameter['eventID']) == list:
|
||||
# multiple event processing
|
||||
events = []
|
||||
for eventID in parameter['eventID']:
|
||||
events.append(os.path.join(datapath, eventID))
|
||||
else:
|
||||
# autoPyLoT was initialized from GUI
|
||||
events = []
|
||||
@ -147,22 +184,41 @@ def autoPyLoT(input_dict=None, parameter=None, inputfile=None, fnames=None, even
|
||||
evID = os.path.split(eventid)[-1]
|
||||
locflag = 2
|
||||
else:
|
||||
# started in tune mode
|
||||
# started in tune or interactive mode
|
||||
datapath = os.path.join(parameter['rootpath'],
|
||||
parameter['datapath'])
|
||||
events = []
|
||||
events.append(os.path.join(datapath,
|
||||
parameter['database'],
|
||||
parameter['eventID']))
|
||||
for eventID in eventid:
|
||||
events.append(os.path.join(datapath,
|
||||
parameter['database'],
|
||||
eventID))
|
||||
|
||||
if not events:
|
||||
print('autoPyLoT: No events given. Return!')
|
||||
return
|
||||
|
||||
for event in events:
|
||||
|
||||
# transform system path separator to '/'
|
||||
for index, eventpath in enumerate(events):
|
||||
eventpath = eventpath.replace(SEPARATOR, '/')
|
||||
events[index] = eventpath
|
||||
|
||||
allpicks = {}
|
||||
glocflag = locflag
|
||||
for eventpath in events:
|
||||
evID = os.path.split(eventpath)[-1]
|
||||
fext = '.xml'
|
||||
filename = os.path.join(eventpath, 'PyLoT_' + evID + fext)
|
||||
try:
|
||||
data = Data(evtdata=filename)
|
||||
data.get_evt_data().path = eventpath
|
||||
print('Reading event data from filename {}...'.format(filename))
|
||||
except Exception as e:
|
||||
print('Could not read event from file {}: {}'.format(filename, e))
|
||||
data = Data()
|
||||
pylot_event = Event(eventpath) # event should be path to event directory
|
||||
data.setEvtData(pylot_event)
|
||||
if fnames == 'None':
|
||||
data.setWFData(glob.glob(os.path.join(datapath, event, '*')))
|
||||
evID = os.path.split(event)[-1]
|
||||
data.setWFData(glob.glob(os.path.join(datapath, eventpath, '*')))
|
||||
# the following is necessary because within
|
||||
# multiple event processing no event ID is provided
|
||||
# in autopylot.in
|
||||
@ -178,10 +234,10 @@ def autoPyLoT(input_dict=None, parameter=None, inputfile=None, fnames=None, even
|
||||
parameter.setParam(eventID=eventID)
|
||||
else:
|
||||
data.setWFData(fnames)
|
||||
|
||||
event = events[0]
|
||||
#now = datetime.datetime.now()
|
||||
#evID = '%d%02d%02d%02d%02d' % (now.year,
|
||||
|
||||
eventpath = events[0]
|
||||
# now = datetime.datetime.now()
|
||||
# evID = '%d%02d%02d%02d%02d' % (now.year,
|
||||
# now.month,
|
||||
# now.day,
|
||||
# now.hour,
|
||||
@ -192,22 +248,31 @@ def autoPyLoT(input_dict=None, parameter=None, inputfile=None, fnames=None, even
|
||||
wfdat = wfdat.select(station=station)
|
||||
if not wfdat:
|
||||
print('Could not find station {}. STOP!'.format(station))
|
||||
return
|
||||
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. Stations: %s' % (event, station))
|
||||
# trim components for each station to avoid problems with different trace starttimes for one station
|
||||
wfdat = check4gaps(wfdat)
|
||||
wfdat = check4doubled(wfdat)
|
||||
wfdat = trim_station_components(wfdat, trim_start=True, trim_end=False)
|
||||
metadata = read_metadata(parameter.get('invdir'))
|
||||
# rotate stations to ZNE
|
||||
wfdat = check4rotated(wfdat, metadata)
|
||||
corr_dat = None
|
||||
if locflag:
|
||||
print("Restitute data ...")
|
||||
corr_dat = restitute_data(wfdat.copy(), *metadata, ncores=ncores)
|
||||
if not corr_dat and locflag:
|
||||
locflag = 2
|
||||
print('Working on event %s. Stations: %s' % (eventpath, station))
|
||||
print(wfdat)
|
||||
##########################################################
|
||||
# !automated picking starts here!
|
||||
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)
|
||||
fdwj = None
|
||||
if fig_dict_wadatijack:
|
||||
fdwj = fig_dict_wadatijack[evID]
|
||||
picks = autopickevent(wfdat, parameter, iplot=iplot, fig_dict=fig_dict,
|
||||
fig_dict_wadatijack=fdwj,
|
||||
ncores=ncores, metadata=metadata, origin=data.get_evt_data().origins)
|
||||
##########################################################
|
||||
# locating
|
||||
if locflag > 0:
|
||||
@ -246,11 +311,11 @@ def autoPyLoT(input_dict=None, parameter=None, inputfile=None, fnames=None, even
|
||||
# calculate 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('rho'), True,
|
||||
iplot)
|
||||
# update pick with moment property values (w0, fc, Mo)
|
||||
for station, props in moment_mag.moment_props.items():
|
||||
picks[station]['P'].update(props)
|
||||
for stats, props in moment_mag.moment_props.items():
|
||||
picks[stats]['P'].update(props)
|
||||
evt = moment_mag.updated_event()
|
||||
net_mw = moment_mag.net_magnitude()
|
||||
print("Network moment magnitude: %4.1f" % net_mw.mag)
|
||||
@ -258,12 +323,12 @@ def autoPyLoT(input_dict=None, parameter=None, inputfile=None, fnames=None, even
|
||||
WAscaling = parameter.get('WAscaling')
|
||||
magscaling = parameter.get('magscaling')
|
||||
local_mag = LocalMagnitude(corr_dat, evt,
|
||||
parameter.get('sstop'),
|
||||
parameter.get('sstop'),
|
||||
WAscaling, True, iplot)
|
||||
for station, amplitude in local_mag.amplitudes.items():
|
||||
picks[station]['S']['Ao'] = amplitude.generic_amplitude
|
||||
for stats, amplitude in local_mag.amplitudes.items():
|
||||
picks[stats]['S']['Ao'] = amplitude.generic_amplitude
|
||||
print("Local station magnitudes scaled with:")
|
||||
print("log(Ao) + %f * log(r) + %f * r + %f" % (WAscaling[0],
|
||||
print("log(Ao) + %f * log(r) + %f * r + %f" % (WAscaling[0],
|
||||
WAscaling[1],
|
||||
WAscaling[2]))
|
||||
evt = local_mag.updated_event(magscaling)
|
||||
@ -289,9 +354,10 @@ def autoPyLoT(input_dict=None, parameter=None, inputfile=None, fnames=None, even
|
||||
break
|
||||
print("autoPyLoT: Starting with iteration No. %d ..." % nlloccounter)
|
||||
if input_dict:
|
||||
if input_dict.has_key('fig_dict'):
|
||||
if 'fig_dict' in input_dict:
|
||||
fig_dict = input_dict['fig_dict']
|
||||
picks = iteratepicker(wfdat, nllocfile, picks, badpicks, parameter, fig_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
|
||||
@ -308,7 +374,7 @@ def autoPyLoT(input_dict=None, parameter=None, inputfile=None, fnames=None, even
|
||||
for key in picks:
|
||||
if picks[key]['P']['weight'] >= 4 or picks[key]['S']['weight'] >= 4:
|
||||
badpicks.append([key, picks[key]['P']['mpp']])
|
||||
print("autoPyLoT: After iteration No. %d: %d bad onsets found ..." % (nlloccounter, \
|
||||
print("autoPyLoT: After iteration No. %d: %d bad onsets found ..." % (nlloccounter,
|
||||
len(badpicks)))
|
||||
if len(badpicks) == 0:
|
||||
print("autoPyLoT: No more bad onsets found, stop iterative picking!")
|
||||
@ -318,11 +384,12 @@ def autoPyLoT(input_dict=None, parameter=None, inputfile=None, fnames=None, even
|
||||
# calculate 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('rho'), True,
|
||||
iplot)
|
||||
# update pick with moment property values (w0, fc, Mo)
|
||||
for station, props in moment_mag.moment_props.items():
|
||||
picks[station]['P'].update(props)
|
||||
for stats, props in moment_mag.moment_props.items():
|
||||
if picks.has_key(stats):
|
||||
picks[stats]['P'].update(props)
|
||||
evt = moment_mag.updated_event()
|
||||
net_mw = moment_mag.net_magnitude()
|
||||
print("Network moment magnitude: %4.1f" % net_mw.mag)
|
||||
@ -330,12 +397,13 @@ def autoPyLoT(input_dict=None, parameter=None, inputfile=None, fnames=None, even
|
||||
WAscaling = parameter.get('WAscaling')
|
||||
magscaling = parameter.get('magscaling')
|
||||
local_mag = LocalMagnitude(corr_dat, evt,
|
||||
parameter.get('sstop'),
|
||||
parameter.get('sstop'),
|
||||
WAscaling, True, iplot)
|
||||
for station, amplitude in local_mag.amplitudes.items():
|
||||
picks[station]['S']['Ao'] = amplitude.generic_amplitude
|
||||
for stats, amplitude in local_mag.amplitudes.items():
|
||||
if picks.has_key(stats):
|
||||
picks[stats]['S']['Ao'] = amplitude.generic_amplitude
|
||||
print("Local station magnitudes scaled with:")
|
||||
print("log(Ao) + %f * log(r) + %f * r + %f" % (WAscaling[0],
|
||||
print("log(Ao) + %f * log(r) + %f * r + %f" % (WAscaling[0],
|
||||
WAscaling[1],
|
||||
WAscaling[2]))
|
||||
evt = local_mag.updated_event(magscaling)
|
||||
@ -350,46 +418,57 @@ def autoPyLoT(input_dict=None, parameter=None, inputfile=None, fnames=None, even
|
||||
# write phase files for various location
|
||||
# and fault mechanism calculation routines
|
||||
# ObsPy event object
|
||||
data.applyEVTData(picks)
|
||||
if evt is not None:
|
||||
event_id = eventpath.split('/')[-1]
|
||||
evt.resource_id = ResourceIdentifier('smi:local/' + event_id)
|
||||
data.applyEVTData(evt, 'event')
|
||||
fnqml = '%s/PyLoT_%s' % (event, evID)
|
||||
data.exportEvent(fnqml, fnext='.xml', fcheck='manual')
|
||||
data.applyEVTData(picks)
|
||||
if savexml:
|
||||
if savepath == 'None' or savepath == None:
|
||||
saveEvtPath = eventpath
|
||||
else:
|
||||
saveEvtPath = savepath
|
||||
fnqml = '%s/PyLoT_%s' % (saveEvtPath, evID)
|
||||
data.exportEvent(fnqml, fnext='.xml', fcheck=['auto', 'magnitude', 'origin'])
|
||||
if locflag == 1:
|
||||
# HYPO71
|
||||
hypo71file = '%s/PyLoT_%s_HYPO71_phases' % (event, evID)
|
||||
hypo71file = '%s/PyLoT_%s_HYPO71_phases' % (eventpath, evID)
|
||||
hypo71.export(picks, hypo71file, parameter)
|
||||
# HYPOSAT
|
||||
hyposatfile = '%s/PyLoT_%s_HYPOSAT_phases' % (event, evID)
|
||||
hyposatfile = '%s/PyLoT_%s_HYPOSAT_phases' % (eventpath, evID)
|
||||
hyposat.export(picks, hyposatfile, parameter)
|
||||
# VELEST
|
||||
velestfile = '%s/PyLoT_%s_VELEST_phases.cnv' % (event, evID)
|
||||
velest.export(picks, velestfile, parameter, evt)
|
||||
# hypoDD
|
||||
hypoddfile = '%s/PyLoT_%s_hypoDD_phases.pha' % (event, evID)
|
||||
hypodd.export(picks, hypoddfile, parameter, evt)
|
||||
# FOCMEC
|
||||
focmecfile = '%s/PyLoT_%s_FOCMEC.in' % (event, evID)
|
||||
focmec.export(picks, focmecfile, parameter, evt)
|
||||
# HASH
|
||||
hashfile = '%s/PyLoT_%s_HASH' % (event, evID)
|
||||
hash.export(picks, hashfile, parameter, evt)
|
||||
# VELEST
|
||||
velestfile = '%s/PyLoT_%s_VELEST_phases.cnv' % (eventpath, evID)
|
||||
velest.export(picks, velestfile, evt, parameter)
|
||||
# hypoDD
|
||||
hypoddfile = '%s/PyLoT_%s_hypoDD_phases.pha' % (eventpath, evID)
|
||||
hypodd.export(picks, hypoddfile, parameter, evt)
|
||||
# FOCMEC
|
||||
focmecfile = '%s/PyLoT_%s_FOCMEC.in' % (eventpath, evID)
|
||||
focmec.export(picks, focmecfile, parameter, evt)
|
||||
# HASH
|
||||
hashfile = '%s/PyLoT_%s_HASH' % (eventpath, evID)
|
||||
hash.export(picks, hashfile, parameter, evt)
|
||||
|
||||
endsplash = '''------------------------------------------\n'
|
||||
-----Finished event %s!-----\n'
|
||||
------------------------------------------'''.format \
|
||||
(version=_getVersionString()) % evID
|
||||
print(endsplash)
|
||||
locflag = glocflag
|
||||
if locflag == 0:
|
||||
print("autoPyLoT was running in non-location mode!")
|
||||
|
||||
# save picks for current event ID to dictionary with ALL picks
|
||||
allpicks[evID] = picks
|
||||
|
||||
endsp = '''####################################\n
|
||||
************************************\n
|
||||
*********autoPyLoT terminates*******\n
|
||||
The Python picking and Location Tool\n
|
||||
************************************'''.format(version=_getVersionString())
|
||||
print(endsp)
|
||||
return picks
|
||||
return allpicks
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
@ -399,30 +478,28 @@ if __name__ == "__main__":
|
||||
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
|
||||
parameters for autoPyLoT''')
|
||||
parameters for autoPyLoT''')
|
||||
parser.add_argument('-p', '-P', '--iplot', type=int,
|
||||
action='store',
|
||||
help='''optional, logical variable for plotting: 0=none, 1=partial, 2=all''')
|
||||
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,
|
||||
parser.add_argument('-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('-c', '-C', '--ncores', type=int,
|
||||
action='store', default=0,
|
||||
help='''optional, number of CPU cores used for parallel processing (default: all available(=0))''')
|
||||
|
||||
cla = parser.parse_args()
|
||||
|
||||
picks = autoPyLoT(inputfile=str(cla.inputfile), fnames=str(cla.fnames),
|
||||
eventid=str(cla.eventid), savepath=str(cla.spath))
|
||||
|
||||
picks = autoPyLoT(inputfile=str(cla.inputfile), fnames=str(cla.fnames),
|
||||
eventid=str(cla.eventid), savepath=str(cla.spath),
|
||||
ncores=cla.ncores, iplot=int(cla.iplot))
|
||||
|
8
git_out
@ -1,8 +0,0 @@
|
||||
git pull
|
||||
Entferne qrc_resources.py
|
||||
KONFLIKT (ändern/löschen): pylot/core/pick/getSNR.py gelöscht in HEAD und geändert in 67dd66535a213ba5c7cfe2be52aa6d5a7e8b7324. Stand 67dd66535a213ba5c7cfe2be52aa6d5a7e8b7324 von pylot/core/pick/getSNR.py wurde im Arbeitsbereich gelassen.
|
||||
KONFLIKT (ändern/löschen): pylot/core/pick/fmpicker.py gelöscht in HEAD und geändert in 67dd66535a213ba5c7cfe2be52aa6d5a7e8b7324. Stand 67dd66535a213ba5c7cfe2be52aa6d5a7e8b7324 von pylot/core/pick/fmpicker.py wurde im Arbeitsbereich gelassen.
|
||||
KONFLIKT (ändern/löschen): pylot/core/pick/earllatepicker.py gelöscht in HEAD und geändert in 67dd66535a213ba5c7cfe2be52aa6d5a7e8b7324. Stand 67dd66535a213ba5c7cfe2be52aa6d5a7e8b7324 von pylot/core/pick/earllatepicker.py wurde im Arbeitsbereich gelassen.
|
||||
Automatisches Zusammenfügen von icons.qrc
|
||||
Automatischer Merge fehlgeschlagen; beheben Sie die Konflikte und committen Sie dann das Ergebnis.
|
||||
|
@ -1,17 +1,19 @@
|
||||
<html><head><title>PyLoT - the Python picking and Localisation Tool</title></head>
|
||||
<html>
|
||||
<head><title>PyLoT - the Python picking and Localisation Tool</title></head>
|
||||
<body>
|
||||
<p><b>PyLoT</b> is a program which is capable of picking seismic phases,
|
||||
exporting these as numerous standard phase format and localize the corresponding
|
||||
seismic event with external software as, e.g.:</p>
|
||||
exporting these as numerous standard phase format and localize the corresponding
|
||||
seismic event with external software as, e.g.:</p>
|
||||
<ul type="circle">
|
||||
<li><a href="http://alomax.free.fr/nlloc/index.html">NonLinLoc</a></li>
|
||||
<li>HypoInvers</li>
|
||||
<li>HypoSat</li>
|
||||
<li>whatever you want ...</li>
|
||||
<li><a href="http://alomax.free.fr/nlloc/index.html">NonLinLoc</a></li>
|
||||
<li>HypoInvers</li>
|
||||
<li>HypoSat</li>
|
||||
<li>whatever you want ...</li>
|
||||
</ul>
|
||||
<p>Read more on the
|
||||
<a href="https://ariadne.geophysik.rub.de/trac/PyLoT/wiki/">PyLoT WikiPage</a>.</p>
|
||||
<a href="https://ariadne.geophysik.rub.de/trac/PyLoT/wiki/">PyLoT WikiPage</a>.</p>
|
||||
<p>Bug reports are very much appreciated and can also be delivered on our
|
||||
<a href="https://ariadne.geophysik.rub.de/trac/PyLoT">PyLoT TracPage</a> after
|
||||
successful registration.</p>
|
||||
</body></html>
|
||||
<a href="https://ariadne.geophysik.rub.de/trac/PyLoT">PyLoT TracPage</a> after
|
||||
successful registration.</p>
|
||||
</body>
|
||||
</html>
|
||||
|
@ -2,6 +2,8 @@
|
||||
<qresource>
|
||||
<file>icons/pylot.ico</file>
|
||||
<file>icons/pylot.png</file>
|
||||
<file>icons/back.png</file>
|
||||
<file>icons/home.png</file>
|
||||
<file>icons/newfile.png</file>
|
||||
<file>icons/open.png</file>
|
||||
<file>icons/openproject.png</file>
|
||||
@ -23,6 +25,8 @@
|
||||
<file>icons/savepicks.png</file>
|
||||
<file>icons/preferences.png</file>
|
||||
<file>icons/parameter.png</file>
|
||||
<file>icons/inventory.png</file>
|
||||
<file>icons/map.png</file>
|
||||
<file>icons/openloc.png</file>
|
||||
<file>icons/compare_button.png</file>
|
||||
<file>icons/locate_button.png</file>
|
||||
|
Before ![]() (image error) Size: 31 KiB After ![]() (image error) Size: 26 KiB ![]() ![]() |
Before ![]() (image error) Size: 52 KiB After ![]() (image error) Size: 30 KiB ![]() ![]() |
BIN
icons/back.png
Normal file
After ![]() (image error) Size: 16 KiB |
BIN
icons/home.png
Normal file
After ![]() (image error) Size: 23 KiB |
BIN
icons/inventory.png
Normal file
After ![]() (image error) Size: 24 KiB |
Before ![]() (image error) Size: 25 KiB After ![]() (image error) Size: 22 KiB ![]() ![]() |
BIN
icons/map.png
Normal file
After ![]() (image error) Size: 56 KiB |
Before ![]() (image error) Size: 50 KiB After ![]() (image error) Size: 50 KiB ![]() ![]() |
Before ![]() (image error) Size: 63 KiB After ![]() (image error) Size: 57 KiB ![]() ![]() |
Before ![]() (image error) Size: 53 KiB After ![]() (image error) Size: 50 KiB ![]() ![]() |
Before ![]() (image error) Size: 60 KiB After ![]() (image error) Size: 52 KiB ![]() ![]() |
BIN
icons/pylot.png
Before ![]() (image error) Size: 22 KiB After ![]() (image error) Size: 39 KiB ![]() ![]() |
BIN
icons/save.png
Before ![]() (image error) Size: 19 KiB After ![]() (image error) Size: 19 KiB ![]() ![]() |
BIN
icons/saveas.png
Before ![]() (image error) Size: 25 KiB After ![]() (image error) Size: 25 KiB ![]() ![]() |
Before ![]() (image error) Size: 32 KiB After ![]() (image error) Size: 28 KiB ![]() ![]() |
Before ![]() (image error) Size: 36 KiB After ![]() (image error) Size: 35 KiB ![]() ![]() |
Before ![]() (image error) Size: 42 KiB After ![]() (image error) Size: 41 KiB ![]() ![]() |
205107
icons_rc.py → icons_rc_2.py
104841
icons_rc_3.py
Normal file
@ -1,100 +0,0 @@
|
||||
%This is a parameter input file for autoPyLoT.
|
||||
%All main and special settings regarding data handling
|
||||
%and picking are to be set here!
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
||||
#main settings#
|
||||
/DATA/Insheim #rootpath# %project path
|
||||
EVENT_DATA/LOCAL #datapath# %data path
|
||||
2013.02_Insheim #database# %name of data base
|
||||
e0019.048.13 #eventID# %certain evnt ID for processing
|
||||
True #apverbose#
|
||||
PILOT #datastructure# %choose data structure
|
||||
0 #iplot# %flag for plotting: 0 none, 1, partly, >1 everything
|
||||
AUTOPHASES_AIC_HOS4_ARH #phasefile# %name of autoPILOT output phase file
|
||||
AUTOLOC_AIC_HOS4_ARH #locfile# %name of autoPILOT output location file
|
||||
AUTOFOCMEC_AIC_HOS4_ARH.in #focmecin# %name of focmec input file containing polarities
|
||||
HYPOSAT #locrt# %location routine used ("HYPOINVERSE" or "HYPOSAT")
|
||||
6 #pmin# %minimum required P picks for location
|
||||
4 #p0min# %minimum required P picks for location if at least
|
||||
%3 excellent P picks are found
|
||||
2 #smin# %minimum required S picks for location
|
||||
/home/ludger/bin/run_HYPOSAT4autoPILOT.csh #cshellp# %path and name of c-shell script to run location routine
|
||||
7.6 8.5 #blon# %longitude bounding for location map
|
||||
49 49.4 #blat# %lattitude bounding for location map
|
||||
#parameters for moment magnitude estimation#
|
||||
5000 #vp# %average P-wave velocity
|
||||
2800 #vs# %average S-wave velocity
|
||||
2200 #rho# %rock density [kg/m^3]
|
||||
300 #Qp# %quality factor for P waves
|
||||
100 #Qs# %quality factor for S waves
|
||||
#common settings picker#
|
||||
15 #pstart# %start time [s] for calculating CF for P-picking
|
||||
40 #pstop# %end time [s] for calculating CF for P-picking
|
||||
-1.0 #sstart# %start time [s] after or before(-) P-onset for calculating CF for S-picking
|
||||
7 #sstop# %end time [s] after P-onset for calculating CF for S-picking
|
||||
2 20 #bpz1# %lower/upper corner freq. of first band pass filter Z-comp. [Hz]
|
||||
2 30 #bpz2# %lower/upper corner freq. of second band pass filter Z-comp. [Hz]
|
||||
2 15 #bph1# %lower/upper corner freq. of first band pass filter H-comp. [Hz]
|
||||
2 20 #bph2# %lower/upper corner freq. of second band pass filter z-comp. [Hz]
|
||||
#special settings for calculating CF#
|
||||
%!!Be careful when editing the following!!
|
||||
#Z-component#
|
||||
HOS #algoP# %choose algorithm for P-onset determination (HOS, ARZ, or AR3)
|
||||
7 #tlta# %for HOS-/AR-AIC-picker, length of LTA window [s]
|
||||
4 #hosorder# %for HOS-picker, order of Higher Order Statistics
|
||||
2 #Parorder# %for AR-picker, order of AR process of Z-component
|
||||
1.2 #tdet1z# %for AR-picker, length of AR determination window [s] for Z-component, 1st pick
|
||||
0.4 #tpred1z# %for AR-picker, length of AR prediction window [s] for Z-component, 1st pick
|
||||
0.6 #tdet2z# %for AR-picker, length of AR determination window [s] for Z-component, 2nd pick
|
||||
0.2 #tpred2z# %for AR-picker, length of AR prediction window [s] for Z-component, 2nd pick
|
||||
0.001 #addnoise# %add noise to seismogram for stable AR prediction
|
||||
3 0.1 0.5 0.1 #tsnrz# %for HOS/AR, window lengths for SNR-and slope estimation [tnoise,tsafetey,tsignal,tslope] [s]
|
||||
3 #pickwinP# %for initial AIC pick, length of P-pick window [s]
|
||||
8 #Precalcwin# %for HOS/AR, window length [s] for recalculation of CF (relative to 1st pick)
|
||||
0 #peps4aic# %for HOS/AR, artificial uplift of samples of AIC-function (P)
|
||||
0.2 #aictsmooth# %for HOS/AR, take average of samples for smoothing of AIC-function [s]
|
||||
0.1 #tsmoothP# %for HOS/AR, take average of samples for smoothing CF [s]
|
||||
0.001 #ausP# %for HOS/AR, artificial uplift of samples (aus) of CF (P)
|
||||
1.3 #nfacP# %for HOS/AR, noise factor for noise level determination (P)
|
||||
#H-components#
|
||||
ARH #algoS# %choose algorithm for S-onset determination (ARH or AR3)
|
||||
0.8 #tdet1h# %for HOS/AR, length of AR-determination window [s], H-components, 1st pick
|
||||
0.4 #tpred1h# %for HOS/AR, length of AR-prediction window [s], H-components, 1st pick
|
||||
0.6 #tdet2h# %for HOS/AR, length of AR-determinaton window [s], H-components, 2nd pick
|
||||
0.3 #tpred2h# %for HOS/AR, length of AR-prediction window [s], H-components, 2nd pick
|
||||
4 #Sarorder# %for AR-picker, order of AR process of H-components
|
||||
6 #Srecalcwin# %for AR-picker, window length [s] for recalculation of CF (2nd pick) (H)
|
||||
3 #pickwinS# %for initial AIC pick, length of S-pick window [s]
|
||||
2 0.2 1.5 0.5 #tsnrh# %for ARH/AR3, window lengths for SNR-and slope estimation [tnoise,tsafetey,tsignal,tslope] [s]
|
||||
0.05 #aictsmoothS# %for AIC-picker, take average of samples for smoothing of AIC-function [s]
|
||||
0.02 #tsmoothS# %for AR-picker, take average of samples for smoothing CF [s] (S)
|
||||
0.2 #pepsS# %for AR-picker, artificial uplift of samples of CF (S)
|
||||
0.4 #ausS# %for HOS/AR, artificial uplift of samples (aus) of CF (S)
|
||||
1.5 #nfacS# %for AR-picker, noise factor for noise level determination (S)
|
||||
%first-motion picker%
|
||||
1 #minfmweight# %minimum required p weight for first-motion determination
|
||||
2 #minFMSNR# %miniumum required SNR for first-motion determination
|
||||
0.2 #fmpickwin# %pick window around P onset for calculating zero crossings
|
||||
%quality assessment%
|
||||
#inital AIC onset#
|
||||
0.01 0.02 0.04 0.08 #timeerrorsP# %discrete time errors [s] corresponding to picking weights [0 1 2 3] for P
|
||||
0.04 0.08 0.16 0.32 #timeerrorsS# %discrete time errors [s] corresponding to picking weights [0 1 2 3] for S
|
||||
80 #minAICPslope# %below this slope [counts/s] the initial P pick is rejected
|
||||
1.2 #minAICPSNR# %below this SNR the initial P pick is rejected
|
||||
50 #minAICSslope# %below this slope [counts/s] the initial S pick is rejected
|
||||
1.5 #minAICSSNR# %below this SNR the initial S pick is rejected
|
||||
#check duration of signal using envelope function#
|
||||
1.5 #prepickwin# %pre-signal window length [s] for noise level estimation
|
||||
0.7 #minsiglength# %minimum required length of signal [s]
|
||||
0.2 #sgap# %safety gap between noise and signal window [s]
|
||||
2 #noisefactor# %noiselevel*noisefactor=threshold
|
||||
60 #minpercent# %per cent of samples required higher than threshold
|
||||
#check for spuriously picked S-onsets#
|
||||
3.0 #zfac# %P-amplitude must exceed zfac times RMS-S amplitude
|
||||
#jackknife-processing for P-picks#
|
||||
3 #thresholdweight#%minimum required weight of picks
|
||||
3 #dttolerance# %maximum allowed deviation of P picks from median [s]
|
||||
4 #minstats# %minimum number of stations with reliable P picks
|
||||
3 #Sdttolerance# %maximum allowed deviation from Wadati-diagram
|
||||
|
@ -1,99 +0,0 @@
|
||||
%This is a parameter input file for autoPyLoT.
|
||||
%All main and special settings regarding data handling
|
||||
%and picking are to be set here!
|
||||
%Parameters are optimized for local data sets!
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
#main settings#
|
||||
/DATA/Insheim #rootpath# %project path
|
||||
EVENT_DATA/LOCAL #datapath# %data path
|
||||
2016.08_Insheim #database# %name of data base
|
||||
e0007.224.16 #eventID# %event ID for single event processing
|
||||
/DATA/Insheim/STAT_INFO #invdir# %full path to inventory or dataless-seed file
|
||||
PILOT #datastructure#%choose data structure
|
||||
0 #iplot# %flag for plotting: 0 none, 1 partly, >1 everything
|
||||
True #apverbose# %choose 'True' or 'False' for terminal output
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
#NLLoc settings#
|
||||
/home/ludger/NLLOC #nllocbin# %path to NLLoc executable
|
||||
/home/ludger/NLLOC/Insheim #nllocroot# %root of NLLoc-processing directory
|
||||
AUTOPHASES.obs #phasefile# %name of autoPyLoT-output phase file for NLLoc
|
||||
%(in nllocroot/obs)
|
||||
Insheim_min1d032016_auto.in #ctrfile# %name of autoPyLoT-output control file for NLLoc
|
||||
%(in nllocroot/run)
|
||||
ttime #ttpatter# %pattern of NLLoc ttimes from grid
|
||||
%(in nllocroot/times)
|
||||
AUTOLOC_nlloc #outpatter# %pattern of NLLoc-output file
|
||||
%(returns 'eventID_outpatter')
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
#parameters for seismic moment estimation#
|
||||
3530 #vp# %average P-wave velocity
|
||||
2500 #rho# %average rock density [kg/m^3]
|
||||
300 0.8 #Qp# %quality factor for P waves ([Qp, ap], Qp*f^a)
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
AUTOFOCMEC_AIC_HOS4_ARH.in #focmecin# %name of focmec input file containing derived polarities
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
#common settings picker#
|
||||
15.0 #pstart# %start time [s] for calculating CF for P-picking
|
||||
60.0 #pstop# %end time [s] for calculating CF for P-picking
|
||||
-1.0 #sstart# %start time [s] relative to P-onset for calculating CF for S-picking
|
||||
10.0 #sstop# %end time [s] after P-onset for calculating CF for S-picking
|
||||
2 20 #bpz1# %lower/upper corner freq. of first band pass filter Z-comp. [Hz]
|
||||
2 30 #bpz2# %lower/upper corner freq. of second band pass filter Z-comp. [Hz]
|
||||
2 15 #bph1# %lower/upper corner freq. of first band pass filter H-comp. [Hz]
|
||||
2 20 #bph2# %lower/upper corner freq. of second band pass filter z-comp. [Hz]
|
||||
#special settings for calculating CF#
|
||||
%!!Edit the following only if you know what you are doing!!%
|
||||
#Z-component#
|
||||
HOS #algoP# %choose algorithm for P-onset determination (HOS, ARZ, or AR3)
|
||||
7.0 #tlta# %for HOS-/AR-AIC-picker, length of LTA window [s]
|
||||
4 #hosorder# %for HOS-picker, order of Higher Order Statistics
|
||||
2 #Parorder# %for AR-picker, order of AR process of Z-component
|
||||
1.2 #tdet1z# %for AR-picker, length of AR determination window [s] for Z-component, 1st pick
|
||||
0.4 #tpred1z# %for AR-picker, length of AR prediction window [s] for Z-component, 1st pick
|
||||
0.6 #tdet2z# %for AR-picker, length of AR determination window [s] for Z-component, 2nd pick
|
||||
0.2 #tpred2z# %for AR-picker, length of AR prediction window [s] for Z-component, 2nd pick
|
||||
0.001 #addnoise# %add noise to seismogram for stable AR prediction
|
||||
3 0.1 0.5 0.5 #tsnrz# %for HOS/AR, window lengths for SNR-and slope estimation [tnoise,tsafetey,tsignal,tslope] [s]
|
||||
3.0 #pickwinP# %for initial AIC pick, length of P-pick window [s]
|
||||
6.0 #Precalcwin# %for HOS/AR, window length [s] for recalculation of CF (relative to 1st pick)
|
||||
0.2 #aictsmooth# %for HOS/AR, take average of samples for smoothing of AIC-function [s]
|
||||
0.1 #tsmoothP# %for HOS/AR, take average of samples for smoothing CF [s]
|
||||
0.001 #ausP# %for HOS/AR, artificial uplift of samples (aus) of CF (P)
|
||||
1.3 #nfacP# %for HOS/AR, noise factor for noise level determination (P)
|
||||
#H-components#
|
||||
ARH #algoS# %choose algorithm for S-onset determination (ARH or AR3)
|
||||
0.8 #tdet1h# %for HOS/AR, length of AR-determination window [s], H-components, 1st pick
|
||||
0.4 #tpred1h# %for HOS/AR, length of AR-prediction window [s], H-components, 1st pick
|
||||
0.6 #tdet2h# %for HOS/AR, length of AR-determinaton window [s], H-components, 2nd pick
|
||||
0.3 #tpred2h# %for HOS/AR, length of AR-prediction window [s], H-components, 2nd pick
|
||||
4 #Sarorder# %for AR-picker, order of AR process of H-components
|
||||
5.0 #Srecalcwin# %for AR-picker, window length [s] for recalculation of CF (2nd pick) (H)
|
||||
3.0 #pickwinS# %for initial AIC pick, length of S-pick window [s]
|
||||
2 0.2 1.5 0.5 #tsnrh# %for ARH/AR3, window lengths for SNR-and slope estimation [tnoise,tsafetey,tsignal,tslope] [s]
|
||||
0.5 #aictsmoothS# %for AIC-picker, take average of samples for smoothing of AIC-function [s]
|
||||
0.7 #tsmoothS# %for AR-picker, take average of samples for smoothing CF [s] (S)
|
||||
0.9 #ausS# %for HOS/AR, artificial uplift of samples (aus) of CF (S)
|
||||
1.5 #nfacS# %for AR-picker, noise factor for noise level determination (S)
|
||||
%first-motion picker%
|
||||
1 #minfmweight# %minimum required P weight for first-motion determination
|
||||
2 #minFMSNR# %miniumum required SNR for first-motion determination
|
||||
0.2 #fmpickwin# %pick window around P onset for calculating zero crossings
|
||||
%quality assessment%
|
||||
#inital AIC onset#
|
||||
0.01 0.02 0.04 0.08 #timeerrorsP# %discrete time errors [s] corresponding to picking weights [0 1 2 3] for P
|
||||
0.04 0.08 0.16 0.32 #timeerrorsS# %discrete time errors [s] corresponding to picking weights [0 1 2 3] for S
|
||||
4 #minAICPslope# %below this slope [counts/s] the initial P pick is rejected
|
||||
1.2 #minAICPSNR# %below this SNR the initial P pick is rejected
|
||||
2 #minAICSslope# %below this slope [counts/s] the initial S pick is rejected
|
||||
1.5 #minAICSSNR# %below this SNR the initial S pick is rejected
|
||||
#check duration of signal using envelope function#
|
||||
3 #minsiglength# %minimum required length of signal [s]
|
||||
1.0 #noisefactor# %noiselevel*noisefactor=threshold
|
||||
40 #minpercent# %required percentage of samples higher than threshold
|
||||
#check for spuriously picked S-onsets#
|
||||
2.0 #zfac# %P-amplitude must exceed at least zfac times RMS-S amplitude
|
||||
#check statistics of P onsets#
|
||||
2.5 #mdttolerance# %maximum allowed deviation of P picks from median [s]
|
||||
#wadati check#
|
||||
1.0 #wdttolerance# %maximum allowed deviation from Wadati-diagram
|
||||
|
@ -1,100 +0,0 @@
|
||||
%This is a parameter input file for autoPyLoT.
|
||||
%All main and special settings regarding data handling
|
||||
%and picking are to be set here!
|
||||
%Parameters are optimized for regional data sets!
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
|
||||
#main settings#
|
||||
/DATA/Egelados #rootpath# %project path
|
||||
EVENT_DATA/LOCAL #datapath# %data path
|
||||
2006.01_Nisyros #database# %name of data base
|
||||
e1412.008.06 #eventID# %event ID for single event processing
|
||||
/DATA/Egelados/STAT_INFO #invdir# %full path to inventory or dataless-seed file
|
||||
PILOT #datastructure# %choose data structure
|
||||
0 #iplot# %flag for plotting: 0 none, 1, partly, >1 everything
|
||||
True #apverbose# %choose 'True' or 'False' for terminal output
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
#NLLoc settings#
|
||||
/home/ludger/NLLOC #nllocbin# %path to NLLoc executable
|
||||
/home/ludger/NLLOC/Insheim #nllocroot# %root of NLLoc-processing directory
|
||||
AUTOPHASES.obs #phasefile# %name of autoPyLoT-output phase file for NLLoc
|
||||
%(in nllocroot/obs)
|
||||
Insheim_min1d2015_auto.in #ctrfile# %name of autoPyLoT-output control file for NLLoc
|
||||
%(in nllocroot/run)
|
||||
ttime #ttpatter# %pattern of NLLoc ttimes from grid
|
||||
%(in nllocroot/times)
|
||||
AUTOLOC_nlloc #outpatter# %pattern of NLLoc-output file
|
||||
%(returns 'eventID_outpatter')
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
#parameters for seismic moment estimation#
|
||||
3530 #vp# %average P-wave velocity
|
||||
2700 #rho# %average rock density [kg/m^3]
|
||||
1000f**0.8 #Qp# %quality factor for P waves (Qp*f^a)
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
AUTOFOCMEC_AIC_HOS4_ARH.in #focmecin# %name of focmec input file containing derived polarities
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
#common settings picker#
|
||||
20 #pstart# %start time [s] for calculating CF for P-picking
|
||||
100 #pstop# %end time [s] for calculating CF for P-picking
|
||||
1.0 #sstart# %start time [s] after or before(-) P-onset for calculating CF for S-picking
|
||||
100 #sstop# %end time [s] after P-onset for calculating CF for S-picking
|
||||
3 10 #bpz1# %lower/upper corner freq. of first band pass filter Z-comp. [Hz]
|
||||
3 12 #bpz2# %lower/upper corner freq. of second band pass filter Z-comp. [Hz]
|
||||
3 8 #bph1# %lower/upper corner freq. of first band pass filter H-comp. [Hz]
|
||||
3 6 #bph2# %lower/upper corner freq. of second band pass filter H-comp. [Hz]
|
||||
#special settings for calculating CF#
|
||||
%!!Be careful when editing the following!!
|
||||
#Z-component#
|
||||
HOS #algoP# %choose algorithm for P-onset determination (HOS, ARZ, or AR3)
|
||||
7 #tlta# %for HOS-/AR-AIC-picker, length of LTA window [s]
|
||||
4 #hosorder# %for HOS-picker, order of Higher Order Statistics
|
||||
2 #Parorder# %for AR-picker, order of AR process of Z-component
|
||||
1.2 #tdet1z# %for AR-picker, length of AR determination window [s] for Z-component, 1st pick
|
||||
0.4 #tpred1z# %for AR-picker, length of AR prediction window [s] for Z-component, 1st pick
|
||||
0.6 #tdet2z# %for AR-picker, length of AR determination window [s] for Z-component, 2nd pick
|
||||
0.2 #tpred2z# %for AR-picker, length of AR prediction window [s] for Z-component, 2nd pick
|
||||
0.001 #addnoise# %add noise to seismogram for stable AR prediction
|
||||
5 0.2 3.0 1.5 #tsnrz# %for HOS/AR, window lengths for SNR-and slope estimation [tnoise,tsafetey,tsignal,tslope] [s]
|
||||
3 #pickwinP# %for initial AIC and refined pick, length of P-pick window [s]
|
||||
8 #Precalcwin# %for HOS/AR, window length [s] for recalculation of CF (relative to 1st pick)
|
||||
1.0 #aictsmooth# %for HOS/AR, take average of samples for smoothing of AIC-function [s]
|
||||
0.3 #tsmoothP# %for HOS/AR, take average of samples for smoothing CF [s]
|
||||
0.3 #ausP# %for HOS/AR, artificial uplift of samples (aus) of CF (P)
|
||||
1.3 #nfacP# %for HOS/AR, noise factor for noise level determination (P)
|
||||
#H-components#
|
||||
ARH #algoS# %choose algorithm for S-onset determination (ARH or AR3)
|
||||
0.8 #tdet1h# %for HOS/AR, length of AR-determination window [s], H-components, 1st pick
|
||||
0.4 #tpred1h# %for HOS/AR, length of AR-prediction window [s], H-components, 1st pick
|
||||
0.6 #tdet2h# %for HOS/AR, length of AR-determinaton window [s], H-components, 2nd pick
|
||||
0.3 #tpred2h# %for HOS/AR, length of AR-prediction window [s], H-components, 2nd pick
|
||||
4 #Sarorder# %for AR-picker, order of AR process of H-components
|
||||
10 #Srecalcwin# %for AR-picker, window length [s] for recalculation of CF (2nd pick) (H)
|
||||
25 #pickwinS# %for initial AIC and refined pick, length of S-pick window [s]
|
||||
5 0.2 3.0 3.0 #tsnrh# %for ARH/AR3, window lengths for SNR-and slope estimation [tnoise,tsafetey,tsignal,tslope] [s]
|
||||
3.5 #aictsmoothS# %for AIC-picker, take average of samples for smoothing of AIC-function [s]
|
||||
1.0 #tsmoothS# %for AR-picker, take average of samples for smoothing CF [s] (S)
|
||||
0.2 #ausS# %for HOS/AR, artificial uplift of samples (aus) of CF (S)
|
||||
1.5 #nfacS# %for AR-picker, noise factor for noise level determination (S)
|
||||
%first-motion picker%
|
||||
1 #minfmweight# %minimum required p weight for first-motion determination
|
||||
2 #minFMSNR# %miniumum required SNR for first-motion determination
|
||||
6.0 #fmpickwin# %pick window around P onset for calculating zero crossings
|
||||
%quality assessment%
|
||||
#inital AIC onset#
|
||||
0.04 0.08 0.16 0.32 #timeerrorsP# %discrete time errors [s] corresponding to picking weights [0 1 2 3] for P
|
||||
0.04 0.08 0.16 0.32 #timeerrorsS# %discrete time errors [s] corresponding to picking weights [0 1 2 3] for S
|
||||
3 #minAICPslope# %below this slope [counts/s] the initial P pick is rejected
|
||||
1.2 #minAICPSNR# %below this SNR the initial P pick is rejected
|
||||
5 #minAICSslope# %below this slope [counts/s] the initial S pick is rejected
|
||||
2.5 #minAICSSNR# %below this SNR the initial S pick is rejected
|
||||
#check duration of signal using envelope function#
|
||||
30 #minsiglength# %minimum required length of signal [s]
|
||||
2.5 #noisefactor# %noiselevel*noisefactor=threshold
|
||||
60 #minpercent# %required percentage of samples higher than threshold
|
||||
#check for spuriously picked S-onsets#
|
||||
0.5 #zfac# %P-amplitude must exceed at least zfac times RMS-S amplitude
|
||||
#check statistics of P onsets#
|
||||
45 #mdttolerance# %maximum allowed deviation of P picks from median [s]
|
||||
#wadati check#
|
||||
3.0 #wdttolerance# %maximum allowed deviation from Wadati-diagram
|
||||
|
@ -1,2 +0,0 @@
|
||||
P bandpass 4 2.0 20.0
|
||||
S bandpass 4 2.0 15.0
|
@ -1,98 +0,0 @@
|
||||
%This is a example parameter input file for PyLoT.
|
||||
%All main and special settings regarding data handling
|
||||
%and picking are to be set here!
|
||||
%Parameters shown here are optimized for local data sets!
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
#main settings#
|
||||
/data/Geothermie/Insheim #rootpath# %project path
|
||||
EVENT_DATA/LOCAL #datapath# %data path
|
||||
2013.02_Insheim #database# %name of data base
|
||||
e0019.048.13 #eventID# %event ID for single event processing
|
||||
/data/Geothermie/Insheim/STAT_INFO #invdir# %full path to inventory or dataless-seed file
|
||||
PILOT #datastructure# %choose data structure
|
||||
0 #iplot# %flag for plotting: 0 none, 1 partly, >1 everything
|
||||
True #apverbose# %choose 'True' or 'False' for terminal output
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
#NLLoc settings#
|
||||
/progs/bin #nllocbin# %path to NLLoc executable
|
||||
/data/Geothermie/Insheim/LOCALISATION/NLLoc #nllocroot# %root of NLLoc-processing directory
|
||||
AUTOPHASES.obs #phasefile# %name of autoPyLoT-output phase file for NLLoc
|
||||
%(in nllocroot/obs)
|
||||
Insheim_min1d2015.in #ctrfile# %name of PyLoT-output control file for NLLoc
|
||||
%(in nllocroot/run)
|
||||
ttime #ttpatter# %pattern of NLLoc ttimes from grid
|
||||
%(in nllocroot/times)
|
||||
AUTOLOC_nlloc #outpatter# %pattern of NLLoc-output file
|
||||
%(returns 'eventID_outpatter')
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
#parameters for seismic moment estimation#
|
||||
3530 #vp# %average P-wave velocity
|
||||
2500 #rho# %average rock density [kg/m^3]
|
||||
300 0.8 #Qp# %quality factor for P waves (Qp*f^a); list(Qp, a)
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
AUTOFOCMEC_AIC_HOS4_ARH.in #focmecin# %name of focmec input file containing derived polarities
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
#common settings picker#
|
||||
15.0 #pstart# %start time [s] for calculating CF for P-picking
|
||||
60.0 #pstop# %end time [s] for calculating CF for P-picking
|
||||
-1.0 #sstart# %start time [s] relative to P-onset for calculating CF for S-picking
|
||||
10.0 #sstop# %end time [s] after P-onset for calculating CF for S-picking
|
||||
2 20 #bpz1# %lower/upper corner freq. of first band pass filter Z-comp. [Hz]
|
||||
2 30 #bpz2# %lower/upper corner freq. of second band pass filter Z-comp. [Hz]
|
||||
2 15 #bph1# %lower/upper corner freq. of first band pass filter H-comp. [Hz]
|
||||
2 20 #bph2# %lower/upper corner freq. of second band pass filter z-comp. [Hz]
|
||||
#special settings for calculating CF#
|
||||
%!!Edit the following only if you know what you are doing!!%
|
||||
#Z-component#
|
||||
HOS #algoP# %choose algorithm for P-onset determination (HOS, ARZ, or AR3)
|
||||
7.0 #tlta# %for HOS-/AR-AIC-picker, length of LTA window [s]
|
||||
4 #hosorder# %for HOS-picker, order of Higher Order Statistics
|
||||
2 #Parorder# %for AR-picker, order of AR process of Z-component
|
||||
1.2 #tdet1z# %for AR-picker, length of AR determination window [s] for Z-component, 1st pick
|
||||
0.4 #tpred1z# %for AR-picker, length of AR prediction window [s] for Z-component, 1st pick
|
||||
0.6 #tdet2z# %for AR-picker, length of AR determination window [s] for Z-component, 2nd pick
|
||||
0.2 #tpred2z# %for AR-picker, length of AR prediction window [s] for Z-component, 2nd pick
|
||||
0.001 #addnoise# %add noise to seismogram for stable AR prediction
|
||||
3 0.1 0.5 0.5 #tsnrz# %for HOS/AR, window lengths for SNR-and slope estimation [tnoise,tsafetey,tsignal,tslope] [s]
|
||||
3.0 #pickwinP# %for initial AIC pick, length of P-pick window [s]
|
||||
6.0 #Precalcwin# %for HOS/AR, window length [s] for recalculation of CF (relative to 1st pick)
|
||||
0.2 #aictsmooth# %for HOS/AR, take average of samples for smoothing of AIC-function [s]
|
||||
0.1 #tsmoothP# %for HOS/AR, take average of samples for smoothing CF [s]
|
||||
0.001 #ausP# %for HOS/AR, artificial uplift of samples (aus) of CF (P)
|
||||
1.3 #nfacP# %for HOS/AR, noise factor for noise level determination (P)
|
||||
#H-components#
|
||||
ARH #algoS# %choose algorithm for S-onset determination (ARH or AR3)
|
||||
0.8 #tdet1h# %for HOS/AR, length of AR-determination window [s], H-components, 1st pick
|
||||
0.4 #tpred1h# %for HOS/AR, length of AR-prediction window [s], H-components, 1st pick
|
||||
0.6 #tdet2h# %for HOS/AR, length of AR-determinaton window [s], H-components, 2nd pick
|
||||
0.3 #tpred2h# %for HOS/AR, length of AR-prediction window [s], H-components, 2nd pick
|
||||
4 #Sarorder# %for AR-picker, order of AR process of H-components
|
||||
5.0 #Srecalcwin# %for AR-picker, window length [s] for recalculation of CF (2nd pick) (H)
|
||||
3.0 #pickwinS# %for initial AIC pick, length of S-pick window [s]
|
||||
2 0.2 1.5 0.5 #tsnrh# %for ARH/AR3, window lengths for SNR-and slope estimation [tnoise,tsafetey,tsignal,tslope] [s]
|
||||
0.5 #aictsmoothS# %for AIC-picker, take average of samples for smoothing of AIC-function [s]
|
||||
0.7 #tsmoothS# %for AR-picker, take average of samples for smoothing CF [s] (S)
|
||||
0.9 #ausS# %for HOS/AR, artificial uplift of samples (aus) of CF (S)
|
||||
1.5 #nfacS# %for AR-picker, noise factor for noise level determination (S)
|
||||
%first-motion picker%
|
||||
1 #minfmweight# %minimum required P weight for first-motion determination
|
||||
2 #minFMSNR# %miniumum required SNR for first-motion determination
|
||||
0.2 #fmpickwin# %pick window around P onset for calculating zero crossings
|
||||
%quality assessment%
|
||||
#inital AIC onset#
|
||||
0.01 0.02 0.04 0.08 #timeerrorsP# %discrete time errors [s] corresponding to picking weights [0 1 2 3] for P
|
||||
0.04 0.08 0.16 0.32 #timeerrorsS# %discrete time errors [s] corresponding to picking weights [0 1 2 3] for S
|
||||
4 #minAICPslope# %below this slope [counts/s] the initial P pick is rejected
|
||||
1.2 #minAICPSNR# %below this SNR the initial P pick is rejected
|
||||
2 #minAICSslope# %below this slope [counts/s] the initial S pick is rejected
|
||||
1.5 #minAICSSNR# %below this SNR the initial S pick is rejected
|
||||
#check duration of signal using envelope function#
|
||||
3 #minsiglength# %minimum required length of signal [s]
|
||||
1.0 #noisefactor# %noiselevel*noisefactor=threshold
|
||||
40 #minpercent# %required percentage of samples higher than threshold
|
||||
#check for spuriously picked S-onsets#
|
||||
2.0 #zfac# %P-amplitude must exceed at least zfac times RMS-S amplitude
|
||||
#check statistics of P onsets#
|
||||
2.5 #mdttolerance# %maximum allowed deviation of P picks from median [s]
|
||||
#wadati check#
|
||||
1.0 #wdttolerance# %maximum allowed deviation from Wadati-diagram
|
100
inputs/pylot_global.in
Normal file
@ -0,0 +1,100 @@
|
||||
%This is a parameter input file for PyLoT/autoPyLoT.
|
||||
%All main and special settings regarding data handling
|
||||
%and picking are to be set here!
|
||||
%Parameters are optimized for %extent data sets!
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
#main settings#
|
||||
#rootpath# %project path
|
||||
#datapath# %data path
|
||||
#database# %name of data base
|
||||
#eventID# %event ID for single event processing (* for all events found in database)
|
||||
#invdir# %full path to inventory or dataless-seed file
|
||||
PILOT #datastructure# %choose data structure
|
||||
True #apverbose# %choose 'True' or 'False' for terminal output
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
#NLLoc settings#
|
||||
None #nllocbin# %path to NLLoc executable
|
||||
None #nllocroot# %root of NLLoc-processing directory
|
||||
None #phasefile# %name of autoPyLoT-output phase file for NLLoc
|
||||
None #ctrfile# %name of autoPyLoT-output control file for NLLoc
|
||||
ttime #ttpatter# %pattern of NLLoc ttimes from grid
|
||||
AUTOLOC_nlloc #outpatter# %pattern of NLLoc-output file
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
#parameters for seismic moment estimation#
|
||||
3530.0 #vp# %average P-wave velocity
|
||||
2500.0 #rho# %average rock density [kg/m^3]
|
||||
300.0 0.8 #Qp# %quality factor for P waves (Qp*f^a); list(Qp, a)
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
#settings local magnitude#
|
||||
1.0 1.0 1.0 #WAscaling# %Scaling relation (log(Ao)+Alog(r)+Br+C) of Wood-Anderson amplitude Ao [nm] If zeros are set, original Richter magnitude is calculated!
|
||||
1.0 1.0 #magscaling# %Scaling relation for derived local magnitude [a*Ml+b]. If zeros are set, no scaling of network magnitude is applied!
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
#filter settings#
|
||||
0.01 0.01 #minfreq# %Lower filter frequency [P, S]
|
||||
0.3 0.3 #maxfreq# %Upper filter frequency [P, S]
|
||||
3 3 #filter_order# %filter order [P, S]
|
||||
bandpass bandpass #filter_type# %filter type (bandpass, bandstop, lowpass, highpass) [P, S]
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
#common settings picker#
|
||||
global #extent# %extent of array ("local", "regional" or "global")
|
||||
-150.0 #pstart# %start time [s] for calculating CF for P-picking (if TauPy: seconds relative to estimated onset)
|
||||
600.0 #pstop# %end time [s] for calculating CF for P-picking (if TauPy: seconds relative to estimated onset)
|
||||
200.0 #sstart# %start time [s] relative to P-onset for calculating CF for S-picking
|
||||
1150.0 #sstop# %end time [s] after P-onset for calculating CF for S-picking
|
||||
True #use_taup# %use estimated traveltimes from TauPy for calculating windows for CF
|
||||
iasp91 #taup_model# %define TauPy model for traveltime estimation. Possible values: 1066a, 1066b, ak135, ak135f, herrin, iasp91, jb, prem, pwdk, sp6
|
||||
0.05 0.5 #bpz1# %lower/upper corner freq. of first band pass filter Z-comp. [Hz]
|
||||
0.001 0.5 #bpz2# %lower/upper corner freq. of second band pass filter Z-comp. [Hz]
|
||||
0.05 0.5 #bph1# %lower/upper corner freq. of first band pass filter H-comp. [Hz]
|
||||
0.001 0.5 #bph2# %lower/upper corner freq. of second band pass filter z-comp. [Hz]
|
||||
#special settings for calculating CF#
|
||||
%!!Edit the following only if you know what you are doing!!%
|
||||
#Z-component#
|
||||
HOS #algoP# %choose algorithm for P-onset determination (HOS, ARZ, or AR3)
|
||||
150.0 #tlta# %for HOS-/AR-AIC-picker, length of LTA window [s]
|
||||
4 #hosorder# %for HOS-picker, order of Higher Order Statistics
|
||||
2 #Parorder# %for AR-picker, order of AR process of Z-component
|
||||
16.0 #tdet1z# %for AR-picker, length of AR determination window [s] for Z-component, 1st pick
|
||||
10.0 #tpred1z# %for AR-picker, length of AR prediction window [s] for Z-component, 1st pick
|
||||
12.0 #tdet2z# %for AR-picker, length of AR determination window [s] for Z-component, 2nd pick
|
||||
6.0 #tpred2z# %for AR-picker, length of AR prediction window [s] for Z-component, 2nd pick
|
||||
0.001 #addnoise# %add noise to seismogram for stable AR prediction
|
||||
60.0 10.0 40.0 10.0 #tsnrz# %for HOS/AR, window lengths for SNR-and slope estimation [tnoise, tsafetey, tsignal, tslope] [s]
|
||||
150.0 #pickwinP# %for initial AIC pick, length of P-pick window [s]
|
||||
35.0 #Precalcwin# %for HOS/AR, window length [s] for recalculation of CF (relative to 1st pick)
|
||||
6.0 #aictsmooth# %for HOS/AR, take average of samples for smoothing of AIC-function [s]
|
||||
4.0 #tsmoothP# %for HOS/AR, take average of samples for smoothing CF [s]
|
||||
0.001 #ausP# %for HOS/AR, artificial uplift of samples (aus) of CF (P)
|
||||
1.1 #nfacP# %for HOS/AR, noise factor for noise level determination (P)
|
||||
#H-components#
|
||||
ARH #algoS# %choose algorithm for S-onset determination (ARH or AR3)
|
||||
12.0 #tdet1h# %for HOS/AR, length of AR-determination window [s], H-components, 1st pick
|
||||
6.0 #tpred1h# %for HOS/AR, length of AR-prediction window [s], H-components, 1st pick
|
||||
8.0 #tdet2h# %for HOS/AR, length of AR-determinaton window [s], H-components, 2nd pick
|
||||
4.0 #tpred2h# %for HOS/AR, length of AR-prediction window [s], H-components, 2nd pick
|
||||
4 #Sarorder# %for AR-picker, order of AR process of H-components
|
||||
30.0 #Srecalcwin# %for AR-picker, window length [s] for recalculation of CF (2nd pick) (H)
|
||||
195.0 #pickwinS# %for initial AIC pick, length of S-pick window [s]
|
||||
100.0 10.0 45.0 10.0 #tsnrh# %for ARH/AR3, window lengths for SNR-and slope estimation [tnoise, tsafetey, tsignal, tslope] [s]
|
||||
22.0 #aictsmoothS# %for AIC-picker, take average of samples for smoothing of AIC-function [s]
|
||||
10.0 #tsmoothS# %for AR-picker, take average of samples for smoothing CF [s] (S)
|
||||
0.001 #ausS# %for HOS/AR, artificial uplift of samples (aus) of CF (S)
|
||||
1.2 #nfacS# %for AR-picker, noise factor for noise level determination (S)
|
||||
#first-motion picker#
|
||||
1 #minfmweight# %minimum required P weight for first-motion determination
|
||||
3.0 #minFMSNR# %miniumum required SNR for first-motion determination
|
||||
10.0 #fmpickwin# %pick window around P onset for calculating zero crossings
|
||||
#quality assessment#
|
||||
1.0 2.0 4.0 8.0 #timeerrorsP# %discrete time errors [s] corresponding to picking weights [0 1 2 3] for P
|
||||
4.0 8.0 16.0 32.0 #timeerrorsS# %discrete time errors [s] corresponding to picking weights [0 1 2 3] for S
|
||||
0.5 #minAICPslope# %below this slope [counts/s] the initial P pick is rejected
|
||||
1.1 #minAICPSNR# %below this SNR the initial P pick is rejected
|
||||
1.0 #minAICSslope# %below this slope [counts/s] the initial S pick is rejected
|
||||
1.3 #minAICSSNR# %below this SNR the initial S pick is rejected
|
||||
5.0 #minsiglength# %length of signal part for which amplitudes must exceed noiselevel [s]
|
||||
1.0 #noisefactor# %noiselevel*noisefactor=threshold
|
||||
10.0 #minpercent# %required percentage of amplitudes exceeding threshold
|
||||
1.2 #zfac# %P-amplitude must exceed at least zfac times RMS-S amplitude
|
||||
25.0 #mdttolerance# %maximum allowed deviation of P picks from median [s]
|
||||
50.0 #wdttolerance# %maximum allowed deviation from Wadati-diagram
|
||||
5.0 #jackfactor# %pick is removed if the variance of the subgroup with the pick removed is larger than the mean variance of all subgroups times safety factor
|
100
inputs/pylot_local.in
Normal file
@ -0,0 +1,100 @@
|
||||
%This is a parameter input file for PyLoT/autoPyLoT.
|
||||
%All main and special settings regarding data handling
|
||||
%and picking are to be set here!
|
||||
%Parameters are optimized for %extent data sets!
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
#main settings#
|
||||
#rootpath# %project path
|
||||
#datapath# %data path
|
||||
#database# %name of data base
|
||||
#eventID# %event ID for single event processing (* for all events found in database)
|
||||
#invdir# %full path to inventory or dataless-seed file
|
||||
PILOT #datastructure# %choose data structure
|
||||
True #apverbose# %choose 'True' or 'False' for terminal output
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
#NLLoc settings#
|
||||
None #nllocbin# %path to NLLoc executable
|
||||
None #nllocroot# %root of NLLoc-processing directory
|
||||
None #phasefile# %name of autoPyLoT-output phase file for NLLoc
|
||||
None #ctrfile# %name of autoPyLoT-output control file for NLLoc
|
||||
ttime #ttpatter# %pattern of NLLoc ttimes from grid
|
||||
AUTOLOC_nlloc #outpatter# %pattern of NLLoc-output file
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
#parameters for seismic moment estimation#
|
||||
3530.0 #vp# %average P-wave velocity
|
||||
2500.0 #rho# %average rock density [kg/m^3]
|
||||
300.0 0.8 #Qp# %quality factor for P waves (Qp*f^a); list(Qp, a)
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
#settings local magnitude#
|
||||
1.11 0.0009 -2.0 #WAscaling# %Scaling relation (log(Ao)+Alog(r)+Br+C) of Wood-Anderson amplitude Ao [nm] If zeros are set, original Richter magnitude is calculated!
|
||||
1.0382 -0.447 #magscaling# %Scaling relation for derived local magnitude [a*Ml+b]. If zeros are set, no scaling of network magnitude is applied!
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
#filter settings#
|
||||
1.0 1.0 #minfreq# %Lower filter frequency [P, S]
|
||||
10.0 10.0 #maxfreq# %Upper filter frequency [P, S]
|
||||
2 2 #filter_order# %filter order [P, S]
|
||||
bandpass bandpass #filter_type# %filter type (bandpass, bandstop, lowpass, highpass) [P, S]
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
#common settings picker#
|
||||
local #extent# %extent of array ("local", "regional" or "global")
|
||||
15.0 #pstart# %start time [s] for calculating CF for P-picking
|
||||
60.0 #pstop# %end time [s] for calculating CF for P-picking
|
||||
-1.0 #sstart# %start time [s] relative to P-onset for calculating CF for S-picking
|
||||
10.0 #sstop# %end time [s] after P-onset for calculating CF for S-picking
|
||||
True #use_taup# %use estimated traveltimes from TauPy for calculating windows for CF
|
||||
iasp91 #taup_model# %define TauPy model for traveltime estimation
|
||||
2.0 10.0 #bpz1# %lower/upper corner freq. of first band pass filter Z-comp. [Hz]
|
||||
2.0 12.0 #bpz2# %lower/upper corner freq. of second band pass filter Z-comp. [Hz]
|
||||
2.0 8.0 #bph1# %lower/upper corner freq. of first band pass filter H-comp. [Hz]
|
||||
2.0 10.0 #bph2# %lower/upper corner freq. of second band pass filter z-comp. [Hz]
|
||||
#special settings for calculating CF#
|
||||
%!!Edit the following only if you know what you are doing!!%
|
||||
#Z-component#
|
||||
HOS #algoP# %choose algorithm for P-onset determination (HOS, ARZ, or AR3)
|
||||
7.0 #tlta# %for HOS-/AR-AIC-picker, length of LTA window [s]
|
||||
4 #hosorder# %for HOS-picker, order of Higher Order Statistics
|
||||
2 #Parorder# %for AR-picker, order of AR process of Z-component
|
||||
1.2 #tdet1z# %for AR-picker, length of AR determination window [s] for Z-component, 1st pick
|
||||
0.4 #tpred1z# %for AR-picker, length of AR prediction window [s] for Z-component, 1st pick
|
||||
0.6 #tdet2z# %for AR-picker, length of AR determination window [s] for Z-component, 2nd pick
|
||||
0.2 #tpred2z# %for AR-picker, length of AR prediction window [s] for Z-component, 2nd pick
|
||||
0.001 #addnoise# %add noise to seismogram for stable AR prediction
|
||||
3.0 0.1 0.5 1.0 #tsnrz# %for HOS/AR, window lengths for SNR-and slope estimation [tnoise, tsafetey, tsignal, tslope] [s]
|
||||
3.0 #pickwinP# %for initial AIC pick, length of P-pick window [s]
|
||||
6.0 #Precalcwin# %for HOS/AR, window length [s] for recalculation of CF (relative to 1st pick)
|
||||
0.2 #aictsmooth# %for HOS/AR, take average of samples for smoothing of AIC-function [s]
|
||||
0.1 #tsmoothP# %for HOS/AR, take average of samples for smoothing CF [s]
|
||||
0.001 #ausP# %for HOS/AR, artificial uplift of samples (aus) of CF (P)
|
||||
1.3 #nfacP# %for HOS/AR, noise factor for noise level determination (P)
|
||||
#H-components#
|
||||
ARH #algoS# %choose algorithm for S-onset determination (ARH or AR3)
|
||||
0.8 #tdet1h# %for HOS/AR, length of AR-determination window [s], H-components, 1st pick
|
||||
0.4 #tpred1h# %for HOS/AR, length of AR-prediction window [s], H-components, 1st pick
|
||||
0.6 #tdet2h# %for HOS/AR, length of AR-determinaton window [s], H-components, 2nd pick
|
||||
0.3 #tpred2h# %for HOS/AR, length of AR-prediction window [s], H-components, 2nd pick
|
||||
4 #Sarorder# %for AR-picker, order of AR process of H-components
|
||||
5.0 #Srecalcwin# %for AR-picker, window length [s] for recalculation of CF (2nd pick) (H)
|
||||
4.0 #pickwinS# %for initial AIC pick, length of S-pick window [s]
|
||||
2.0 0.3 1.5 1.0 #tsnrh# %for ARH/AR3, window lengths for SNR-and slope estimation [tnoise, tsafetey, tsignal, tslope] [s]
|
||||
1.0 #aictsmoothS# %for AIC-picker, take average of samples for smoothing of AIC-function [s]
|
||||
0.7 #tsmoothS# %for AR-picker, take average of samples for smoothing CF [s] (S)
|
||||
0.9 #ausS# %for HOS/AR, artificial uplift of samples (aus) of CF (S)
|
||||
1.5 #nfacS# %for AR-picker, noise factor for noise level determination (S)
|
||||
#first-motion picker#
|
||||
1 #minfmweight# %minimum required P weight for first-motion determination
|
||||
2.0 #minFMSNR# %miniumum required SNR for first-motion determination
|
||||
0.2 #fmpickwin# %pick window around P onset for calculating zero crossings
|
||||
#quality assessment#
|
||||
0.02 0.04 0.08 0.16 #timeerrorsP# %discrete time errors [s] corresponding to picking weights [0 1 2 3] for P
|
||||
0.04 0.08 0.16 0.32 #timeerrorsS# %discrete time errors [s] corresponding to picking weights [0 1 2 3] for S
|
||||
0.8 #minAICPslope# %below this slope [counts/s] the initial P pick is rejected
|
||||
1.1 #minAICPSNR# %below this SNR the initial P pick is rejected
|
||||
1.0 #minAICSslope# %below this slope [counts/s] the initial S pick is rejected
|
||||
1.5 #minAICSSNR# %below this SNR the initial S pick is rejected
|
||||
1.0 #minsiglength# %length of signal part for which amplitudes must exceed noiselevel [s]
|
||||
1.0 #noisefactor# %noiselevel*noisefactor=threshold
|
||||
10.0 #minpercent# %required percentage of amplitudes exceeding threshold
|
||||
1.5 #zfac# %P-amplitude must exceed at least zfac times RMS-S amplitude
|
||||
6.0 #mdttolerance# %maximum allowed deviation of P picks from median [s]
|
||||
1.0 #wdttolerance# %maximum allowed deviation from Wadati-diagram
|
||||
5.0 #jackfactor# %pick is removed if the variance of the subgroup with the pick removed is larger than the mean variance of all subgroups times safety factor
|
100
inputs/pylot_regional.in
Normal file
@ -0,0 +1,100 @@
|
||||
%This is a parameter input file for PyLoT/autoPyLoT.
|
||||
%All main and special settings regarding data handling
|
||||
%and picking are to be set here!
|
||||
%Parameters are optimized for %extent data sets!
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
#main settings#
|
||||
#rootpath# %project path
|
||||
#datapath# %data path
|
||||
#database# %name of data base
|
||||
#eventID# %event ID for single event processing (* for all events found in database)
|
||||
#invdir# %full path to inventory or dataless-seed file
|
||||
PILOT #datastructure# %choose data structure
|
||||
True #apverbose# %choose 'True' or 'False' for terminal output
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
#NLLoc settings#
|
||||
None #nllocbin# %path to NLLoc executable
|
||||
None #nllocroot# %root of NLLoc-processing directory
|
||||
None #phasefile# %name of autoPyLoT-output phase file for NLLoc
|
||||
None #ctrfile# %name of autoPyLoT-output control file for NLLoc
|
||||
ttime #ttpatter# %pattern of NLLoc ttimes from grid
|
||||
AUTOLOC_nlloc #outpatter# %pattern of NLLoc-output file
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
#parameters for seismic moment estimation#
|
||||
3530.0 #vp# %average P-wave velocity
|
||||
2500.0 #rho# %average rock density [kg/m^3]
|
||||
300.0 0.8 #Qp# %quality factor for P waves (Qp*f^a); list(Qp, a)
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
#settings local magnitude#
|
||||
1.11 0.0009 -2.0 #WAscaling# %Scaling relation (log(Ao)+Alog(r)+Br+C) of Wood-Anderson amplitude Ao [nm] If zeros are set, original Richter magnitude is calculated!
|
||||
1.0382 -0.447 #magscaling# %Scaling relation for derived local magnitude [a*Ml+b]. If zeros are set, no scaling of network magnitude is applied!
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
#filter settings#
|
||||
1.0 1.0 #minfreq# %Lower filter frequency [P, S]
|
||||
10.0 10.0 #maxfreq# %Upper filter frequency [P, S]
|
||||
2 2 #filter_order# %filter order [P, S]
|
||||
bandpass bandpass #filter_type# %filter type (bandpass, bandstop, lowpass, highpass) [P, S]
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
#common settings picker#
|
||||
local #extent# %extent of array ("local", "regional" or "global")
|
||||
15.0 #pstart# %start time [s] for calculating CF for P-picking
|
||||
60.0 #pstop# %end time [s] for calculating CF for P-picking
|
||||
-1.0 #sstart# %start time [s] relative to P-onset for calculating CF for S-picking
|
||||
10.0 #sstop# %end time [s] after P-onset for calculating CF for S-picking
|
||||
True #use_taup# %use estimated traveltimes from TauPy for calculating windows for CF
|
||||
iasp91 #taup_model# %define TauPy model for traveltime estimation
|
||||
2.0 10.0 #bpz1# %lower/upper corner freq. of first band pass filter Z-comp. [Hz]
|
||||
2.0 12.0 #bpz2# %lower/upper corner freq. of second band pass filter Z-comp. [Hz]
|
||||
2.0 8.0 #bph1# %lower/upper corner freq. of first band pass filter H-comp. [Hz]
|
||||
2.0 10.0 #bph2# %lower/upper corner freq. of second band pass filter z-comp. [Hz]
|
||||
#special settings for calculating CF#
|
||||
%!!Edit the following only if you know what you are doing!!%
|
||||
#Z-component#
|
||||
HOS #algoP# %choose algorithm for P-onset determination (HOS, ARZ, or AR3)
|
||||
7.0 #tlta# %for HOS-/AR-AIC-picker, length of LTA window [s]
|
||||
4 #hosorder# %for HOS-picker, order of Higher Order Statistics
|
||||
2 #Parorder# %for AR-picker, order of AR process of Z-component
|
||||
1.2 #tdet1z# %for AR-picker, length of AR determination window [s] for Z-component, 1st pick
|
||||
0.4 #tpred1z# %for AR-picker, length of AR prediction window [s] for Z-component, 1st pick
|
||||
0.6 #tdet2z# %for AR-picker, length of AR determination window [s] for Z-component, 2nd pick
|
||||
0.2 #tpred2z# %for AR-picker, length of AR prediction window [s] for Z-component, 2nd pick
|
||||
0.001 #addnoise# %add noise to seismogram for stable AR prediction
|
||||
3.0 0.1 0.5 1.0 #tsnrz# %for HOS/AR, window lengths for SNR-and slope estimation [tnoise, tsafetey, tsignal, tslope] [s]
|
||||
3.0 #pickwinP# %for initial AIC pick, length of P-pick window [s]
|
||||
6.0 #Precalcwin# %for HOS/AR, window length [s] for recalculation of CF (relative to 1st pick)
|
||||
0.2 #aictsmooth# %for HOS/AR, take average of samples for smoothing of AIC-function [s]
|
||||
0.1 #tsmoothP# %for HOS/AR, take average of samples for smoothing CF [s]
|
||||
0.001 #ausP# %for HOS/AR, artificial uplift of samples (aus) of CF (P)
|
||||
1.3 #nfacP# %for HOS/AR, noise factor for noise level determination (P)
|
||||
#H-components#
|
||||
ARH #algoS# %choose algorithm for S-onset determination (ARH or AR3)
|
||||
0.8 #tdet1h# %for HOS/AR, length of AR-determination window [s], H-components, 1st pick
|
||||
0.4 #tpred1h# %for HOS/AR, length of AR-prediction window [s], H-components, 1st pick
|
||||
0.6 #tdet2h# %for HOS/AR, length of AR-determinaton window [s], H-components, 2nd pick
|
||||
0.3 #tpred2h# %for HOS/AR, length of AR-prediction window [s], H-components, 2nd pick
|
||||
4 #Sarorder# %for AR-picker, order of AR process of H-components
|
||||
5.0 #Srecalcwin# %for AR-picker, window length [s] for recalculation of CF (2nd pick) (H)
|
||||
4.0 #pickwinS# %for initial AIC pick, length of S-pick window [s]
|
||||
2.0 0.3 1.5 1.0 #tsnrh# %for ARH/AR3, window lengths for SNR-and slope estimation [tnoise, tsafetey, tsignal, tslope] [s]
|
||||
1.0 #aictsmoothS# %for AIC-picker, take average of samples for smoothing of AIC-function [s]
|
||||
0.7 #tsmoothS# %for AR-picker, take average of samples for smoothing CF [s] (S)
|
||||
0.9 #ausS# %for HOS/AR, artificial uplift of samples (aus) of CF (S)
|
||||
1.5 #nfacS# %for AR-picker, noise factor for noise level determination (S)
|
||||
#first-motion picker#
|
||||
1 #minfmweight# %minimum required P weight for first-motion determination
|
||||
2.0 #minFMSNR# %miniumum required SNR for first-motion determination
|
||||
0.2 #fmpickwin# %pick window around P onset for calculating zero crossings
|
||||
#quality assessment#
|
||||
0.02 0.04 0.08 0.16 #timeerrorsP# %discrete time errors [s] corresponding to picking weights [0 1 2 3] for P
|
||||
0.04 0.08 0.16 0.32 #timeerrorsS# %discrete time errors [s] corresponding to picking weights [0 1 2 3] for S
|
||||
0.8 #minAICPslope# %below this slope [counts/s] the initial P pick is rejected
|
||||
1.1 #minAICPSNR# %below this SNR the initial P pick is rejected
|
||||
1.0 #minAICSslope# %below this slope [counts/s] the initial S pick is rejected
|
||||
1.5 #minAICSSNR# %below this SNR the initial S pick is rejected
|
||||
1.0 #minsiglength# %length of signal part for which amplitudes must exceed noiselevel [s]
|
||||
1.0 #noisefactor# %noiselevel*noisefactor=threshold
|
||||
10.0 #minpercent# %required percentage of amplitudes exceeding threshold
|
||||
1.5 #zfac# %P-amplitude must exceed at least zfac times RMS-S amplitude
|
||||
6.0 #mdttolerance# %maximum allowed deviation of P picks from median [s]
|
||||
1.0 #wdttolerance# %maximum allowed deviation from Wadati-diagram
|
||||
5.0 #jackfactor# %pick is removed if the variance of the subgroup with the pick removed is larger than the mean variance of all subgroups times safety factor
|
25
makePyLoT.py
@ -158,24 +158,29 @@ def buildPyLoT(verbosity=None):
|
||||
|
||||
|
||||
def installPyLoT(verbosity=None):
|
||||
files_to_copy = {'autoPyLoT_local.in':['~', '.pylot'],
|
||||
'autoPyLoT_regional.in':['~', '.pylot'],
|
||||
'filter.in':['~', '.pylot']}
|
||||
files_to_copy = {'pylot_local.in': ['~', '.pylot'],
|
||||
'pylot_regional.in': ['~', '.pylot'],
|
||||
'pylot_global.in': ['~', '.pylot']}
|
||||
if verbosity > 0:
|
||||
print ('starting installation of PyLoT ...')
|
||||
print('starting installation of PyLoT ...')
|
||||
if verbosity > 1:
|
||||
print ('copying input files into destination folder ...')
|
||||
print('copying input files into destination folder ...')
|
||||
ans = input('please specify scope of interest '
|
||||
'([0]=local, 1=regional) :') or 0
|
||||
'([0]=local, 1=regional, 2=global) :') or 0
|
||||
if not isinstance(ans, int):
|
||||
ans = int(ans)
|
||||
ans = 'local' if ans is 0 else 'regional'
|
||||
if ans == 0:
|
||||
ans = 'local'
|
||||
elif ans == 1:
|
||||
ans = 'regional'
|
||||
elif ans == 2:
|
||||
ans = 'global'
|
||||
link_dest = []
|
||||
for file, destination in files_to_copy.items():
|
||||
link_file = ans in file
|
||||
if link_file:
|
||||
link_dest = copy.deepcopy(destination)
|
||||
link_dest.append('autoPyLoT.in')
|
||||
link_dest.append('pylot.in')
|
||||
link_dest = os.path.join(*link_dest)
|
||||
destination.append(file)
|
||||
destination = os.path.join(*destination)
|
||||
@ -183,7 +188,7 @@ def installPyLoT(verbosity=None):
|
||||
assert not os.path.isabs(srcfile), 'source files seem to be ' \
|
||||
'corrupted ...'
|
||||
if verbosity > 1:
|
||||
print ('copying file {file} to folder {dest}'.format(file=file, dest=destination))
|
||||
print('copying file {file} to folder {dest}'.format(file=file, dest=destination))
|
||||
shutil.copyfile(srcfile, destination)
|
||||
if link_file:
|
||||
if verbosity:
|
||||
@ -191,8 +196,6 @@ def installPyLoT(verbosity=None):
|
||||
os.symlink(destination, link_dest)
|
||||
|
||||
|
||||
|
||||
|
||||
def cleanUp(verbosity=None):
|
||||
if verbosity >= 1:
|
||||
print('cleaning up build files...')
|
||||
|
BIN
pylot/PyLoT.ico
Before (image error) Size: 2.2 KiB |
@ -6,27 +6,27 @@ Revised/extended summer 2017.
|
||||
|
||||
:author: Ludger Küperkoch / MAGS2 EP3 working group
|
||||
"""
|
||||
import os
|
||||
import matplotlib.pyplot as plt
|
||||
import numpy as np
|
||||
import obspy.core.event as ope
|
||||
from obspy.geodetics import degrees2kilometers
|
||||
from scipy import integrate, signal
|
||||
from scipy.optimize import curve_fit
|
||||
from pylot.core.pick.utils import getsignalwin, crossings_nonzero_all, \
|
||||
select_for_phase
|
||||
from pylot.core.util.utils import common_range, fit_curve
|
||||
from scipy import integrate, signal
|
||||
from scipy.optimize import curve_fit
|
||||
|
||||
|
||||
def richter_magnitude_scaling(delta):
|
||||
distance = np.array([0, 10, 20, 25, 30, 35,40, 45, 50, 60, 70, 75, 85, 90, 100, 110,
|
||||
distance = np.array([0, 10, 20, 25, 30, 35, 40, 45, 50, 60, 70, 75, 85, 90, 100, 110,
|
||||
120, 130, 140, 150, 160, 170, 180, 190, 200, 210, 230, 240, 250,
|
||||
260, 270, 280, 290, 300, 310, 320, 330, 340, 350, 360, 370, 380,
|
||||
390, 400, 430, 470, 510, 560, 600, 700, 800, 900, 1000])
|
||||
richter_scaling = np.array([1.4, 1.5, 1.7, 1.9, 2.1, 2.3, 2.4, 2.5, 2.6, 2.8, 2.8, 2.9,
|
||||
2.9, 3.0, 3.1, 3.1, 3.2, 3.2, 3.3, 3.3, 3.4, 3.4, 3.5, 3.5,
|
||||
3.6, 3.7, 3.7, 3.8, 3.8, 3.9, 3.9, 4.0, 4.0, 4.1, 4.2, 4.2,
|
||||
4.2, 4.2, 4.3, 4.3, 4.3, 4.4, 4.4, 4.5, 4.6, 4.7, 4.8, 4.9,
|
||||
5.1, 5.2, 5.4, 5.5, 5.7])
|
||||
richter_scaling = np.array([1.4, 1.5, 1.7, 1.9, 2.1, 2.3, 2.4, 2.5, 2.6, 2.8, 2.8, 2.9,
|
||||
2.9, 3.0, 3.1, 3.1, 3.2, 3.2, 3.3, 3.3, 3.4, 3.4, 3.5, 3.5,
|
||||
3.6, 3.7, 3.7, 3.8, 3.8, 3.9, 3.9, 4.0, 4.0, 4.1, 4.2, 4.2,
|
||||
4.2, 4.2, 4.3, 4.3, 4.3, 4.4, 4.4, 4.5, 4.6, 4.7, 4.8, 4.9,
|
||||
5.1, 5.2, 5.4, 5.5, 5.7])
|
||||
# prepare spline interpolation to calculate return value
|
||||
func, params = fit_curve(distance, richter_scaling)
|
||||
return func(delta, params)
|
||||
@ -47,7 +47,7 @@ class Magnitude(object):
|
||||
|
||||
def __str__(self):
|
||||
print(
|
||||
'number of stations used: {0}\n'.format(len(self.magnitudes.values())))
|
||||
'number of stations used: {0}\n'.format(len(self.magnitudes.values())))
|
||||
print('\tstation\tmagnitude')
|
||||
for s, m in self.magnitudes.items(): print('\t{0}\t{1}'.format(s, m))
|
||||
|
||||
@ -126,8 +126,8 @@ class Magnitude(object):
|
||||
# scaling necessary
|
||||
print("Scaling network magnitude ...")
|
||||
mag = ope.Magnitude(
|
||||
mag=np.median([M.mag for M in self.magnitudes.values()]) *\
|
||||
magscaling[0] + magscaling[1],
|
||||
mag=np.median([M.mag for M in self.magnitudes.values()]) * \
|
||||
magscaling[0] + magscaling[1],
|
||||
magnitude_type=self.type,
|
||||
origin_id=self.origin_id,
|
||||
station_count=len(self.magnitudes),
|
||||
@ -192,6 +192,14 @@ class LocalMagnitude(Magnitude):
|
||||
|
||||
def peak_to_peak(self, st, t0):
|
||||
|
||||
try:
|
||||
iplot = int(self.plot_flag)
|
||||
except:
|
||||
if self.plot_flag == True or self.plot_flag == 'True':
|
||||
iplot = 2
|
||||
else:
|
||||
iplot = 0
|
||||
|
||||
# simulate Wood-Anderson response
|
||||
st.simulate(paz_remove=None, paz_simulate=self._paz)
|
||||
|
||||
@ -215,7 +223,7 @@ class LocalMagnitude(Magnitude):
|
||||
th = np.arange(0, len(sqH) * dt, dt)
|
||||
# get maximum peak within pick window
|
||||
iwin = getsignalwin(th, t0 - stime, self.calc_win)
|
||||
ii = min([iwin[len(iwin)-1], len(th)])
|
||||
ii = min([iwin[len(iwin) - 1], len(th)])
|
||||
iwin = iwin[0:ii]
|
||||
wapp = np.max(sqH[iwin])
|
||||
if self.verbose:
|
||||
@ -224,7 +232,7 @@ class LocalMagnitude(Magnitude):
|
||||
|
||||
# check for plot flag (for debugging only)
|
||||
fig = None
|
||||
if self.plot_flag > 1:
|
||||
if iplot > 1:
|
||||
st.plot()
|
||||
fig = plt.figure()
|
||||
ax = fig.add_subplot(111)
|
||||
@ -250,8 +258,8 @@ class LocalMagnitude(Magnitude):
|
||||
if not wf:
|
||||
if self.verbose:
|
||||
print(
|
||||
'WARNING: no waveform data found for station {0}'.format(
|
||||
station))
|
||||
'WARNING: no waveform data found for station {0}'.format(
|
||||
station))
|
||||
continue
|
||||
delta = degrees2kilometers(a.distance)
|
||||
onset = pick.time
|
||||
@ -270,13 +278,14 @@ class LocalMagnitude(Magnitude):
|
||||
if str(self.wascaling) == '[0.0, 0.0, 0.0]':
|
||||
print("Calculating original Richter magnitude ...")
|
||||
magnitude = ope.StationMagnitude(mag=np.log10(a0) \
|
||||
+ richter_magnitude_scaling(delta))
|
||||
+ richter_magnitude_scaling(delta))
|
||||
else:
|
||||
print("Calculating scaled local magnitude ...")
|
||||
a0 = a0 * 1e03 # mm to nm (see Havskov & Ottemöller, 2010)
|
||||
a0 = a0 * 1e03 # mm to nm (see Havskov & Ottemöller, 2010)
|
||||
magnitude = ope.StationMagnitude(mag=np.log10(a0) \
|
||||
+ self.wascaling[0] * np.log10(delta) + self.wascaling[1]
|
||||
* delta + self.wascaling[2])
|
||||
+ self.wascaling[0] * np.log10(delta) + self.wascaling[1]
|
||||
* delta + self.wascaling[
|
||||
2])
|
||||
magnitude.origin_id = self.origin_id
|
||||
magnitude.waveform_id = pick.waveform_id
|
||||
magnitude.amplitude_id = amplitude.resource_id
|
||||
@ -397,8 +406,8 @@ def calcMoMw(wfstream, w0, rho, vp, delta, verbosity=False):
|
||||
|
||||
if verbosity:
|
||||
print(
|
||||
"calcMoMw: Calculating seismic moment Mo and moment magnitude Mw for station {0} ...".format(
|
||||
tr.stats.station))
|
||||
"calcMoMw: Calculating seismic moment Mo and moment magnitude Mw for station {0} ...".format(
|
||||
tr.stats.station))
|
||||
|
||||
# additional common parameters for calculating Mo
|
||||
rP = 2 / np.sqrt(
|
||||
@ -412,8 +421,8 @@ def calcMoMw(wfstream, w0, rho, vp, delta, verbosity=False):
|
||||
|
||||
if verbosity:
|
||||
print(
|
||||
"calcMoMw: Calculated seismic moment Mo = {0} Nm => Mw = {1:3.1f} ".format(
|
||||
Mo, Mw))
|
||||
"calcMoMw: Calculated seismic moment Mo = {0} Nm => Mw = {1:3.1f} ".format(
|
||||
Mo, Mw))
|
||||
|
||||
return Mo, Mw
|
||||
|
||||
@ -452,7 +461,15 @@ def calcsourcespec(wfstream, onset, vp, delta, azimuth, incidence,
|
||||
:type: integer
|
||||
'''
|
||||
if verbosity:
|
||||
print ("Calculating source spectrum for station %s ...." % wfstream[0].stats.station)
|
||||
print("Calculating source spectrum for station %s ...." % wfstream[0].stats.station)
|
||||
|
||||
try:
|
||||
iplot = int(iplot)
|
||||
except:
|
||||
if iplot == True or iplot == 'True':
|
||||
iplot = 2
|
||||
else:
|
||||
iplot = 0
|
||||
|
||||
# get Q value
|
||||
Q, A = qp
|
||||
@ -509,9 +526,9 @@ def calcsourcespec(wfstream, onset, vp, delta, azimuth, incidence,
|
||||
zc = crossings_nonzero_all(wfzc)
|
||||
if np.size(zc) == 0 or len(zc) <= 3:
|
||||
if verbosity:
|
||||
print ("calcsourcespec: Something is wrong with the waveform, "
|
||||
"no zero crossings derived!\n")
|
||||
print ("No calculation of source spectrum possible!")
|
||||
print("calcsourcespec: Something is wrong with the waveform, "
|
||||
"no zero crossings derived!\n")
|
||||
print("No calculation of source spectrum possible!")
|
||||
plotflag = 0
|
||||
else:
|
||||
plotflag = 1
|
||||
@ -558,22 +575,22 @@ def calcsourcespec(wfstream, onset, vp, delta, azimuth, incidence,
|
||||
[optspecfit, _] = curve_fit(synthsourcespec, F, YYcor, [w0in, Fcin])
|
||||
w0 = optspecfit[0]
|
||||
fc = optspecfit[1]
|
||||
#w01 = optspecfit[0]
|
||||
#fc1 = optspecfit[1]
|
||||
# w01 = optspecfit[0]
|
||||
# fc1 = optspecfit[1]
|
||||
if verbosity:
|
||||
print ("calcsourcespec: Determined w0-value: %e m/Hz, \n"
|
||||
"calcsourcespec: Determined corner frequency: %f Hz" % (w0, fc))
|
||||
print("calcsourcespec: Determined w0-value: %e m/Hz, \n"
|
||||
"calcsourcespec: Determined corner frequency: %f Hz" % (w0, fc))
|
||||
|
||||
# use of conventional fitting
|
||||
# [w02, fc2] = fitSourceModel(F, YYcor, Fcin, iplot, verbosity)
|
||||
# use of conventional fitting
|
||||
# [w02, fc2] = fitSourceModel(F, YYcor, Fcin, iplot, verbosity)
|
||||
|
||||
# get w0 and fc as median of both
|
||||
# source spectrum fits
|
||||
#w0 = np.median([w01, w02])
|
||||
#fc = np.median([fc1, fc2])
|
||||
#if verbosity:
|
||||
# print("calcsourcespec: Using w0-value = %e m/Hz and fc = %f Hz" % (
|
||||
# w0, fc))
|
||||
# get w0 and fc as median of both
|
||||
# source spectrum fits
|
||||
# w0 = np.median([w01, w02])
|
||||
# fc = np.median([fc1, fc2])
|
||||
# if verbosity:
|
||||
# print("calcsourcespec: Using w0-value = %e m/Hz and fc = %f Hz" % (
|
||||
# w0, fc))
|
||||
|
||||
if iplot > 1:
|
||||
f1 = plt.figure()
|
||||
@ -600,9 +617,9 @@ def calcsourcespec(wfstream, onset, vp, delta, azimuth, incidence,
|
||||
p3, = plt.loglog(F, YYcor, 'r')
|
||||
p4, = plt.loglog(F, fit, 'g')
|
||||
plt.loglog([fc, fc], [w0 / 100, w0], 'g')
|
||||
plt.legend([p1, p2, p3, p4], ['Raw Spectrum', \
|
||||
'Used Raw Spectrum', \
|
||||
'Q-Corrected Spectrum', \
|
||||
plt.legend([p1, p2, p3, p4], ['Raw Spectrum',
|
||||
'Used Raw Spectrum',
|
||||
'Q-Corrected Spectrum',
|
||||
'Fit to Spectrum'])
|
||||
plt.title('Source Spectrum from P Pulse, w0=%e m/Hz, fc=%6.2f Hz' \
|
||||
% (w0, fc))
|
||||
@ -650,6 +667,14 @@ def fitSourceModel(f, S, fc0, iplot, verbosity=False):
|
||||
:type: float
|
||||
'''
|
||||
|
||||
try:
|
||||
iplot = int(iplot)
|
||||
except:
|
||||
if iplot == True or iplot == 'True':
|
||||
iplot = 2
|
||||
else:
|
||||
iplot = 0
|
||||
|
||||
w0 = []
|
||||
stdw0 = []
|
||||
fc = []
|
||||
@ -659,9 +684,9 @@ def fitSourceModel(f, S, fc0, iplot, verbosity=False):
|
||||
# left side of initial corner frequency
|
||||
fcstopl = max(f[0], fc0 - max(1, fc0 / 2))
|
||||
il = np.where(f <= fcstopl)
|
||||
il = il[0][np.size(il) - 1]
|
||||
il = il[0][np.size(il) - 1]
|
||||
# right side of initial corner frequency
|
||||
fcstopr = min(fc0 + (fc0 / 2), f[len(f) - 1])
|
||||
fcstopr = min(fc0 + (fc0 / 2), f[len(f) - 1])
|
||||
ir = np.where(f >= fcstopr)
|
||||
# check, if fcstopr is available
|
||||
if np.size(ir) == 0:
|
||||
@ -672,16 +697,16 @@ def fitSourceModel(f, S, fc0, iplot, verbosity=False):
|
||||
|
||||
# vary corner frequency around initial point
|
||||
print("fitSourceModel: Varying corner frequency "
|
||||
"around initial corner frequency ...")
|
||||
"around initial corner frequency ...")
|
||||
# check difference of il and ir in order to
|
||||
# keep calculation time acceptable
|
||||
idiff = ir - il
|
||||
if idiff > 10000:
|
||||
increment = 100
|
||||
increment = 100
|
||||
elif idiff <= 20:
|
||||
increment = 1
|
||||
increment = 1
|
||||
else:
|
||||
increment = 10
|
||||
increment = 10
|
||||
|
||||
for i in range(il, ir, increment):
|
||||
FC = f[i]
|
||||
@ -707,10 +732,10 @@ def fitSourceModel(f, S, fc0, iplot, verbosity=False):
|
||||
w0 = max(S)
|
||||
if verbosity:
|
||||
print(
|
||||
"fitSourceModel: best fc: {0} Hz, best w0: {1} m/Hz".format(fc, w0))
|
||||
"fitSourceModel: best fc: {0} Hz, best w0: {1} m/Hz".format(fc, w0))
|
||||
|
||||
if iplot > 1:
|
||||
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')
|
||||
@ -719,7 +744,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')
|
||||
|
@ -1,242 +0,0 @@
|
||||
#!/usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
Created August/September 2015.
|
||||
|
||||
:author: Ludger Küperkoch / MAGS2 EP3 working group
|
||||
"""
|
||||
|
||||
import matplotlib.pyplot as plt
|
||||
import numpy as np
|
||||
from obspy.core import Stream
|
||||
from pylot.core.pick.utils import getsignalwin
|
||||
from scipy.optimize import curve_fit
|
||||
|
||||
class Magnitude(object):
|
||||
'''
|
||||
Superclass for calculating Wood-Anderson peak-to-peak
|
||||
amplitudes, local magnitudes and moment magnitudes.
|
||||
'''
|
||||
|
||||
def __init__(self, wfstream, To, pwin, iplot):
|
||||
'''
|
||||
:param: wfstream
|
||||
:type: `~obspy.core.stream.Stream
|
||||
|
||||
:param: To, onset time, P- or S phase
|
||||
:type: float
|
||||
|
||||
:param: pwin, pick window [To To+pwin] to get maximum
|
||||
peak-to-peak amplitude (WApp) or to calculate
|
||||
source spectrum (DCfc)
|
||||
:type: float
|
||||
|
||||
:param: iplot, no. of figure window for plotting interims results
|
||||
:type: integer
|
||||
|
||||
'''
|
||||
|
||||
assert isinstance(wfstream, Stream), "%s is not a stream object" % str(wfstream)
|
||||
|
||||
self.setwfstream(wfstream)
|
||||
self.setTo(To)
|
||||
self.setpwin(pwin)
|
||||
self.setiplot(iplot)
|
||||
self.calcwapp()
|
||||
self.calcsourcespec()
|
||||
|
||||
|
||||
def getwfstream(self):
|
||||
return self.wfstream
|
||||
|
||||
def setwfstream(self, wfstream):
|
||||
self.wfstream = wfstream
|
||||
|
||||
def getTo(self):
|
||||
return self.To
|
||||
|
||||
def setTo(self, To):
|
||||
self.To = To
|
||||
|
||||
def getpwin(self):
|
||||
return self.pwin
|
||||
|
||||
def setpwin(self, pwin):
|
||||
self.pwin = pwin
|
||||
|
||||
def getiplot(self):
|
||||
return self.iplot
|
||||
|
||||
def setiplot(self, iplot):
|
||||
self.iplot = iplot
|
||||
|
||||
def getwapp(self):
|
||||
return self.wapp
|
||||
|
||||
def getw0(self):
|
||||
return self.w0
|
||||
|
||||
def getfc(self):
|
||||
return self.fc
|
||||
|
||||
def calcwapp(self):
|
||||
self.wapp = None
|
||||
|
||||
def calcsourcespec(self):
|
||||
self.sourcespek = None
|
||||
|
||||
class WApp(Magnitude):
|
||||
'''
|
||||
Method to derive peak-to-peak amplitude as seen on a Wood-Anderson-
|
||||
seismograph. Has to be derived from instrument corrected traces!
|
||||
'''
|
||||
|
||||
def calcwapp(self):
|
||||
print ("Getting Wood-Anderson peak-to-peak amplitude ...")
|
||||
print ("Simulating Wood-Anderson seismograph ...")
|
||||
|
||||
self.wapp = None
|
||||
stream = self.getwfstream()
|
||||
|
||||
# poles, zeros and sensitivity of WA seismograph
|
||||
# (see Uhrhammer & Collins, 1990, BSSA, pp. 702-716)
|
||||
paz_wa = {
|
||||
'poles': [5.6089 - 5.4978j, -5.6089 - 5.4978j],
|
||||
'zeros': [0j, 0j],
|
||||
'gain': 2080,
|
||||
'sensitivity': 1}
|
||||
|
||||
stream.simulate(paz_remove=None, paz_simulate=paz_wa)
|
||||
|
||||
trH1 = stream[0].data
|
||||
trH2 = stream[1].data
|
||||
ilen = min([len(trH1), len(trH2)])
|
||||
# get RMS of both horizontal components
|
||||
sqH = np.sqrt(np.power(trH1[0:ilen], 2) + np.power(trH2[0:ilen], 2))
|
||||
# get time array
|
||||
th = np.arange(0, len(sqH) * stream[0].stats.delta, stream[0].stats.delta)
|
||||
# get maximum peak within pick window
|
||||
iwin = getsignalwin(th, self.getTo(), self.getpwin())
|
||||
self.wapp = np.max(sqH[iwin])
|
||||
print ("Determined Wood-Anderson peak-to-peak amplitude: %f mm") % self.wapp
|
||||
|
||||
if self.getiplot() > 1:
|
||||
stream.plot()
|
||||
f = plt.figure(2)
|
||||
plt.plot(th, sqH)
|
||||
plt.plot(th[iwin], sqH[iwin], 'g')
|
||||
plt.plot([self.getTo(), self.getTo()], [0, max(sqH)], 'r', linewidth=2)
|
||||
plt.title('Station %s, RMS Horizontal Traces, WA-peak-to-peak=%4.1f mm' \
|
||||
% (stream[0].stats.station, self.wapp))
|
||||
plt.xlabel('Time [s]')
|
||||
plt.ylabel('Displacement [mm]')
|
||||
plt.show()
|
||||
raw_input()
|
||||
plt.close(f)
|
||||
|
||||
|
||||
class DCfc(Magnitude):
|
||||
'''
|
||||
Method to calculate the source spectrum and to derive from that the plateau
|
||||
(so-called DC-value) and the corner frequency assuming Aki's omega-square
|
||||
source model. Has to be derived from instrument corrected displacement traces!
|
||||
'''
|
||||
|
||||
def calcsourcespec(self):
|
||||
print ("Calculating source spectrum ....")
|
||||
|
||||
self.w0 = None # DC-value
|
||||
self.fc = None # corner frequency
|
||||
|
||||
stream = self.getwfstream()
|
||||
tr = stream[0]
|
||||
|
||||
# get time array
|
||||
t = np.arange(0, len(tr) * tr.stats.delta, tr.stats.delta)
|
||||
iwin = getsignalwin(t, self.getTo(), self.getpwin())
|
||||
xdat = tr.data[iwin]
|
||||
|
||||
# fft
|
||||
fny = tr.stats.sampling_rate / 2
|
||||
l = len(xdat) / tr.stats.sampling_rate
|
||||
n = tr.stats.sampling_rate * l # number of fft bins after Bath
|
||||
# find next power of 2 of data length
|
||||
m = pow(2, np.ceil(np.log(len(xdat)) / np.log(2)))
|
||||
N = int(np.power(m, 2))
|
||||
y = tr.stats.delta * np.fft.fft(xdat, N)
|
||||
Y = abs(y[: N/2])
|
||||
L = (N - 1) / tr.stats.sampling_rate
|
||||
f = np.arange(0, fny, 1/L)
|
||||
|
||||
# remove zero-frequency and frequencies above
|
||||
# corner frequency of seismometer (assumed
|
||||
# to be 100 Hz)
|
||||
fi = np.where((f >= 1) & (f < 100))
|
||||
F = f[fi]
|
||||
YY = Y[fi]
|
||||
# get plateau (DC value) and corner frequency
|
||||
# initial guess of plateau
|
||||
DCin = np.mean(YY[0:100])
|
||||
# initial guess of corner frequency
|
||||
# where spectral level reached 50% of flat level
|
||||
iin = np.where(YY >= 0.5 * DCin)
|
||||
Fcin = F[iin[0][np.size(iin) - 1]]
|
||||
fit = synthsourcespec(F, DCin, Fcin)
|
||||
[optspecfit, pcov] = curve_fit(synthsourcespec, F, YY.real, [DCin, Fcin])
|
||||
self.w0 = optspecfit[0]
|
||||
self.fc = optspecfit[1]
|
||||
print ("DCfc: Determined DC-value: %e m/Hz, \n" \
|
||||
"Determined corner frequency: %f Hz" % (self.w0, self.fc))
|
||||
|
||||
|
||||
#if self.getiplot() > 1:
|
||||
iplot=2
|
||||
if iplot > 1:
|
||||
print ("DCfc: Determined DC-value: %e m/Hz, \n"
|
||||
"Determined corner frequency: %f Hz" % (self.w0, self.fc))
|
||||
|
||||
|
||||
if self.getiplot() > 1:
|
||||
f1 = plt.figure()
|
||||
plt.subplot(2,1,1)
|
||||
# show displacement in mm
|
||||
plt.plot(t, np.multiply(tr, 1000), 'k')
|
||||
plt.plot(t[iwin], np.multiply(xdat, 1000), 'g')
|
||||
plt.title('Seismogram and P pulse, station %s' % tr.stats.station)
|
||||
plt.xlabel('Time since %s' % tr.stats.starttime)
|
||||
plt.ylabel('Displacement [mm]')
|
||||
|
||||
plt.subplot(2,1,2)
|
||||
plt.loglog(f, Y.real, 'k')
|
||||
plt.loglog(F, YY.real)
|
||||
plt.loglog(F, fit, 'g')
|
||||
plt.title('Source Spectrum from P Pulse, DC=%e m/Hz, fc=%4.1f Hz' \
|
||||
% (self.w0, self.fc))
|
||||
plt.xlabel('Frequency [Hz]')
|
||||
plt.ylabel('Amplitude [m/Hz]')
|
||||
plt.grid()
|
||||
plt.show()
|
||||
raw_input()
|
||||
plt.close(f1)
|
||||
|
||||
|
||||
def synthsourcespec(f, omega0, fcorner):
|
||||
'''
|
||||
Calculates synthetic source spectrum from given plateau and corner
|
||||
frequency assuming Akis omega-square model.
|
||||
|
||||
:param: f, frequencies
|
||||
:type: array
|
||||
|
||||
:param: omega0, DC-value (plateau) of source spectrum
|
||||
:type: float
|
||||
|
||||
:param: fcorner, corner frequency of source spectrum
|
||||
:type: float
|
||||
'''
|
||||
|
||||
#ssp = omega0 / (pow(2, (1 + f / fcorner)))
|
||||
ssp = omega0 / (1 + pow(2, (f / fcorner)))
|
||||
|
||||
return ssp
|
||||
|
@ -3,15 +3,18 @@
|
||||
|
||||
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 as ObsPyEvent
|
||||
from obspy.io.sac import SacIOError
|
||||
from pylot.core.io.phases import readPILOTEvent, picks_from_picksdict, \
|
||||
picksdict_from_pilot, merge_picks
|
||||
from pylot.core.util.errors import FormatError, OverwriteError
|
||||
from pylot.core.util.utils import fnConstructor, full_range
|
||||
from pylot.core.util.event import Event
|
||||
from pylot.core.util.utils import fnConstructor, full_range
|
||||
import pylot.core.loc.velest as velest
|
||||
|
||||
|
||||
class Data(object):
|
||||
"""
|
||||
@ -39,7 +42,7 @@ class Data(object):
|
||||
elif isinstance(evtdata, dict):
|
||||
evt = readPILOTEvent(**evtdata)
|
||||
evtdata = evt
|
||||
elif isinstance(evtdata, basestring):
|
||||
elif isinstance(evtdata, str):
|
||||
try:
|
||||
cat = read_events(evtdata)
|
||||
if len(cat) is not 1:
|
||||
@ -75,7 +78,7 @@ class Data(object):
|
||||
def __add__(self, other):
|
||||
assert isinstance(other, Data), "operands must be of same type 'Data'"
|
||||
rs_id = self.get_evt_data().get('resource_id')
|
||||
rs_id_other = other.get_evt_data().get('resource_id')
|
||||
rs_id_other = other.get_evt_data().get('resource_id')
|
||||
if other.isNew() and not self.isNew():
|
||||
picks_to_add = other.get_evt_data().picks
|
||||
old_picks = self.get_evt_data().picks
|
||||
@ -98,7 +101,7 @@ class Data(object):
|
||||
def getPicksStr(self):
|
||||
picks_str = ''
|
||||
for pick in self.get_evt_data().picks:
|
||||
picks_str += str(PyLoT) + '\n'
|
||||
picks_str += str(pick) + '\n'
|
||||
return picks_str
|
||||
|
||||
def getParent(self):
|
||||
@ -147,89 +150,158 @@ class Data(object):
|
||||
# handle forbidden filenames especially on windows systems
|
||||
return fnConstructor(str(ID))
|
||||
|
||||
def exportEvent(self, fnout, fnext='.xml', fcheck='auto'):
|
||||
def checkEvent(self, event, fcheck, forceOverwrite=False):
|
||||
if 'origin' in fcheck:
|
||||
self.replaceOrigin(event, forceOverwrite)
|
||||
if 'magnitude' in fcheck:
|
||||
self.replaceMagnitude(event, forceOverwrite)
|
||||
if 'auto' in fcheck:
|
||||
self.replacePicks(event, 'auto')
|
||||
if 'manual' in fcheck:
|
||||
self.replacePicks(event, 'manual')
|
||||
|
||||
def replaceOrigin(self, event, forceOverwrite=False):
|
||||
if self.get_evt_data().origins or forceOverwrite:
|
||||
if event.origins:
|
||||
print("Found origin, replace it by new origin.")
|
||||
event.origins = self.get_evt_data().origins
|
||||
|
||||
def replaceMagnitude(self, event, forceOverwrite=False):
|
||||
if self.get_evt_data().magnitudes or forceOverwrite:
|
||||
if event.magnitudes:
|
||||
print("Found magnitude, replace it by new magnitude")
|
||||
event.magnitudes = self.get_evt_data().magnitudes
|
||||
|
||||
def replacePicks(self, event, picktype):
|
||||
checkflag = 0
|
||||
picks = event.picks
|
||||
# remove existing picks
|
||||
for j, pick in reversed(list(enumerate(picks))):
|
||||
if picktype in str(pick.method_id.id):
|
||||
picks.pop(j)
|
||||
checkflag = 1
|
||||
if checkflag:
|
||||
print("Found %s pick(s), remove them and append new picks to catalog." % picktype)
|
||||
|
||||
# append new picks
|
||||
for pick in self.get_evt_data().picks:
|
||||
if picktype in str(pick.method_id.id):
|
||||
picks.append(pick)
|
||||
|
||||
def exportEvent(self, fnout, fnext='.xml', fcheck='auto', upperErrors=None):
|
||||
|
||||
"""
|
||||
|
||||
:param fnout:
|
||||
:param fnext:
|
||||
:param fcheck:
|
||||
:raise KeyError:
|
||||
:param fnout: basename of file
|
||||
:param fnext: file extension
|
||||
:param fcheck: check and delete existing information
|
||||
can be a str or a list of strings of ['manual', 'auto', 'origin', 'magnitude']
|
||||
"""
|
||||
from pylot.core.util.defaults import OUTPUTFORMATS
|
||||
|
||||
if not type(fcheck) == list:
|
||||
fcheck = [fcheck]
|
||||
|
||||
try:
|
||||
evtformat = OUTPUTFORMATS[fnext]
|
||||
except KeyError as e:
|
||||
errmsg = '{0}; selected file extension {1} not ' \
|
||||
'supported'.format(e, fnext)
|
||||
raise FormatError(errmsg)
|
||||
|
||||
|
||||
# check for already existing xml-file
|
||||
if fnext == '.xml':
|
||||
if os.path.isfile(fnout + fnext):
|
||||
print("xml-file already exists! Check content ...")
|
||||
cat_old = read_events(fnout + fnext)
|
||||
checkflag = 0
|
||||
for j in range(len(cat_old.events[0].picks)):
|
||||
if cat_old.events[0].picks[j].method_id.id.split('/')[1] == fcheck:
|
||||
print("Found %s pick(s), append to new catalog." % fcheck)
|
||||
checkflag = 1
|
||||
break
|
||||
if checkflag == 1:
|
||||
self.get_evt_data().write(fnout + fnext, format=evtformat)
|
||||
cat_new = read_events(fnout + fnext)
|
||||
cat_new.append(cat_old.events[0])
|
||||
cat_new.write(fnout + fnext, format=evtformat)
|
||||
else:
|
||||
self.get_evt_data().write(fnout + fnext, format=evtformat)
|
||||
else:
|
||||
self.get_evt_data().write(fnout + fnext, format=evtformat)
|
||||
|
||||
# try exporting event via ObsPy
|
||||
cat = read_events(fnout + fnext)
|
||||
if len(cat) > 1:
|
||||
raise IOError('Ambigious event information in file {}'.format(fnout + fnext))
|
||||
if len(cat) < 1:
|
||||
raise IOError('No event information in file {}'.format(fnout + fnext))
|
||||
event = cat[0]
|
||||
if not event.resource_id == self.get_evt_data().resource_id:
|
||||
raise IOError("Missmatching event resource id's: {} and {}".format(event.resource_id,
|
||||
self.get_evt_data().resource_id))
|
||||
self.checkEvent(event, fcheck)
|
||||
self.setEvtData(event)
|
||||
self.get_evt_data().write(fnout + fnext, format=evtformat)
|
||||
# try exporting event
|
||||
else:
|
||||
evtdata_org = self.get_evt_data()
|
||||
picks = evtdata_org.picks
|
||||
eventpath = evtdata_org.path
|
||||
picks_copy = copy.deepcopy(picks)
|
||||
evtdata_copy = Event(eventpath)
|
||||
evtdata_copy.picks = picks_copy
|
||||
|
||||
# check for stations picked automatically as well as manually
|
||||
# Prefer manual picks!
|
||||
evtdata_copy = self.get_evt_data().copy()
|
||||
evtdata_org = self.get_evt_data()
|
||||
for i in range(len(evtdata_org.picks)):
|
||||
if evtdata_org.picks[i].method_id == 'manual':
|
||||
mstation = evtdata_org.picks[i].waveform_id.station_code
|
||||
mstation_ext = mstation + '_'
|
||||
for k in range(len(evtdata_copy.picks)):
|
||||
if evtdata_copy.picks[k].waveform_id.station_code == mstation or \
|
||||
evtdata_copy.picks[k].waveform_id.station_code == mstation_ext and \
|
||||
evtdata_copy.picks[k].method_id == 'auto':
|
||||
del evtdata_copy.picks[k]
|
||||
break
|
||||
lendiff = len(evtdata_org.picks) - len(evtdata_copy.picks)
|
||||
for i in range(len(picks)):
|
||||
if picks[i].method_id == 'manual':
|
||||
mstation = picks[i].waveform_id.station_code
|
||||
mstation_ext = mstation + '_'
|
||||
for k in range(len(picks_copy)):
|
||||
if ((picks_copy[k].waveform_id.station_code == mstation) or
|
||||
(picks_copy[k].waveform_id.station_code == mstation_ext)) and \
|
||||
(picks_copy[k].method_id == 'auto'):
|
||||
del picks_copy[k]
|
||||
break
|
||||
lendiff = len(picks) - len(picks_copy)
|
||||
if lendiff is not 0:
|
||||
print("Manual as well as automatic picks available. Prefered the {} manual ones!".format(lendiff))
|
||||
print("Manual as well as automatic picks available. Prefered the {} manual ones!".format(lendiff))
|
||||
|
||||
if upperErrors:
|
||||
# check for pick uncertainties exceeding adjusted upper errors
|
||||
# Picks with larger uncertainties will not be saved in output file!
|
||||
for j in range(len(picks)):
|
||||
for i in range(len(picks_copy)):
|
||||
if picks_copy[i].phase_hint[0] == 'P':
|
||||
if (picks_copy[i].time_errors['upper_uncertainty'] >= upperErrors[0]) or \
|
||||
(picks_copy[i].time_errors['uncertainty'] == None):
|
||||
print("Uncertainty exceeds or equal adjusted upper time error!")
|
||||
print("Adjusted uncertainty: {}".format(upperErrors[0]))
|
||||
print("Pick uncertainty: {}".format(picks_copy[i].time_errors['uncertainty']))
|
||||
print("{1} P-Pick of station {0} will not be saved in outputfile".format(
|
||||
picks_copy[i].waveform_id.station_code,
|
||||
picks_copy[i].method_id))
|
||||
print("#")
|
||||
del picks_copy[i]
|
||||
break
|
||||
if picks_copy[i].phase_hint[0] == 'S':
|
||||
if (picks_copy[i].time_errors['upper_uncertainty'] >= upperErrors[1]) or \
|
||||
(picks_copy[i].time_errors['uncertainty'] == None):
|
||||
print("Uncertainty exceeds or equal adjusted upper time error!")
|
||||
print("Adjusted uncertainty: {}".format(upperErrors[1]))
|
||||
print("Pick uncertainty: {}".format(picks_copy[i].time_errors['uncertainty']))
|
||||
print("{1} S-Pick of station {0} will not be saved in outputfile".format(
|
||||
picks_copy[i].waveform_id.station_code,
|
||||
picks_copy[i].method_id))
|
||||
print("#")
|
||||
del picks_copy[i]
|
||||
break
|
||||
|
||||
if fnext == '.obs':
|
||||
try:
|
||||
evtdata_copy.write(fnout + fnext, format=evtformat)
|
||||
# write header afterwards
|
||||
evid = str(evtdata_org.resource_id).split('/')[1]
|
||||
header = '# EQEVENT: Label: EQ%s Loc: X 0.00 Y 0.00 Z 10.00 OT 0.00 \n' % evid
|
||||
nllocfile = open(fnout + fnext)
|
||||
l = nllocfile.readlines()
|
||||
nllocfile.close()
|
||||
l.insert(0, header)
|
||||
nllocfile = open(fnout + fnext, 'w')
|
||||
nllocfile.write("".join(l))
|
||||
nllocfile.close()
|
||||
except KeyError as e:
|
||||
raise KeyError('''{0} export format
|
||||
try:
|
||||
evtdata_copy.write(fnout + fnext, format=evtformat)
|
||||
# write header afterwards
|
||||
evid = str(evtdata_org.resource_id).split('/')[1]
|
||||
header = '# EQEVENT: Label: EQ%s Loc: X 0.00 Y 0.00 Z 10.00 OT 0.00 \n' % evid
|
||||
nllocfile = open(fnout + fnext)
|
||||
l = nllocfile.readlines()
|
||||
nllocfile.close()
|
||||
l.insert(0, header)
|
||||
nllocfile = open(fnout + fnext, 'w')
|
||||
nllocfile.write("".join(l))
|
||||
nllocfile.close()
|
||||
except KeyError as e:
|
||||
raise KeyError('''{0} export format
|
||||
not implemented: {1}'''.format(evtformat, e))
|
||||
if fnext == '.cnv':
|
||||
try:
|
||||
evtdata_org.write(fnout + fnext, format=evtformat)
|
||||
except KeyError as e:
|
||||
raise KeyError('''{0} export format
|
||||
try:
|
||||
velest.export(picks_copy, fnout + fnext, eventinfo=self.get_evt_data())
|
||||
except KeyError as e:
|
||||
raise KeyError('''{0} export format
|
||||
not implemented: {1}'''.format(evtformat, e))
|
||||
|
||||
|
||||
def getComp(self):
|
||||
"""
|
||||
|
||||
@ -294,7 +366,7 @@ class Data(object):
|
||||
except Exception as e:
|
||||
warnmsg += '{0}\n{1}\n'.format(fname, e)
|
||||
except SacIOError as se:
|
||||
warnmsg += '{0}\n{1}\n'.format(fname, se)
|
||||
warnmsg += '{0}\n{1}\n'.format(fname, se)
|
||||
if warnmsg:
|
||||
warnmsg = 'WARNING: unable to read\n' + warnmsg
|
||||
print(warnmsg)
|
||||
@ -359,21 +431,20 @@ 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)
|
||||
# firstonset = find_firstonset(picks)
|
||||
# check for automatic picks
|
||||
print("Writing phases to ObsPy-quakeml file")
|
||||
for key in picks:
|
||||
if picks[key]['P']['picker'] == 'auto':
|
||||
print("Existing picks will be overwritten!")
|
||||
picks = picks_from_picksdict(picks)
|
||||
break
|
||||
print("Existing picks will be overwritten!")
|
||||
picks = picks_from_picksdict(picks)
|
||||
break
|
||||
else:
|
||||
if self.get_evt_data().picks:
|
||||
raise OverwriteError('Existing picks would be overwritten!')
|
||||
break
|
||||
else:
|
||||
picks = picks_from_picksdict(picks)
|
||||
break
|
||||
if self.get_evt_data().picks:
|
||||
raise OverwriteError('Existing picks would be overwritten!')
|
||||
else:
|
||||
picks = picks_from_picksdict(picks)
|
||||
break
|
||||
self.get_evt_data().picks = picks
|
||||
# if 'smi:local' in self.getID() and firstonset:
|
||||
# fonset_str = firstonset.strftime('%Y_%m_%d_%H_%M_%S')
|
||||
@ -381,7 +452,6 @@ class Data(object):
|
||||
# ID.convertIDToQuakeMLURI(authority_id=authority_id)
|
||||
# self.get_evt_data().resource_id = ID
|
||||
|
||||
|
||||
def applyEvent(event):
|
||||
"""
|
||||
takes an `obspy.core.event.Event` object and applies all new
|
||||
@ -393,13 +463,13 @@ class Data(object):
|
||||
else:
|
||||
# prevent overwriting original pick information
|
||||
event_old = self.get_evt_data()
|
||||
print(event_old.resource_id, event.resource_id)
|
||||
if not event_old.resource_id == event.resource_id:
|
||||
print("WARNING: Missmatch in event resource id's: {} and {}".format(
|
||||
event_old.resource_id,
|
||||
event.resource_id))
|
||||
picks = copy.deepcopy(event_old.picks)
|
||||
event = merge_picks(event, picks)
|
||||
else:
|
||||
picks = copy.deepcopy(event_old.picks)
|
||||
event = merge_picks(event, picks)
|
||||
# apply event information from location
|
||||
event_old.update(event)
|
||||
|
||||
@ -408,7 +478,6 @@ class Data(object):
|
||||
|
||||
applydata[typ](data)
|
||||
self._new = False
|
||||
|
||||
|
||||
|
||||
class GenericDataStructure(object):
|
||||
|
@ -3,293 +3,401 @@
|
||||
|
||||
defaults = {'rootpath': {'type': str,
|
||||
'tooltip': 'project path',
|
||||
'value': ''},
|
||||
|
||||
'value': '',
|
||||
'namestring': 'Root path'},
|
||||
|
||||
'datapath': {'type': str,
|
||||
'tooltip': 'data path',
|
||||
'value': ''},
|
||||
|
||||
'value': '',
|
||||
'namestring': 'Data path'},
|
||||
|
||||
'database': {'type': str,
|
||||
'tooltip': 'name of data base',
|
||||
'value': ''},
|
||||
|
||||
'value': '',
|
||||
'namestring': 'Database path'},
|
||||
|
||||
'eventID': {'type': str,
|
||||
'tooltip': 'event ID for single event processing (* for all events found in database)',
|
||||
'value': ''},
|
||||
|
||||
'value': '',
|
||||
'namestring': 'Event ID'},
|
||||
|
||||
'extent': {'type': str,
|
||||
'tooltip': 'extent of array ("local", "regional" or "global")',
|
||||
'value': 'local'},
|
||||
|
||||
'value': 'local',
|
||||
'namestring': 'Array extent'},
|
||||
|
||||
'invdir': {'type': str,
|
||||
'tooltip': 'full path to inventory or dataless-seed file',
|
||||
'value': ''},
|
||||
|
||||
'value': '',
|
||||
'namestring': 'Inversion dir'},
|
||||
|
||||
'datastructure': {'type': str,
|
||||
'tooltip': 'choose data structure',
|
||||
'value': 'PILOT'},
|
||||
|
||||
'value': 'PILOT',
|
||||
'namestring': 'Datastructure'},
|
||||
|
||||
'apverbose': {'type': bool,
|
||||
'tooltip': "choose 'True' or 'False' for terminal output",
|
||||
'value': True},
|
||||
|
||||
'value': True,
|
||||
'namestring': 'App. verbosity'},
|
||||
|
||||
'nllocbin': {'type': str,
|
||||
'tooltip': 'path to NLLoc executable',
|
||||
'value': ''},
|
||||
|
||||
'value': '',
|
||||
'namestring': 'NLLoc bin path'},
|
||||
|
||||
'nllocroot': {'type': str,
|
||||
'tooltip': 'root of NLLoc-processing directory',
|
||||
'value': ''},
|
||||
|
||||
'value': '',
|
||||
'namestring': 'NLLoc root path'},
|
||||
|
||||
'phasefile': {'type': str,
|
||||
'tooltip': 'name of autoPyLoT-output phase file for NLLoc',
|
||||
'value': 'AUTOPHASES.obs'},
|
||||
|
||||
'value': 'AUTOPHASES.obs',
|
||||
'namestring': 'Phase filename'},
|
||||
|
||||
'ctrfile': {'type': str,
|
||||
'tooltip': 'name of autoPyLoT-output control file for NLLoc',
|
||||
'value': 'Insheim_min1d2015_auto.in'},
|
||||
|
||||
'value': 'Insheim_min1d2015_auto.in',
|
||||
'namestring': 'Control filename'},
|
||||
|
||||
'ttpatter': {'type': str,
|
||||
'tooltip': 'pattern of NLLoc ttimes from grid',
|
||||
'value': 'ttime'},
|
||||
|
||||
'value': 'ttime',
|
||||
'namestring': 'Traveltime pattern'},
|
||||
|
||||
'outpatter': {'type': str,
|
||||
'tooltip': 'pattern of NLLoc-output file',
|
||||
'value': 'AUTOLOC_nlloc'},
|
||||
|
||||
'value': 'AUTOLOC_nlloc',
|
||||
'namestring': 'NLLoc output pattern'},
|
||||
|
||||
'vp': {'type': float,
|
||||
'tooltip': 'average P-wave velocity',
|
||||
'value': 3530.},
|
||||
|
||||
'value': 3530.,
|
||||
'namestring': 'P-velocity'},
|
||||
|
||||
'rho': {'type': float,
|
||||
'tooltip': 'average rock density [kg/m^3]',
|
||||
'value': 2500.},
|
||||
|
||||
'value': 2500.,
|
||||
'namestring': 'Density'},
|
||||
|
||||
'Qp': {'type': (float, float),
|
||||
'tooltip': 'quality factor for P waves (Qp*f^a); list(Qp, a)',
|
||||
'value': (300., 0.8)},
|
||||
|
||||
'value': (300., 0.8),
|
||||
'namestring': ('Quality factor', 'Qp1', 'Qp2')},
|
||||
|
||||
'pstart': {'type': float,
|
||||
'tooltip': 'start time [s] for calculating CF for P-picking',
|
||||
'value': 15.0},
|
||||
|
||||
'tooltip': 'start time [s] for calculating CF for P-picking (if TauPy:'
|
||||
' seconds relative to estimated onset)',
|
||||
'value': 15.0,
|
||||
'namestring': 'P start'},
|
||||
|
||||
'pstop': {'type': float,
|
||||
'tooltip': 'end time [s] for calculating CF for P-picking',
|
||||
'value': 60.0},
|
||||
|
||||
'tooltip': 'end time [s] for calculating CF for P-picking (if TauPy:'
|
||||
' seconds relative to estimated onset)',
|
||||
'value': 60.0,
|
||||
'namestring': 'P stop'},
|
||||
|
||||
'sstart': {'type': float,
|
||||
'tooltip': 'start time [s] relative to P-onset for calculating CF for S-picking',
|
||||
'value': -1.0},
|
||||
|
||||
'value': -1.0,
|
||||
'namestring': 'S start'},
|
||||
|
||||
'sstop': {'type': float,
|
||||
'tooltip': 'end time [s] after P-onset for calculating CF for S-picking',
|
||||
'value': 10.0},
|
||||
|
||||
'value': 10.0,
|
||||
'namestring': 'S stop'},
|
||||
|
||||
'bpz1': {'type': (float, float),
|
||||
'tooltip': 'lower/upper corner freq. of first band pass filter Z-comp. [Hz]',
|
||||
'value': (2, 20)},
|
||||
|
||||
'value': (2, 20),
|
||||
'namestring': ('Z-bandpass 1', 'Lower', 'Upper')},
|
||||
|
||||
'bpz2': {'type': (float, float),
|
||||
'tooltip': 'lower/upper corner freq. of second band pass filter Z-comp. [Hz]',
|
||||
'value': (2, 30)},
|
||||
|
||||
'value': (2, 30),
|
||||
'namestring': ('Z-bandpass 2', 'Lower', 'Upper')},
|
||||
|
||||
'bph1': {'type': (float, float),
|
||||
'tooltip': 'lower/upper corner freq. of first band pass filter H-comp. [Hz]',
|
||||
'value': (2, 15)},
|
||||
|
||||
'value': (2, 15),
|
||||
'namestring': ('H-bandpass 1', 'Lower', 'Upper')},
|
||||
|
||||
'bph2': {'type': (float, float),
|
||||
'tooltip': 'lower/upper corner freq. of second band pass filter z-comp. [Hz]',
|
||||
'value': (2, 20)},
|
||||
|
||||
'value': (2, 20),
|
||||
'namestring': ('H-bandpass 2', 'Lower', 'Upper')},
|
||||
|
||||
'algoP': {'type': str,
|
||||
'tooltip': 'choose algorithm for P-onset determination (HOS, ARZ, or AR3)',
|
||||
'value': 'HOS'},
|
||||
|
||||
'value': 'HOS',
|
||||
'namestring': 'P algorithm'},
|
||||
|
||||
'tlta': {'type': float,
|
||||
'tooltip': 'for HOS-/AR-AIC-picker, length of LTA window [s]',
|
||||
'value': 7.0},
|
||||
|
||||
'value': 7.0,
|
||||
'namestring': 'LTA window'},
|
||||
|
||||
'hosorder': {'type': int,
|
||||
'tooltip': 'for HOS-picker, order of Higher Order Statistics',
|
||||
'value': 4},
|
||||
|
||||
'value': 4,
|
||||
'namestring': 'HOS order'},
|
||||
|
||||
'Parorder': {'type': int,
|
||||
'tooltip': 'for AR-picker, order of AR process of Z-component',
|
||||
'value': 2},
|
||||
|
||||
'value': 2,
|
||||
'namestring': 'AR order P'},
|
||||
|
||||
'tdet1z': {'type': float,
|
||||
'tooltip': 'for AR-picker, length of AR determination window [s] for Z-component, 1st pick',
|
||||
'value': 1.2},
|
||||
|
||||
'value': 1.2,
|
||||
'namestring': 'AR det. window Z 1'},
|
||||
|
||||
'tpred1z': {'type': float,
|
||||
'tooltip': 'for AR-picker, length of AR prediction window [s] for Z-component, 1st pick',
|
||||
'value': 0.4},
|
||||
|
||||
'value': 0.4,
|
||||
'namestring': 'AR pred. window Z 1'},
|
||||
|
||||
'tdet2z': {'type': float,
|
||||
'tooltip': 'for AR-picker, length of AR determination window [s] for Z-component, 2nd pick',
|
||||
'value': 0.6},
|
||||
|
||||
'value': 0.6,
|
||||
'namestring': 'AR det. window Z 2'},
|
||||
|
||||
'tpred2z': {'type': float,
|
||||
'tooltip': 'for AR-picker, length of AR prediction window [s] for Z-component, 2nd pick',
|
||||
'value': 0.2},
|
||||
|
||||
'value': 0.2,
|
||||
'namestring': 'AR pred. window Z 2'},
|
||||
|
||||
'addnoise': {'type': float,
|
||||
'tooltip': 'add noise to seismogram for stable AR prediction',
|
||||
'value': 0.001},
|
||||
|
||||
'value': 0.001,
|
||||
'namestring': 'Add noise'},
|
||||
|
||||
'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)},
|
||||
|
||||
'value': (3, 0.1, 0.5, 1.0),
|
||||
'namestring': ('SNR windows P', 'Noise', 'Safety', 'Signal', 'Slope')},
|
||||
|
||||
'pickwinP': {'type': float,
|
||||
'tooltip': 'for initial AIC pick, length of P-pick window [s]',
|
||||
'value': 3.0},
|
||||
|
||||
'value': 3.0,
|
||||
'namestring': 'AIC window P'},
|
||||
|
||||
'Precalcwin': {'type': float,
|
||||
'tooltip': 'for HOS/AR, window length [s] for recalculation of CF (relative to 1st pick)',
|
||||
'value': 6.0},
|
||||
|
||||
'value': 6.0,
|
||||
'namestring': 'Recal. window P'},
|
||||
|
||||
'aictsmooth': {'type': float,
|
||||
'tooltip': 'for HOS/AR, take average of samples for smoothing of AIC-function [s]',
|
||||
'value': 0.2},
|
||||
|
||||
'value': 0.2,
|
||||
'namestring': 'AIC smooth P'},
|
||||
|
||||
'tsmoothP': {'type': float,
|
||||
'tooltip': 'for HOS/AR, take average of samples for smoothing CF [s]',
|
||||
'value': 0.1},
|
||||
|
||||
'value': 0.1,
|
||||
'namestring': 'CF smooth P'},
|
||||
|
||||
'ausP': {'type': float,
|
||||
'tooltip': 'for HOS/AR, artificial uplift of samples (aus) of CF (P)',
|
||||
'value': 0.001},
|
||||
|
||||
'value': 0.001,
|
||||
'namestring': 'Artificial uplift P'},
|
||||
|
||||
'nfacP': {'type': float,
|
||||
'tooltip': 'for HOS/AR, noise factor for noise level determination (P)',
|
||||
'value': 1.3},
|
||||
|
||||
'value': 1.3,
|
||||
'namestring': 'Noise factor P'},
|
||||
|
||||
'algoS': {'type': str,
|
||||
'tooltip': 'choose algorithm for S-onset determination (ARH or AR3)',
|
||||
'value': 'ARH'},
|
||||
|
||||
'value': 'ARH',
|
||||
'namestring': 'S algorithm'},
|
||||
|
||||
'tdet1h': {'type': float,
|
||||
'tooltip': 'for HOS/AR, length of AR-determination window [s], H-components, 1st pick',
|
||||
'value': 0.8},
|
||||
|
||||
'value': 0.8,
|
||||
'namestring': 'AR det. window H 1'},
|
||||
|
||||
'tpred1h': {'type': float,
|
||||
'tooltip': 'for HOS/AR, length of AR-prediction window [s], H-components, 1st pick',
|
||||
'value': 0.4},
|
||||
|
||||
'value': 0.4,
|
||||
'namestring': 'AR pred. window H 1'},
|
||||
|
||||
'tdet2h': {'type': float,
|
||||
'tooltip': 'for HOS/AR, length of AR-determinaton window [s], H-components, 2nd pick',
|
||||
'value': 0.6},
|
||||
|
||||
'value': 0.6,
|
||||
'namestring': 'AR det. window H 2'},
|
||||
|
||||
'tpred2h': {'type': float,
|
||||
'tooltip': 'for HOS/AR, length of AR-prediction window [s], H-components, 2nd pick',
|
||||
'value': 0.3},
|
||||
|
||||
'value': 0.3,
|
||||
'namestring': 'AR pred. window H 2'},
|
||||
|
||||
'Sarorder': {'type': int,
|
||||
'tooltip': 'for AR-picker, order of AR process of H-components',
|
||||
'value': 4},
|
||||
|
||||
'value': 4,
|
||||
'namestring': 'AR order S'},
|
||||
|
||||
'Srecalcwin': {'type': float,
|
||||
'tooltip': 'for AR-picker, window length [s] for recalculation of CF (2nd pick) (H)',
|
||||
'value': 5.0},
|
||||
|
||||
'value': 5.0,
|
||||
'namestring': 'Recal. window S'},
|
||||
|
||||
'pickwinS': {'type': float,
|
||||
'tooltip': 'for initial AIC pick, length of S-pick window [s]',
|
||||
'value': 3.0},
|
||||
|
||||
'value': 3.0,
|
||||
'namestring': 'AIC window S'},
|
||||
|
||||
'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)},
|
||||
|
||||
'value': (2, 0.2, 1.5, 0.5),
|
||||
'namestring': ('SNR windows S', 'Noise', 'Safety', 'Signal', 'Slope')},
|
||||
|
||||
'aictsmoothS': {'type': float,
|
||||
'tooltip': 'for AIC-picker, take average of samples for smoothing of AIC-function [s]',
|
||||
'value': 0.5},
|
||||
|
||||
'value': 0.5,
|
||||
'namestring': 'AIC smooth S'},
|
||||
|
||||
'tsmoothS': {'type': float,
|
||||
'tooltip': 'for AR-picker, take average of samples for smoothing CF [s] (S)',
|
||||
'value': 0.7},
|
||||
|
||||
'value': 0.7,
|
||||
'namestring': 'CF smooth S'},
|
||||
|
||||
'ausS': {'type': float,
|
||||
'tooltip': 'for HOS/AR, artificial uplift of samples (aus) of CF (S)',
|
||||
'value': 0.9},
|
||||
|
||||
'value': 0.9,
|
||||
'namestring': 'Artificial uplift S'},
|
||||
|
||||
'nfacS': {'type': float,
|
||||
'tooltip': 'for AR-picker, noise factor for noise level determination (S)',
|
||||
'value': 1.5},
|
||||
|
||||
'value': 1.5,
|
||||
'namestring': 'Noise factor S'},
|
||||
|
||||
'minfmweight': {'type': int,
|
||||
'tooltip': 'minimum required P weight for first-motion determination',
|
||||
'value': 1},
|
||||
|
||||
'value': 1,
|
||||
'namestring': 'Min. P weight'},
|
||||
|
||||
'minFMSNR': {'type': float,
|
||||
'tooltip': 'miniumum required SNR for first-motion determination',
|
||||
'value': 2.},
|
||||
|
||||
'value': 2.,
|
||||
'namestring': 'Min SNR'},
|
||||
|
||||
'fmpickwin': {'type': float,
|
||||
'tooltip': 'pick window around P onset for calculating zero crossings',
|
||||
'value': 0.2},
|
||||
|
||||
'value': 0.2,
|
||||
'namestring': 'Zero crossings window'},
|
||||
|
||||
'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)},
|
||||
|
||||
'value': (0.01, 0.02, 0.04, 0.08),
|
||||
'namestring': ('Time errors P', '0', '1', '2', '3')},
|
||||
|
||||
'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)},
|
||||
|
||||
'value': (0.04, 0.08, 0.16, 0.32),
|
||||
'namestring': ('Time errors S', '0', '1', '2', '3')},
|
||||
|
||||
'minAICPslope': {'type': float,
|
||||
'tooltip': 'below this slope [counts/s] the initial P pick is rejected',
|
||||
'value': 0.8},
|
||||
|
||||
'value': 0.8,
|
||||
'namestring': 'Min. slope P'},
|
||||
|
||||
'minAICPSNR': {'type': float,
|
||||
'tooltip': 'below this SNR the initial P pick is rejected',
|
||||
'value': 1.1},
|
||||
|
||||
'value': 1.1,
|
||||
'namestring': 'Min. SNR P'},
|
||||
|
||||
'minAICSslope': {'type': float,
|
||||
'tooltip': 'below this slope [counts/s] the initial S pick is rejected',
|
||||
'value': 1.},
|
||||
|
||||
'value': 1.,
|
||||
'namestring': 'Min. slope S'},
|
||||
|
||||
'minAICSSNR': {'type': float,
|
||||
'tooltip': 'below this SNR the initial S pick is rejected',
|
||||
'value': 1.5},
|
||||
|
||||
'value': 1.5,
|
||||
'namestring': 'Min. SNR S'},
|
||||
|
||||
'minsiglength': {'type': float,
|
||||
'tooltip': 'length of signal part for which amplitudes must exceed noiselevel [s]',
|
||||
'value': 1.},
|
||||
|
||||
'value': 1.,
|
||||
'namestring': 'Min. signal length'},
|
||||
|
||||
'noisefactor': {'type': float,
|
||||
'tooltip': 'noiselevel*noisefactor=threshold',
|
||||
'value': 1.0},
|
||||
|
||||
'value': 1.0,
|
||||
'namestring': 'Noise factor'},
|
||||
|
||||
'minpercent': {'type': float,
|
||||
'tooltip': 'required percentage of amplitudes exceeding threshold',
|
||||
'value': 10.},
|
||||
|
||||
'value': 10.,
|
||||
'namestring': 'Min amplitude [%]'},
|
||||
|
||||
'zfac': {'type': float,
|
||||
'tooltip': 'P-amplitude must exceed at least zfac times RMS-S amplitude',
|
||||
'value': 1.5},
|
||||
|
||||
'value': 1.5,
|
||||
'namestring': 'Z factor'},
|
||||
|
||||
'mdttolerance': {'type': float,
|
||||
'tooltip': 'maximum allowed deviation of P picks from median [s]',
|
||||
'value': 6.0},
|
||||
|
||||
'value': 6.0,
|
||||
'namestring': 'Median tolerance'},
|
||||
|
||||
'wdttolerance': {'type': float,
|
||||
'tooltip': 'maximum allowed deviation from Wadati-diagram',
|
||||
'value': 1.0},
|
||||
|
||||
'value': 1.0,
|
||||
'namestring': 'Wadati tolerance'},
|
||||
|
||||
'jackfactor': {'type': float,
|
||||
'tooltip': 'pick is removed if the variance of the subgroup with the pick removed is larger than the mean variance of all subgroups times safety factor',
|
||||
'value': 5.0,
|
||||
'namestring': 'Jackknife safety factor'},
|
||||
|
||||
'WAscaling': {'type': (float, float, float),
|
||||
'tooltip': 'Scaling relation (log(Ao)+Alog(r)+Br+C) of Wood-Anderson amplitude Ao [nm] \
|
||||
If zeros are set, original Richter magnitude is calculated!',
|
||||
'value': (0., 0., 0.)},
|
||||
'tooltip': 'Scaling relation (log(Ao)+Alog(r)+Br+C) of Wood-Anderson amplitude Ao [nm] \
|
||||
If zeros are set, original Richter magnitude is calculated!',
|
||||
'value': (0., 0., 0.),
|
||||
'namestring': ('Wood-Anderson scaling', '', '', '')},
|
||||
|
||||
'magscaling': {'type': (float, float),
|
||||
'tooltip': 'Scaling relation for derived local magnitude [a*Ml+b]. \
|
||||
If zeros are set, no scaling of network magnitude is applied!',
|
||||
'value': (0., 0.)}
|
||||
}
|
||||
'tooltip': 'Scaling relation for derived local magnitude [a*Ml+b]. \
|
||||
If zeros are set, no scaling of network magnitude is applied!',
|
||||
'value': (0., 0.),
|
||||
'namestring': ('Local mag. scaling', '', '')},
|
||||
|
||||
settings_main={
|
||||
'dirs':[
|
||||
'minfreq': {'type': (float, float),
|
||||
'tooltip': 'Lower filter frequency [P, S]',
|
||||
'value': (1.0, 1.0),
|
||||
'namestring': ('Lower freq.', 'P', 'S')},
|
||||
|
||||
'maxfreq': {'type': (float, float),
|
||||
'tooltip': 'Upper filter frequency [P, S]',
|
||||
'value': (10.0, 10.0),
|
||||
'namestring': ('Upper freq.', 'P', 'S')},
|
||||
|
||||
'filter_order': {'type': (int, int),
|
||||
'tooltip': 'filter order [P, S]',
|
||||
'value': (2, 2),
|
||||
'namestring': ('Order', 'P', 'S')},
|
||||
|
||||
'filter_type': {'type': (str, str),
|
||||
'tooltip': 'filter type (bandpass, bandstop, lowpass, highpass) [P, S]',
|
||||
'value': ('bandpass', 'bandpass'),
|
||||
'namestring': ('Type', 'P', 'S')},
|
||||
|
||||
'use_taup': {'type': bool,
|
||||
'tooltip': 'use estimated traveltimes from TauPy for calculating windows for CF',
|
||||
'value': True,
|
||||
'namestring': 'Use TauPy'},
|
||||
|
||||
'taup_model': {'type': str,
|
||||
'tooltip': 'define TauPy model for traveltime estimation. Possible values: 1066a, 1066b, ak135, ak135f, herrin, iasp91, jb, prem, pwdk, sp6',
|
||||
'value': 'iasp91',
|
||||
'namestring': 'TauPy model'}
|
||||
}
|
||||
|
||||
settings_main = {
|
||||
'dirs': [
|
||||
'rootpath',
|
||||
'datapath',
|
||||
'database',
|
||||
@ -297,34 +405,41 @@ settings_main={
|
||||
'invdir',
|
||||
'datastructure',
|
||||
'apverbose'],
|
||||
'nlloc':[
|
||||
'nlloc': [
|
||||
'nllocbin',
|
||||
'nllocroot',
|
||||
'phasefile',
|
||||
'ctrfile',
|
||||
'ttpatter',
|
||||
'outpatter'],
|
||||
'smoment':[
|
||||
'smoment': [
|
||||
'vp',
|
||||
'rho',
|
||||
'Qp'],
|
||||
'localmag':[
|
||||
'localmag': [
|
||||
'WAscaling',
|
||||
'magscaling'],
|
||||
'pick':[
|
||||
'filter': [
|
||||
'minfreq',
|
||||
'maxfreq',
|
||||
'filter_order',
|
||||
'filter_type'],
|
||||
'pick': [
|
||||
'extent',
|
||||
'pstart',
|
||||
'pstop',
|
||||
'sstart',
|
||||
'sstop',
|
||||
'use_taup',
|
||||
'taup_model',
|
||||
'bpz1',
|
||||
'bpz2',
|
||||
'bph1',
|
||||
'bph2']
|
||||
}
|
||||
|
||||
settings_special_pick={
|
||||
'z':[
|
||||
settings_special_pick = {
|
||||
'z': [
|
||||
'algoP',
|
||||
'tlta',
|
||||
'hosorder',
|
||||
@ -341,7 +456,7 @@ settings_special_pick={
|
||||
'tsmoothP',
|
||||
'ausP',
|
||||
'nfacP'],
|
||||
'h':[
|
||||
'h': [
|
||||
'algoS',
|
||||
'tdet1h',
|
||||
'tpred1h',
|
||||
@ -355,11 +470,11 @@ settings_special_pick={
|
||||
'tsmoothS',
|
||||
'ausS',
|
||||
'nfacS'],
|
||||
'fm':[
|
||||
'fm': [
|
||||
'minfmweight',
|
||||
'minFMSNR',
|
||||
'fmpickwin'],
|
||||
'quality':[
|
||||
'quality': [
|
||||
'timeerrorsP',
|
||||
'timeerrorsS',
|
||||
'minAICPslope',
|
||||
@ -371,5 +486,6 @@ settings_special_pick={
|
||||
'minpercent',
|
||||
'zfac',
|
||||
'mdttolerance',
|
||||
'wdttolerance']
|
||||
'wdttolerance',
|
||||
'jackfactor'],
|
||||
}
|
||||
|
@ -1,8 +1,9 @@
|
||||
#!/usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
from pylot.core.io import default_parameters
|
||||
from pylot.core.util.errors import ParameterError
|
||||
import default_parameters
|
||||
|
||||
|
||||
class PylotParameter(object):
|
||||
'''
|
||||
@ -69,13 +70,13 @@ class PylotParameter(object):
|
||||
|
||||
# Set default values of parameter names
|
||||
def __init_default_paras(self):
|
||||
parameters=default_parameters.defaults
|
||||
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
|
||||
|
||||
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 "PylotParameter('%s')" % self.__filename
|
||||
@ -107,7 +108,7 @@ class PylotParameter(object):
|
||||
yield key, value
|
||||
|
||||
def hasParam(self, parameter):
|
||||
if self.__parameter.has_key(parameter):
|
||||
if parameter in self.__parameter.keys():
|
||||
return True
|
||||
return False
|
||||
|
||||
@ -136,12 +137,13 @@ class PylotParameter(object):
|
||||
return self._settings_special_pick
|
||||
|
||||
def get_all_para_names(self):
|
||||
all_names=[]
|
||||
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()['localmag']
|
||||
all_names += self.get_main_para_names()['pick']
|
||||
all_names += self.get_main_para_names()['pick']
|
||||
all_names += self.get_main_para_names()['filter']
|
||||
all_names += self.get_special_para_names()['z']
|
||||
all_names += self.get_special_para_names()['h']
|
||||
all_names += self.get_special_para_names()['fm']
|
||||
@ -155,14 +157,14 @@ class PylotParameter(object):
|
||||
message = 'Type check failed for param: {}, is type: {}, expected type:{}'
|
||||
message = message.format(param, is_type, expect_type)
|
||||
print(Warning(message))
|
||||
|
||||
|
||||
def setParamKV(self, param, value):
|
||||
self.__setitem__(param, value)
|
||||
|
||||
def setParam(self, **kwargs):
|
||||
for key in kwargs:
|
||||
self.__setitem__(key, kwargs[key])
|
||||
|
||||
|
||||
@staticmethod
|
||||
def _printParameterError(errmsg):
|
||||
print('ParameterError:\n non-existent parameter %s' % errmsg)
|
||||
@ -171,7 +173,7 @@ class PylotParameter(object):
|
||||
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:
|
||||
@ -208,7 +210,10 @@ class PylotParameter(object):
|
||||
vallist = value.strip().split(' ')
|
||||
val = []
|
||||
for val0 in vallist:
|
||||
val0 = float(val0)
|
||||
try:
|
||||
val0 = float(val0)
|
||||
except:
|
||||
pass
|
||||
val.append(val0)
|
||||
else:
|
||||
val = str(value.strip())
|
||||
@ -221,9 +226,9 @@ class PylotParameter(object):
|
||||
# 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'+
|
||||
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 %{} data sets!\n'.format(self.get_main_para_names()['pick'][0]))
|
||||
separator = '%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n'
|
||||
|
||||
@ -236,16 +241,18 @@ class PylotParameter(object):
|
||||
'parameters for seismic moment estimation', separator)
|
||||
self.write_section(fid_out, self.get_main_para_names()['localmag'],
|
||||
'settings local magnitude', separator)
|
||||
self.write_section(fid_out, self.get_main_para_names()['filter'],
|
||||
'filter settings', separator)
|
||||
self.write_section(fid_out, self.get_main_para_names()['pick'],
|
||||
'common settings picker', separator)
|
||||
fid_out.write(('#special settings for calculating CF#\n'+
|
||||
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)
|
||||
'first-motion picker', None)
|
||||
self.write_section(fid_out, self.get_special_para_names()['quality'],
|
||||
'quality assessment', None)
|
||||
|
||||
@ -261,7 +268,7 @@ class PylotParameter(object):
|
||||
if type(value) == list or type(value) == tuple:
|
||||
value_tmp = ''
|
||||
for vl in value:
|
||||
value_tmp+= '{} '.format(vl)
|
||||
value_tmp += '{} '.format(vl)
|
||||
value = value_tmp
|
||||
tooltip = self.get_defaults()[name]['tooltip']
|
||||
if not len(str(value)) > l_val:
|
||||
@ -277,7 +284,7 @@ class PylotParameter(object):
|
||||
ttip = '%{:<{}}\n'.format(tooltip, l_ttip)
|
||||
else:
|
||||
ttip = '%{}\n'.format(tooltip)
|
||||
line = value+name+ttip
|
||||
line = value + name + ttip
|
||||
fid.write(line)
|
||||
|
||||
|
||||
@ -335,12 +342,13 @@ class FilterOptions(object):
|
||||
def parseFilterOptions(self):
|
||||
if self:
|
||||
robject = {'type': self.getFilterType(), 'corners': self.getOrder()}
|
||||
if len(self.getFreq()) > 1:
|
||||
if not self.getFilterType() in ['highpass', 'lowpass']:
|
||||
robject['freqmin'] = self.getFreq()[0]
|
||||
robject['freqmax'] = self.getFreq()[1]
|
||||
else:
|
||||
robject['freq'] = self.getFreq() if type(self.getFreq()) is \
|
||||
float else self.getFreq()[0]
|
||||
elif self.getFilterType() == 'highpass':
|
||||
robject['freq'] = self.getFreq()[0]
|
||||
elif self.getFilterType() == 'lowpass':
|
||||
robject['freq'] = self.getFreq()[1]
|
||||
return robject
|
||||
return None
|
||||
|
||||
|
@ -2,19 +2,23 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
import glob
|
||||
import obspy.core.event as ope
|
||||
import os
|
||||
import scipy.io as sio
|
||||
import warnings
|
||||
from obspy.core import UTCDateTime
|
||||
from obspy.core.util import AttribDict
|
||||
|
||||
import matplotlib.pyplot as plt
|
||||
import numpy as np
|
||||
import obspy.core.event as ope
|
||||
import scipy.io as sio
|
||||
from obspy.core import UTCDateTime
|
||||
from obspy.core.event import read_events
|
||||
from obspy.core.util import AttribDict
|
||||
from pylot.core.io.inputs import PylotParameter
|
||||
from pylot.core.io.location import create_arrival, create_event, \
|
||||
create_magnitude, create_origin, create_pick
|
||||
from pylot.core.io.location import create_event, \
|
||||
create_magnitude
|
||||
from pylot.core.pick.utils import select_for_phase
|
||||
from pylot.core.util.utils import getOwner, full_range, four_digits
|
||||
|
||||
|
||||
def add_amplitudes(event, amplitudes):
|
||||
amplitude_list = []
|
||||
for pick in event.picks:
|
||||
@ -33,6 +37,7 @@ def add_amplitudes(event, amplitudes):
|
||||
event.amplitudes = amplitude_list
|
||||
return event
|
||||
|
||||
|
||||
def readPILOTEvent(phasfn=None, locfn=None, authority_id='RUB', **kwargs):
|
||||
"""
|
||||
readPILOTEvent - function
|
||||
@ -189,26 +194,35 @@ def picksdict_from_picks(evt):
|
||||
PyLoT
|
||||
:param evt: Event object contain all available information
|
||||
:type evt: `~obspy.core.event.Event`
|
||||
:return: pick dictionary
|
||||
:return: pick dictionary (auto and manual)
|
||||
"""
|
||||
picks = {}
|
||||
picksdict = {
|
||||
'manual': {},
|
||||
'auto': {}
|
||||
}
|
||||
for pick in evt.picks:
|
||||
phase = {}
|
||||
station = pick.waveform_id.station_code
|
||||
channel = pick.waveform_id.channel_code
|
||||
network = pick.waveform_id.network_code
|
||||
try:
|
||||
onsets = picks[station]
|
||||
except KeyError as e:
|
||||
#print(e)
|
||||
onsets = {}
|
||||
mpp = pick.time
|
||||
spe = pick.time_errors.uncertainty
|
||||
try:
|
||||
picker = str(pick.method_id)
|
||||
if picker.startswith('smi:local/'):
|
||||
picker = picker.split('smi:local/')[1]
|
||||
except IndexError:
|
||||
picker = 'manual' # MP MP TODO maybe improve statement
|
||||
try:
|
||||
onsets = picksdict[picker][station]
|
||||
except KeyError as e:
|
||||
# print(e)
|
||||
onsets = {}
|
||||
try:
|
||||
lpp = mpp + pick.time_errors.upper_uncertainty
|
||||
epp = mpp - pick.time_errors.lower_uncertainty
|
||||
except TypeError as e:
|
||||
msg = e.message + ',\n falling back to symmetric uncertainties'
|
||||
msg = e + ',\n falling back to symmetric uncertainties'
|
||||
warnings.warn(msg)
|
||||
lpp = mpp + spe
|
||||
epp = mpp - spe
|
||||
@ -218,17 +232,12 @@ def picksdict_from_picks(evt):
|
||||
phase['spe'] = spe
|
||||
phase['channel'] = channel
|
||||
phase['network'] = network
|
||||
try:
|
||||
picker = str(pick.method_id)
|
||||
if picker.startswith('smi:local/'):
|
||||
picker = picker.split('smi:local/')[1]
|
||||
phase['picker'] = picker
|
||||
except IndexError:
|
||||
pass
|
||||
phase['picker'] = picker
|
||||
|
||||
onsets[pick.phase_hint] = phase.copy()
|
||||
picks[station] = onsets.copy()
|
||||
return picks
|
||||
picksdict[picker][station] = onsets.copy()
|
||||
return picksdict
|
||||
|
||||
|
||||
def picks_from_picksdict(picks, creation_info=None):
|
||||
picks_list = list()
|
||||
@ -238,8 +247,8 @@ def picks_from_picksdict(picks, creation_info=None):
|
||||
continue
|
||||
onset = phase['mpp']
|
||||
try:
|
||||
ccode = phase['channel']
|
||||
ncode = phase['network']
|
||||
ccode = phase['channel']
|
||||
ncode = phase['network']
|
||||
except:
|
||||
continue
|
||||
pick = ope.Pick()
|
||||
@ -253,8 +262,8 @@ def picks_from_picksdict(picks, creation_info=None):
|
||||
lpp = phase['lpp']
|
||||
pick.time_errors.lower_uncertainty = onset - epp
|
||||
pick.time_errors.upper_uncertainty = lpp - onset
|
||||
except KeyError as e:
|
||||
warnings.warn(e.message, RuntimeWarning)
|
||||
except (KeyError, TypeError) as e:
|
||||
warnings.warn(str(e), RuntimeWarning)
|
||||
try:
|
||||
picker = phase['picker']
|
||||
except KeyError as e:
|
||||
@ -263,8 +272,8 @@ def picks_from_picksdict(picks, creation_info=None):
|
||||
pick.phase_hint = label
|
||||
pick.method_id = ope.ResourceIdentifier(id=picker)
|
||||
pick.waveform_id = ope.WaveformStreamID(station_code=station,
|
||||
channel_code=ccode,
|
||||
network_code=ncode)
|
||||
channel_code=ccode,
|
||||
network_code=ncode)
|
||||
try:
|
||||
polarity = phase['fm']
|
||||
if polarity == 'U' or '+':
|
||||
@ -274,7 +283,7 @@ def picks_from_picksdict(picks, creation_info=None):
|
||||
else:
|
||||
pick.polarity = 'undecidable'
|
||||
except KeyError as e:
|
||||
if 'fm' in e.message: # no polarity information found for this phase
|
||||
if 'fm' in str(e): # no polarity information found for this phase
|
||||
pass
|
||||
else:
|
||||
raise e
|
||||
@ -286,7 +295,7 @@ def reassess_pilot_db(root_dir, db_dir, out_dir=None, fn_param=None, verbosity=0
|
||||
import glob
|
||||
|
||||
db_root = os.path.join(root_dir, db_dir)
|
||||
evt_list = glob.glob1(db_root,'e????.???.??')
|
||||
evt_list = glob.glob1(db_root, 'e????.???.??')
|
||||
|
||||
for evt in evt_list:
|
||||
if verbosity > 0:
|
||||
@ -294,7 +303,6 @@ def reassess_pilot_db(root_dir, db_dir, out_dir=None, fn_param=None, verbosity=0
|
||||
reassess_pilot_event(root_dir, db_dir, evt, out_dir, fn_param, verbosity)
|
||||
|
||||
|
||||
|
||||
def reassess_pilot_event(root_dir, db_dir, event_id, out_dir=None, fn_param=None, verbosity=0):
|
||||
from obspy import read
|
||||
|
||||
@ -302,7 +310,6 @@ def reassess_pilot_event(root_dir, db_dir, event_id, out_dir=None, fn_param=None
|
||||
from pylot.core.pick.utils import earllatepicker
|
||||
|
||||
if fn_param is None:
|
||||
import pylot.core.util.defaults as defaults
|
||||
fn_param = defaults.AUTOMATIC_DEFAULTS
|
||||
|
||||
default = PylotParameter(fn_param, verbosity)
|
||||
@ -336,7 +343,8 @@ def reassess_pilot_event(root_dir, db_dir, event_id, out_dir=None, fn_param=None
|
||||
except Exception as e:
|
||||
if 'No file matching file pattern:' in e.message:
|
||||
if verbosity > 0:
|
||||
warnings.warn('no waveform data found for station {station}'.format(station=station), RuntimeWarning)
|
||||
warnings.warn('no waveform data found for station {station}'.format(station=station),
|
||||
RuntimeWarning)
|
||||
datacheck.append(fn_pattern + ' (no data)\n')
|
||||
continue
|
||||
else:
|
||||
@ -360,7 +368,7 @@ def reassess_pilot_event(root_dir, db_dir, event_id, out_dir=None, fn_param=None
|
||||
default.get('nfac{0}'.format(phase)),
|
||||
default.get('tsnrz' if phase == 'P' else 'tsnrh'),
|
||||
Pick1=rel_pick,
|
||||
iplot=None,
|
||||
iplot=0,
|
||||
verbosity=0)
|
||||
if epp is None or lpp is None:
|
||||
continue
|
||||
@ -392,10 +400,10 @@ def reassess_pilot_event(root_dir, db_dir, event_id, out_dir=None, fn_param=None
|
||||
os.makedirs(out_dir)
|
||||
fnout_prefix = os.path.join(out_dir, 'PyLoT_{0}.'.format(event_id))
|
||||
evt.write(fnout_prefix + 'xml', format='QUAKEML')
|
||||
#evt.write(fnout_prefix + 'cnv', format='VELEST')
|
||||
# evt.write(fnout_prefix + 'cnv', format='VELEST')
|
||||
|
||||
|
||||
def writephases(arrivals, fformat, filename, parameter, eventinfo=None):
|
||||
def writephases(arrivals, fformat, filename, parameter=None, eventinfo=None):
|
||||
"""
|
||||
Function of methods to write phases to the following standard file
|
||||
formats used for locating earthquakes:
|
||||
@ -421,10 +429,10 @@ def writephases(arrivals, fformat, filename, parameter, eventinfo=None):
|
||||
:param: eventinfo, optional, needed for VELEST-cnv file
|
||||
and FOCMEC- and HASH-input files
|
||||
:type: `obspy.core.event.Event` object
|
||||
"""
|
||||
"""
|
||||
|
||||
if fformat == 'NLLoc':
|
||||
print ("Writing phases to %s for NLLoc" % filename)
|
||||
print("Writing phases to %s for NLLoc" % filename)
|
||||
fid = open("%s" % filename, 'w')
|
||||
# write header
|
||||
fid.write('# EQEVENT: %s Label: EQ%s Loc: X 0.00 Y 0.00 Z 10.00 OT 0.00 \n' %
|
||||
@ -448,7 +456,7 @@ def writephases(arrivals, fformat, filename, parameter, eventinfo=None):
|
||||
ss = onset.second
|
||||
ms = onset.microsecond
|
||||
ss_ms = ss + ms / 1000000.0
|
||||
pweight = 1 # use pick
|
||||
pweight = 1 # use pick
|
||||
try:
|
||||
if arrivals[key]['P']['weight'] >= 4:
|
||||
pweight = 0 # do not use pick
|
||||
@ -475,7 +483,7 @@ def writephases(arrivals, fformat, filename, parameter, eventinfo=None):
|
||||
ss = onset.second
|
||||
ms = onset.microsecond
|
||||
ss_ms = ss + ms / 1000000.0
|
||||
sweight = 1 # use pick
|
||||
sweight = 1 # use pick
|
||||
try:
|
||||
if arrivals[key]['S']['weight'] >= 4:
|
||||
sweight = 0 # do not use pick
|
||||
@ -493,15 +501,15 @@ def writephases(arrivals, fformat, filename, parameter, eventinfo=None):
|
||||
|
||||
fid.close()
|
||||
elif fformat == 'HYPO71':
|
||||
print ("Writing phases to %s for HYPO71" % filename)
|
||||
print("Writing phases to %s for HYPO71" % filename)
|
||||
fid = open("%s" % filename, 'w')
|
||||
# write header
|
||||
fid.write(' %s\n' %
|
||||
parameter.get('eventID'))
|
||||
parameter.get('eventID'))
|
||||
for key in arrivals:
|
||||
if arrivals[key]['P']['weight'] < 4:
|
||||
stat = key
|
||||
if len(stat) > 4: # HYPO71 handles only 4-string station IDs
|
||||
if len(stat) > 4: # HYPO71 handles only 4-string station IDs
|
||||
stat = stat[1:5]
|
||||
Ponset = arrivals[key]['P']['mpp']
|
||||
Sonset = arrivals[key]['S']['mpp']
|
||||
@ -541,41 +549,39 @@ def writephases(arrivals, fformat, filename, parameter, eventinfo=None):
|
||||
elif sweight >= 2:
|
||||
sstr = 'E'
|
||||
fid.write('%-4s%sP%s%d %02d%02d%02d%02d%02d%5.2f %s%sS %d %s\n' % (stat,
|
||||
pstr,
|
||||
fm,
|
||||
pweight,
|
||||
year,
|
||||
month,
|
||||
day,
|
||||
hh,
|
||||
mm,
|
||||
ss_ms,
|
||||
Sss_ms,
|
||||
sstr,
|
||||
sweight,
|
||||
Ao))
|
||||
pstr,
|
||||
fm,
|
||||
pweight,
|
||||
year,
|
||||
month,
|
||||
day,
|
||||
hh,
|
||||
mm,
|
||||
ss_ms,
|
||||
Sss_ms,
|
||||
sstr,
|
||||
sweight,
|
||||
Ao))
|
||||
else:
|
||||
fid.write('%-4s%sP%s%d %02d%02d%02d%02d%02d%5.2f %s\n' % (stat,
|
||||
pstr,
|
||||
fm,
|
||||
pweight,
|
||||
year,
|
||||
month,
|
||||
day,
|
||||
hh,
|
||||
mm,
|
||||
ss_ms,
|
||||
Ao))
|
||||
pstr,
|
||||
fm,
|
||||
pweight,
|
||||
year,
|
||||
month,
|
||||
day,
|
||||
hh,
|
||||
mm,
|
||||
ss_ms,
|
||||
Ao))
|
||||
|
||||
fid.close()
|
||||
|
||||
elif fformat == 'HYPOSAT':
|
||||
print ("Writing phases to %s for HYPOSAT" % filename)
|
||||
print("Writing phases to %s for HYPOSAT" % filename)
|
||||
fid = open("%s" % filename, 'w')
|
||||
# write header
|
||||
fid.write('%s, event %s \n' % (parameter.get('database'), parameter.get('eventID')))
|
||||
errP = parameter.get('timeerrorsP')
|
||||
errS = parameter.get('timeerrorsS')
|
||||
for key in arrivals:
|
||||
# P onsets
|
||||
if arrivals[key].has_key('P'):
|
||||
@ -592,7 +598,7 @@ def writephases(arrivals, fformat, filename, parameter, eventinfo=None):
|
||||
# use symmetrized picking error as std
|
||||
# (read the HYPOSAT manual)
|
||||
pstd = arrivals[key]['P']['spe']
|
||||
fid.write('%-5s P1 %4.0f %02d %02d %02d %02d %05.02f %5.3f -999. 0.00 -999. 0.00\n'
|
||||
fid.write('%-5s P1 %4.0f %02d %02d %02d %02d %05.02f %5.3f -999. 0.00 -999. 0.00\n'
|
||||
% (key, pyear, pmonth, pday, phh, pmm, Pss, pstd))
|
||||
# S onsets
|
||||
if arrivals[key].has_key('S') and arrivals[key]['S']:
|
||||
@ -607,16 +613,20 @@ def writephases(arrivals, fformat, filename, parameter, eventinfo=None):
|
||||
sms = Sonset.microsecond
|
||||
Sss = sss + sms / 1000000.0
|
||||
sstd = arrivals[key]['S']['spe']
|
||||
fid.write('%-5s S1 %4.0f %02d %02d %02d %02d %05.02f %5.3f -999. 0.00 -999. 0.00\n'
|
||||
fid.write('%-5s S1 %4.0f %02d %02d %02d %02d %05.02f %5.3f -999. 0.00 -999. 0.00\n'
|
||||
% (key, syear, smonth, sday, shh, smm, Sss, sstd))
|
||||
fid.close()
|
||||
|
||||
elif fformat == 'VELEST':
|
||||
print ("Writing phases to %s for VELEST" % filename)
|
||||
print("Writing phases to %s for VELEST" % filename)
|
||||
fid = open("%s" % filename, 'w')
|
||||
# get informations needed in cnv-file
|
||||
# check, whether latitude is N or S and longitude is E or W
|
||||
eventsource = eventinfo.origins[0]
|
||||
try:
|
||||
eventsource = eventinfo.origins[0]
|
||||
except:
|
||||
print("No source origin calculated yet, thus no cnv-file creation possible!")
|
||||
return
|
||||
if eventsource['latitude'] < 0:
|
||||
cns = 'S'
|
||||
else:
|
||||
@ -628,14 +638,14 @@ def writephases(arrivals, fformat, filename, parameter, eventinfo=None):
|
||||
# get last two integers of origin year
|
||||
stime = eventsource['time']
|
||||
if stime.year - 2000 >= 0:
|
||||
syear = stime.year - 2000
|
||||
syear = stime.year - 2000
|
||||
else:
|
||||
syear = stime.year - 1900
|
||||
ifx = 0 # default value, see VELEST manual, pp. 22-23
|
||||
syear = stime.year - 1900
|
||||
ifx = 0 # default value, see VELEST manual, pp. 22-23
|
||||
# write header
|
||||
fid.write('%s%02d%02d %02d%02d %05.2f %7.4f%c %8.4f%c %7.2f %6.2f %02.0f 0.0 0.03 1.0 1.0\n' % (
|
||||
syear, stime.month, stime.day, stime.hour, stime.minute, stime.second, eventsource['latitude'],
|
||||
cns, eventsource['longitude'], cew, eventsource['depth'],eventinfo.magnitudes[0]['mag'], ifx))
|
||||
syear, stime.month, stime.day, stime.hour, stime.minute, stime.second, eventsource['latitude'],
|
||||
cns, eventsource['longitude'], cew, eventsource['depth'], eventinfo.magnitudes[0]['mag'], ifx))
|
||||
n = 0
|
||||
for key in arrivals:
|
||||
# P onsets
|
||||
@ -643,33 +653,33 @@ def writephases(arrivals, fformat, filename, parameter, eventinfo=None):
|
||||
if arrivals[key]['P']['weight'] < 4:
|
||||
n += 1
|
||||
stat = key
|
||||
if len(stat) > 4: # VELEST handles only 4-string station IDs
|
||||
if len(stat) > 4: # VELEST handles only 4-string station IDs
|
||||
stat = stat[1:5]
|
||||
Ponset = arrivals[key]['P']['mpp']
|
||||
Pweight = arrivals[key]['P']['weight']
|
||||
Prt = Ponset - stime # onset time relative to source time
|
||||
Prt = Ponset - stime # onset time relative to source time
|
||||
if n % 6 is not 0:
|
||||
fid.write('%-4sP%d%6.2f' % (stat, Pweight, Prt))
|
||||
fid.write('%-4sP%d%6.2f' % (stat, Pweight, Prt))
|
||||
else:
|
||||
fid.write('%-4sP%d%6.2f\n' % (stat, Pweight, Prt))
|
||||
# S onsets
|
||||
fid.write('%-4sP%d%6.2f\n' % (stat, Pweight, Prt))
|
||||
# S onsets
|
||||
if arrivals[key].has_key('S'):
|
||||
if arrivals[key]['S']['weight'] < 4:
|
||||
n += 1
|
||||
stat = key
|
||||
if len(stat) > 4: # VELEST handles only 4-string station IDs
|
||||
if len(stat) > 4: # VELEST handles only 4-string station IDs
|
||||
stat = stat[1:5]
|
||||
Sonset = arrivals[key]['S']['mpp']
|
||||
Sweight = arrivals[key]['S']['weight']
|
||||
Srt = Ponset - stime # onset time relative to source time
|
||||
Srt = Ponset - stime # onset time relative to source time
|
||||
if n % 6 is not 0:
|
||||
fid.write('%-4sS%d%6.2f' % (stat, Sweight, Srt))
|
||||
fid.write('%-4sS%d%6.2f' % (stat, Sweight, Srt))
|
||||
else:
|
||||
fid.write('%-4sS%d%6.2f\n' % (stat, Sweight, Srt))
|
||||
fid.write('%-4sS%d%6.2f\n' % (stat, Sweight, Srt))
|
||||
fid.close()
|
||||
|
||||
elif fformat == 'hypoDD':
|
||||
print ("Writing phases to %s for hypoDD" % filename)
|
||||
print("Writing phases to %s for hypoDD" % filename)
|
||||
fid = open("%s" % filename, 'w')
|
||||
# get event information needed for hypoDD-phase file
|
||||
eventsource = eventinfo.origins[0]
|
||||
@ -678,59 +688,62 @@ def writephases(arrivals, fformat, filename, parameter, eventinfo=None):
|
||||
hddID = event.split('.')[0][1:5]
|
||||
# write header
|
||||
fid.write('# %d %d %d %d %d %5.2f %7.4f +%6.4f %7.4f %4.2f 0.1 0.5 %4.2f %s\n' % (
|
||||
stime.year, stime.month, stime.day, stime.hour, stime.minute, stime.second,
|
||||
eventsource['latitude'], eventsource['longitude'], eventsource['depth'] / 1000,
|
||||
eventinfo.magnitudes[0]['mag'], eventsource['quality']['standard_error'], hddID))
|
||||
stime.year, stime.month, stime.day, stime.hour, stime.minute, stime.second,
|
||||
eventsource['latitude'], eventsource['longitude'], eventsource['depth'] / 1000,
|
||||
eventinfo.magnitudes[0]['mag'], eventsource['quality']['standard_error'], hddID))
|
||||
for key in arrivals:
|
||||
if arrivals[key].has_key('P'):
|
||||
# P onsets
|
||||
if arrivals[key]['P']['weight'] < 4:
|
||||
Ponset = arrivals[key]['P']['mpp']
|
||||
Prt = Ponset - stime # onset time relative to source time
|
||||
fid.write('%s %6.3f 1 P\n' % (key, Prt))
|
||||
# S onsets
|
||||
Prt = Ponset - stime # onset time relative to source time
|
||||
fid.write('%s %6.3f 1 P\n' % (key, Prt))
|
||||
# S onsets
|
||||
if arrivals[key]['S']['weight'] < 4:
|
||||
Sonset = arrivals[key]['S']['mpp']
|
||||
Srt = Sonset - stime # onset time relative to source time
|
||||
fid.write('%-5s %6.3f 1 S\n' % (key, Srt))
|
||||
Srt = Sonset - stime # onset time relative to source time
|
||||
fid.write('%-5s %6.3f 1 S\n' % (key, Srt))
|
||||
|
||||
fid.close()
|
||||
|
||||
elif fformat == 'FOCMEC':
|
||||
print ("Writing phases to %s for FOCMEC" % filename)
|
||||
print("Writing phases to %s for FOCMEC" % filename)
|
||||
fid = open("%s" % filename, 'w')
|
||||
# get event information needed for FOCMEC-input file
|
||||
eventsource = eventinfo.origins[0]
|
||||
stime = eventsource['time']
|
||||
# write header line including event information
|
||||
fid.write('%s %d%02d%02d%02d%02d%02.0f %7.4f %6.4f %3.1f %3.1f\n' % (parameter.get('eventID'),
|
||||
stime.year, stime.month, stime.day, stime.hour, stime.minute, stime.second,
|
||||
eventsource['latitude'], eventsource['longitude'], eventsource['depth'] / 1000,
|
||||
eventinfo.magnitudes[0]['mag']))
|
||||
stime.year, stime.month, stime.day,
|
||||
stime.hour, stime.minute, stime.second,
|
||||
eventsource['latitude'],
|
||||
eventsource['longitude'],
|
||||
eventsource['depth'] / 1000,
|
||||
eventinfo.magnitudes[0]['mag']))
|
||||
picks = eventinfo.picks
|
||||
for key in arrivals:
|
||||
if arrivals[key].has_key('P'):
|
||||
if arrivals[key]['P']['weight'] < 4 and arrivals[key]['P']['fm'] is not None:
|
||||
stat = key
|
||||
for i in range(len(picks)):
|
||||
station = picks[i].waveform_id.station_code
|
||||
if station == stat:
|
||||
# get resource ID
|
||||
resid_picks = picks[i].get('resource_id')
|
||||
# find same ID in eventinfo
|
||||
# there it is the pick_id!!
|
||||
for j in range(len(eventinfo.origins[0].arrivals)):
|
||||
resid_eventinfo = eventinfo.origins[0].arrivals[j].get('pick_id')
|
||||
if resid_eventinfo == resid_picks and eventinfo.origins[0].arrivals[j].phase == 'P':
|
||||
if len(stat) > 4: # FOCMEC handles only 4-string station IDs
|
||||
stat = stat[1:5]
|
||||
az = eventinfo.origins[0].arrivals[j].get('azimuth')
|
||||
inz = eventinfo.origins[0].arrivals[j].get('takeoff_angle')
|
||||
fid.write('%-4s %6.2f %6.2f%s \n' % (stat,
|
||||
az,
|
||||
inz,
|
||||
arrivals[key]['P']['fm']))
|
||||
break
|
||||
station = picks[i].waveform_id.station_code
|
||||
if station == stat:
|
||||
# get resource ID
|
||||
resid_picks = picks[i].get('resource_id')
|
||||
# find same ID in eventinfo
|
||||
# there it is the pick_id!!
|
||||
for j in range(len(eventinfo.origins[0].arrivals)):
|
||||
resid_eventinfo = eventinfo.origins[0].arrivals[j].get('pick_id')
|
||||
if resid_eventinfo == resid_picks and eventinfo.origins[0].arrivals[j].phase == 'P':
|
||||
if len(stat) > 4: # FOCMEC handles only 4-string station IDs
|
||||
stat = stat[1:5]
|
||||
az = eventinfo.origins[0].arrivals[j].get('azimuth')
|
||||
inz = eventinfo.origins[0].arrivals[j].get('takeoff_angle')
|
||||
fid.write('%-4s %6.2f %6.2f%s \n' % (stat,
|
||||
az,
|
||||
inz,
|
||||
arrivals[key]['P']['fm']))
|
||||
break
|
||||
|
||||
fid.close()
|
||||
|
||||
@ -739,9 +752,9 @@ def writephases(arrivals, fformat, filename, parameter, eventinfo=None):
|
||||
# HASH-driver 1 and 2 (see HASH manual!)
|
||||
filename1 = filename + 'drv1' + '.phase'
|
||||
filename2 = filename + 'drv2' + '.phase'
|
||||
print ("Writing phases to %s for HASH for HASH-driver 1" % filename1)
|
||||
print("Writing phases to %s for HASH for HASH-driver 1" % filename1)
|
||||
fid1 = open("%s" % filename1, 'w')
|
||||
print ("Writing phases to %s for HASH for HASH-driver 2" % filename2)
|
||||
print("Writing phases to %s for HASH for HASH-driver 2" % filename2)
|
||||
fid2 = open("%s" % filename2, 'w')
|
||||
# get event information needed for HASH-input file
|
||||
eventsource = eventinfo.origins[0]
|
||||
@ -756,26 +769,32 @@ def writephases(arrivals, fformat, filename, parameter, eventinfo=None):
|
||||
erz = eventsource.depth_errors['uncertainty']
|
||||
stime = eventsource['time']
|
||||
if stime.year - 2000 >= 0:
|
||||
syear = stime.year - 2000
|
||||
syear = stime.year - 2000
|
||||
else:
|
||||
syear = stime.year - 1900
|
||||
syear = stime.year - 1900
|
||||
picks = eventinfo.picks
|
||||
# write header line including event information
|
||||
# for HASH-driver 1
|
||||
fid1.write('%s%02d%02d%02d%02d%5.2f%2dN%5.2f%3dE%5.2f%6.3f%4.2f%5.2f%5.2f%s\n' % (syear,
|
||||
stime.month, stime.day, stime.hour, stime.minute, stime.second,
|
||||
latdeg, latmin, londeg, lonmin, eventsource['depth'],
|
||||
eventinfo.magnitudes[0]['mag'], erh, erz,
|
||||
hashID))
|
||||
stime.month, stime.day,
|
||||
stime.hour, stime.minute,
|
||||
stime.second,
|
||||
latdeg, latmin, londeg,
|
||||
lonmin, eventsource['depth'],
|
||||
eventinfo.magnitudes[0][
|
||||
'mag'], erh, erz,
|
||||
hashID))
|
||||
# write header line including event information
|
||||
# for HASH-driver 2
|
||||
fid2.write('%d%02d%02d%02d%02d%5.2f%dN%5.2f%3dE%6.2f%5.2f %d %5.2f %5.2f %4.2f %s \n' % (syear, stime.month, stime.day,
|
||||
stime.hour, stime.minute, stime.second,
|
||||
latdeg,latmin,londeg, lonmin,
|
||||
eventsource['depth'],
|
||||
eventsource['quality']['used_phase_count'],
|
||||
erh, erz, eventinfo.magnitudes[0]['mag'],
|
||||
hashID))
|
||||
fid2.write(
|
||||
'%d%02d%02d%02d%02d%5.2f%dN%5.2f%3dE%6.2f%5.2f %d %5.2f %5.2f %4.2f %s \n' % (
|
||||
syear, stime.month, stime.day,
|
||||
stime.hour, stime.minute, stime.second,
|
||||
latdeg, latmin, londeg, lonmin,
|
||||
eventsource['depth'],
|
||||
eventsource['quality']['used_phase_count'],
|
||||
erh, erz, eventinfo.magnitudes[0]['mag'],
|
||||
hashID))
|
||||
|
||||
# write phase lines
|
||||
for key in arrivals:
|
||||
@ -786,36 +805,38 @@ def writephases(arrivals, fformat, filename, parameter, eventinfo=None):
|
||||
ncode = arrivals[key]['P']['network']
|
||||
|
||||
if arrivals[key]['P']['weight'] < 2:
|
||||
Pqual='I'
|
||||
Pqual = 'I'
|
||||
else:
|
||||
Pqual='E'
|
||||
|
||||
Pqual = 'E'
|
||||
|
||||
for i in range(len(picks)):
|
||||
station = picks[i].waveform_id.station_code
|
||||
if station == stat:
|
||||
# get resource ID
|
||||
resid_picks = picks[i].get('resource_id')
|
||||
# find same ID in eventinfo
|
||||
# there it is the pick_id!!
|
||||
for j in range(len(eventinfo.origins[0].arrivals)):
|
||||
resid_eventinfo = eventinfo.origins[0].arrivals[j].get('pick_id')
|
||||
if resid_eventinfo == resid_picks and eventinfo.origins[0].arrivals[j].phase == 'P':
|
||||
if len(stat) > 4: # HASH handles only 4-string station IDs
|
||||
stat = stat[1:5]
|
||||
az = eventinfo.origins[0].arrivals[j].get('azimuth')
|
||||
inz = eventinfo.origins[0].arrivals[j].get('takeoff_angle')
|
||||
dist = eventinfo.origins[0].arrivals[j].get('distance')
|
||||
# write phase line for HASH-driver 1
|
||||
fid1.write('%-4s%sP%s%d 0 %3.1f %03d %03d 2 1 %s\n' % (stat, Pqual, arrivals[key]['P']['fm'], arrivals[key]['P']['weight'],
|
||||
dist, inz, az, ccode))
|
||||
# write phase line for HASH-driver 2
|
||||
fid2.write('%-4s %s %s %s %s \n' % (
|
||||
stat,
|
||||
ncode,
|
||||
ccode,
|
||||
Pqual,
|
||||
arrivals[key]['P']['fm']))
|
||||
break
|
||||
station = picks[i].waveform_id.station_code
|
||||
if station == stat:
|
||||
# get resource ID
|
||||
resid_picks = picks[i].get('resource_id')
|
||||
# find same ID in eventinfo
|
||||
# there it is the pick_id!!
|
||||
for j in range(len(eventinfo.origins[0].arrivals)):
|
||||
resid_eventinfo = eventinfo.origins[0].arrivals[j].get('pick_id')
|
||||
if resid_eventinfo == resid_picks and eventinfo.origins[0].arrivals[j].phase == 'P':
|
||||
if len(stat) > 4: # HASH handles only 4-string station IDs
|
||||
stat = stat[1:5]
|
||||
az = eventinfo.origins[0].arrivals[j].get('azimuth')
|
||||
inz = eventinfo.origins[0].arrivals[j].get('takeoff_angle')
|
||||
dist = eventinfo.origins[0].arrivals[j].get('distance')
|
||||
# write phase line for HASH-driver 1
|
||||
fid1.write(
|
||||
'%-4s%sP%s%d 0 %3.1f %03d %03d 2 1 %s\n' % (
|
||||
stat, Pqual, arrivals[key]['P']['fm'], arrivals[key]['P']['weight'],
|
||||
dist, inz, az, ccode))
|
||||
# write phase line for HASH-driver 2
|
||||
fid2.write('%-4s %s %s %s %s \n' % (
|
||||
stat,
|
||||
ncode,
|
||||
ccode,
|
||||
Pqual,
|
||||
arrivals[key]['P']['fm']))
|
||||
break
|
||||
|
||||
fid1.write(' %s' % hashID)
|
||||
fid1.close()
|
||||
@ -841,7 +862,155 @@ def merge_picks(event, picks):
|
||||
network = pick.waveform_id.network_code
|
||||
method = pick.method_id
|
||||
for p in event.picks:
|
||||
if p.waveform_id.station_code == station and p.phase_hint == phase:
|
||||
if p.waveform_id.station_code == station\
|
||||
and p.waveform_id.network_code == network\
|
||||
and p.phase_hint == phase\
|
||||
and (str(p.method_id) in str(method)
|
||||
or str(method) in str(p.method_id)):
|
||||
p.time, p.time_errors, p.waveform_id.network_code, p.method_id = time, err, network, method
|
||||
del time, err, phase, station, network, method
|
||||
return event
|
||||
|
||||
|
||||
def getQualitiesfromxml(xmlnames, ErrorsP, ErrorsS, plotflag=1):
|
||||
"""
|
||||
Script to get onset uncertainties from Quakeml.xml files created by PyLoT.
|
||||
Uncertainties are tranformed into quality classes and visualized via histogram if desired.
|
||||
Ludger Küperkoch, BESTEC GmbH, 07/2017
|
||||
"""
|
||||
|
||||
from pylot.core.pick.utils import getQualityFromUncertainty
|
||||
from pylot.core.util.utils import loopIdentifyPhase, identifyPhase
|
||||
|
||||
# read all onset weights
|
||||
Pw0 = []
|
||||
Pw1 = []
|
||||
Pw2 = []
|
||||
Pw3 = []
|
||||
Pw4 = []
|
||||
Sw0 = []
|
||||
Sw1 = []
|
||||
Sw2 = []
|
||||
Sw3 = []
|
||||
Sw4 = []
|
||||
for names in xmlnames:
|
||||
print("Getting onset weights from {}".format(names))
|
||||
cat = read_events(names)
|
||||
cat_copy = cat.copy()
|
||||
arrivals = cat.events[0].picks
|
||||
arrivals_copy = cat_copy.events[0].picks
|
||||
# Prefere manual picks if qualities are sufficient!
|
||||
for Pick in arrivals:
|
||||
if (Pick.method_id.id).split('/')[1] == 'manual':
|
||||
mstation = Pick.waveform_id.station_code
|
||||
mstation_ext = mstation + '_'
|
||||
for mpick in arrivals_copy:
|
||||
phase = identifyPhase(loopIdentifyPhase(Pick.phase_hint))
|
||||
if phase == 'P':
|
||||
if ((mpick.waveform_id.station_code == mstation) or
|
||||
(mpick.waveform_id.station_code == mstation_ext)) and \
|
||||
((mpick.method_id).split('/')[1] == 'auto') and \
|
||||
(mpick.time_errors['uncertainty'] <= ErrorsP[3]):
|
||||
del mpick
|
||||
break
|
||||
elif phase == 'S':
|
||||
if ((mpick.waveform_id.station_code == mstation) or
|
||||
(mpick.waveform_id.station_code == mstation_ext)) and \
|
||||
((mpick.method_id).split('/')[1] == 'auto') and \
|
||||
(mpick.time_errors['uncertainty'] <= ErrorsS[3]):
|
||||
del mpick
|
||||
break
|
||||
lendiff = len(arrivals) - len(arrivals_copy)
|
||||
if lendiff is not 0:
|
||||
print("Found manual as well as automatic picks, prefered the {} manual ones!".format(lendiff))
|
||||
|
||||
for Pick in arrivals_copy:
|
||||
phase = identifyPhase(loopIdentifyPhase(Pick.phase_hint))
|
||||
if phase == 'P':
|
||||
Pqual = getQualityFromUncertainty(Pick.time_errors.uncertainty, ErrorsP)
|
||||
if Pqual == 0:
|
||||
Pw0.append(Pick.time_errors.uncertainty)
|
||||
elif Pqual == 1:
|
||||
Pw1.append(Pick.time_errors.uncertainty)
|
||||
elif Pqual == 2:
|
||||
Pw2.append(Pick.time_errors.uncertainty)
|
||||
elif Pqual == 3:
|
||||
Pw3.append(Pick.time_errors.uncertainty)
|
||||
elif Pqual == 4:
|
||||
Pw4.append(Pick.time_errors.uncertainty)
|
||||
elif phase == 'S':
|
||||
Squal = getQualityFromUncertainty(Pick.time_errors.uncertainty, ErrorsS)
|
||||
if Squal == 0:
|
||||
Sw0.append(Pick.time_errors.uncertainty)
|
||||
elif Squal == 1:
|
||||
Sw1.append(Pick.time_errors.uncertainty)
|
||||
elif Squal == 2:
|
||||
Sw2.append(Pick.time_errors.uncertainty)
|
||||
elif Squal == 3:
|
||||
Sw3.append(Pick.time_errors.uncertainty)
|
||||
elif Squal == 4:
|
||||
Sw4.append(Pick.time_errors.uncertainty)
|
||||
else:
|
||||
print("Phase hint not defined for picking!")
|
||||
pass
|
||||
|
||||
if plotflag == 0:
|
||||
Punc = [Pw0, Pw1, Pw2, Pw3, Pw4]
|
||||
Sunc = [Sw0, Sw1, Sw2, Sw3, Sw4]
|
||||
return Punc, Sunc
|
||||
else:
|
||||
# get percentage of weights
|
||||
numPweights = np.sum([len(Pw0), len(Pw1), len(Pw2), len(Pw3), len(Pw4)])
|
||||
numSweights = np.sum([len(Sw0), len(Sw1), len(Sw2), len(Sw3), len(Sw4)])
|
||||
if len(Pw0) > 0:
|
||||
P0perc = 100 / numPweights * len(Pw0)
|
||||
else:
|
||||
P0perc = 0
|
||||
if len(Pw1) > 0:
|
||||
P1perc = 100 / numPweights * len(Pw1)
|
||||
else:
|
||||
P1perc = 0
|
||||
if len(Pw2) > 0:
|
||||
P2perc = 100 / numPweights * len(Pw2)
|
||||
else:
|
||||
P2perc = 0
|
||||
if len(Pw3) > 0:
|
||||
P3perc = 100 / numPweights * len(Pw3)
|
||||
else:
|
||||
P3perc = 0
|
||||
if len(Pw4) > 0:
|
||||
P4perc = 100 / numPweights * len(Pw4)
|
||||
else:
|
||||
P4perc = 0
|
||||
if len(Sw0) > 0:
|
||||
S0perc = 100 / numSweights * len(Sw0)
|
||||
else:
|
||||
S0perc = 0
|
||||
if len(Sw1) > 0:
|
||||
S1perc = 100 / numSweights * len(Sw1)
|
||||
else:
|
||||
S1perc = 0
|
||||
if len(Sw2) > 0:
|
||||
S2perc = 100 / numSweights * len(Sw2)
|
||||
else:
|
||||
S2perc = 0
|
||||
if len(Sw3) > 0:
|
||||
S3perc = 100 / numSweights * len(Sw3)
|
||||
else:
|
||||
S3perc = 0
|
||||
if len(Sw4) > 0:
|
||||
S4perc = 100 / numSweights * len(Sw4)
|
||||
else:
|
||||
S4perc = 0
|
||||
|
||||
weights = ('0', '1', '2', '3', '4')
|
||||
y_pos = np.arange(len(weights))
|
||||
width = 0.34
|
||||
plt.bar(y_pos - width, [P0perc, P1perc, P2perc, P3perc, P4perc], width, color='black')
|
||||
plt.bar(y_pos, [S0perc, S1perc, S2perc, S3perc, S4perc], width, color='red')
|
||||
plt.ylabel('%')
|
||||
plt.xticks(y_pos, weights)
|
||||
plt.xlim([-0.5, 4.5])
|
||||
plt.xlabel('Qualities')
|
||||
plt.title('{0} P-Qualities, {1} S-Qualities'.format(numPweights, numSweights))
|
||||
plt.show()
|
||||
|
@ -6,6 +6,7 @@ from pylot.core.util.version import get_git_version as _getVersionString
|
||||
|
||||
__version__ = _getVersionString()
|
||||
|
||||
|
||||
def export(picks, fnout, parameter, eventinfo):
|
||||
'''
|
||||
Take <picks> dictionary and exports picking data to a focmec
|
||||
|
@ -6,6 +6,7 @@ from pylot.core.util.version import get_git_version as _getVersionString
|
||||
|
||||
__version__ = _getVersionString()
|
||||
|
||||
|
||||
def export(picks, fnout, parameter, eventinfo):
|
||||
'''
|
||||
Take <picks> dictionary and exports picking data to a HASH
|
||||
|
@ -6,6 +6,7 @@ from pylot.core.util.version import get_git_version as _getVersionString
|
||||
|
||||
__version__ = _getVersionString()
|
||||
|
||||
|
||||
def export(picks, fnout, parameter):
|
||||
'''
|
||||
Take <picks> dictionary and exports picking data to a HYPO71
|
||||
|
@ -6,6 +6,7 @@ from pylot.core.util.version import get_git_version as _getVersionString
|
||||
|
||||
__version__ = _getVersionString()
|
||||
|
||||
|
||||
def export(picks, fnout, parameter, eventinfo):
|
||||
'''
|
||||
Take <picks> dictionary and exports picking data to a hypoDD
|
||||
|
@ -6,6 +6,7 @@ from pylot.core.util.version import get_git_version as _getVersionString
|
||||
|
||||
__version__ = _getVersionString()
|
||||
|
||||
|
||||
def export(picks, fnout, parameter):
|
||||
'''
|
||||
Take <picks> dictionary and exports picking data to a HYPOSAT
|
||||
|
@ -1,9 +1,10 @@
|
||||
#!/usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
import subprocess
|
||||
import os
|
||||
import glob
|
||||
import os
|
||||
import subprocess
|
||||
|
||||
from obspy import read_events
|
||||
from pylot.core.io.phases import writephases
|
||||
from pylot.core.util.utils import getPatternLine, runProgram, which
|
||||
@ -11,9 +12,11 @@ from pylot.core.util.version import get_git_version as _getVersionString
|
||||
|
||||
__version__ = _getVersionString()
|
||||
|
||||
|
||||
class NLLocError(EnvironmentError):
|
||||
pass
|
||||
|
||||
|
||||
def export(picks, fnout, parameter):
|
||||
'''
|
||||
Take <picks> dictionary and exports picking data to a NLLOC-obs
|
||||
@ -58,7 +61,7 @@ def modify_inputs(ctrfn, root, nllocoutn, phasefn, tttn):
|
||||
locfiles = 'LOCFILES %s NLLOC_OBS %s %s 0\n' % (phasefile, tttable, nllocout)
|
||||
|
||||
# modification of NLLoc-control file
|
||||
print ("Modifying NLLoc-control file %s ..." % ctrfile)
|
||||
print("Modifying NLLoc-control file %s ..." % ctrfile)
|
||||
curlocfiles = getPatternLine(ctrfile, 'LOCFILES')
|
||||
nllfile = open(ctrfile, 'r')
|
||||
filedata = nllfile.read()
|
||||
@ -94,7 +97,7 @@ def locate(fnin, infile=None):
|
||||
|
||||
def read_location(fn):
|
||||
path, file = os.path.split(fn)
|
||||
file = glob.glob1(path, file + '.[0-9]*.grid0.loc.hyp')
|
||||
file = glob.glob1(path, file + '.[0-9]*.grid0.loc.hyp')
|
||||
if len(file) > 1:
|
||||
raise IOError('ambiguous location name {0}'.format(file))
|
||||
fn = os.path.join(path, file[0])
|
||||
|
@ -6,7 +6,8 @@ from pylot.core.util.version import get_git_version as _getVersionString
|
||||
|
||||
__version__ = _getVersionString()
|
||||
|
||||
def export(picks, fnout, parameter, eventinfo):
|
||||
|
||||
def export(picks, fnout, eventinfo, parameter=None):
|
||||
'''
|
||||
Take <picks> dictionary and exports picking data to a VELEST-cnv
|
||||
<phasefile> without creating an ObsPy event object.
|
||||
@ -17,11 +18,11 @@ def export(picks, fnout, parameter, eventinfo):
|
||||
:param fnout: complete path to the exporting obs file
|
||||
:type fnout: str
|
||||
|
||||
:param: parameter, all input information
|
||||
:type: object
|
||||
|
||||
:param: eventinfo, source time needed for VELEST-cnv format
|
||||
:type: list object
|
||||
|
||||
:param: parameter, all input information
|
||||
:type: object
|
||||
'''
|
||||
# write phases to VELEST-phase file
|
||||
writephases(picks, 'VELEST', fnout, parameter, eventinfo)
|
||||
|
@ -11,25 +11,37 @@ function conglomerate utils.
|
||||
|
||||
import matplotlib.pyplot as plt
|
||||
import numpy as np
|
||||
from pylot.core.io.data import Data
|
||||
from pylot.core.io.inputs import PylotParameter
|
||||
from pylot.core.pick.picker import AICPicker, PragPicker
|
||||
from pylot.core.pick.charfuns import CharacteristicFunction
|
||||
from pylot.core.pick.charfuns import HOScf, AICcf, ARZcf, ARHcf, AR3Ccf
|
||||
from pylot.core.pick.picker import AICPicker, PragPicker
|
||||
from pylot.core.pick.utils import checksignallength, checkZ4S, earllatepicker, \
|
||||
getSNR, fmpicker, checkPonsets, wadaticheck
|
||||
from pylot.core.util.utils import getPatternLine, gen_Pool
|
||||
from pylot.core.io.data import Data
|
||||
from pylot.core.util.utils import getPatternLine, gen_Pool,\
|
||||
real_Bool, identifyPhaseID
|
||||
|
||||
from obspy.taup import TauPyModel
|
||||
|
||||
|
||||
def autopickevent(data, param, iplot=0, fig_dict=None):
|
||||
def autopickevent(data, param, iplot=0, fig_dict=None, fig_dict_wadatijack=None, ncores=0, metadata=None, origin=None):
|
||||
stations = []
|
||||
all_onsets = {}
|
||||
input_tuples = []
|
||||
try:
|
||||
iplot = int(iplot)
|
||||
except:
|
||||
if iplot == True or iplot == 'True':
|
||||
iplot = 2
|
||||
else:
|
||||
iplot = 0
|
||||
|
||||
|
||||
# get some parameters for quality control from
|
||||
# parameter input file (usually autoPyLoT.in).
|
||||
# parameter input file (usually pylot.in).
|
||||
wdttolerance = param.get('wdttolerance')
|
||||
mdttolerance = param.get('mdttolerance')
|
||||
jackfactor = param.get('jackfactor')
|
||||
apverbose = param.get('apverbose')
|
||||
for n in range(len(data)):
|
||||
station = data[n].stats.station
|
||||
@ -41,46 +53,67 @@ def autopickevent(data, param, iplot=0, fig_dict=None):
|
||||
for station in stations:
|
||||
topick = data.select(station=station)
|
||||
|
||||
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 == None or iplot == 'None' or iplot == 0:
|
||||
input_tuples.append((topick, param, apverbose, metadata, origin))
|
||||
if iplot > 0:
|
||||
all_onsets[station] = autopickstation(topick, param, verbose=apverbose,
|
||||
iplot=iplot, fig_dict=fig_dict,
|
||||
metadata=metadata, origin=origin)
|
||||
|
||||
if iplot>0:
|
||||
if iplot > 0:
|
||||
print('iPlot Flag active: NO MULTIPROCESSING possible.')
|
||||
return all_onsets
|
||||
|
||||
pool = gen_Pool()
|
||||
# rename str for ncores in case ncores == 0 (use all cores)
|
||||
ncores_str = ncores if ncores != 0 else 'all available'
|
||||
|
||||
print('Autopickstation: Distribute autopicking for {} '
|
||||
'stations on {} cores.'.format(len(input_tuples), ncores_str))
|
||||
|
||||
pool = gen_Pool(ncores)
|
||||
result = pool.map(call_autopickstation, input_tuples)
|
||||
pool.close()
|
||||
|
||||
for pick in result:
|
||||
station = pick['station']
|
||||
pick.pop('station')
|
||||
all_onsets[station] = pick
|
||||
if pick:
|
||||
station = pick['station']
|
||||
pick.pop('station')
|
||||
all_onsets[station] = pick
|
||||
|
||||
return all_onsets
|
||||
#return all_onsets
|
||||
|
||||
# quality control
|
||||
# median check and jackknife on P-onset times
|
||||
jk_checked_onsets = checkPonsets(all_onsets, mdttolerance, iplot)
|
||||
jk_checked_onsets = checkPonsets(all_onsets, mdttolerance, jackfactor, 1, fig_dict_wadatijack)
|
||||
#return jk_checked_onsets
|
||||
# check S-P times (Wadati)
|
||||
return wadaticheck(jk_checked_onsets, wdttolerance, iplot)
|
||||
wadationsets = wadaticheck(jk_checked_onsets, wdttolerance, 1, fig_dict_wadatijack)
|
||||
return wadationsets
|
||||
|
||||
|
||||
def call_autopickstation(input_tuple):
|
||||
wfstream, pickparam, verbose = input_tuple
|
||||
#multiprocessing not possible with interactive plotting
|
||||
return autopickstation(wfstream, pickparam, verbose, iplot=0)
|
||||
wfstream, pickparam, verbose, metadata, origin = input_tuple
|
||||
# multiprocessing not possible with interactive plotting
|
||||
return autopickstation(wfstream, pickparam, verbose, iplot=0, metadata=metadata, origin=origin)
|
||||
|
||||
|
||||
def autopickstation(wfstream, pickparam, verbose=False, iplot=0, fig_dict=None):
|
||||
def get_source_coords(parser, station_id):
|
||||
station_coords = None
|
||||
try:
|
||||
station_coords = parser.get_coordinates(station_id)
|
||||
except Exception as e:
|
||||
print('Could not get source coordinates for station {}: {}'.format(station_id, e))
|
||||
return station_coords
|
||||
|
||||
|
||||
def autopickstation(wfstream, pickparam, verbose=False,
|
||||
iplot=0, fig_dict=None, metadata=None, origin=None):
|
||||
"""
|
||||
:param wfstream: `~obspy.core.stream.Stream` containing waveform
|
||||
:type wfstream: obspy.core.stream.Stream
|
||||
|
||||
:param pickparam: container of picking parameters from input file,
|
||||
usually autoPyLoT.in
|
||||
usually pylot.in
|
||||
:type pickparam: PylotParameter
|
||||
:param verbose:
|
||||
:type verbose: bool
|
||||
@ -88,11 +121,10 @@ def autopickstation(wfstream, pickparam, verbose=False, iplot=0, fig_dict=None):
|
||||
"""
|
||||
|
||||
# declaring pickparam variables (only for convenience)
|
||||
# read your autoPyLoT.in for details!
|
||||
# read your pylot.in for details!
|
||||
plt_flag = 0
|
||||
|
||||
# special parameters for P picking
|
||||
iplot = iplot
|
||||
|
||||
algoP = pickparam.get('algoP')
|
||||
pstart = pickparam.get('pstart')
|
||||
pstop = pickparam.get('pstop')
|
||||
@ -102,6 +134,7 @@ def autopickstation(wfstream, pickparam, verbose=False, iplot=0, fig_dict=None):
|
||||
bpz1 = pickparam.get('bpz1')
|
||||
bpz2 = pickparam.get('bpz2')
|
||||
pickwinP = pickparam.get('pickwinP')
|
||||
aictsmoothP = pickparam.get('aictsmooth')
|
||||
tsmoothP = pickparam.get('tsmoothP')
|
||||
ausP = pickparam.get('ausP')
|
||||
nfacP = pickparam.get('nfacP')
|
||||
@ -117,6 +150,8 @@ def autopickstation(wfstream, pickparam, verbose=False, iplot=0, fig_dict=None):
|
||||
algoS = pickparam.get('algoS')
|
||||
sstart = pickparam.get('sstart')
|
||||
sstop = pickparam.get('sstop')
|
||||
use_taup = real_Bool(pickparam.get('use_taup'))
|
||||
taup_model = pickparam.get('taup_model')
|
||||
bph1 = pickparam.get('bph1')
|
||||
bph2 = pickparam.get('bph2')
|
||||
tsnrh = pickparam.get('tsnrh')
|
||||
@ -182,25 +217,82 @@ def autopickstation(wfstream, pickparam, verbose=False, iplot=0, fig_dict=None):
|
||||
if len(ndat) == 0: # check for other components
|
||||
ndat = wfstream.select(component="1")
|
||||
|
||||
if not zdat:
|
||||
print('No z-component found for station {}. STOP'.format(wfstream[0].stats.station))
|
||||
return
|
||||
|
||||
if algoP == 'HOS' or algoP == 'ARZ' and zdat is not None:
|
||||
msg = '##################################################\nautopickstation:' \
|
||||
' Working on P onset of station {station}\nFiltering vertical ' \
|
||||
'trace ...\n{data}'.format(station=zdat[0].stats.station,
|
||||
'trace ...\n{data}'.format(station=wfstream[0].stats.station,
|
||||
data=str(zdat))
|
||||
if verbose: print(msg)
|
||||
z_copy = zdat.copy()
|
||||
# filter and taper data
|
||||
tr_filt = zdat[0].copy()
|
||||
#remove constant offset from data to avoid unwanted filter response
|
||||
tr_filt.detrend(type='demean')
|
||||
# filter and taper data
|
||||
tr_filt.filter('bandpass', freqmin=bpz1[0], freqmax=bpz1[1],
|
||||
zerophase=False)
|
||||
tr_filt.taper(max_percentage=0.05, type='hann')
|
||||
z_copy[0].data = tr_filt.data
|
||||
##############################################################
|
||||
# check length of waveform and compare with cut times
|
||||
Lc = pstop - pstart
|
||||
|
||||
# for global seismology: use tau-p method for estimating travel times (needs source and station coords.)
|
||||
# if not given: sets Lc to infinity to use full stream
|
||||
if use_taup == True:
|
||||
Lc = np.inf
|
||||
print('autopickstation: use_taup flag active.')
|
||||
if not metadata[1]:
|
||||
print('Warning: Could not use TauPy to estimate onsets as there are no metadata given.')
|
||||
else:
|
||||
station_id = wfstream[0].get_id()
|
||||
parser = metadata[1]
|
||||
station_coords = get_source_coords(parser, station_id)
|
||||
if station_coords and origin:
|
||||
source_origin = origin[0]
|
||||
model = TauPyModel(taup_model)
|
||||
arrivals = model.get_travel_times_geo(
|
||||
source_origin.depth,
|
||||
source_origin.latitude,
|
||||
source_origin.longitude,
|
||||
station_coords['latitude'],
|
||||
station_coords['longitude']
|
||||
)
|
||||
phases = {'P': [],
|
||||
'S': []}
|
||||
for arr in arrivals:
|
||||
phases[identifyPhaseID(arr.phase.name)].append(arr)
|
||||
|
||||
# get first P and S onsets from arrivals list
|
||||
arrP, estFirstP = min([(arr, arr.time) for arr in phases['P']], key = lambda t: t[1])
|
||||
arrS, estFirstS = min([(arr, arr.time) for arr in phases['S']], key = lambda t: t[1])
|
||||
print('autopick: estimated first arrivals for P: {} s, S:{} s after event'
|
||||
' origin time using TauPy'.format(estFirstP, estFirstS))
|
||||
|
||||
# modifiy pstart and pstop relative to estimated first P arrival (relative to station time axis)
|
||||
pstart += (source_origin.time + estFirstP) - zdat[0].stats.starttime
|
||||
pstop += (source_origin.time + estFirstP) - zdat[0].stats.starttime
|
||||
print('autopick: CF calculation times respectively:'
|
||||
' pstart: {} s, pstop: {} s'.format(pstart, pstop))
|
||||
elif not origin:
|
||||
print('No source origins given!')
|
||||
|
||||
# make sure pstart and pstop are inside zdat[0]
|
||||
pstart = max(pstart, 0)
|
||||
pstop = min(pstop, len(zdat[0])*zdat[0].stats.delta)
|
||||
|
||||
if not use_taup == True or origin:
|
||||
Lc = pstop - pstart
|
||||
|
||||
Lwf = zdat[0].stats.endtime - zdat[0].stats.starttime
|
||||
Ldiff = Lwf - Lc
|
||||
if Ldiff < 0:
|
||||
if not Lwf > 0:
|
||||
print('autopickstation: empty trace! Return!')
|
||||
return
|
||||
|
||||
Ldiff = Lwf - abs(Lc)
|
||||
if Ldiff < 0 or pstop <= pstart:
|
||||
msg = 'autopickstation: Cutting times are too large for actual ' \
|
||||
'waveform!\nUsing entire waveform instead!'
|
||||
if verbose: print(msg)
|
||||
@ -235,9 +327,17 @@ def autopickstation(wfstream, pickparam, verbose=False, iplot=0, fig_dict=None):
|
||||
key = 'aicFig'
|
||||
if fig_dict:
|
||||
fig = fig_dict[key]
|
||||
linecolor = fig_dict['plot_style']['linecolor']['rgba_mpl']
|
||||
else:
|
||||
fig = None
|
||||
aicpick = AICPicker(aiccf, tsnrz, pickwinP, iplot, None, tsmoothP, fig=fig)
|
||||
linecolor = 'k'
|
||||
aicpick = AICPicker(aiccf, tsnrz, pickwinP, iplot, None, aictsmoothP, fig=fig, linecolor=linecolor)
|
||||
# add pstart and pstop to aic plot
|
||||
if fig:
|
||||
for ax in fig.axes:
|
||||
ax.vlines(pstart, ax.get_ylim()[0], ax.get_ylim()[1], color='c', linestyles='dashed', label='P start')
|
||||
ax.vlines(pstop, ax.get_ylim()[0], ax.get_ylim()[1], color='c', linestyles='dashed', label='P stop')
|
||||
ax.legend(loc=1)
|
||||
##############################################################
|
||||
if aicpick.getpick() is not None:
|
||||
# check signal length to detect spuriously picked noise peaks
|
||||
@ -254,16 +354,21 @@ def autopickstation(wfstream, pickparam, verbose=False, iplot=0, fig_dict=None):
|
||||
key = 'slength'
|
||||
if fig_dict:
|
||||
fig = fig_dict[key]
|
||||
linecolor = fig_dict['plot_style']['linecolor']['rgba_mpl']
|
||||
else:
|
||||
fig = None
|
||||
linecolor = 'k'
|
||||
Pflag = checksignallength(zne, aicpick.getpick(), tsnrz,
|
||||
minsiglength / 2,
|
||||
nfacsl, minpercent, iplot,
|
||||
fig)
|
||||
fig, linecolor)
|
||||
else:
|
||||
# filter and taper horizontal traces
|
||||
trH1_filt = edat.copy()
|
||||
trH2_filt = ndat.copy()
|
||||
# remove constant offset from data to avoid unwanted filter response
|
||||
trH1_filt.detrend(type='demean')
|
||||
trH2_filt.detrend(type='demean')
|
||||
trH1_filt.filter('bandpass', freqmin=bph1[0],
|
||||
freqmax=bph1[1],
|
||||
zerophase=False)
|
||||
@ -276,12 +381,14 @@ def autopickstation(wfstream, pickparam, verbose=False, iplot=0, fig_dict=None):
|
||||
zne += trH2_filt
|
||||
if fig_dict:
|
||||
fig = fig_dict['slength']
|
||||
linecolor = fig_dict['plot_style']['linecolor']['rgba_mpl']
|
||||
else:
|
||||
fig = None
|
||||
linecolor = 'k'
|
||||
Pflag = checksignallength(zne, aicpick.getpick(), tsnrz,
|
||||
minsiglength,
|
||||
nfacsl, minpercent, iplot,
|
||||
fig)
|
||||
fig, linecolor)
|
||||
|
||||
if Pflag == 1:
|
||||
# check for spuriously picked S onset
|
||||
@ -291,13 +398,15 @@ def autopickstation(wfstream, pickparam, verbose=False, iplot=0, fig_dict=None):
|
||||
'Skipping control function checkZ4S.'
|
||||
if verbose: print(msg)
|
||||
else:
|
||||
if iplot>1:
|
||||
if iplot > 1:
|
||||
if fig_dict:
|
||||
fig = fig_dict['checkZ4s']
|
||||
linecolor = fig_dict['plot_style']['linecolor']['rgba_mpl']
|
||||
else:
|
||||
fig = None
|
||||
linecolor = 'k'
|
||||
Pflag = checkZ4S(zne, aicpick.getpick(), zfac,
|
||||
tsnrz[3], iplot, fig)
|
||||
tsnrz[2], iplot, fig, linecolor)
|
||||
if Pflag == 0:
|
||||
Pmarker = 'SinsteadP'
|
||||
Pweight = 9
|
||||
@ -306,8 +415,11 @@ def autopickstation(wfstream, pickparam, verbose=False, iplot=0, fig_dict=None):
|
||||
Pweight = 9
|
||||
##############################################################
|
||||
# go on with processing if AIC onset passes quality control
|
||||
if (aicpick.getSlope() >= minAICPslope and
|
||||
aicpick.getSNR() >= minAICPSNR and Pflag == 1):
|
||||
slope = aicpick.getSlope()
|
||||
if not slope:
|
||||
slope = 0
|
||||
if (slope >= minAICPslope and
|
||||
aicpick.getSNR() >= minAICPSNR and Pflag == 1):
|
||||
aicPflag = 1
|
||||
msg = 'AIC P-pick passes quality control: Slope: {0} counts/s, ' \
|
||||
'SNR: {1}\nGo on with refined picking ...\n' \
|
||||
@ -317,6 +429,7 @@ def autopickstation(wfstream, pickparam, verbose=False, iplot=0, fig_dict=None):
|
||||
# re-filter waveform with larger bandpass
|
||||
z_copy = zdat.copy()
|
||||
tr_filt = zdat[0].copy()
|
||||
tr_filt.detrend(type='demean')
|
||||
tr_filt.filter('bandpass', freqmin=bpz2[0], freqmax=bpz2[1],
|
||||
zerophase=False)
|
||||
tr_filt.taper(max_percentage=0.05, type='hann')
|
||||
@ -346,10 +459,12 @@ def autopickstation(wfstream, pickparam, verbose=False, iplot=0, fig_dict=None):
|
||||
algoP=algoP)
|
||||
if fig_dict:
|
||||
fig = fig_dict['refPpick']
|
||||
linecolor = fig_dict['plot_style']['linecolor']['rgba_mpl']
|
||||
else:
|
||||
fig = None
|
||||
linecolor = 'k'
|
||||
refPpick = PragPicker(cf2, tsnrz, pickwinP, iplot, ausP, tsmoothP,
|
||||
aicpick.getpick(), fig)
|
||||
aicpick.getpick(), fig, linecolor)
|
||||
mpickP = refPpick.getpick()
|
||||
#############################################################
|
||||
if mpickP is not None:
|
||||
@ -358,28 +473,34 @@ def autopickstation(wfstream, pickparam, verbose=False, iplot=0, fig_dict=None):
|
||||
if iplot:
|
||||
if fig_dict:
|
||||
fig = fig_dict['el_Ppick']
|
||||
linecolor = fig_dict['plot_style']['linecolor']['rgba_mpl']
|
||||
else:
|
||||
fig = None
|
||||
linecolor = 'k'
|
||||
epickP, lpickP, Perror = earllatepicker(z_copy, nfacP, tsnrz,
|
||||
mpickP, iplot, fig=fig)
|
||||
mpickP, iplot, fig=fig,
|
||||
linecolor=linecolor)
|
||||
else:
|
||||
epickP, lpickP, Perror = earllatepicker(z_copy, nfacP, tsnrz,
|
||||
mpickP, iplot)
|
||||
mpickP, iplot)
|
||||
|
||||
# get SNR
|
||||
[SNRP, SNRPdB, Pnoiselevel] = getSNR(z_copy, tsnrz, mpickP)
|
||||
|
||||
# weight P-onset using symmetric error
|
||||
if Perror <= timeerrorsP[0]:
|
||||
Pweight = 0
|
||||
elif timeerrorsP[0] < Perror <= timeerrorsP[1]:
|
||||
Pweight = 1
|
||||
elif timeerrorsP[1] < Perror <= timeerrorsP[2]:
|
||||
Pweight = 2
|
||||
elif timeerrorsP[2] < Perror <= timeerrorsP[3]:
|
||||
Pweight = 3
|
||||
elif Perror > timeerrorsP[3]:
|
||||
if Perror == None:
|
||||
Pweight = 4
|
||||
else:
|
||||
if Perror <= timeerrorsP[0]:
|
||||
Pweight = 0
|
||||
elif timeerrorsP[0] < Perror <= timeerrorsP[1]:
|
||||
Pweight = 1
|
||||
elif timeerrorsP[1] < Perror <= timeerrorsP[2]:
|
||||
Pweight = 2
|
||||
elif timeerrorsP[2] < Perror <= timeerrorsP[3]:
|
||||
Pweight = 3
|
||||
elif Perror > timeerrorsP[3]:
|
||||
Pweight = 4
|
||||
|
||||
##############################################################
|
||||
# get first motion of P onset
|
||||
@ -388,11 +509,12 @@ def autopickstation(wfstream, pickparam, verbose=False, iplot=0, fig_dict=None):
|
||||
if iplot:
|
||||
if fig_dict:
|
||||
fig = fig_dict['fm_picker']
|
||||
linecolor = fig_dict['plot_style']['linecolor']['rgba_mpl']
|
||||
else:
|
||||
fig = None
|
||||
FM = fmpicker(zdat, z_copy, fmpickwin, mpickP, iplot, fig)
|
||||
FM = fmpicker(zdat, z_copy, fmpickwin, mpickP, iplot, fig, linecolor)
|
||||
else:
|
||||
FM = fmpicker(zdat, z_copy, fmpickwin, mpickP, iplot)
|
||||
FM = fmpicker(zdat, z_copy, fmpickwin, mpickP, iplot)
|
||||
else:
|
||||
FM = 'N'
|
||||
|
||||
@ -402,6 +524,8 @@ def autopickstation(wfstream, pickparam, verbose=False, iplot=0, fig_dict=None):
|
||||
SNRPdB,
|
||||
FM)
|
||||
print(msg)
|
||||
msg = 'autopickstation: Refined P-Pick: {} s | P-Error: {} s'.format(mpickP, Perror)
|
||||
print(msg)
|
||||
Sflag = 1
|
||||
|
||||
else:
|
||||
@ -419,16 +543,46 @@ def autopickstation(wfstream, pickparam, verbose=False, iplot=0, fig_dict=None):
|
||||
print('autopickstation: No vertical component data available!, '
|
||||
'Skipping station!')
|
||||
|
||||
if edat is not None and ndat is not None and len(edat) > 0 and len(
|
||||
ndat) > 0 and Pweight < 4:
|
||||
if ((len(edat) > 0 and len(ndat) == 0) or (
|
||||
len(ndat) > 0 and len(edat) == 0)) and Pweight < 4:
|
||||
msg = 'Go on picking S onset ...\n' \
|
||||
'##################################################\n' \
|
||||
'Only one horizontal component available!\n' \
|
||||
'ARH prediction requires at least 2 components!\n' \
|
||||
'Copying existing horizontal component ...'
|
||||
if verbose: print(msg)
|
||||
|
||||
# check which component is missing
|
||||
if len(edat) == 0:
|
||||
edat = ndat
|
||||
else:
|
||||
ndat = edat
|
||||
|
||||
pickSonset = (edat is not None and ndat is not None and len(edat) > 0 and len(
|
||||
ndat) > 0 and Pweight < 4)
|
||||
|
||||
if pickSonset:
|
||||
# determine time window for calculating CF after P onset
|
||||
cuttimesh = [
|
||||
round(max([mpickP + sstart, 0])), # MP MP relative time axis
|
||||
round(min([
|
||||
mpickP + sstop,
|
||||
edat[0].stats.endtime-edat[0].stats.starttime,
|
||||
ndat[0].stats.endtime-ndat[0].stats.starttime
|
||||
]))
|
||||
]
|
||||
|
||||
if not cuttimesh[1] >= cuttimesh[0]:
|
||||
print('Cut window for horizontal phases too small! Will not pick S onsets.')
|
||||
pickSonset = False
|
||||
|
||||
if pickSonset:
|
||||
msg = 'Go on picking S onset ...\n' \
|
||||
'##################################################\n' \
|
||||
'Working on S onset of station {0}\nFiltering horizontal ' \
|
||||
'traces ...'.format(edat[0].stats.station)
|
||||
if verbose: print(msg)
|
||||
# determine time window for calculating CF after P onset
|
||||
cuttimesh = [round(max([mpickP + sstart, 0])),
|
||||
round(min([mpickP + sstop, Lwf]))]
|
||||
|
||||
|
||||
if algoS == 'ARH':
|
||||
# re-create stream object including both horizontal components
|
||||
@ -438,6 +592,8 @@ def autopickstation(wfstream, pickparam, verbose=False, iplot=0, fig_dict=None):
|
||||
# filter and taper data
|
||||
trH1_filt = hdat[0].copy()
|
||||
trH2_filt = hdat[1].copy()
|
||||
trH1_filt.detrend(type='demean')
|
||||
trH2_filt.detrend(type='demean')
|
||||
trH1_filt.filter('bandpass', freqmin=bph1[0], freqmax=bph1[1],
|
||||
zerophase=False)
|
||||
trH2_filt.filter('bandpass', freqmin=bph1[0], freqmax=bph1[1],
|
||||
@ -456,6 +612,9 @@ def autopickstation(wfstream, pickparam, verbose=False, iplot=0, fig_dict=None):
|
||||
trH1_filt = hdat[0].copy()
|
||||
trH2_filt = hdat[1].copy()
|
||||
trH3_filt = hdat[2].copy()
|
||||
trH1_filt.detrend(type='demean')
|
||||
trH2_filt.detrend(type='demean')
|
||||
trH3_filt.detrend(type='demean')
|
||||
trH1_filt.filter('bandpass', freqmin=bph1[0], freqmax=bph1[1],
|
||||
zerophase=False)
|
||||
trH2_filt.filter('bandpass', freqmin=bph1[0], freqmax=bph1[1],
|
||||
@ -493,15 +652,20 @@ def autopickstation(wfstream, pickparam, verbose=False, iplot=0, fig_dict=None):
|
||||
# of class AutoPicking
|
||||
if fig_dict:
|
||||
fig = fig_dict['aicARHfig']
|
||||
linecolor = fig_dict['plot_style']['linecolor']['rgba_mpl']
|
||||
else:
|
||||
fig = None
|
||||
linecolor = 'k'
|
||||
aicarhpick = AICPicker(haiccf, tsnrh, pickwinS, iplot, None,
|
||||
aictsmoothS, fig=fig)
|
||||
aictsmoothS, fig=fig, linecolor=linecolor)
|
||||
###############################################################
|
||||
# go on with processing if AIC onset passes quality control
|
||||
if (aicarhpick.getSlope() >= minAICSslope and
|
||||
aicarhpick.getSNR() >= minAICSSNR and
|
||||
aicarhpick.getpick() is not None):
|
||||
slope = aicarhpick.getSlope()
|
||||
if not slope:
|
||||
slope = 0
|
||||
if (slope >= minAICSslope and
|
||||
aicarhpick.getSNR() >= minAICSSNR and
|
||||
aicarhpick.getpick() is not None):
|
||||
aicSflag = 1
|
||||
msg = 'AIC S-pick passes quality control: Slope: {0} counts/s, ' \
|
||||
'SNR: {1}\nGo on with refined picking ...\n' \
|
||||
@ -518,6 +682,8 @@ def autopickstation(wfstream, pickparam, verbose=False, iplot=0, fig_dict=None):
|
||||
if algoS == 'ARH':
|
||||
trH1_filt = hdat[0].copy()
|
||||
trH2_filt = hdat[1].copy()
|
||||
trH1_filt.detrend(type='demean')
|
||||
trH2_filt.detrend(type='demean')
|
||||
trH1_filt.filter('bandpass', freqmin=bph2[0], freqmax=bph2[1],
|
||||
zerophase=False)
|
||||
trH2_filt.filter('bandpass', freqmin=bph2[0], freqmax=bph2[1],
|
||||
@ -533,6 +699,9 @@ def autopickstation(wfstream, pickparam, verbose=False, iplot=0, fig_dict=None):
|
||||
trH1_filt = hdat[0].copy()
|
||||
trH2_filt = hdat[1].copy()
|
||||
trH3_filt = hdat[2].copy()
|
||||
trH1_filt.detrend(type='demean')
|
||||
trH2_filt.detrend(type='demean')
|
||||
trH3_filt.detrend(type='demean')
|
||||
trH1_filt.filter('bandpass', freqmin=bph2[0], freqmax=bph2[1],
|
||||
zerophase=False)
|
||||
trH2_filt.filter('bandpass', freqmin=bph2[0], freqmax=bph2[1],
|
||||
@ -552,10 +721,12 @@ def autopickstation(wfstream, pickparam, verbose=False, iplot=0, fig_dict=None):
|
||||
# get refined onset time from CF2 using class Picker
|
||||
if fig_dict:
|
||||
fig = fig_dict['refSpick']
|
||||
linecolor = fig_dict['plot_style']['linecolor']['rgba_mpl']
|
||||
else:
|
||||
fig = None
|
||||
linecolor = 'k'
|
||||
refSpick = PragPicker(arhcf2, tsnrh, pickwinS, iplot, ausS,
|
||||
tsmoothS, aicarhpick.getpick(), fig)
|
||||
tsmoothS, aicarhpick.getpick(), fig, linecolor)
|
||||
mpickS = refSpick.getpick()
|
||||
#############################################################
|
||||
if mpickS is not None:
|
||||
@ -565,27 +736,33 @@ def autopickstation(wfstream, pickparam, verbose=False, iplot=0, fig_dict=None):
|
||||
if iplot:
|
||||
if fig_dict:
|
||||
fig = fig_dict['el_S1pick']
|
||||
linecolor = fig_dict['plot_style']['linecolor']['rgba_mpl']
|
||||
else:
|
||||
fig = None
|
||||
epickS1, lpickS1, Serror1 = earllatepicker(h_copy, nfacS,
|
||||
tsnrh,
|
||||
mpickS, iplot,
|
||||
fig=fig)
|
||||
linecolor = 'k'
|
||||
epickS1, lpickS1, Serror1 = earllatepicker(h_copy, nfacS,
|
||||
tsnrh,
|
||||
mpickS, iplot,
|
||||
fig=fig,
|
||||
linecolor=linecolor)
|
||||
else:
|
||||
epickS1, lpickS1, Serror1 = earllatepicker(h_copy, nfacS,
|
||||
tsnrh,
|
||||
mpickS, iplot)
|
||||
|
||||
|
||||
h_copy[0].data = trH2_filt.data
|
||||
if iplot:
|
||||
if fig_dict:
|
||||
fig = fig_dict['el_S2pick']
|
||||
linecolor = fig_dict['plot_style']['linecolor']['rgba_mpl']
|
||||
else:
|
||||
fig = None
|
||||
linecolor = ''
|
||||
epickS2, lpickS2, Serror2 = earllatepicker(h_copy, nfacS,
|
||||
tsnrh,
|
||||
mpickS, iplot,
|
||||
fig=fig)
|
||||
fig=fig,
|
||||
linecolor=linecolor)
|
||||
else:
|
||||
epickS2, lpickS2, Serror2 = earllatepicker(h_copy, nfacS,
|
||||
tsnrh,
|
||||
@ -629,6 +806,9 @@ def autopickstation(wfstream, pickparam, verbose=False, iplot=0, fig_dict=None):
|
||||
lpickS = lpick[ipick]
|
||||
Serror = pickerr[ipick]
|
||||
|
||||
msg = 'autopickstation: Refined S-Pick: {} s | S-Error: {} s'.format(mpickS, Serror)
|
||||
print(msg)
|
||||
|
||||
# get SNR
|
||||
[SNRS, SNRSdB, Snoiselevel] = getSNR(h_copy, tsnrh, mpickS)
|
||||
|
||||
@ -651,7 +831,6 @@ def autopickstation(wfstream, pickparam, verbose=False, iplot=0, fig_dict=None):
|
||||
################################################################
|
||||
# get Wood-Anderson peak-to-peak amplitude
|
||||
# initialize Data object
|
||||
data = Data()
|
||||
# re-create stream object including both horizontal components
|
||||
hdat = edat.copy()
|
||||
hdat += ndat
|
||||
@ -670,21 +849,33 @@ def autopickstation(wfstream, pickparam, verbose=False, iplot=0, fig_dict=None):
|
||||
############################################################
|
||||
# get Wood-Anderson peak-to-peak amplitude
|
||||
# initialize Data object
|
||||
data = Data()
|
||||
# re-create stream object including both horizontal components
|
||||
hdat = edat.copy()
|
||||
hdat += ndat
|
||||
|
||||
else:
|
||||
print('autopickstation: No horizontal component data available or ' \
|
||||
print('autopickstation: No horizontal component data available or '
|
||||
'bad P onset, skipping S picking!')
|
||||
|
||||
##############################################################
|
||||
try:
|
||||
iplot = int(iplot)
|
||||
except:
|
||||
if iplot == True or iplot == 'True':
|
||||
iplot = 2
|
||||
else:
|
||||
iplot = 0
|
||||
|
||||
if iplot > 0:
|
||||
# plot vertical trace
|
||||
if not fig_dict:
|
||||
if fig_dict == None or fig_dict == 'None':
|
||||
fig = plt.figure()
|
||||
plt_flag = 1
|
||||
linecolor = 'k'
|
||||
else:
|
||||
fig = fig_dict['mainFig']
|
||||
linecolor = fig_dict['plot_style']['linecolor']['rgba_mpl']
|
||||
fig._tight = True
|
||||
ax1 = fig.add_subplot(311)
|
||||
tdata = np.arange(0, zdat[0].stats.npts / tr_filt.stats.sampling_rate,
|
||||
tr_filt.stats.delta)
|
||||
@ -692,7 +883,7 @@ def autopickstation(wfstream, pickparam, verbose=False, iplot=0, fig_dict=None):
|
||||
wfldiff = len(tr_filt.data) - len(tdata)
|
||||
if wfldiff < 0:
|
||||
tdata = tdata[0:len(tdata) - abs(wfldiff)]
|
||||
ax1.plot(tdata, tr_filt.data / max(tr_filt.data), 'k', label='Data')
|
||||
ax1.plot(tdata, tr_filt.data / max(tr_filt.data), color=linecolor, linewidth=0.7, label='Data')
|
||||
if Pweight < 4:
|
||||
ax1.plot(cf1.getTimeArray(), cf1.getCF() / max(cf1.getCF()),
|
||||
'b', label='CF1')
|
||||
@ -706,7 +897,7 @@ def autopickstation(wfstream, pickparam, verbose=False, iplot=0, fig_dict=None):
|
||||
ax1.plot([aicpick.getpick() - 0.5, aicpick.getpick() + 0.5],
|
||||
[-1, -1], 'r')
|
||||
ax1.plot([refPpick.getpick(), refPpick.getpick()],
|
||||
[-1.3, 1.3], 'r', linewidth=2, label='Final P Pick')
|
||||
[-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)
|
||||
ax1.plot([refPpick.getpick() - 0.5, refPpick.getpick() + 0.5],
|
||||
@ -714,28 +905,35 @@ def autopickstation(wfstream, pickparam, verbose=False, iplot=0, fig_dict=None):
|
||||
ax1.plot([lpickP, lpickP], [-1.1, 1.1], 'r--', label='lpp')
|
||||
ax1.plot([epickP, epickP], [-1.1, 1.1], 'r--', label='epp')
|
||||
ax1.set_title('%s, %s, P Weight=%d, SNR=%7.2f, SNR[dB]=%7.2f '
|
||||
'Polarity: %s' % (tr_filt.stats.station,
|
||||
tr_filt.stats.channel,
|
||||
Pweight,
|
||||
SNRP,
|
||||
SNRPdB,
|
||||
FM))
|
||||
'Polarity: %s' % (tr_filt.stats.station,
|
||||
tr_filt.stats.channel,
|
||||
Pweight,
|
||||
SNRP,
|
||||
SNRPdB,
|
||||
FM))
|
||||
else:
|
||||
ax1.set_title('%s, P Weight=%d, SNR=None, '
|
||||
'SNRdB=None' % (tr_filt.stats.channel, Pweight))
|
||||
'SNRdB=None' % (tr_filt.stats.channel, Pweight))
|
||||
else:
|
||||
ax1.set_title('%s, %s, P Weight=%d' % (tr_filt.stats.station,
|
||||
tr_filt.stats.channel,
|
||||
Pweight))
|
||||
ax1.legend()
|
||||
tr_filt.stats.channel,
|
||||
Pweight))
|
||||
ax1.legend(loc=1)
|
||||
ax1.set_yticks([])
|
||||
ax1.set_ylim([-1.5, 1.5])
|
||||
ax1.set_ylabel('Normalized Counts')
|
||||
#fig.suptitle(tr_filt.stats.starttime)
|
||||
|
||||
# fig.suptitle(tr_filt.stats.starttime)
|
||||
try:
|
||||
len(edat[0])
|
||||
except:
|
||||
edat = ndat
|
||||
try:
|
||||
len(ndat[0])
|
||||
except:
|
||||
ndat = edat
|
||||
if len(edat[0]) > 1 and len(ndat[0]) > 1 and Sflag == 1:
|
||||
# plot horizontal traces
|
||||
ax2 = fig.add_subplot(3,1,2,sharex=ax1)
|
||||
ax2 = fig.add_subplot(3, 1, 2, sharex=ax1)
|
||||
th1data = np.arange(0,
|
||||
trH1_filt.stats.npts /
|
||||
trH1_filt.stats.sampling_rate,
|
||||
@ -744,13 +942,13 @@ def autopickstation(wfstream, pickparam, verbose=False, iplot=0, fig_dict=None):
|
||||
wfldiff = len(trH1_filt.data) - len(th1data)
|
||||
if wfldiff < 0:
|
||||
th1data = th1data[0:len(th1data) - abs(wfldiff)]
|
||||
ax2.plot(th1data, trH1_filt.data / max(trH1_filt.data), 'k', label='Data')
|
||||
ax2.plot(th1data, trH1_filt.data / max(trH1_filt.data), color=linecolor, linewidth=0.7, label='Data')
|
||||
if Pweight < 4:
|
||||
ax2.plot(arhcf1.getTimeArray(),
|
||||
arhcf1.getCF() / max(arhcf1.getCF()), 'b', label='CF1')
|
||||
if aicSflag == 1:
|
||||
if aicSflag == 1 and Sweight < 4:
|
||||
ax2.plot(arhcf2.getTimeArray(),
|
||||
arhcf2.getCF() / max(arhcf2.getCF()), 'm', label='CF2')
|
||||
arhcf2.getCF() / max(arhcf2.getCF()), 'm', label='CF2')
|
||||
ax2.plot(
|
||||
[aicarhpick.getpick(), aicarhpick.getpick()],
|
||||
[-1, 1], 'g', label='Initial S Onset')
|
||||
@ -778,13 +976,13 @@ def autopickstation(wfstream, pickparam, verbose=False, iplot=0, fig_dict=None):
|
||||
else:
|
||||
ax2.set_title('%s, S Weight=%d, SNR=None, SNRdB=None' % (
|
||||
trH1_filt.stats.channel, Sweight))
|
||||
ax2.legend()
|
||||
ax2.legend(loc=1)
|
||||
ax2.set_yticks([])
|
||||
ax2.set_ylim([-1.5, 1.5])
|
||||
ax2.set_ylabel('Normalized Counts')
|
||||
#fig.suptitle(trH1_filt.stats.starttime)
|
||||
# fig.suptitle(trH1_filt.stats.starttime)
|
||||
|
||||
ax3 = fig.add_subplot(3,1,3, sharex=ax1)
|
||||
ax3 = fig.add_subplot(3, 1, 3, sharex=ax1)
|
||||
th2data = np.arange(0,
|
||||
trH2_filt.stats.npts /
|
||||
trH2_filt.stats.sampling_rate,
|
||||
@ -793,7 +991,7 @@ def autopickstation(wfstream, pickparam, verbose=False, iplot=0, fig_dict=None):
|
||||
wfldiff = len(trH2_filt.data) - len(th2data)
|
||||
if wfldiff < 0:
|
||||
th2data = th2data[0:len(th2data) - abs(wfldiff)]
|
||||
ax3.plot(th2data, trH2_filt.data / max(trH2_filt.data), 'k', label='Data')
|
||||
ax3.plot(th2data, trH2_filt.data / max(trH2_filt.data), color=linecolor, linewidth=0.7, label='Data')
|
||||
if Pweight < 4:
|
||||
p22, = ax3.plot(arhcf1.getTimeArray(),
|
||||
arhcf1.getCF() / max(arhcf1.getCF()), 'b', label='CF1')
|
||||
@ -821,18 +1019,23 @@ def autopickstation(wfstream, pickparam, verbose=False, iplot=0, fig_dict=None):
|
||||
[-1.3, -1.3], 'g', linewidth=2)
|
||||
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.legend(loc=1)
|
||||
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)
|
||||
if plt_flag == 1:
|
||||
fig.show()
|
||||
try: input()
|
||||
except SyntaxError: pass
|
||||
plt.close(fig)
|
||||
##########################################################################
|
||||
# calculate "real" onset times
|
||||
if lpickP is not None and lpickP == mpickP:
|
||||
lpickP += timeerrorsP[0]
|
||||
lpickP += zdat[0].stats.delta
|
||||
if epickP is not None and epickP == mpickP:
|
||||
epickP -= timeerrorsP[0]
|
||||
epickP -= zdat[0].stats.delta
|
||||
if mpickP is not None and epickP is not None and lpickP is not None:
|
||||
lpickP = zdat[0].stats.starttime + lpickP
|
||||
epickP = zdat[0].stats.starttime + epickP
|
||||
@ -844,20 +1047,27 @@ def autopickstation(wfstream, pickparam, verbose=False, iplot=0, fig_dict=None):
|
||||
epickP = zdat[0].stats.starttime - timeerrorsP[3]
|
||||
mpickP = zdat[0].stats.starttime
|
||||
|
||||
if edat:
|
||||
hdat = edat[0]
|
||||
elif ndat:
|
||||
hdat = ndat[0]
|
||||
else:
|
||||
return
|
||||
|
||||
if lpickS is not None and lpickS == mpickS:
|
||||
lpickS += timeerrorsS[0]
|
||||
lpickS += hdat.stats.delta
|
||||
if epickS is not None and epickS == mpickS:
|
||||
epickS -= timeerrorsS[0]
|
||||
epickS -= hdat.stats.delta
|
||||
if mpickS is not None and epickS is not None and lpickS is not None:
|
||||
lpickS = edat[0].stats.starttime + lpickS
|
||||
epickS = edat[0].stats.starttime + epickS
|
||||
mpickS = edat[0].stats.starttime + mpickS
|
||||
lpickS = hdat.stats.starttime + lpickS
|
||||
epickS = hdat.stats.starttime + epickS
|
||||
mpickS = hdat.stats.starttime + mpickS
|
||||
else:
|
||||
# dummy values (start of seismic trace) in order to derive
|
||||
# theoretical onset times for iteratve picking
|
||||
lpickS = edat[0].stats.starttime + timeerrorsS[3]
|
||||
epickS = edat[0].stats.starttime - timeerrorsS[3]
|
||||
mpickS = edat[0].stats.starttime
|
||||
lpickS = hdat.stats.starttime + timeerrorsS[3]
|
||||
epickS = hdat.stats.starttime - timeerrorsS[3]
|
||||
mpickS = hdat.stats.starttime
|
||||
|
||||
# create dictionary
|
||||
# for P phase
|
||||
@ -867,8 +1077,8 @@ def autopickstation(wfstream, pickparam, verbose=False, iplot=0, fig_dict=None):
|
||||
snrdb=SNRPdB, weight=Pweight, fm=FM, w0=None, fc=None, Mo=None,
|
||||
Mw=None, picker=picker, marked=Pmarker)
|
||||
# add S phase
|
||||
ccode = edat[0].stats.channel
|
||||
ncode = edat[0].stats.network
|
||||
ccode = hdat.stats.channel
|
||||
ncode = hdat.stats.network
|
||||
spick = dict(channel=ccode, network=ncode, lpp=lpickS, epp=epickS, mpp=mpickS, spe=Serror, snr=SNRS,
|
||||
snrdb=SNRSdB, weight=Sweight, fm=None, picker=picker, Ao=Ao)
|
||||
# merge picks into returning dictionary
|
||||
@ -923,17 +1133,21 @@ def iteratepicker(wf, NLLocfile, picks, badpicks, pickparameter, fig_dict=None):
|
||||
Precalcwin_old = pickparameter.get('Precalcwin')
|
||||
noisefactor_old = pickparameter.get('noisefactor')
|
||||
zfac_old = pickparameter.get('zfac')
|
||||
pickparameter.setParam(
|
||||
pstart=max([0, badpicks[i][1] - wf2pick[0].stats.starttime \
|
||||
- pickparameter.get('tlta')]))
|
||||
pickparameter.setParam(pstop=pickparameter.get('pstart') + \
|
||||
(3 * pickparameter.get('tlta')))
|
||||
pickparameter.setParam(sstop=pickparameter.get('sstop') / 2)
|
||||
pickparameter.setParam(pickwinP=pickparameter.get('pickwinP') / 2)
|
||||
pickparameter.setParam(
|
||||
Precalcwin=pickparameter.get('Precalcwin') / 2)
|
||||
pickparameter.setParam(noisefactor=1.0)
|
||||
pickparameter.setParam(zfac=1.0)
|
||||
twindows = pickparameter.get('tsnrz')
|
||||
tsafety = twindows[1]
|
||||
pstart = max([0, badpicks[i][1] - wf2pick[0].stats.starttime - pickparameter.get('tlta')])
|
||||
if abs(float(res)) <= tsafety / 2 or pstart == 0:
|
||||
print("iteratepicker: Small residuum, leave parameters unchanged for this phase!")
|
||||
else:
|
||||
pickparameter.setParam(pstart=pstart)
|
||||
pickparameter.setParam(pstop=pickparameter.get('pstart') + \
|
||||
(pickparameter.get('Precalcwin')))
|
||||
pickparameter.setParam(sstop=pickparameter.get('sstop') / 2)
|
||||
pickparameter.setParam(pickwinP=pickparameter.get('pickwinP') / 2)
|
||||
pickparameter.setParam(Precalcwin=pickparameter.get('Precalcwin') / 2)
|
||||
pickparameter.setParam(noisefactor=1.0)
|
||||
pickparameter.setParam(zfac=1.0)
|
||||
|
||||
print(
|
||||
"iteratepicker: The following picking parameters have been modified for iterative picking:")
|
||||
print(
|
||||
|
@ -17,7 +17,6 @@ autoregressive prediction: application ot local and regional distances, Geophys.
|
||||
:author: MAGS2 EP3 working group
|
||||
"""
|
||||
|
||||
import matplotlib.pyplot as plt
|
||||
import numpy as np
|
||||
from obspy.core import Stream
|
||||
|
||||
@ -27,7 +26,7 @@ class CharacteristicFunction(object):
|
||||
SuperClass for different types of characteristic functions.
|
||||
'''
|
||||
|
||||
def __init__(self, data, cut, t2=None, order=None, t1=None, fnoise=None, stealthMode=False):
|
||||
def __init__(self, data, cut, t2=None, order=None, t1=None, fnoise=None):
|
||||
'''
|
||||
Initialize data type object with information from the original
|
||||
Seismogram.
|
||||
@ -64,7 +63,6 @@ class CharacteristicFunction(object):
|
||||
self.calcCF(self.getDataArray())
|
||||
self.arpara = np.array([])
|
||||
self.xpred = np.array([])
|
||||
self._stealthMode = stealthMode
|
||||
|
||||
def __str__(self):
|
||||
return '''\n\t{name} object:\n
|
||||
@ -138,9 +136,6 @@ class CharacteristicFunction(object):
|
||||
def getXCF(self):
|
||||
return self.xcf
|
||||
|
||||
def _getStealthMode(self):
|
||||
return self._stealthMode()
|
||||
|
||||
def getDataArray(self, cut=None):
|
||||
'''
|
||||
If cut times are given, time series is cut from cut[0] (start time)
|
||||
@ -225,13 +220,11 @@ class AICcf(CharacteristicFunction):
|
||||
|
||||
def calcCF(self, data):
|
||||
|
||||
# if self._getStealthMode() is False:
|
||||
# print 'Calculating AIC ...'
|
||||
x = self.getDataArray()
|
||||
xnp = x[0].data
|
||||
nn = np.isnan(xnp)
|
||||
if len(nn) > 1:
|
||||
xnp[nn] = 0
|
||||
ind = np.where(~np.isnan(xnp))[0]
|
||||
if ind.size:
|
||||
xnp[:ind[0]] = xnp[ind[0]]
|
||||
datlen = len(xnp)
|
||||
k = np.arange(1, datlen)
|
||||
cf = np.zeros(datlen)
|
||||
@ -265,13 +258,9 @@ class HOScf(CharacteristicFunction):
|
||||
if len(nn) > 1:
|
||||
xnp[nn] = 0
|
||||
if self.getOrder() == 3: # this is skewness
|
||||
# if self._getStealthMode() is False:
|
||||
# print 'Calculating skewness ...'
|
||||
y = np.power(xnp, 3)
|
||||
y1 = np.power(xnp, 2)
|
||||
elif self.getOrder() == 4: # this is kurtosis
|
||||
# if self._getStealthMode() is False:
|
||||
# print 'Calculating kurtosis ...'
|
||||
y = np.power(xnp, 4)
|
||||
y1 = np.power(xnp, 2)
|
||||
|
||||
@ -297,9 +286,12 @@ class HOScf(CharacteristicFunction):
|
||||
elif self.getOrder() == 4:
|
||||
LTA[j] = lta / np.power(lta1, 2)
|
||||
|
||||
nn = np.isnan(LTA)
|
||||
if len(nn) > 1:
|
||||
LTA[nn] = 0
|
||||
# remove NaN's with first not-NaN-value,
|
||||
# so autopicker doesnt pick discontinuity at start of the trace
|
||||
ind = np.where(~np.isnan(LTA))[0]
|
||||
if ind.size:
|
||||
first = ind[0]
|
||||
LTA[:first] = LTA[first]
|
||||
self.cf = LTA
|
||||
self.xcf = x
|
||||
|
||||
@ -307,7 +299,7 @@ class HOScf(CharacteristicFunction):
|
||||
class ARZcf(CharacteristicFunction):
|
||||
def calcCF(self, data):
|
||||
|
||||
print 'Calculating AR-prediction error from single trace ...'
|
||||
print('Calculating AR-prediction error from single trace ...')
|
||||
x = self.getDataArray(self.getCut())
|
||||
xnp = x[0].data
|
||||
nn = np.isnan(xnp)
|
||||
@ -343,7 +335,8 @@ class ARZcf(CharacteristicFunction):
|
||||
cf = tap * cf
|
||||
io = np.where(cf == 0)
|
||||
ino = np.where(cf > 0)
|
||||
cf[io] = cf[ino[0][0]]
|
||||
if np.size(ino):
|
||||
cf[io] = cf[ino[0][0]]
|
||||
|
||||
self.cf = cf
|
||||
self.xcf = x
|
||||
@ -430,7 +423,7 @@ class ARZcf(CharacteristicFunction):
|
||||
class ARHcf(CharacteristicFunction):
|
||||
def calcCF(self, data):
|
||||
|
||||
print 'Calculating AR-prediction error from both horizontal traces ...'
|
||||
print('Calculating AR-prediction error from both horizontal traces ...')
|
||||
|
||||
xnp = self.getDataArray(self.getCut())
|
||||
n0 = np.isnan(xnp[0].data)
|
||||
@ -466,7 +459,7 @@ class ARHcf(CharacteristicFunction):
|
||||
# prediction error = CF
|
||||
cf[i + lpred] = np.sqrt(np.sum(np.power(self.xpred[0][i:i + lpred] - xnp[0][i:i + lpred], 2) \
|
||||
+ np.power(self.xpred[1][i:i + lpred] - xnp[1][i:i + lpred], 2)) / (
|
||||
2 * lpred))
|
||||
2 * lpred))
|
||||
nn = np.isnan(cf)
|
||||
if len(nn) > 1:
|
||||
cf[nn] = 0
|
||||
@ -475,7 +468,8 @@ class ARHcf(CharacteristicFunction):
|
||||
cf = tap * cf
|
||||
io = np.where(cf == 0)
|
||||
ino = np.where(cf > 0)
|
||||
cf[io] = cf[ino[0][0]]
|
||||
if np.size(ino):
|
||||
cf[io] = cf[ino[0][0]]
|
||||
|
||||
self.cf = cf
|
||||
self.xcf = xnp
|
||||
@ -567,7 +561,7 @@ class ARHcf(CharacteristicFunction):
|
||||
class AR3Ccf(CharacteristicFunction):
|
||||
def calcCF(self, data):
|
||||
|
||||
print 'Calculating AR-prediction error from all 3 components ...'
|
||||
print('Calculating AR-prediction error from all 3 components ...')
|
||||
|
||||
xnp = self.getDataArray(self.getCut())
|
||||
n0 = np.isnan(xnp[0].data)
|
||||
@ -608,7 +602,7 @@ class AR3Ccf(CharacteristicFunction):
|
||||
cf[i + lpred] = np.sqrt(np.sum(np.power(self.xpred[0][i:i + lpred] - xnp[0][i:i + lpred], 2) \
|
||||
+ np.power(self.xpred[1][i:i + lpred] - xnp[1][i:i + lpred], 2) \
|
||||
+ np.power(self.xpred[2][i:i + lpred] - xnp[2][i:i + lpred], 2)) / (
|
||||
3 * lpred))
|
||||
3 * lpred))
|
||||
nn = np.isnan(cf)
|
||||
if len(nn) > 1:
|
||||
cf[nn] = 0
|
||||
@ -617,7 +611,8 @@ class AR3Ccf(CharacteristicFunction):
|
||||
cf = tap * cf
|
||||
io = np.where(cf == 0)
|
||||
ino = np.where(cf > 0)
|
||||
cf[io] = cf[ino[0][0]]
|
||||
if np.size(ino):
|
||||
cf[io] = cf[ino[0][0]]
|
||||
|
||||
self.cf = cf
|
||||
self.xcf = xnp
|
||||
|
@ -4,11 +4,11 @@
|
||||
import copy
|
||||
import operator
|
||||
import os
|
||||
import numpy as np
|
||||
import glob
|
||||
import matplotlib.pyplot as plt
|
||||
from obspy import read_events
|
||||
|
||||
import matplotlib.pyplot as plt
|
||||
import numpy as np
|
||||
from obspy import read_events
|
||||
from obspy.core import AttribDict
|
||||
from pylot.core.io.phases import picksdict_from_picks
|
||||
from pylot.core.util.pdf import ProbabilityDensityFunction
|
||||
from pylot.core.util.utils import find_in_list
|
||||
@ -27,16 +27,8 @@ class Comparison(object):
|
||||
"""
|
||||
|
||||
def __init__(self, **kwargs):
|
||||
names = list()
|
||||
self._pdfs = dict()
|
||||
for name, fn in kwargs.items():
|
||||
if isinstance(fn, PDFDictionary):
|
||||
self._pdfs[name] = fn
|
||||
elif isinstance(fn, dict):
|
||||
self._pdfs[name] = PDFDictionary(fn)
|
||||
else:
|
||||
self._pdfs[name] = PDFDictionary.from_quakeml(fn)
|
||||
names.append(name)
|
||||
names = self.iter_kwargs(kwargs)
|
||||
if len(names) > 2:
|
||||
raise ValueError('Comparison is only defined for two '
|
||||
'arguments!')
|
||||
@ -48,6 +40,40 @@ class Comparison(object):
|
||||
return False
|
||||
return True
|
||||
|
||||
def iter_kwargs(self, kwargs):
|
||||
names = list()
|
||||
for name, fn in kwargs.items():
|
||||
if name == 'eventlist':
|
||||
names = self.init_by_eventlist(fn)
|
||||
break
|
||||
if isinstance(fn, PDFDictionary):
|
||||
self._pdfs[name] = fn
|
||||
elif isinstance(fn, dict) or isinstance(fn, AttribDict):
|
||||
self._pdfs[name] = PDFDictionary(fn)
|
||||
else:
|
||||
self._pdfs[name] = PDFDictionary.from_quakeml(fn)
|
||||
names.append(name)
|
||||
return names
|
||||
|
||||
def init_by_eventlist(self, eventlist):
|
||||
# create one dictionary containing all picks for all events (therefore modify station key)
|
||||
global_picksdict = {}
|
||||
for event in eventlist:
|
||||
automanu = {'manu': event.pylot_picks,
|
||||
'auto': event.pylot_autopicks}
|
||||
for method, picksdict in automanu.items():
|
||||
if not method in global_picksdict.keys():
|
||||
global_picksdict[method] = {}
|
||||
for station, picks in picksdict.items():
|
||||
new_picksdict = global_picksdict[method]
|
||||
# new id combining event and station in one dictionary for all events
|
||||
id = '{}_{}'.format(event.pylot_id, station)
|
||||
new_picksdict[id] = picks
|
||||
for method, picksdict in global_picksdict.items():
|
||||
self._pdfs[method] = PDFDictionary(picksdict)
|
||||
names = list(global_picksdict.keys())
|
||||
return names
|
||||
|
||||
def get(self, name):
|
||||
return self._pdfs[name]
|
||||
|
||||
@ -92,8 +118,8 @@ class Comparison(object):
|
||||
"""
|
||||
compare_pdfs = dict()
|
||||
|
||||
pdf_a = self.get(self.names[0]).generate_pdf_data(type)
|
||||
pdf_b = self.get(self.names[1]).generate_pdf_data(type)
|
||||
pdf_a = self.get('auto').generate_pdf_data(type)
|
||||
pdf_b = self.get('manu').generate_pdf_data(type)
|
||||
|
||||
for station, phases in pdf_a.items():
|
||||
if station in pdf_b.keys():
|
||||
@ -154,7 +180,7 @@ class Comparison(object):
|
||||
def get_array(self, phase, method_name):
|
||||
method = operator.methodcaller(method_name)
|
||||
pdf_list = self.get_all(phase)
|
||||
rarray = map(method, pdf_list)
|
||||
rarray = list(map(method, pdf_list))
|
||||
return np.array(rarray)
|
||||
|
||||
def get_expectation_array(self, phase):
|
||||
@ -252,11 +278,7 @@ class PDFDictionary(object):
|
||||
|
||||
@classmethod
|
||||
def from_quakeml(self, fn):
|
||||
cat = read_events(fn)
|
||||
if len(cat) > 1:
|
||||
raise NotImplementedError('reading more than one event at the same '
|
||||
'time is not implemented yet! Sorry!')
|
||||
return PDFDictionary(picksdict_from_picks(cat[0]))
|
||||
return PDFDictionary(fn)
|
||||
|
||||
def get_all(self, phase):
|
||||
rlist = list()
|
||||
@ -334,7 +356,7 @@ class PDFDictionary(object):
|
||||
axarr[l].set_title(phase)
|
||||
if l is 0:
|
||||
axann = axarr[l].annotate(station, xy=(.05, .5),
|
||||
xycoords='axes fraction')
|
||||
xycoords='axes fraction')
|
||||
bbox_props = dict(boxstyle='round', facecolor='lightgrey',
|
||||
alpha=.7)
|
||||
axann.set_bbox(bbox_props)
|
||||
@ -352,7 +374,6 @@ class PDFstatistics(object):
|
||||
Takes a path as argument.
|
||||
"""
|
||||
|
||||
|
||||
def __init__(self, directory):
|
||||
"""Initiates some values needed when dealing with pdfs later"""
|
||||
self._rootdir = directory
|
||||
@ -449,7 +470,7 @@ class PDFstatistics(object):
|
||||
else:
|
||||
raise ValueError("for call to method {0} value has to be "
|
||||
"defined but is 'None' ".format(method_options[
|
||||
property.upper()]))
|
||||
property.upper()]))
|
||||
|
||||
for pdf_dict in self:
|
||||
# create worklist
|
||||
@ -459,7 +480,7 @@ class PDFstatistics(object):
|
||||
|
||||
return rlist
|
||||
|
||||
def writeThetaToFile(self,array,out_dir):
|
||||
def writeThetaToFile(self, array, out_dir):
|
||||
"""
|
||||
Method to write array like data to file. Useful since acquiring can take
|
||||
serious amount of time when dealing with large databases.
|
||||
@ -471,16 +492,16 @@ class PDFstatistics(object):
|
||||
"""
|
||||
fid = open(os.path.join(out_dir), 'w')
|
||||
for val in array:
|
||||
fid.write(str(val)+'\n')
|
||||
fid.write(str(val) + '\n')
|
||||
fid.close()
|
||||
|
||||
|
||||
def main():
|
||||
root_dir ='/home/sebastianp/Codetesting/xmls/'
|
||||
root_dir = '/home/sebastianp/Codetesting/xmls/'
|
||||
Insheim = PDFstatistics(root_dir)
|
||||
Insheim.curphase = 'p'
|
||||
qdlist = Insheim.get('qdf', 0.2)
|
||||
print qdlist
|
||||
print(qdlist)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
@ -19,12 +19,14 @@ calculated after Diehl & Kissling (2009).
|
||||
:author: MAGS2 EP3 working group / Ludger Kueperkoch
|
||||
"""
|
||||
|
||||
import numpy as np
|
||||
import matplotlib.pyplot as plt
|
||||
from pylot.core.pick.utils import getnoisewin, getsignalwin
|
||||
from pylot.core.pick.charfuns import CharacteristicFunction
|
||||
import warnings
|
||||
|
||||
import matplotlib.pyplot as plt
|
||||
import numpy as np
|
||||
from scipy.signal import argrelmax
|
||||
from pylot.core.pick.charfuns import CharacteristicFunction
|
||||
from pylot.core.pick.utils import getnoisewin, getsignalwin
|
||||
|
||||
|
||||
class AutoPicker(object):
|
||||
'''
|
||||
@ -34,7 +36,7 @@ class AutoPicker(object):
|
||||
|
||||
warnings.simplefilter('ignore')
|
||||
|
||||
def __init__(self, cf, TSNR, PickWindow, iplot=None, aus=None, Tsmooth=None, Pick1=None, fig=None):
|
||||
def __init__(self, cf, TSNR, PickWindow, iplot=0, aus=None, Tsmooth=None, Pick1=None, fig=None, linecolor='k'):
|
||||
'''
|
||||
:param: cf, characteristic function, on which the picking algorithm is applied
|
||||
:type: `~pylot.core.pick.CharFuns.CharacteristicFunction` object
|
||||
@ -61,7 +63,8 @@ class AutoPicker(object):
|
||||
'''
|
||||
|
||||
assert isinstance(cf, CharacteristicFunction), "%s is not a CharacteristicFunction object" % str(cf)
|
||||
|
||||
self._linecolor = linecolor
|
||||
self._pickcolor_p = 'b'
|
||||
self.cf = cf.getCF()
|
||||
self.Tcf = cf.getTimeArray()
|
||||
self.Data = cf.getXCF()
|
||||
@ -153,6 +156,15 @@ class AICPicker(AutoPicker):
|
||||
self.Pick = None
|
||||
self.slope = None
|
||||
self.SNR = None
|
||||
plt_flag = 0
|
||||
try:
|
||||
iplot = int(self.iplot)
|
||||
except:
|
||||
if self.iplot == True or self.iplot == 'True':
|
||||
iplot = 2
|
||||
else:
|
||||
iplot = 0
|
||||
|
||||
# find NaN's
|
||||
nn = np.isnan(self.cf)
|
||||
if len(nn) > 1:
|
||||
@ -208,106 +220,146 @@ class AICPicker(AutoPicker):
|
||||
inoise = getnoisewin(self.Tcf, self.Pick, self.TSNR[0], self.TSNR[1])
|
||||
# check, if these are counts or m/s, important for slope estimation!
|
||||
# this is quick and dirty, better solution?
|
||||
if max(self.Data[0].data < 1e-3):
|
||||
self.Data[0].data = self.Data[0].data * 1000000
|
||||
if max(self.Data[0].data < 1e-3) and max(self.Data[0].data >= 1e-6):
|
||||
self.Data[0].data = self.Data[0].data * 1000000.
|
||||
elif max(self.Data[0].data < 1e-6):
|
||||
self.Data[0].data = self.Data[0].data * 1e13
|
||||
# get signal window
|
||||
isignal = getsignalwin(self.Tcf, self.Pick, self.TSNR[2])
|
||||
ii = min([isignal[len(isignal)-1], len(self.Tcf)])
|
||||
if len(isignal) == 0:
|
||||
return
|
||||
ii = min([isignal[len(isignal) - 1], len(self.Tcf)])
|
||||
isignal = isignal[0:ii]
|
||||
try:
|
||||
aic[isignal]
|
||||
self.Data[0].data[isignal]
|
||||
except IndexError as e:
|
||||
msg = "Time series out of bounds! {}".format(e)
|
||||
print(msg)
|
||||
return
|
||||
msg = "Time series out of bounds! {}".format(e)
|
||||
print(msg)
|
||||
return
|
||||
# calculate SNR from CF
|
||||
self.SNR = max(abs(aic[isignal] - np.mean(aic[isignal]))) / \
|
||||
max(abs(aic[inoise] - np.mean(aic[inoise])))
|
||||
self.SNR = max(abs(self.Data[0].data[isignal] - np.mean(self.Data[0].data[isignal]))) / \
|
||||
max(abs(self.Data[0].data[inoise] - np.mean(self.Data[0].data[inoise])))
|
||||
# calculate slope from CF after initial pick
|
||||
# get slope window
|
||||
tslope = self.TSNR[3] # slope determination window
|
||||
islope = np.where((self.Tcf <= min([self.Pick + tslope, len(self.Data[0].data)])) \
|
||||
& (self.Tcf >= self.Pick))
|
||||
islope = np.where((self.Tcf <= min([self.Pick + tslope, self.Tcf[-1]])) \
|
||||
& (self.Tcf >= self.Pick)) # TODO: put this in a seperate function like getsignalwin
|
||||
# find maximum within slope determination window
|
||||
# 'cause slope should be calculated up to first local minimum only!
|
||||
imax = np.argmax(self.Data[0].data[islope])
|
||||
iislope = islope[0][0:imax]
|
||||
if len(iislope) <= 2:
|
||||
try:
|
||||
dataslope = self.Data[0].data[islope[0][0:-1]]
|
||||
except IndexError:
|
||||
print("Slope Calculation: empty array islope, check signal window")
|
||||
return
|
||||
if len(dataslope) < 1:
|
||||
print('No data in slope window found!')
|
||||
return
|
||||
imaxs, = argrelmax(dataslope)
|
||||
if imaxs.size:
|
||||
imax = imaxs[0]
|
||||
else:
|
||||
imax = np.argmax(dataslope)
|
||||
iislope = islope[0][0:imax + 1]
|
||||
if len(iislope) < 2:
|
||||
# calculate slope from initial onset to maximum of AIC function
|
||||
print("AICPicker: Not enough data samples left for slope calculation!")
|
||||
print("Calculating slope from initial onset to maximum of AIC function ...")
|
||||
imax = np.argmax(aicsmooth[islope])
|
||||
imax = np.argmax(aicsmooth[islope[0][0:-1]])
|
||||
if imax == 0:
|
||||
print("AICPicker: Maximum for slope determination right at the beginning of the window!")
|
||||
print("Choose longer slope determination window!")
|
||||
if self.iplot > 1:
|
||||
if not self.fig:
|
||||
fig = plt.figure() #self.iplot) ### WHY? MP MP
|
||||
if self.fig == None or self.fig == 'None':
|
||||
fig = plt.figure()
|
||||
plt_flag = 1
|
||||
else:
|
||||
fig = self.fig
|
||||
ax = fig.add_subplot(111)
|
||||
x = self.Data[0].data
|
||||
ax.plot(self.Tcf, x / max(x), 'k', label='(HOS-/AR-) Data')
|
||||
ax.plot(self.Tcf, x / max(x), color=self._linecolor, linewidth=0.7, label='(HOS-/AR-) Data')
|
||||
ax.plot(self.Tcf, aicsmooth / max(aicsmooth), 'r', label='Smoothed AIC-CF')
|
||||
ax.legend()
|
||||
ax.legend(loc=1)
|
||||
ax.set_xlabel('Time [s] since %s' % self.Data[0].stats.starttime)
|
||||
ax.set_yticks([])
|
||||
ax.set_title(self.Data[0].stats.station)
|
||||
if plt_flag == 1:
|
||||
fig.show()
|
||||
try: input()
|
||||
except SyntaxError: pass
|
||||
plt.close(fig)
|
||||
return
|
||||
iislope = islope[0][0:imax]
|
||||
iislope = islope[0][0:imax+1]
|
||||
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)
|
||||
datafit = np.polyval(P, xslope)
|
||||
if datafit[0] >= datafit[len(datafit) - 1]:
|
||||
if datafit[0] >= datafit[-1]:
|
||||
print('AICPicker: Negative slope, bad onset skipped!')
|
||||
return
|
||||
self.slope = 1 / tslope * (datafit[len(dataslope) - 1] - datafit[0])
|
||||
self.slope = 1 / (len(dataslope) * self.Data[0].stats.delta) * (datafit[-1] - datafit[0])
|
||||
|
||||
else:
|
||||
self.SNR = None
|
||||
self.slope = None
|
||||
|
||||
if self.iplot > 1:
|
||||
if not self.fig:
|
||||
fig = plt.figure()#self.iplot)
|
||||
if iplot > 1:
|
||||
if self.fig == None or self.fig == 'None':
|
||||
fig = plt.figure() # self.iplot)
|
||||
plt_flag = 1
|
||||
else:
|
||||
fig = self.fig
|
||||
fig._tight = True
|
||||
ax1 = fig.add_subplot(211)
|
||||
x = self.Data[0].data
|
||||
ax1.plot(self.Tcf, x / max(x), 'k', label='(HOS-/AR-) Data')
|
||||
if len(self.Tcf) > len(self.Data[0].data): # why? LK
|
||||
self.Tcf = self.Tcf[0:len(self.Tcf)-1]
|
||||
ax1.plot(self.Tcf, x / max(x), color=self._linecolor, linewidth=0.7, 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()
|
||||
|
||||
ax1.legend(loc=1)
|
||||
|
||||
if self.Pick is not None:
|
||||
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')
|
||||
|
||||
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 = fig.add_subplot(2, 1, 2, sharex=ax1)
|
||||
ax2.plot(self.Tcf, x, color=self._linecolor, linewidth=0.7, 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')
|
||||
|
||||
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))
|
||||
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()
|
||||
ax2.legend(loc=1)
|
||||
if plt_flag == 1:
|
||||
fig.show()
|
||||
try: input()
|
||||
except SyntaxError: pass
|
||||
plt.close(fig)
|
||||
else:
|
||||
ax1.set_title(self.Data[0].stats.station)
|
||||
if plt_flag == 1:
|
||||
fig.show()
|
||||
try: input()
|
||||
except SyntaxError: pass
|
||||
plt.close(fig)
|
||||
|
||||
if self.Pick == None:
|
||||
print('AICPicker: Could not find minimum, picking window too short?')
|
||||
|
||||
|
||||
return
|
||||
|
||||
|
||||
@ -317,7 +369,15 @@ class PragPicker(AutoPicker):
|
||||
'''
|
||||
|
||||
def calcPick(self):
|
||||
|
||||
|
||||
try:
|
||||
iplot = int(self.getiplot())
|
||||
except:
|
||||
if self.getiplot() == True or self.getiplot() == 'True':
|
||||
iplot = 2
|
||||
else:
|
||||
iplot = 0
|
||||
|
||||
if self.getpick1() is not None:
|
||||
print('PragPicker: Get most likely pick from HOS- or AR-CF using pragmatic picking algorithm ...')
|
||||
|
||||
@ -325,6 +385,7 @@ class PragPicker(AutoPicker):
|
||||
self.SNR = None
|
||||
self.slope = None
|
||||
pickflag = 0
|
||||
plt_flag = 0
|
||||
# smooth CF
|
||||
ismooth = int(round(self.Tsmooth / self.dt))
|
||||
cfsmooth = np.zeros(len(self.cf))
|
||||
@ -349,12 +410,19 @@ class PragPicker(AutoPicker):
|
||||
ipick1 = np.argmin(abs(self.Tcf - self.getpick1()))
|
||||
cfpick1 = 2 * self.cf[ipick1]
|
||||
|
||||
# check trend of CF, i.e. differences of CF and adjust aus regarding this trend
|
||||
# check trend of CF, i.e. differences of CF and adjust aus ("artificial uplift
|
||||
# of picks") regarding this trend
|
||||
# prominent trend: decrease aus
|
||||
# flat: use given aus
|
||||
cfdiff = np.diff(cfipick)
|
||||
if len(cfdiff)<20:
|
||||
print('PragPicker: Very few samples for CF. Check LTA window dimensions!')
|
||||
i0diff = np.where(cfdiff > 0)
|
||||
cfdiff = cfdiff[i0diff]
|
||||
if len(cfdiff)<1:
|
||||
print('PragPicker: Negative slope for CF. Check LTA window dimensions! STOP')
|
||||
self.Pick = None
|
||||
return
|
||||
minaus = min(cfdiff * (1 + self.aus))
|
||||
aus1 = max([minaus, self.aus])
|
||||
|
||||
@ -375,15 +443,20 @@ class PragPicker(AutoPicker):
|
||||
break
|
||||
|
||||
# now we look to the left
|
||||
for i in range(ipick1, max([ipick1 - lpickwindow + 1, 2]), -1):
|
||||
if self.cf[i + 1] > self.cf[i] and self.cf[i - 1] >= self.cf[i]:
|
||||
if cfsmooth[i - 1] * (1 + aus1) >= cfsmooth[i]:
|
||||
if cfpick1 >= self.cf[i]:
|
||||
pick_l = self.Tcf[i]
|
||||
self.Pick = pick_l
|
||||
flagpick_r = 1
|
||||
cfpick_l = self.cf[i]
|
||||
break
|
||||
if len(self.cf) > ipick1 +1:
|
||||
for i in range(ipick1, max([ipick1 - lpickwindow + 1, 2]), -1):
|
||||
if self.cf[i + 1] > self.cf[i] and self.cf[i - 1] >= self.cf[i]:
|
||||
if cfsmooth[i - 1] * (1 + aus1) >= cfsmooth[i]:
|
||||
if cfpick1 >= self.cf[i]:
|
||||
pick_l = self.Tcf[i]
|
||||
self.Pick = pick_l
|
||||
flagpick_r = 1
|
||||
cfpick_l = self.cf[i]
|
||||
break
|
||||
else:
|
||||
msg ='PragPicker: Initial onset too close to start of CF! \
|
||||
Stop finalizing pick to the left.'
|
||||
print(msg)
|
||||
|
||||
# now decide which pick: left or right?
|
||||
if flagpick_l > 0 and flagpick_r > 0 and cfpick_l <= 3 * cfpick_r:
|
||||
@ -396,27 +469,34 @@ class PragPicker(AutoPicker):
|
||||
self.Pick = pick_l
|
||||
pickflag = 1
|
||||
else:
|
||||
print('PragPicker: Could not find reliable onset!')
|
||||
print("PragPicker: Could not find reliable onset!")
|
||||
self.Pick = None
|
||||
pickflag = 0
|
||||
|
||||
if self.getiplot() > 1:
|
||||
if not self.fig:
|
||||
fig = plt.figure()#self.getiplot())
|
||||
if iplot > 1:
|
||||
if self.fig == None or self.fig == 'None':
|
||||
fig = plt.figure() # self.getiplot())
|
||||
plt_flag = 1
|
||||
else:
|
||||
fig = self.fig
|
||||
fig._tight = True
|
||||
ax = fig.add_subplot(111)
|
||||
ax.plot(Tcfpick, cfipick, 'k', label='CF')
|
||||
ax.plot(Tcfpick, cfipick, color=self._linecolor, linewidth=0.7, label='CF')
|
||||
ax.plot(Tcfpick, cfsmoothipick, 'r', label='Smoothed CF')
|
||||
if pickflag > 0:
|
||||
ax.plot([self.Pick, self.Pick], [min(cfipick), max(cfipick)], 'b', linewidth=2, label='Pick')
|
||||
ax.plot([self.Pick, self.Pick], [min(cfipick), max(cfipick)], self._pickcolor_p, 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()
|
||||
ax.legend(loc=1)
|
||||
if plt_flag == 1:
|
||||
fig.show()
|
||||
try: input()
|
||||
except SyntaxError: pass
|
||||
plt.close(fig)
|
||||
return
|
||||
|
||||
else:
|
||||
print('PragPicker: No initial onset time given! Check input!')
|
||||
print("PragPicker: No initial onset time given! Check input!")
|
||||
self.Pick = None
|
||||
return
|
||||
|
@ -9,12 +9,13 @@
|
||||
"""
|
||||
|
||||
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, verbosity=1, fig=None):
|
||||
def earllatepicker(X, nfac, TSNR, Pick1, iplot=0, verbosity=1, fig=None, linecolor='k'):
|
||||
'''
|
||||
Function to derive earliest and latest possible pick after Diehl & Kissling (2009)
|
||||
as reasonable uncertainties. Latest possible pick is based on noise level,
|
||||
@ -41,14 +42,23 @@ def earllatepicker(X, nfac, TSNR, Pick1, iplot=None, verbosity=1, fig=None):
|
||||
assert isinstance(X, Stream), "%s is not a stream object" % str(X)
|
||||
|
||||
if verbosity == 2:
|
||||
print('earllatepicker:')
|
||||
print('earllatepicker:')
|
||||
print('nfac:', nfac)
|
||||
print('Init pick:', Pick1)
|
||||
print('TSNR (T_noise, T_gap, T_signal):', TSNR)
|
||||
|
||||
|
||||
LPick = None
|
||||
EPick = None
|
||||
PickError = None
|
||||
plt_flag = 0
|
||||
try:
|
||||
iplot = int(iplot)
|
||||
except:
|
||||
if iplot == True or iplot == 'True':
|
||||
iplot = 2
|
||||
else:
|
||||
iplot = 0
|
||||
|
||||
if verbosity:
|
||||
print('earllatepicker: Get earliest and latest possible pick'
|
||||
' relative to most likely pick ...')
|
||||
@ -69,14 +79,14 @@ def earllatepicker(X, nfac, TSNR, Pick1, iplot=None, verbosity=1, fig=None):
|
||||
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 verbosity:
|
||||
print ("earllatepicker: Signal lower than noise level!\n"
|
||||
"Skip this trace!")
|
||||
print("earllatepicker: Signal lower than noise level!\n"
|
||||
"Skip this trace!")
|
||||
return LPick, EPick, PickError
|
||||
il = min(np.min(ilup) if ilup.size else float('inf'),
|
||||
np.min(ildown) if ildown.size else float('inf'))
|
||||
@ -84,7 +94,7 @@ def earllatepicker(X, nfac, TSNR, Pick1, iplot=None, verbosity=1, fig=None):
|
||||
|
||||
# get earliest possible pick
|
||||
|
||||
EPick = np.nan;
|
||||
EPick = np.nan
|
||||
count = 0
|
||||
pis = isignal
|
||||
|
||||
@ -117,34 +127,41 @@ def earllatepicker(X, nfac, TSNR, Pick1, iplot=None, verbosity=1, fig=None):
|
||||
PickError = symmetrize_error(diffti_te, diffti_tl)
|
||||
|
||||
if iplot > 1:
|
||||
if not fig:
|
||||
fig = plt.figure()#iplot)
|
||||
if fig == None or fig == 'None':
|
||||
fig = plt.figure() # iplot)
|
||||
plt_flag = 1
|
||||
fig._tight = True
|
||||
ax = fig.add_subplot(111)
|
||||
ax.plot(t, x, 'k', label='Data')
|
||||
ax.plot(t, x, color=linecolor, linewidth=0.7, 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',
|
||||
ax.plot([t[0], t[int(len(t)) - 1]], [nlevel, nlevel], color=linecolor, linewidth=0.7, linestyle='dashed', label='Noise Level')
|
||||
ax.plot(t[pis[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([t[0], t[int(len(t)) - 1]], [-nlevel, -nlevel], color=linecolor, linewidth=0.7, linestyle='dashed')
|
||||
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([LPick, LPick], [max(x) / 2, -max(x) / 2], color=linecolor, linewidth=0.7, linestyle='dashed', label='lpp')
|
||||
ax.plot([EPick, EPick], [max(x) / 2, -max(x) / 2], color=linecolor, linewidth=0.7, linestyle='dashed', label='epp')
|
||||
ax.plot([Pick1 + PickError, Pick1 + PickError],
|
||||
[max(x) / 2, -max(x) / 2], 'r--', label='spe')
|
||||
[max(x) / 2, -max(x) / 2], 'r--', label='spe')
|
||||
ax.plot([Pick1 - PickError, Pick1 - PickError],
|
||||
[max(x) / 2, -max(x) / 2], 'r--')
|
||||
[max(x) / 2, -max(x) / 2], 'r--')
|
||||
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)
|
||||
ax.legend()
|
||||
ax.legend(loc=1)
|
||||
if plt_flag == 1:
|
||||
fig.show()
|
||||
try: input()
|
||||
except SyntaxError: pass
|
||||
plt.close(fig)
|
||||
|
||||
return EPick, LPick, PickError
|
||||
|
||||
|
||||
def fmpicker(Xraw, Xfilt, pickwin, Pick, iplot=None, fig=None):
|
||||
def fmpicker(Xraw, Xfilt, pickwin, Pick, iplot=0, fig=None, linecolor='k'):
|
||||
'''
|
||||
Function to derive first motion (polarity) of given phase onset Pick.
|
||||
Calculation is based on zero crossings determined within time window pickwin
|
||||
@ -166,6 +183,15 @@ def fmpicker(Xraw, Xfilt, pickwin, Pick, iplot=None, fig=None):
|
||||
:type: int
|
||||
'''
|
||||
|
||||
plt_flag = 0
|
||||
try:
|
||||
iplot = int(iplot)
|
||||
except:
|
||||
if iplot == True or iplot == 'True':
|
||||
iplot = 2
|
||||
else:
|
||||
iplot = 0
|
||||
|
||||
warnings.simplefilter('ignore', np.RankWarning)
|
||||
|
||||
assert isinstance(Xraw, Stream), "%s is not a stream object" % str(Xraw)
|
||||
@ -173,15 +199,17 @@ def fmpicker(Xraw, Xfilt, pickwin, Pick, iplot=None, fig=None):
|
||||
|
||||
FM = None
|
||||
if Pick is not None:
|
||||
print ("fmpicker: Get first motion (polarity) of onset using unfiltered seismogram...")
|
||||
print("fmpicker: Get first motion (polarity) of onset using unfiltered seismogram...")
|
||||
|
||||
xraw = Xraw[0].data
|
||||
xfilt = Xfilt[0].data
|
||||
t = np.arange(0, Xraw[0].stats.npts / Xraw[0].stats.sampling_rate,
|
||||
Xraw[0].stats.delta)
|
||||
# get pick window
|
||||
ipick = np.where(
|
||||
(t <= min([Pick + pickwin, len(Xraw[0])])) & (t >= Pick))
|
||||
ipick = np.where((t <= min([Pick + pickwin, len(Xraw[0])])) & (t >= Pick))
|
||||
if len(ipick[0]) <= 1:
|
||||
print('fmpicker: Zero crossings window to short!')
|
||||
return
|
||||
# remove mean
|
||||
xraw[ipick] = xraw[ipick] - np.mean(xraw[ipick])
|
||||
xfilt[ipick] = xfilt[ipick] - np.mean(xfilt[ipick])
|
||||
@ -204,6 +232,10 @@ def fmpicker(Xraw, Xfilt, pickwin, Pick, iplot=None, fig=None):
|
||||
if len(zc1) == 3:
|
||||
break
|
||||
|
||||
if len(zc1) < 3:
|
||||
print('fmpicker: Could not determine zero crossings!')
|
||||
return
|
||||
|
||||
# if time difference betweeen 1st and 2cnd zero crossing
|
||||
# is too short, get time difference between 1st and 3rd
|
||||
# to derive maximum
|
||||
@ -211,16 +243,16 @@ def fmpicker(Xraw, Xfilt, pickwin, Pick, iplot=None, fig=None):
|
||||
li1 = index1[1]
|
||||
else:
|
||||
li1 = index1[0]
|
||||
if np.size(xraw[ipick[0][1]:ipick[0][li1]]) == 0:
|
||||
print ("fmpicker: Onset on unfiltered trace too emergent for first motion determination!")
|
||||
if np.size(xraw[ipick[0][1]:ipick[0][li1]]) == 0 or len(index1) <= 1:
|
||||
print("fmpicker: Onset on unfiltered trace too emergent for first motion determination!")
|
||||
P1 = None
|
||||
else:
|
||||
imax1 = np.argmax(abs(xraw[ipick[0][1]:ipick[0][li1]]))
|
||||
if imax1 == 0:
|
||||
imax1 = np.argmax(abs(xraw[ipick[0][1]:ipick[0][index1[1]]]))
|
||||
if imax1 == 0:
|
||||
print ("fmpicker: Zero crossings too close!")
|
||||
print ("Skip first motion determination!")
|
||||
print("fmpicker: Zero crossings too close!")
|
||||
print("Skip first motion determination!")
|
||||
return FM
|
||||
|
||||
islope1 = np.where((t >= Pick) & (t <= Pick + t[imax1]))
|
||||
@ -253,16 +285,16 @@ def fmpicker(Xraw, Xfilt, pickwin, Pick, iplot=None, fig=None):
|
||||
li2 = index2[1]
|
||||
else:
|
||||
li2 = index2[0]
|
||||
if np.size(xfilt[ipick[0][1]:ipick[0][li2]]) == 0:
|
||||
print ("fmpicker: Onset on filtered trace too emergent for first motion determination!")
|
||||
if np.size(xfilt[ipick[0][1]:ipick[0][li2]]) == 0 or len(index2) <= 1:
|
||||
print("fmpicker: Onset on filtered trace too emergent for first motion determination!")
|
||||
P2 = None
|
||||
else:
|
||||
imax2 = np.argmax(abs(xfilt[ipick[0][1]:ipick[0][li2]]))
|
||||
if imax2 == 0:
|
||||
imax2 = np.argmax(abs(xfilt[ipick[0][1]:ipick[0][index2[1]]]))
|
||||
if imax2 == 0:
|
||||
print ("fmpicker: Zero crossings too close!")
|
||||
print ("Skip first motion determination!")
|
||||
print("fmpicker: Zero crossings too close!")
|
||||
print("Skip first motion determination!")
|
||||
return FM
|
||||
|
||||
islope2 = np.where((t >= Pick) & (t <= Pick + t[imax2]))
|
||||
@ -286,29 +318,31 @@ def fmpicker(Xraw, Xfilt, pickwin, Pick, iplot=None, fig=None):
|
||||
elif P1[0] > 0 >= P2[0]:
|
||||
FM = '+'
|
||||
|
||||
print ("fmpicker: Found polarity %s" % FM)
|
||||
print("fmpicker: Found polarity %s" % FM)
|
||||
|
||||
if iplot > 1:
|
||||
if not fig:
|
||||
fig = plt.figure()#iplot)
|
||||
if fig == None or fig == 'None':
|
||||
fig = plt.figure() # iplot)
|
||||
plt_flag = 1
|
||||
fig._tight = True
|
||||
ax1 = fig.add_subplot(211)
|
||||
ax1.plot(t, xraw, 'k')
|
||||
ax1.plot(t, xraw, color=linecolor, linewidth=0.7)
|
||||
ax1.plot([Pick, Pick], [max(xraw), -max(xraw)], 'b', linewidth=2, label='Pick')
|
||||
if P1 is not None:
|
||||
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.legend(loc=1)
|
||||
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)
|
||||
|
||||
ax2=fig.add_subplot(2,1,2, sharex=ax1)
|
||||
ax2 = fig.add_subplot(2, 1, 2, sharex=ax1)
|
||||
ax2.set_title('First-Motion Determination, Filtered Data')
|
||||
ax2.plot(t, xfilt, 'k')
|
||||
ax2.plot(t, xfilt, color=linecolor, linewidth=0.7)
|
||||
ax2.plot([Pick, Pick], [max(xfilt), -max(xfilt)], 'b',
|
||||
linewidth=2)
|
||||
linewidth=2)
|
||||
if P2 is not None:
|
||||
ax2.plot(t[islope2], xfilt[islope2])
|
||||
ax2.plot(zc2, np.zeros(len(zc2)), '*g', markersize=14)
|
||||
@ -316,6 +350,11 @@ def fmpicker(Xraw, Xfilt, pickwin, Pick, iplot=None, fig=None):
|
||||
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([])
|
||||
if plt_flag == 1:
|
||||
fig.show()
|
||||
try: input()
|
||||
except SyntaxError: pass
|
||||
plt.close(fig)
|
||||
|
||||
return FM
|
||||
|
||||
@ -357,9 +396,9 @@ def getSNR(X, TSNR, t1, tracenum=0):
|
||||
assert isinstance(X, Stream), "%s is not a stream object" % str(X)
|
||||
|
||||
SNR = None
|
||||
SNRdb = None
|
||||
SNRdB = None
|
||||
noiselevel = None
|
||||
|
||||
|
||||
x = X[tracenum].data
|
||||
npts = X[tracenum].stats.npts
|
||||
sr = X[tracenum].stats.sampling_rate
|
||||
@ -372,7 +411,7 @@ def getSNR(X, TSNR, t1, tracenum=0):
|
||||
# get signal window
|
||||
isignal = getsignalwin(t, t1, TSNR[2])
|
||||
if np.size(inoise) < 1:
|
||||
print ("getSNR: Empty array inoise, check noise window!")
|
||||
print("getSNR: Empty array inoise, check noise window!")
|
||||
return SNR, SNRdB, noiselevel
|
||||
|
||||
# demean over entire waveform
|
||||
@ -380,13 +419,13 @@ def getSNR(X, TSNR, t1, tracenum=0):
|
||||
|
||||
# calculate ratios
|
||||
noiselevel = np.sqrt(np.mean(np.square(x[inoise])))
|
||||
#signallevel = np.sqrt(np.mean(np.square(x[isignal])))
|
||||
# signallevel = np.sqrt(np.mean(np.square(x[isignal])))
|
||||
|
||||
if np.size(isignal) < 1:
|
||||
print ("getSNR: Empty array isignal, check signal window!")
|
||||
print("getSNR: Empty array isignal, check signal window!")
|
||||
return SNR, SNRdB, noiselevel
|
||||
|
||||
#noiselevel = np.abs(x[inoise]).max()
|
||||
|
||||
# noiselevel = np.abs(x[inoise]).max()
|
||||
signallevel = np.abs(x[isignal]).max()
|
||||
|
||||
SNR = signallevel / noiselevel
|
||||
@ -418,9 +457,9 @@ def getnoisewin(t, t1, tnoise, tgap):
|
||||
inoise, = np.where((t <= max([t1 - tgap, 0])) \
|
||||
& (t >= max([t1 - tnoise - tgap, 0])))
|
||||
if np.size(inoise) < 1:
|
||||
inoise, = np.where((t>=t[0]) & (t<=t1))
|
||||
inoise, = np.where((t >= t[0]) & (t <= t1))
|
||||
if np.size(inoise) < 1:
|
||||
print ("getnoisewin: Empty array inoise, check noise window!")
|
||||
print("getnoisewin: Empty array inoise, check noise window!")
|
||||
|
||||
return inoise
|
||||
|
||||
@ -441,10 +480,10 @@ def getsignalwin(t, t1, tsignal):
|
||||
'''
|
||||
|
||||
# get signal window
|
||||
isignal, = np.where((t <= min([t1 + tsignal, len(t)])) \
|
||||
isignal, = np.where((t <= min([t1 + tsignal, t[-1]])) \
|
||||
& (t >= t1))
|
||||
if np.size(isignal) < 1:
|
||||
print ("getsignalwin: Empty array isignal, check signal window!")
|
||||
print("getsignalwin: Empty array isignal, check signal window!")
|
||||
|
||||
return isignal
|
||||
|
||||
@ -473,24 +512,25 @@ def getResolutionWindow(snr, extent):
|
||||
>>> getResolutionWindow(2)
|
||||
2.5
|
||||
"""
|
||||
|
||||
|
||||
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[extent]['VLRW']
|
||||
elif snr < 2.:
|
||||
time_resolution = res_wins[extent]['LRW']
|
||||
elif snr < 3.:
|
||||
time_resolution = res_wins[extent]['MRW']
|
||||
elif snr >3.:
|
||||
time_resolution = res_wins[extent]['HRW']
|
||||
if snr:
|
||||
if snr < 1.5:
|
||||
time_resolution = res_wins[extent]['VLRW']
|
||||
elif snr < 2.:
|
||||
time_resolution = res_wins[extent]['LRW']
|
||||
elif snr < 3.:
|
||||
time_resolution = res_wins[extent]['MRW']
|
||||
elif snr > 3.:
|
||||
time_resolution = res_wins[extent]['HRW']
|
||||
else:
|
||||
time_resolution = res_wins[extent]['VLRW']
|
||||
|
||||
|
||||
return time_resolution / 2
|
||||
|
||||
|
||||
@ -528,7 +568,7 @@ def select_for_phase(st, phase):
|
||||
return sel_st
|
||||
|
||||
|
||||
def wadaticheck(pickdic, dttolerance, iplot):
|
||||
def wadaticheck(pickdic, dttolerance, iplot=0, fig_dict=None):
|
||||
'''
|
||||
Function to calculate Wadati-diagram from given P and S onsets in order
|
||||
to detect S pick outliers. If a certain S-P time deviates by dttolerance
|
||||
@ -551,7 +591,10 @@ def wadaticheck(pickdic, dttolerance, iplot):
|
||||
Ppicks = []
|
||||
Spicks = []
|
||||
SPtimes = []
|
||||
for key in pickdic:
|
||||
stations = []
|
||||
ibad = 0
|
||||
|
||||
for key in list(pickdic.keys()):
|
||||
if pickdic[key]['P']['weight'] < 4 and pickdic[key]['S']['weight'] < 4:
|
||||
# calculate S-P time
|
||||
spt = pickdic[key]['S']['mpp'] - pickdic[key]['P']['mpp']
|
||||
@ -572,25 +615,29 @@ def wadaticheck(pickdic, dttolerance, iplot):
|
||||
|
||||
# calculate vp/vs ratio before check
|
||||
vpvsr = p1[0] + 1
|
||||
print ("###############################################")
|
||||
print ("wadaticheck: Average Vp/Vs ratio before check: %f" % vpvsr)
|
||||
print("###############################################")
|
||||
print("wadaticheck: Average Vp/Vs ratio before check: %f" % vpvsr)
|
||||
|
||||
checkedPpicks = []
|
||||
checkedSpicks = []
|
||||
checkedSPtimes = []
|
||||
badstations = []
|
||||
# calculate deviations from Wadati regression
|
||||
ii = 0
|
||||
ibad = 0
|
||||
for key in pickdic:
|
||||
if pickdic[key].has_key('SPt'):
|
||||
for key in list(pickdic.keys()):
|
||||
if 'SPt' in pickdic[key]:
|
||||
stations.append(key)
|
||||
wddiff = abs(pickdic[key]['SPt'] - wdfit[ii])
|
||||
ii += 1
|
||||
# check, if deviation is larger than adjusted
|
||||
if wddiff > dttolerance:
|
||||
# mark onset and downgrade S-weight to 9
|
||||
# (not used anymore)
|
||||
marker = 'badWadatiCheck'
|
||||
pickdic[key]['S']['weight'] = 9
|
||||
# remove pick from dictionary
|
||||
pickdic.pop(key)
|
||||
# # mark onset and downgrade S-weight to 9
|
||||
# # (not used anymore)
|
||||
# marker = 'badWadatiCheck'
|
||||
# pickdic[key]['S']['weight'] = 9
|
||||
badstations.append(key)
|
||||
ibad += 1
|
||||
else:
|
||||
marker = 'goodWadatiCheck'
|
||||
@ -601,7 +648,10 @@ def wadaticheck(pickdic, dttolerance, iplot):
|
||||
checkedSPtime = pickdic[key]['S']['mpp'] - pickdic[key]['P']['mpp']
|
||||
checkedSPtimes.append(checkedSPtime)
|
||||
|
||||
pickdic[key]['S']['marked'] = marker
|
||||
pickdic[key]['S']['marked'] = marker
|
||||
#pickdic[key]['S']['marked'] = marker
|
||||
print("wadaticheck: the following stations failed the check:")
|
||||
print(badstations)
|
||||
|
||||
if len(checkedPpicks) >= 3:
|
||||
# calculate new slope
|
||||
@ -610,42 +660,67 @@ def wadaticheck(pickdic, dttolerance, iplot):
|
||||
|
||||
# calculate vp/vs ratio after check
|
||||
cvpvsr = p2[0] + 1
|
||||
print ("wadaticheck: Average Vp/Vs ratio after check: %f" % cvpvsr)
|
||||
print ("wadatacheck: Skipped %d S pick(s)" % ibad)
|
||||
print("wadaticheck: Average Vp/Vs ratio after check: %f" % cvpvsr)
|
||||
print("wadatacheck: Skipped %d S pick(s)" % ibad)
|
||||
else:
|
||||
print ("###############################################")
|
||||
print ("wadatacheck: Not enough checked S-P times available!")
|
||||
print ("Skip Wadati check!")
|
||||
print("###############################################")
|
||||
print("wadaticheck: Not enough checked S-P times available!")
|
||||
print("Skip Wadati check!")
|
||||
wfitflag = 1
|
||||
wdfit2 = None
|
||||
|
||||
checkedonsets = pickdic
|
||||
|
||||
else:
|
||||
print ("wadaticheck: Not enough S-P times available for reliable regression!")
|
||||
print ("Skip wadati check!")
|
||||
print("wadaticheck: Not enough S-P times available for reliable regression!")
|
||||
print("Skip wadati check!")
|
||||
wfitflag = 1
|
||||
|
||||
# plot results
|
||||
if iplot > 0:
|
||||
plt.figure()#iplot)
|
||||
f1, = plt.plot(Ppicks, SPtimes, 'ro')
|
||||
if wfitflag == 0:
|
||||
f2, = plt.plot(Ppicks, wdfit, 'k')
|
||||
f3, = plt.plot(checkedPpicks, checkedSPtimes, 'ko')
|
||||
f4, = plt.plot(checkedPpicks, wdfit2, 'g')
|
||||
plt.title('Wadati-Diagram, %d S-P Times, Vp/Vs(raw)=%5.2f,' \
|
||||
'Vp/Vs(checked)=%5.2f' % (len(SPtimes), vpvsr, cvpvsr))
|
||||
plt.legend([f1, f2, f3, f4], ['Skipped S-Picks', 'Wadati 1',
|
||||
'Reliable S-Picks', 'Wadati 2'], loc='best')
|
||||
if fig_dict:
|
||||
fig = fig_dict['wadati']
|
||||
linecolor = fig_dict['plot_style']['linecolor']['rgba_mpl']
|
||||
plt_flag = 0
|
||||
else:
|
||||
plt.title('Wadati-Diagram, %d S-P Times' % len(SPtimes))
|
||||
fig = plt.figure()
|
||||
linecolor = 'k'
|
||||
plt_flag = 1
|
||||
ax = fig.add_subplot(111)
|
||||
if ibad > 0:
|
||||
ax.plot(Ppicks, SPtimes, 'ro', label='Skipped S-Picks')
|
||||
if wfitflag == 0:
|
||||
ax.plot(Ppicks, wdfit, color=linecolor, linewidth=0.7, label='Wadati 1')
|
||||
ax.plot(Ppicks, wdfit+dttolerance, color='0.9', linewidth=0.5, label='Wadati 1 Tolerance')
|
||||
ax.plot(Ppicks, wdfit-dttolerance, color='0.9', linewidth=0.5)
|
||||
ax.plot(checkedPpicks, wdfit2, 'g', label='Wadati 2')
|
||||
ax.plot(checkedPpicks, checkedSPtimes, color=linecolor,
|
||||
linewidth=0, marker='o', label='Reliable S-Picks')
|
||||
for Ppick, SPtime, station in zip(Ppicks, SPtimes, stations):
|
||||
ax.text(Ppick, SPtime + 0.01, '{0}'.format(station), color='0.25')
|
||||
|
||||
plt.ylabel('S-P Times [s]')
|
||||
plt.xlabel('P Times [s]')
|
||||
ax.set_title('Wadati-Diagram, %d S-P Times, Vp/Vs(raw)=%5.2f,' \
|
||||
'Vp/Vs(checked)=%5.2f' % (len(SPtimes), vpvsr, cvpvsr))
|
||||
ax.legend(loc=1, numpoints=1)
|
||||
else:
|
||||
ax.set_title('Wadati-Diagram, %d S-P Times' % len(SPtimes))
|
||||
|
||||
ax.set_ylabel('S-P Times [s]')
|
||||
ax.set_xlabel('P Times [s]')
|
||||
if plt_flag:
|
||||
fig.show()
|
||||
|
||||
return checkedonsets
|
||||
|
||||
|
||||
def checksignallength(X, pick, TSNR, minsiglength, nfac, minpercent, iplot=0, fig=None):
|
||||
def RMS(X):
|
||||
'''
|
||||
Function returns root mean square of a given array X
|
||||
'''
|
||||
return np.sqrt(np.sum(np.power(X, 2)) / len(X))
|
||||
|
||||
|
||||
def checksignallength(X, pick, TSNR, minsiglength, nfac, minpercent, iplot=0, fig=None, linecolor='k'):
|
||||
'''
|
||||
Function to detect spuriously picked noise peaks.
|
||||
Uses RMS trace of all 3 components (if available) to determine,
|
||||
@ -676,9 +751,18 @@ def checksignallength(X, pick, TSNR, minsiglength, nfac, minpercent, iplot=0, fi
|
||||
: type: int
|
||||
'''
|
||||
|
||||
plt_flag = 0
|
||||
try:
|
||||
iplot = int(iplot)
|
||||
except:
|
||||
if iplot == True or iplot == 'True':
|
||||
iplot = 2
|
||||
else:
|
||||
iplot = 0
|
||||
|
||||
assert isinstance(X, Stream), "%s is not a stream object" % str(X)
|
||||
|
||||
print ("Checking signal length ...")
|
||||
print("Checking signal length ...")
|
||||
|
||||
if len(X) > 1:
|
||||
# all three components available
|
||||
@ -691,51 +775,59 @@ def checksignallength(X, pick, TSNR, minsiglength, nfac, minpercent, iplot=0, fi
|
||||
rms = np.sqrt((np.power(x1, 2) + np.power(x2, 2) + np.power(x3, 2)) / 3)
|
||||
else:
|
||||
x1 = X[0].data
|
||||
rms = np.sqrt(np.power(2, x1))
|
||||
ilen = len(x1)
|
||||
rms = abs(x1)
|
||||
|
||||
t = np.arange(0, ilen / X[0].stats.sampling_rate,
|
||||
X[0].stats.delta)
|
||||
|
||||
# get noise window in front of pick plus saftey gap
|
||||
inoise = getnoisewin(t, pick - 0.5, TSNR[0], TSNR[1])
|
||||
inoise = getnoisewin(t, pick, TSNR[0], TSNR[1])
|
||||
# get signal window
|
||||
isignal = getsignalwin(t, pick, minsiglength)
|
||||
# calculate minimum adjusted signal level
|
||||
minsiglevel = max(rms[inoise]) * nfac
|
||||
minsiglevel = np.mean(rms[inoise]) * nfac
|
||||
# minimum adjusted number of samples over minimum signal level
|
||||
minnum = len(isignal) * minpercent / 100
|
||||
# get number of samples above minimum adjusted signal level
|
||||
numoverthr = len(np.where(rms[isignal] >= minsiglevel)[0])
|
||||
|
||||
if numoverthr >= minnum:
|
||||
print ("checksignallength: Signal reached required length.")
|
||||
print("checksignallength: Signal reached required length.")
|
||||
returnflag = 1
|
||||
else:
|
||||
print ("checksignallength: Signal shorter than required minimum signal length!")
|
||||
print ("Presumably picked noise peak, pick is rejected!")
|
||||
print ("(min. signal length required: %s s)" % minsiglength)
|
||||
print("checksignallength: Signal shorter than required minimum signal length!")
|
||||
print("Presumably picked noise peak, pick is rejected!")
|
||||
print("(min. signal length required: %s s)" % minsiglength)
|
||||
returnflag = 0
|
||||
|
||||
if iplot == 2:
|
||||
if not fig:
|
||||
fig = plt.figure()#iplot)
|
||||
if iplot > 1:
|
||||
if fig == None or fig == 'None':
|
||||
fig = plt.figure() # iplot)
|
||||
plt_flag = 1
|
||||
fig._tight = True
|
||||
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, rms, color=linecolor, linewidth=0.7, 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.legend(loc=1)
|
||||
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([])
|
||||
if plt_flag == 1:
|
||||
fig.show()
|
||||
try: input()
|
||||
except SyntaxError: pass
|
||||
plt.close(fig)
|
||||
|
||||
return returnflag
|
||||
|
||||
|
||||
def checkPonsets(pickdic, dttolerance, iplot):
|
||||
def checkPonsets(pickdic, dttolerance, jackfactor=5, iplot=0, fig_dict=None):
|
||||
'''
|
||||
Function to check statistics of P-onset times: Control deviation from
|
||||
median (maximum adjusted deviation = dttolerance) and apply pseudo-
|
||||
@ -757,24 +849,26 @@ def checkPonsets(pickdic, dttolerance, iplot):
|
||||
# search for good quality P picks
|
||||
Ppicks = []
|
||||
stations = []
|
||||
for key in pickdic:
|
||||
if pickdic[key]['P']['weight'] < 4:
|
||||
for station in pickdic:
|
||||
if pickdic[station]['P']['weight'] < 4:
|
||||
# add P onsets to list
|
||||
UTCPpick = UTCDateTime(pickdic[key]['P']['mpp'])
|
||||
UTCPpick = UTCDateTime(pickdic[station]['P']['mpp'])
|
||||
Ppicks.append(UTCPpick.timestamp)
|
||||
stations.append(key)
|
||||
stations.append(station)
|
||||
|
||||
# apply jackknife bootstrapping on variance of P onsets
|
||||
print ("###############################################")
|
||||
print ("checkPonsets: Apply jackknife bootstrapping on P-onset times ...")
|
||||
print("###############################################")
|
||||
print("checkPonsets: Apply jackknife bootstrapping on P-onset times ...")
|
||||
[xjack, PHI_pseudo, PHI_sub] = jackknife(Ppicks, 'VAR', 1)
|
||||
if not xjack:
|
||||
return
|
||||
# get pseudo variances smaller than average variances
|
||||
# (times safety factor), these picks passed jackknife test
|
||||
ij = np.where(PHI_pseudo <= 5 * xjack)
|
||||
ij = np.where(PHI_pseudo <= jackfactor * xjack)
|
||||
# these picks did not pass jackknife test
|
||||
badjk = np.where(PHI_pseudo > 5 * xjack)
|
||||
badjk = np.where(PHI_pseudo > jackfactor * xjack)
|
||||
badjkstations = np.array(stations)[badjk]
|
||||
print ("checkPonsets: %d pick(s) did not pass jackknife test!" % len(badjkstations))
|
||||
print("checkPonsets: %d pick(s) did not pass jackknife test!" % len(badjkstations))
|
||||
print(badjkstations)
|
||||
|
||||
# calculate median from these picks
|
||||
@ -787,9 +881,10 @@ def checkPonsets(pickdic, dttolerance, iplot):
|
||||
goodstations = np.array(stations)[igood]
|
||||
badstations = np.array(stations)[ibad]
|
||||
|
||||
print ("checkPonsets: %d pick(s) deviate too much from median!" % len(ibad))
|
||||
print ("checkPonsets: Skipped %d P pick(s) out of %d" % (len(badstations) \
|
||||
+ len(badjkstations), len(stations)))
|
||||
print("checkPonsets: %d pick(s) deviate too much from median!" % len(ibad))
|
||||
print(badstations)
|
||||
print("checkPonsets: Skipped %d P pick(s) out of %d" % (len(badstations) \
|
||||
+ len(badjkstations), len(stations)))
|
||||
|
||||
goodmarker = 'goodPonsetcheck'
|
||||
badmarker = 'badPonsetcheck'
|
||||
@ -798,34 +893,52 @@ def checkPonsets(pickdic, dttolerance, iplot):
|
||||
# mark P onset as checked and keep P weight
|
||||
pickdic[goodstations[i]]['P']['marked'] = goodmarker
|
||||
for i in range(0, len(badstations)):
|
||||
# mark P onset and downgrade P weight to 9
|
||||
# (not used anymore)
|
||||
pickdic[badstations[i]]['P']['marked'] = badmarker
|
||||
pickdic[badstations[i]]['P']['weight'] = 9
|
||||
# remove pick from dictionary
|
||||
pickdic.pop(badstations[i])
|
||||
for i in range(0, len(badjkstations)):
|
||||
# mark P onset and downgrade P weight to 9
|
||||
# (not used anymore)
|
||||
pickdic[badjkstations[i]]['P']['marked'] = badjkmarker
|
||||
pickdic[badjkstations[i]]['P']['weight'] = 9
|
||||
# remove pick from dictionary
|
||||
pickdic.pop(badjkstations[i])
|
||||
# for i in range(0, len(badstations)):
|
||||
# # mark P onset and downgrade P weight to 9
|
||||
# # (not used anymore)
|
||||
# pickdic[badstations[i]]['P']['marked'] = badmarker
|
||||
# pickdic[badstations[i]]['P']['weight'] = 9
|
||||
# for i in range(0, len(badjkstations)):
|
||||
# # mark P onset and downgrade P weight to 9
|
||||
# # (not used anymore)
|
||||
# pickdic[badjkstations[i]]['P']['marked'] = badjkmarker
|
||||
# pickdic[badjkstations[i]]['P']['weight'] = 9
|
||||
|
||||
checkedonsets = pickdic
|
||||
|
||||
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)
|
||||
if fig_dict:
|
||||
fig = fig_dict['jackknife']
|
||||
plt_flag = 0
|
||||
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.01, '{0}'.format(stations[i]))
|
||||
fig = plt.figure()
|
||||
plt_flag = 1
|
||||
ax = fig.add_subplot(111)
|
||||
|
||||
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('Jackknifing and Median Tests on P Onsets')
|
||||
if len(badstations) > 0:
|
||||
ax.plot(ibad, np.array(Ppicks)[ibad], marker ='o', markerfacecolor='orange', markersize=14,
|
||||
linestyle='None', label='Median Skipped P Picks')
|
||||
if len(badjkstations) > 0:
|
||||
ax.plot(badjk[0], np.array(Ppicks)[badjk], 'ro', markersize=14, label='Jackknife Skipped P Picks')
|
||||
ax.plot(igood, np.array(Ppicks)[igood], 'go', markersize=14, label='Good P Picks')
|
||||
ax.plot([0, len(Ppicks) - 1], [pmedian, pmedian], 'g', linewidth=2, label='Median')
|
||||
ax.plot([0, len(Ppicks) - 1], [pmedian + dttolerance, pmedian + dttolerance], 'g--', linewidth=1.2,
|
||||
dashes=[25, 25], label='Median Tolerance')
|
||||
ax.plot([0, len(Ppicks) - 1], [pmedian - dttolerance, pmedian - dttolerance], 'g--', linewidth=1.2,
|
||||
dashes=[25, 25])
|
||||
for index, pick in enumerate(Ppicks):
|
||||
ax.text(index, pick + 0.01, '{0}'.format(stations[index]), color='0.25')
|
||||
ax.set_xlabel('Number of P Picks')
|
||||
ax.set_ylabel('Onset Time [s] from 1.1.1970') # MP MP Improve this?
|
||||
ax.legend(loc=1, numpoints=1)
|
||||
ax.set_title('Jackknifing and Median Tests on P Onsets')
|
||||
if plt_flag:
|
||||
fig.show()
|
||||
|
||||
return checkedonsets
|
||||
|
||||
@ -854,13 +967,13 @@ def jackknife(X, phi, h):
|
||||
PHI_sub = None
|
||||
|
||||
# determine number of subgroups
|
||||
g = len(X) / h
|
||||
|
||||
if type(g) is not int:
|
||||
print ("jackknife: Cannot divide quantity X in equal sized subgroups!")
|
||||
print ("Choose another size for subgroups!")
|
||||
if len(X) % h:
|
||||
print("jackknife: Cannot divide quantity X in equal sized subgroups!")
|
||||
print("Choose another size for subgroups!")
|
||||
return PHI_jack, PHI_pseudo, PHI_sub
|
||||
else:
|
||||
g = int(len(X) / h)
|
||||
# estimator of undisturbed spot check
|
||||
if phi == 'MEA':
|
||||
phi_sc = np.mean(X)
|
||||
@ -894,7 +1007,7 @@ def jackknife(X, phi, h):
|
||||
return PHI_jack, PHI_pseudo, PHI_sub
|
||||
|
||||
|
||||
def checkZ4S(X, pick, zfac, checkwin, iplot, fig=None):
|
||||
def checkZ4S(X, pick, zfac, checkwin, iplot, fig=None, linecolor='k'):
|
||||
'''
|
||||
Function to compare energy content of vertical trace with
|
||||
energy content of horizontal traces to detect spuriously
|
||||
@ -923,10 +1036,20 @@ def checkZ4S(X, pick, zfac, checkwin, iplot, fig=None):
|
||||
are shown
|
||||
: type: int
|
||||
'''
|
||||
|
||||
plt_flag = 0
|
||||
try:
|
||||
iplot = int(iplot)
|
||||
except:
|
||||
if iplot == True or iplot == 'True':
|
||||
iplot = 2
|
||||
else:
|
||||
iplot = 0
|
||||
|
||||
|
||||
assert isinstance(X, Stream), "%s is not a stream object" % str(X)
|
||||
|
||||
print ("Check for spuriously picked S onset instead of P onset ...")
|
||||
print("Check for spuriously picked S onset instead of P onset ...")
|
||||
|
||||
returnflag = 0
|
||||
|
||||
@ -941,74 +1064,122 @@ def checkZ4S(X, pick, zfac, checkwin, iplot, fig=None):
|
||||
if len(ndat) == 0: # check for other components
|
||||
ndat = X.select(component="1")
|
||||
|
||||
z = zdat[0].data
|
||||
# get earliest time of all 3 traces
|
||||
min_t = min(zdat[0].stats.starttime, edat[0].stats.starttime, ndat[0].stats.starttime)
|
||||
|
||||
# generate time arrays for all 3 traces
|
||||
tz = np.arange(0, zdat[0].stats.npts / zdat[0].stats.sampling_rate,
|
||||
zdat[0].stats.delta)
|
||||
tn = np.arange(0, ndat[0].stats.npts / ndat[0].stats.sampling_rate,
|
||||
ndat[0].stats.delta)
|
||||
te = np.arange(0, edat[0].stats.npts / edat[0].stats.sampling_rate,
|
||||
edat[0].stats.delta)
|
||||
|
||||
# calculate RMS trace from vertical component
|
||||
absz = np.sqrt(np.power(z, 2))
|
||||
# calculate RMS trace from both horizontal traces
|
||||
# make sure, both traces have equal lengths
|
||||
lene = len(edat[0].data)
|
||||
lenn = len(ndat[0].data)
|
||||
minlen = min([lene, lenn])
|
||||
absen = np.sqrt(np.power(edat[0].data[0:minlen - 1], 2) \
|
||||
+ np.power(ndat[0].data[0:minlen - 1], 2))
|
||||
zdiff = (zdat[0].stats.starttime - min_t)
|
||||
ndiff = (ndat[0].stats.starttime - min_t)
|
||||
ediff = (edat[0].stats.starttime - min_t)
|
||||
|
||||
# get signal window
|
||||
isignal = getsignalwin(tz, pick, checkwin)
|
||||
# get signal windows
|
||||
isignalz = getsignalwin(tz, pick - zdiff, checkwin)
|
||||
isignaln = getsignalwin(tn, pick - ndiff, checkwin)
|
||||
isignale = getsignalwin(te, pick - ediff, 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 RMS of traces
|
||||
rmsz = RMS(zdat[0].data[isignalz])
|
||||
rmsn = RMS(ndat[0].data[isignaln])
|
||||
rmse = RMS(edat[0].data[isignale])
|
||||
|
||||
# calculate threshold
|
||||
minsiglevel = encodalevel * zfac
|
||||
minsiglevel = (rmsn + rmse) / 2 * zfac
|
||||
|
||||
# vertical P-coda level must exceed horizontal P-coda level
|
||||
# zfac times encodalevel
|
||||
if zcodalevel < minsiglevel:
|
||||
print ("checkZ4S: Maybe S onset? Skip this P pick!")
|
||||
if rmsz < minsiglevel:
|
||||
print("checkZ4S: Maybe S onset? Skip this P pick!")
|
||||
else:
|
||||
print ("checkZ4S: P onset passes checkZ4S test!")
|
||||
print("checkZ4S: P onset passes checkZ4S test!")
|
||||
returnflag = 1
|
||||
|
||||
if iplot > 1:
|
||||
te = np.arange(0, edat[0].stats.npts / edat[0].stats.sampling_rate,
|
||||
edat[0].stats.delta)
|
||||
tn = np.arange(0, ndat[0].stats.npts / ndat[0].stats.sampling_rate,
|
||||
ndat[0].stats.delta)
|
||||
if not fig:
|
||||
fig = plt.figure()
|
||||
ax = fig.add_subplot(111)
|
||||
ax.plot(tz, z / max(z), 'k')
|
||||
ax.axvspan(tz[isignal[0]], tz[isignal[-1]], color='b', alpha=0.2,
|
||||
lw=0, label='Signal Window')
|
||||
ax.plot(te, edat[0].data / max(edat[0].data) + 1, 'k')
|
||||
ax.plot(tn, ndat[0].data / max(ndat[0].data) + 2, 'k')
|
||||
ax.plot([tz[isignal[0]], tz[isignal[len(isignal) - 1]]],
|
||||
[minsiglevel / max(z), minsiglevel / max(z)], 'g',
|
||||
linewidth=2, label='Minimum Signal Level')
|
||||
ax.set_xlabel('Time [s] since %s' % zdat[0].stats.starttime)
|
||||
ax.set_ylabel('Normalized Counts')
|
||||
ax.set_yticks([0, 1, 2], [zdat[0].stats.channel, edat[0].stats.channel,
|
||||
ndat[0].stats.channel])
|
||||
ax.set_title('CheckZ4S, Station %s' % zdat[0].stats.station)
|
||||
ax.legend()
|
||||
rms_dict = {'Z': rmsz,
|
||||
'N': rmsn,
|
||||
'E': rmse}
|
||||
|
||||
traces_dict = {'Z': zdat[0],
|
||||
'N': ndat[0],
|
||||
'E': edat[0]}
|
||||
|
||||
diff_dict = {'Z': zdiff,
|
||||
'N': ndiff,
|
||||
'E': ediff}
|
||||
|
||||
signal_dict = {'Z': isignalz,
|
||||
'N': isignaln,
|
||||
'E': isignale}
|
||||
|
||||
for i, key in enumerate(['Z', 'N', 'E']):
|
||||
rms = rms_dict[key]
|
||||
trace = traces_dict[key]
|
||||
t = np.arange(diff_dict[key], trace.stats.npts / trace.stats.sampling_rate + diff_dict[key],
|
||||
trace.stats.delta)
|
||||
if i == 0:
|
||||
if fig == None or fig == 'None':
|
||||
fig = plt.figure() # self.iplot) ### WHY? MP MP
|
||||
plt_flag = 1
|
||||
ax1 = fig.add_subplot(3, 1, i + 1)
|
||||
ax = ax1
|
||||
ax.set_title('CheckZ4S, Station %s' % zdat[0].stats.station)
|
||||
else:
|
||||
if fig == None or fig == 'None':
|
||||
fig = plt.figure() # self.iplot) ### WHY? MP MP
|
||||
plt_flag = 1
|
||||
ax = fig.add_subplot(3, 1, i + 1, sharex=ax1)
|
||||
fig._tight = True
|
||||
ax.plot(t, abs(trace.data), color='b', label='abs')
|
||||
ax.plot(t, trace.data, color=linecolor, linewidth=0.7)
|
||||
name = str(trace.stats.channel) + ': {}'.format(rms)
|
||||
ax.plot([pick, pick + checkwin], [rms, rms], 'r', label='RMS {}'.format(name))
|
||||
ax.plot([pick, pick], ax.get_ylim(), 'm', label='Pick')
|
||||
ax.set_ylabel('Normalized Counts')
|
||||
ax.axvspan(pick, pick + checkwin, color='c', alpha=0.2,
|
||||
lw=0)
|
||||
ax.legend(loc=1)
|
||||
ax.set_xlabel('Time [s] since %s' % zdat[0].stats.starttime)
|
||||
if plt_flag == 1:
|
||||
fig.show()
|
||||
try: input()
|
||||
except SyntaxError: pass
|
||||
plt.close(fig)
|
||||
return returnflag
|
||||
|
||||
|
||||
def getQualityFromUncertainty(uncertainty, Errors):
|
||||
'''Script to transform uncertainty into quality classes 0-4
|
||||
regarding adjusted time errors Errors.
|
||||
'''
|
||||
|
||||
# set initial quality to 4 (worst) and change only if one condition is hit
|
||||
quality = 4
|
||||
|
||||
if uncertainty == None or uncertainty == 'None':
|
||||
return quality
|
||||
|
||||
if uncertainty <= Errors[0]:
|
||||
quality = 0
|
||||
elif (uncertainty > Errors[0]) and \
|
||||
(uncertainty < Errors[1]):
|
||||
quality = 1
|
||||
elif (uncertainty > Errors[1]) and \
|
||||
(uncertainty < Errors[2]):
|
||||
quality = 2
|
||||
elif (uncertainty > Errors[2]) and \
|
||||
(uncertainty < Errors[3]):
|
||||
quality = 3
|
||||
elif uncertainty > Errors[3]:
|
||||
quality = 4
|
||||
|
||||
return quality
|
||||
|
||||
if __name__ == '__main__':
|
||||
import doctest
|
||||
|
||||
|
@ -1,13 +1,16 @@
|
||||
#!/usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
import urllib2
|
||||
try:
|
||||
from urllib2 import urlopen
|
||||
except:
|
||||
from urllib.request import urlopen
|
||||
|
||||
|
||||
def checkurl(url='https://ariadne.geophysik.rub.de/trac/PyLoT'):
|
||||
def checkurl(url='https://ariadne.geophysik.ruhr-uni-bochum.de/trac/PyLoT/'):
|
||||
try:
|
||||
urllib2.urlopen(url, timeout=1)
|
||||
urlopen(url, timeout=1)
|
||||
return True
|
||||
except urllib2.URLError:
|
||||
except:
|
||||
pass
|
||||
return False
|
||||
|
@ -1,13 +1,11 @@
|
||||
#!/usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
import os
|
||||
import glob
|
||||
import os
|
||||
import sys
|
||||
from obspy.io.xseed import Parser
|
||||
|
||||
import numpy as np
|
||||
|
||||
from obspy import UTCDateTime, read_inventory, read
|
||||
from obspy.io.xseed import Parser
|
||||
from pylot.core.util.utils import key_for_set_value, find_in_list, \
|
||||
@ -117,7 +115,7 @@ def make_time_line(line, datetime):
|
||||
return newline
|
||||
|
||||
|
||||
def evt_head_check(root_dir, out_dir = None):
|
||||
def evt_head_check(root_dir, out_dir=None):
|
||||
"""
|
||||
A function to make sure that an arbitrary number of .gse files have correct values in their header.
|
||||
:param root_dir: a directory leading to the .gse files.
|
||||
@ -170,7 +168,7 @@ def read_metadata(path_to_inventory):
|
||||
invfile = list()
|
||||
respfile = list()
|
||||
# possible file extensions specified here:
|
||||
inv = dict(dless=dlfile, xml=invfile, resp=respfile, dseed=dlfile)
|
||||
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]
|
||||
@ -184,7 +182,7 @@ def read_metadata(path_to_inventory):
|
||||
print("Neither dataless-SEED file, inventory-xml file nor "
|
||||
"RESP-file found!")
|
||||
print("!!WRONG CALCULATION OF SOURCE PARAMETERS!!")
|
||||
robj = None,
|
||||
robj = None,
|
||||
elif invtype == 'dless': # prevent multiple read of large dlsv
|
||||
print("Reading metadata information from dataless-SEED file ...")
|
||||
if len(inv[invtype]) == 1:
|
||||
@ -202,7 +200,7 @@ def restitute_trace(input_tuple):
|
||||
tr, invtype, inobj, unit, force = input_tuple
|
||||
|
||||
remove_trace = False
|
||||
|
||||
|
||||
seed_id = tr.get_id()
|
||||
# check, whether this trace has already been corrected
|
||||
if 'processing' in tr.stats.keys() \
|
||||
@ -245,14 +243,14 @@ def restitute_trace(input_tuple):
|
||||
remove_trace = True
|
||||
# apply restitution to data
|
||||
print("Correcting instrument at station %s, channel %s" \
|
||||
% (tr.stats.station, tr.stats.channel))
|
||||
% (tr.stats.station, tr.stats.channel))
|
||||
try:
|
||||
if invtype in ['resp', 'dless']:
|
||||
try:
|
||||
tr.simulate(**kwargs)
|
||||
tr.simulate(**kwargs)
|
||||
except ValueError as e:
|
||||
vmsg = '{0}'.format(e)
|
||||
print(vmsg)
|
||||
vmsg = '{0}'.format(e)
|
||||
print(vmsg)
|
||||
|
||||
else:
|
||||
tr.attach_response(inventory)
|
||||
@ -271,7 +269,7 @@ def restitute_trace(input_tuple):
|
||||
return tr, remove_trace
|
||||
|
||||
|
||||
def restitute_data(data, invtype, inobj, unit='VEL', force=False):
|
||||
def restitute_data(data, invtype, inobj, unit='VEL', force=False, ncores=0):
|
||||
"""
|
||||
takes a data stream and a path_to_inventory and returns the corrected
|
||||
waveform data stream
|
||||
@ -294,15 +292,15 @@ def restitute_data(data, invtype, inobj, unit='VEL', force=False):
|
||||
for tr in data:
|
||||
input_tuples.append((tr, invtype, inobj, unit, force))
|
||||
data.remove(tr)
|
||||
|
||||
pool = gen_Pool()
|
||||
|
||||
pool = gen_Pool(ncores)
|
||||
result = pool.map(restitute_trace, input_tuples)
|
||||
pool.close()
|
||||
|
||||
|
||||
for tr, remove_trace in result:
|
||||
if not remove_trace:
|
||||
data.traces.append(tr)
|
||||
|
||||
|
||||
# check if ALL traces could be restituted, take care of large datasets
|
||||
# better try restitution for smaller subsets of data (e.g. station by
|
||||
# station)
|
||||
@ -344,8 +342,8 @@ def get_prefilt(trace, tlow=(0.5, 0.9), thi=(5., 2.), verbosity=0):
|
||||
trace.stats.station, trace.stats.channel))
|
||||
# get corner frequencies for pre-filtering
|
||||
fny = trace.stats.sampling_rate / 2
|
||||
fc21 = fny - (fny * thi[0]/100.)
|
||||
fc22 = fny - (fny * thi[1]/100.)
|
||||
fc21 = fny - (fny * thi[0] / 100.)
|
||||
fc22 = fny - (fny * thi[1] / 100.)
|
||||
return (tlow[0], tlow[1], fc21, fc22)
|
||||
|
||||
|
||||
|
@ -7,43 +7,29 @@ Created on Wed Feb 26 12:31:25 2014
|
||||
"""
|
||||
|
||||
import os
|
||||
from pylot.core.loc import nll
|
||||
from pylot.core.loc import hyposat
|
||||
import platform
|
||||
|
||||
from pylot.core.util.utils import readDefaultFilterInformation
|
||||
from pylot.core.loc import hypo71
|
||||
from pylot.core.loc import hypodd
|
||||
from pylot.core.loc import hyposat
|
||||
from pylot.core.loc import nll
|
||||
from pylot.core.loc import velest
|
||||
|
||||
|
||||
def readFilterInformation(fname):
|
||||
def convert2FreqRange(*args):
|
||||
if len(args) > 1:
|
||||
return [float(arg) for arg in args]
|
||||
elif len(args) == 1:
|
||||
return float(args[0])
|
||||
return None
|
||||
# determine system dependent path separator
|
||||
system_name = platform.system()
|
||||
if system_name in ["Linux", "Darwin"]:
|
||||
SEPARATOR = '/'
|
||||
elif system_name == "Windows":
|
||||
SEPARATOR = '\\'
|
||||
|
||||
filter_file = open(fname, 'r')
|
||||
filter_information = dict()
|
||||
for filter_line in filter_file.readlines():
|
||||
filter_line = filter_line.split(' ')
|
||||
for n, pos in enumerate(filter_line):
|
||||
if pos == '\n':
|
||||
filter_line[n] = ''
|
||||
filter_information[filter_line[0]] = {'filtertype': filter_line[1]
|
||||
if filter_line[1]
|
||||
else None,
|
||||
'order': int(filter_line[2])
|
||||
if filter_line[1]
|
||||
else None,
|
||||
'freq': convert2FreqRange(*filter_line[3:])
|
||||
if filter_line[1]
|
||||
else None}
|
||||
return filter_information
|
||||
# suffix for phase name if not phase identified by last letter (P, p, etc.)
|
||||
ALTSUFFIX = ['diff', 'n', 'g', '1', '2', '3']
|
||||
|
||||
|
||||
FILTERDEFAULTS = readFilterInformation(os.path.join(os.path.expanduser('~'),
|
||||
'.pylot',
|
||||
'filter.in'))
|
||||
FILTERDEFAULTS = readDefaultFilterInformation(os.path.join(os.path.expanduser('~'),
|
||||
'.pylot',
|
||||
'pylot.in'))
|
||||
|
||||
TIMEERROR_DEFAULTS = os.path.join(os.path.expanduser('~'),
|
||||
'.pylot',
|
||||
@ -59,14 +45,14 @@ LOCTOOLS = dict(nll=nll, hyposat=hyposat, velest=velest, hypo71=hypo71, hypodd=h
|
||||
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:
|
||||
@ -85,10 +71,10 @@ class SetChannelComponents(object):
|
||||
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 {}.'
|
||||
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 {}.'
|
||||
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:
|
||||
@ -97,7 +83,7 @@ class SetChannelComponents(object):
|
||||
|
||||
def getCompPosition(self, component):
|
||||
return self._getCurrentPosition(component)[0]
|
||||
|
||||
|
||||
def getPlotPosition(self, component):
|
||||
component = str(component)
|
||||
if component in self.compPosition_Map.keys():
|
||||
@ -105,6 +91,5 @@ class SetChannelComponents(object):
|
||||
elif component in self.compName_Map.keys():
|
||||
return self.compPosition_Map[self.compName_Map[component]]
|
||||
else:
|
||||
errMsg='getCompPosition: Unrecognized component {}. Expecting one of {} or {}.'
|
||||
errMsg = 'getCompPosition: Unrecognized component {}. Expecting one of {} or {}.'
|
||||
raise ValueError(errMsg.format(component, self.compPosition_Map.keys(), self.compName_Map.keys()))
|
||||
|
||||
|
@ -25,5 +25,6 @@ class OverwriteError(IOError):
|
||||
class ParameterError(Exception):
|
||||
pass
|
||||
|
||||
|
||||
class ProcessingError(RuntimeError):
|
||||
pass
|
||||
|
@ -5,8 +5,7 @@ import os
|
||||
|
||||
from obspy import UTCDateTime
|
||||
from obspy.core.event import Event as ObsPyEvent
|
||||
from obspy.core.event import Origin, Magnitude, ResourceIdentifier
|
||||
|
||||
from obspy.core.event import Origin, ResourceIdentifier
|
||||
from pylot.core.io.phases import picks_from_picksdict
|
||||
|
||||
|
||||
@ -14,10 +13,11 @@ class Event(ObsPyEvent):
|
||||
'''
|
||||
Pickable class derived from ~obspy.core.event.Event containing information on a single event.
|
||||
'''
|
||||
|
||||
def __init__(self, path):
|
||||
self.pylot_id = path.split('/')[-1]
|
||||
# initialize super class
|
||||
super(Event, self).__init__(resource_id=ResourceIdentifier('smi:local/'+self.pylot_id))
|
||||
super(Event, self).__init__(resource_id=ResourceIdentifier('smi:local/' + self.pylot_id))
|
||||
self.path = path
|
||||
self.database = path.split('/')[-2]
|
||||
self.datapath = path.split('/')[-3]
|
||||
@ -32,13 +32,13 @@ class Event(ObsPyEvent):
|
||||
def get_notes_path(self):
|
||||
notesfile = os.path.join(self.path, 'notes.txt')
|
||||
return notesfile
|
||||
|
||||
|
||||
def get_notes(self):
|
||||
notesfile = self.get_notes_path()
|
||||
if os.path.isfile(notesfile):
|
||||
with open(notesfile) as infile:
|
||||
path = str(infile.readlines()[0].split('\n')[0])
|
||||
text = '[eventInfo: '+path+']'
|
||||
text = '[eventInfo: ' + path + ']'
|
||||
self.addNotes(text)
|
||||
try:
|
||||
datetime = UTCDateTime(path.split('/')[-1])
|
||||
@ -67,31 +67,47 @@ class Event(ObsPyEvent):
|
||||
self._testEvent = bool
|
||||
if bool: self._refEvent = False
|
||||
|
||||
def clearObsPyPicks(self, picktype):
|
||||
for index, pick in reversed(list(enumerate(self.picks))):
|
||||
if picktype in str(pick.method_id):
|
||||
self.picks.pop(index)
|
||||
|
||||
def addPicks(self, picks):
|
||||
'''
|
||||
add pylot picks and overwrite existing
|
||||
add pylot picks and overwrite existing ones
|
||||
'''
|
||||
for station in picks:
|
||||
self.pylot_picks[station] = picks[station]
|
||||
#add ObsPy picks
|
||||
self.picks = picks_from_picksdict(self.pylot_picks)
|
||||
|
||||
# add ObsPy picks (clear old manual and copy all new manual from pylot)
|
||||
self.clearObsPyPicks('manual')
|
||||
self.picks += picks_from_picksdict(self.pylot_picks)
|
||||
|
||||
def addAutopicks(self, autopicks):
|
||||
for station in autopicks:
|
||||
self.pylot_autopicks[station] = autopicks[station]
|
||||
|
||||
# add ObsPy picks (clear old auto and copy all new auto from pylot)
|
||||
self.clearObsPyPicks('auto')
|
||||
self.picks += picks_from_picksdict(self.pylot_autopicks)
|
||||
|
||||
def setPick(self, station, pick):
|
||||
if pick:
|
||||
self.pylot_picks[station] = pick
|
||||
self.picks = picks_from_picksdict(self.pylot_picks)
|
||||
|
||||
else:
|
||||
try:
|
||||
self.pylot_picks.pop(station)
|
||||
except Exception as e:
|
||||
print('Could not remove pick {} from station {}: {}'.format(pick, station, e))
|
||||
self.clearObsPyPicks('manual')
|
||||
self.picks += picks_from_picksdict(self.pylot_picks)
|
||||
|
||||
def setPicks(self, picks):
|
||||
'''
|
||||
set pylot picks and delete and overwrite all existing
|
||||
'''
|
||||
self.pylot_picks = picks
|
||||
self.picks = picks_from_picksdict(self.pylot_picks)
|
||||
|
||||
self.clearObsPyPicks('manual')
|
||||
self.picks += picks_from_picksdict(self.pylot_picks)
|
||||
|
||||
def getPick(self, station):
|
||||
if station in self.pylot_picks.keys():
|
||||
return self.pylot_picks[station]
|
||||
@ -99,13 +115,25 @@ class Event(ObsPyEvent):
|
||||
def getPicks(self):
|
||||
return self.pylot_picks
|
||||
|
||||
def setAutopick(self, station, autopick):
|
||||
if autopick:
|
||||
self.pylot_autopicks[station] = autopick
|
||||
def setAutopick(self, station, pick):
|
||||
if pick:
|
||||
self.pylot_autopicks[station] = pick
|
||||
else:
|
||||
try:
|
||||
self.pylot_autopicks.pop(station)
|
||||
except Exception as e:
|
||||
print('Could not remove pick {} from station {}: {}'.format(pick, station, e))
|
||||
self.clearObsPyPicks('auto')
|
||||
self.picks += picks_from_picksdict(self.pylot_autopicks)
|
||||
|
||||
def setAutopicks(self, picks):
|
||||
'''
|
||||
set pylot picks and delete and overwrite all existing
|
||||
'''
|
||||
self.pylot_autopicks = picks
|
||||
self.clearObsPyPicks('auto')
|
||||
self.picks += picks_from_picksdict(self.pylot_autopicks)
|
||||
|
||||
def setAutopicks(self, autopicks):
|
||||
self.pylot_autopicks = autopicks
|
||||
|
||||
def getAutopick(self, station):
|
||||
if station in self.pylot_autopicks.keys():
|
||||
return self.pylot_autopicks[station]
|
||||
|
@ -1,24 +1,28 @@
|
||||
from mpl_toolkits.basemap import Basemap
|
||||
#!/usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
import matplotlib.pyplot as plt
|
||||
import numpy as np
|
||||
import obspy
|
||||
from matplotlib import cm
|
||||
from scipy.interpolate import griddata
|
||||
from PySide import QtGui
|
||||
from matplotlib.backends.backend_qt4agg import NavigationToolbar2QT as NavigationToolbar
|
||||
from PySide import QtCore, QtGui
|
||||
|
||||
from mpl_toolkits.basemap import Basemap
|
||||
from pylot.core.util.widgets import PickDlg
|
||||
from scipy.interpolate import griddata
|
||||
|
||||
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.metadata = parent.metadata
|
||||
self.parser = parent.metadata[1]
|
||||
self.picks = None
|
||||
self.picks_dict = None
|
||||
@ -28,7 +32,7 @@ class map_projection(QtGui.QWidget):
|
||||
self.init_stations()
|
||||
self.init_basemap(resolution='l')
|
||||
self.init_map()
|
||||
#self.show()
|
||||
# self.show()
|
||||
|
||||
def init_map(self):
|
||||
self.init_lat_lon_dimensions()
|
||||
@ -36,7 +40,7 @@ class map_projection(QtGui.QWidget):
|
||||
self.init_x_y_dimensions()
|
||||
self.connectSignals()
|
||||
self.draw_everything()
|
||||
|
||||
|
||||
def onpick(self, event):
|
||||
ind = event.ind
|
||||
button = event.mouseevent.button
|
||||
@ -44,7 +48,7 @@ class map_projection(QtGui.QWidget):
|
||||
return
|
||||
data = self._parent.get_data().getWFData()
|
||||
for index in ind:
|
||||
station=str(self.station_names[index].split('.')[-1])
|
||||
station = str(self.station_names[index].split('.')[-1])
|
||||
try:
|
||||
pickDlg = PickDlg(self, parameter=self._parent._inputs,
|
||||
data=data.select(station=station),
|
||||
@ -89,7 +93,7 @@ class map_projection(QtGui.QWidget):
|
||||
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
|
||||
|
||||
@ -105,29 +109,29 @@ class map_projection(QtGui.QWidget):
|
||||
|
||||
self.comboBox_am = QtGui.QComboBox()
|
||||
self.comboBox_am.insertItem(0, 'auto')
|
||||
self.comboBox_am.insertItem(1, 'manual')
|
||||
|
||||
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.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=[]
|
||||
station_names = []
|
||||
lat = []
|
||||
lon = []
|
||||
for station in parser.stations:
|
||||
station_name=station[0].station_call_letters
|
||||
network=station[0].network_code
|
||||
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)
|
||||
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
|
||||
@ -135,52 +139,53 @@ class map_projection(QtGui.QWidget):
|
||||
|
||||
def init_picks(self):
|
||||
phase = self.comboBox_phase.currentText()
|
||||
|
||||
def get_picks(station_names):
|
||||
picks=[]
|
||||
picks = []
|
||||
for station in station_names:
|
||||
try:
|
||||
station=station.split('.')[-1]
|
||||
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_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:
|
||||
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=[]
|
||||
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=[]
|
||||
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):
|
||||
@ -188,7 +193,7 @@ class map_projection(QtGui.QWidget):
|
||||
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):
|
||||
@ -196,30 +201,30 @@ class map_projection(QtGui.QWidget):
|
||||
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,
|
||||
# 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')
|
||||
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
|
||||
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)
|
||||
@ -234,7 +239,8 @@ class map_projection(QtGui.QWidget):
|
||||
|
||||
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') ##################
|
||||
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)
|
||||
@ -243,7 +249,7 @@ class map_projection(QtGui.QWidget):
|
||||
|
||||
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')
|
||||
zorder=10, picker=True, edgecolor='m', label='Not Picked')
|
||||
self.cid = self.canvas.mpl_connect('pick_event', self.onpick)
|
||||
if self.eventLoc:
|
||||
lat, lon = self.eventLoc
|
||||
@ -254,11 +260,11 @@ class map_projection(QtGui.QWidget):
|
||||
lon = self.lon_no_nan
|
||||
lat = self.lat_no_nan
|
||||
|
||||
#workaround because of an issue with latlon transformation of arrays with len <3
|
||||
# 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:
|
||||
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:
|
||||
@ -266,11 +272,11 @@ class map_projection(QtGui.QWidget):
|
||||
c=self.picks_no_nan, latlon=True, zorder=11, label='Picked')
|
||||
|
||||
def annotate_ax(self):
|
||||
self.annotations=[]
|
||||
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()
|
||||
self.legend = self.main_ax.legend(loc=1)
|
||||
|
||||
def add_cbar(self, label):
|
||||
cbar = self.main_ax.figure.colorbar(self.sc_picked, fraction=0.025)
|
||||
@ -306,19 +312,19 @@ class map_projection(QtGui.QWidget):
|
||||
def remove_drawings(self):
|
||||
if hasattr(self, 'sc_picked'):
|
||||
self.sc_picked.remove()
|
||||
del(self.sc_picked)
|
||||
del (self.sc_picked)
|
||||
if hasattr(self, 'sc_event'):
|
||||
self.sc_event.remove()
|
||||
del(self.sc_event)
|
||||
del (self.sc_event)
|
||||
if hasattr(self, 'cbar'):
|
||||
self.cbar.remove()
|
||||
del(self.cbar)
|
||||
del (self.cbar)
|
||||
if hasattr(self, 'contourf'):
|
||||
self.remove_contourf()
|
||||
del(self.contourf)
|
||||
del (self.contourf)
|
||||
if hasattr(self, 'cid'):
|
||||
self.canvas.mpl_disconnect(self.cid)
|
||||
del(self.cid)
|
||||
del (self.cid)
|
||||
try:
|
||||
self.sc.remove()
|
||||
except Exception as e:
|
||||
@ -342,18 +348,18 @@ class map_projection(QtGui.QWidget):
|
||||
xlim = map.ax.get_xlim()
|
||||
ylim = map.ax.get_ylim()
|
||||
x, y = event.xdata, event.ydata
|
||||
zoom = {'up': 1./2.,
|
||||
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
|
||||
xdiff = (xlim[1] - xlim[0]) * factor
|
||||
xl = x - 0.5 * xdiff
|
||||
xr = x + 0.5 * xdiff
|
||||
ydiff = (ylim[1]-ylim[0])*factor
|
||||
ydiff = (ylim[1] - ylim[0]) * factor
|
||||
yb = y - 0.5 * ydiff
|
||||
yt = y + 0.5 * ydiff
|
||||
|
||||
@ -363,10 +369,8 @@ class map_projection(QtGui.QWidget):
|
||||
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()
|
||||
|
||||
|
||||
self.qmb.show()
|
||||
|
@ -2,20 +2,23 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
import warnings
|
||||
|
||||
import numpy as np
|
||||
from obspy import UTCDateTime
|
||||
from pylot.core.util.utils import fit_curve, find_nearest, clims
|
||||
from pylot.core.util.utils import fit_curve, clims
|
||||
from pylot.core.util.version import get_git_version as _getVersionString
|
||||
|
||||
__version__ = _getVersionString()
|
||||
__author__ = 'sebastianw'
|
||||
|
||||
|
||||
def create_axis(x0, incr, npts):
|
||||
ax = np.zeros(npts)
|
||||
for i in range(npts):
|
||||
ax[i] = x0 + incr * i
|
||||
return ax
|
||||
|
||||
|
||||
def gauss_parameter(te, tm, tl, eta):
|
||||
'''
|
||||
takes three onset times and returns the parameters sig1, sig2, a1 and a2
|
||||
@ -59,7 +62,7 @@ def exp_parameter(te, tm, tl, eta):
|
||||
return tm, sig1, sig2, a
|
||||
|
||||
|
||||
def gauss_branches(k, (mu, sig1, sig2, a1, a2)):
|
||||
def gauss_branches(k, param_tuple):
|
||||
'''
|
||||
function gauss_branches takes an axes x, a center value mu, two sigma
|
||||
values sig1 and sig2 and two scaling factors a1 and a2 and return a
|
||||
@ -79,6 +82,9 @@ def gauss_branches(k, (mu, sig1, sig2, a1, a2)):
|
||||
:returns fun_vals: list with function values along axes x
|
||||
'''
|
||||
|
||||
# python 3 workaround
|
||||
mu, sig1, sig2, a1, a2 = param_tuple
|
||||
|
||||
def _func(k, mu, sig1, sig2, a1, a2):
|
||||
if k < mu:
|
||||
rval = a1 * 1 / (np.sqrt(2 * np.pi) * sig1) * np.exp(-((k - mu) / sig1) ** 2 / 2)
|
||||
@ -93,7 +99,7 @@ def gauss_branches(k, (mu, sig1, sig2, a1, a2)):
|
||||
return _func(k, mu, sig1, sig2, a1, a2)
|
||||
|
||||
|
||||
def exp_branches(k, (mu, sig1, sig2, a)):
|
||||
def exp_branches(k, param_tuple):
|
||||
'''
|
||||
function exp_branches takes an axes x, a center value mu, two sigma
|
||||
values sig1 and sig2 and a scaling factor a and return a
|
||||
@ -107,6 +113,9 @@ def exp_branches(k, (mu, sig1, sig2, a)):
|
||||
:returns fun_vals: list with function values along axes x:
|
||||
'''
|
||||
|
||||
# python 3 workaround
|
||||
mu, sig1, sig2, a = param_tuple
|
||||
|
||||
def _func(k, mu, sig1, sig2, a):
|
||||
mu = float(mu)
|
||||
if k < mu:
|
||||
@ -239,7 +248,7 @@ class ProbabilityDensityFunction(object):
|
||||
self._x = np.array(x)
|
||||
|
||||
@classmethod
|
||||
def from_pick(self, lbound, barycentre, rbound, incr=0.001, decfact=0.01,
|
||||
def from_pick(self, lbound, barycentre, rbound, incr=0.1, decfact=0.01,
|
||||
type='exp'):
|
||||
'''
|
||||
Initialize a new ProbabilityDensityFunction object.
|
||||
@ -307,14 +316,14 @@ class ProbabilityDensityFunction(object):
|
||||
:return float: rval
|
||||
'''
|
||||
|
||||
#rval = 0
|
||||
#for x in self.axis:
|
||||
# rval = 0
|
||||
# for x in self.axis:
|
||||
# rval += x * self.data(x)
|
||||
rval = self.mu
|
||||
# Not sure about this! That might not be the barycentre.
|
||||
# However, for std calculation (next function)
|
||||
# self.mu is also used!! (LK, 02/2017)
|
||||
return rval
|
||||
return rval
|
||||
|
||||
def standard_deviation(self):
|
||||
mu = self.mu
|
||||
@ -388,7 +397,6 @@ class ProbabilityDensityFunction(object):
|
||||
qu = self.quantile(1 - prob_value)
|
||||
return qu - ql
|
||||
|
||||
|
||||
def quantile_dist_frac(self, x):
|
||||
"""
|
||||
takes a probability value and returns the fraction of two
|
||||
@ -405,8 +413,7 @@ class ProbabilityDensityFunction(object):
|
||||
"""
|
||||
if x <= 0 or x >= 0.25:
|
||||
raise ValueError('Value out of range.')
|
||||
return self.quantile_distance(0.5-x)/self.quantile_distance(x)
|
||||
|
||||
return self.quantile_distance(0.5 - x) / self.quantile_distance(x)
|
||||
|
||||
def plot(self, label=None):
|
||||
import matplotlib.pyplot as plt
|
||||
@ -480,4 +487,3 @@ class ProbabilityDensityFunction(object):
|
||||
x0, npts = self.commonlimits(incr, other)
|
||||
|
||||
return x0, incr, npts
|
||||
|
||||
|
@ -3,6 +3,7 @@
|
||||
|
||||
import matplotlib.pyplot as plt
|
||||
|
||||
|
||||
def create_bin_list(l_boundary, u_boundary, nbins=100):
|
||||
"""
|
||||
takes two boundaries and a number of bins and creates a list of bins for
|
||||
@ -54,4 +55,4 @@ def histplot(array, binlist, xlab='Values',
|
||||
if fnout:
|
||||
plt.savefig(fnout)
|
||||
else:
|
||||
plt.show()
|
||||
plt.show()
|
||||
|
@ -1,82 +1,167 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
import sys, os
|
||||
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, 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(None, None, self.infile, self.fnames, self.eventid, self.savepath)
|
||||
|
||||
print("Autopicking finished!\n")
|
||||
|
||||
try:
|
||||
for station in picks:
|
||||
self.parent().addPicks(station, picks[station], type='auto')
|
||||
except AttributeError:
|
||||
print(picks)
|
||||
sys.stdout = sys.__stdout__
|
||||
self.finished.emit()
|
||||
|
||||
def write(self, text):
|
||||
self.message.emit(text)
|
||||
|
||||
def flush(self):
|
||||
pass
|
||||
import sys, os, traceback
|
||||
import multiprocessing
|
||||
from PySide.QtCore import QThread, Signal, Qt, Slot, QRunnable, QObject
|
||||
from PySide.QtGui import QDialog, QProgressBar, QLabel, QHBoxLayout, QPushButton
|
||||
|
||||
|
||||
class Thread(QThread):
|
||||
message = Signal(str)
|
||||
|
||||
def __init__(self, parent, func, arg=None, progressText=None, pb_widget=None, redirect_stdout=False):
|
||||
|
||||
def __init__(self, parent, func, arg=None, progressText=None,
|
||||
pb_widget=None, redirect_stdout=False, abortButton=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.abortButton = abortButton
|
||||
self.finished.connect(self.hideProgressbar)
|
||||
self.showProgressbar()
|
||||
|
||||
def run(self):
|
||||
if self.redirect_stdout:
|
||||
sys.stdout = self
|
||||
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
|
||||
traceback.print_exc()
|
||||
exctype, value = sys.exc_info ()[:2]
|
||||
self._executedErrorInfo = '{} {} {}'.\
|
||||
format(exctype, value, traceback.format_exc())
|
||||
sys.stdout = sys.__stdout__
|
||||
|
||||
def showProgressbar(self):
|
||||
if self.progressText:
|
||||
|
||||
# generate widget if not given in init
|
||||
if not self.pb_widget:
|
||||
self.pb_widget = QDialog(self.parent())
|
||||
self.pb_widget.setWindowFlags(Qt.SplashScreen)
|
||||
self.pb_widget.setModal(True)
|
||||
|
||||
# add button
|
||||
delete_button = QPushButton('X')
|
||||
delete_button.clicked.connect(self.exit)
|
||||
hl = QHBoxLayout()
|
||||
pb = QProgressBar()
|
||||
pb.setRange(0, 0)
|
||||
hl.addWidget(pb)
|
||||
hl.addWidget(QLabel(self.progressText))
|
||||
if self.abortButton:
|
||||
hl.addWidget(delete_button)
|
||||
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
|
||||
|
||||
|
||||
class Worker(QRunnable):
|
||||
'''
|
||||
Worker class to be run by MultiThread(QThread).
|
||||
'''
|
||||
def __init__(self, fun, args,
|
||||
progressText=None,
|
||||
pb_widget=None,
|
||||
redirect_stdout=False):
|
||||
super(Worker, self).__init__()
|
||||
self.fun = fun
|
||||
self.args = args
|
||||
#self.kwargs = kwargs
|
||||
self.signals = WorkerSignals()
|
||||
self.progressText = progressText
|
||||
self.pb_widget = pb_widget
|
||||
self.redirect_stdout = redirect_stdout
|
||||
|
||||
@Slot()
|
||||
def run(self):
|
||||
if self.redirect_stdout:
|
||||
sys.stdout = self
|
||||
|
||||
try:
|
||||
result = self.fun(self.args)
|
||||
except:
|
||||
exctype, value = sys.exc_info ()[:2]
|
||||
print(exctype, value, traceback.format_exc())
|
||||
self.signals.error.emit ((exctype, value, traceback.format_exc ()))
|
||||
else:
|
||||
self.signals.result.emit(result)
|
||||
finally:
|
||||
self.signals.finished.emit('Done')
|
||||
sys.stdout = sys.__stdout__
|
||||
|
||||
def write(self, text):
|
||||
self.signals.message.emit(text)
|
||||
|
||||
def flush(self):
|
||||
pass
|
||||
|
||||
|
||||
class WorkerSignals(QObject):
|
||||
'''
|
||||
Class to provide signals for Worker Class
|
||||
'''
|
||||
finished = Signal(str)
|
||||
message = Signal(str)
|
||||
error = Signal(tuple)
|
||||
result = Signal(object)
|
||||
|
||||
|
||||
class MultiThread(QThread):
|
||||
finished = Signal(str)
|
||||
message = Signal(str)
|
||||
|
||||
def __init__(self, parent, func, args, ncores=1,
|
||||
progressText=None, pb_widget=None, redirect_stdout=False):
|
||||
QThread.__init__(self, parent)
|
||||
self.func = func
|
||||
self.args = args
|
||||
self.ncores = ncores
|
||||
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 not self.ncores:
|
||||
self.ncores = multiprocessing.cpu_count()
|
||||
pool = multiprocessing.Pool(self.ncores)
|
||||
self.data = pool.map_async(self.func, self.args, callback=self.emitDone)
|
||||
#self.data = pool.apply_async(self.func, self.shotlist, callback=self.emitDone) #emit each time returned
|
||||
pool.close()
|
||||
self._executed = True
|
||||
except Exception as e:
|
||||
self._executed = False
|
||||
self._executedError = e
|
||||
exc_type, exc_obj, exc_tb = sys.exc_info()
|
||||
fname = os.path.split(exc_tb.tb_frame.f_code.co_filename)[1]
|
||||
print('Exception: {}, file: {}, line: {}'.format(exc_type, fname, exc_tb.tb_lineno))
|
||||
sys.stdout = sys.__stdout__
|
||||
|
||||
def __del__(self):
|
||||
self.wait()
|
||||
sys.stdout = sys.__stdout__
|
||||
|
||||
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.setWindowFlags(Qt.SplashScreen)
|
||||
self.pb_widget.setModal(True)
|
||||
hl = QHBoxLayout()
|
||||
pb = QProgressBar()
|
||||
@ -95,4 +180,8 @@ class Thread(QThread):
|
||||
|
||||
def flush(self):
|
||||
pass
|
||||
|
||||
|
||||
def emitDone(self, result):
|
||||
print('emitDone!')
|
||||
self.finished.emit('Done thread!')
|
||||
self.hideProgressbar()
|
||||
|
@ -2,26 +2,57 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
import hashlib
|
||||
import numpy as np
|
||||
from scipy.interpolate import splrep, splev
|
||||
import os
|
||||
import pwd
|
||||
import platform
|
||||
import re
|
||||
import warnings
|
||||
import subprocess
|
||||
from obspy import UTCDateTime, read
|
||||
from pylot.core.io.inputs import PylotParameter
|
||||
|
||||
|
||||
import numpy as np
|
||||
from obspy import UTCDateTime, read
|
||||
from obspy.core import AttribDict
|
||||
from obspy.signal.rotate import rotate2zne
|
||||
from obspy.io.xseed.utils import SEEDParserException
|
||||
|
||||
from pylot.core.io.inputs import PylotParameter
|
||||
from pylot.styles import style_settings
|
||||
|
||||
from scipy.interpolate import splrep, splev
|
||||
from PySide import QtCore, QtGui
|
||||
|
||||
try:
|
||||
import pyqtgraph as pg
|
||||
except Exception as e:
|
||||
print('PyLoT: Could not import pyqtgraph. {}'.format(e))
|
||||
pg = None
|
||||
|
||||
def _pickle_method(m):
|
||||
if m.im_self is None:
|
||||
return getattr, (m.im_class, m.im_func.func_name)
|
||||
else:
|
||||
return getattr, (m.im_self, m.im_func.func_name)
|
||||
|
||||
|
||||
def readDefaultFilterInformation(fname):
|
||||
pparam = PylotParameter(fname)
|
||||
return readFilterInformation(pparam)
|
||||
|
||||
|
||||
def readFilterInformation(pylot_parameter):
|
||||
p_filter = {'filtertype': pylot_parameter['filter_type'][0],
|
||||
'freq': [pylot_parameter['minfreq'][0], pylot_parameter['maxfreq'][0]],
|
||||
'order': int(pylot_parameter['filter_order'][0])}
|
||||
s_filter = {'filtertype': pylot_parameter['filter_type'][1],
|
||||
'freq': [pylot_parameter['minfreq'][1], pylot_parameter['maxfreq'][1]],
|
||||
'order': int(pylot_parameter['filter_order'][1])}
|
||||
filter_information = {'P': p_filter,
|
||||
'S': s_filter}
|
||||
return filter_information
|
||||
|
||||
|
||||
def fit_curve(x, y):
|
||||
return splev, splrep(x, y)
|
||||
|
||||
|
||||
def getindexbounds(f, eta):
|
||||
mi = f.argmax()
|
||||
m = max(f)
|
||||
@ -31,16 +62,55 @@ def getindexbounds(f, eta):
|
||||
return mi, l, u
|
||||
|
||||
|
||||
def gen_Pool(ncores='max'):
|
||||
def gen_Pool(ncores=0):
|
||||
'''
|
||||
:param ncores: number of CPU cores for multiprocessing.Pool, if ncores == 0 use all available
|
||||
:return: multiprocessing.Pool object
|
||||
'''
|
||||
import multiprocessing
|
||||
|
||||
if ncores=='max':
|
||||
ncores=multiprocessing.cpu_count()
|
||||
|
||||
if ncores == 0:
|
||||
ncores = multiprocessing.cpu_count()
|
||||
|
||||
print('gen_Pool: Generated multiprocessing Pool with {} cores\n'.format(ncores))
|
||||
|
||||
pool = multiprocessing.Pool(ncores)
|
||||
return pool
|
||||
|
||||
|
||||
def excludeQualityClasses(picks, qClasses, timeerrorsP, timeerrorsS):
|
||||
'''
|
||||
takes PyLoT picks dictionary and returns a new dictionary with certain classes excluded.
|
||||
:param picks: PyLoT picks dictionary
|
||||
:param qClasses: list (or int) of quality classes (0-4) to exclude
|
||||
:param timeerrorsP: time errors for classes (0-4) for P
|
||||
:param timeerrorsS: time errors for classes (0-4) for S
|
||||
:return: new picks dictionary
|
||||
'''
|
||||
from pylot.core.pick.utils import getQualityFromUncertainty
|
||||
|
||||
if type(qClasses) in [int, float]:
|
||||
qClasses = [qClasses]
|
||||
|
||||
picksdict_new = {}
|
||||
|
||||
phaseError = {'P': timeerrorsP,
|
||||
'S': timeerrorsS}
|
||||
|
||||
for station, phases in picks.items():
|
||||
for phase, pick in phases.items():
|
||||
if not type(pick) in [AttribDict, dict]:
|
||||
continue
|
||||
pickerror = phaseError[identifyPhaseID(phase)]
|
||||
quality = getQualityFromUncertainty(pick['spe'], pickerror)
|
||||
if not quality in qClasses:
|
||||
if not station in picksdict_new:
|
||||
picksdict_new[station] = {}
|
||||
picksdict_new[station][phase] = pick
|
||||
|
||||
return picksdict_new
|
||||
|
||||
|
||||
def clims(lim1, lim2):
|
||||
"""
|
||||
takes two pairs of limits and returns one pair of common limts
|
||||
@ -106,6 +176,7 @@ def findComboBoxIndex(combo_box, val):
|
||||
"""
|
||||
return combo_box.findText(val) if combo_box.findText(val) is not -1 else 0
|
||||
|
||||
|
||||
def find_in_list(list, str):
|
||||
"""
|
||||
takes a list of strings and a string and returns the first list item
|
||||
@ -135,6 +206,7 @@ def find_in_list(list, str):
|
||||
return rlist[0]
|
||||
return None
|
||||
|
||||
|
||||
def find_nearest(array, value):
|
||||
'''
|
||||
function find_nearest takes an array and a value and returns the
|
||||
@ -182,6 +254,22 @@ def fnConstructor(s):
|
||||
return fn
|
||||
|
||||
|
||||
def real_None(value):
|
||||
if value == 'None':
|
||||
return None
|
||||
else:
|
||||
return value
|
||||
|
||||
|
||||
def real_Bool(value):
|
||||
if value == 'True':
|
||||
return True
|
||||
elif value == 'False':
|
||||
return False
|
||||
else:
|
||||
return value
|
||||
|
||||
|
||||
def four_digits(year):
|
||||
"""
|
||||
takes a two digit year integer and returns the correct four digit equivalent
|
||||
@ -258,7 +346,7 @@ def getLogin():
|
||||
returns the actual user's login ID
|
||||
:return: login ID
|
||||
'''
|
||||
return pwd.getpwuid(os.getuid())[0]
|
||||
return os.getlogin()
|
||||
|
||||
|
||||
def getOwner(fn):
|
||||
@ -268,7 +356,15 @@ def getOwner(fn):
|
||||
:type fn: str
|
||||
:return: login ID of the file's owner
|
||||
'''
|
||||
return pwd.getpwuid(os.stat(fn).st_uid).pw_name
|
||||
system_name = platform.system()
|
||||
if system_name in ["Linux", "Darwin"]:
|
||||
import pwd
|
||||
return pwd.getpwuid(os.stat(fn).st_uid).pw_name
|
||||
elif system_name == "Windows":
|
||||
import win32security
|
||||
f = win32security.GetFileSecurity(fn, win32security.OWNER_SECURITY_INFORMATION)
|
||||
(username, domain, sid_name_use) = win32security.LookupAccountSid(None, f.GetSecurityDescriptorOwner())
|
||||
return username
|
||||
|
||||
|
||||
def getPatternLine(fn, pattern):
|
||||
@ -294,6 +390,7 @@ def getPatternLine(fn, pattern):
|
||||
|
||||
return None
|
||||
|
||||
|
||||
def is_executable(fn):
|
||||
"""
|
||||
takes a filename and returns True if the file is executable on the system
|
||||
@ -362,7 +459,7 @@ def key_for_set_value(d):
|
||||
return r
|
||||
|
||||
|
||||
def prepTimeAxis(stime, trace):
|
||||
def prepTimeAxis(stime, trace, verbosity=0):
|
||||
'''
|
||||
takes a starttime and a trace object and returns a valid time axis for
|
||||
plotting
|
||||
@ -376,16 +473,18 @@ def prepTimeAxis(stime, trace):
|
||||
etime = stime + nsamp / srate
|
||||
time_ax = np.arange(stime, etime, tincr)
|
||||
if len(time_ax) < nsamp:
|
||||
print('elongate time axes by one datum')
|
||||
if verbosity:
|
||||
print('elongate time axes by one datum')
|
||||
time_ax = np.arange(stime, etime + tincr, tincr)
|
||||
elif len(time_ax) > nsamp:
|
||||
print('shorten time axes by one datum')
|
||||
if verbosity:
|
||||
print('shorten time axes by one datum')
|
||||
time_ax = np.arange(stime, etime - tincr, tincr)
|
||||
if len(time_ax) != nsamp:
|
||||
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))
|
||||
'{2} length of time vector \n'
|
||||
'delta: {3}'.format(trace.stats.station,
|
||||
nsamp, len(time_ax), tincr))
|
||||
time_ax = None
|
||||
return time_ax
|
||||
|
||||
@ -413,6 +512,91 @@ def find_horizontals(data):
|
||||
return rval
|
||||
|
||||
|
||||
def make_pen(picktype, phase, key, quality):
|
||||
if pg:
|
||||
rgba = pick_color(picktype, phase, quality)
|
||||
linestyle, width = pick_linestyle_pg(picktype, key)
|
||||
pen = pg.mkPen(rgba, width=width, style=linestyle)
|
||||
return pen
|
||||
|
||||
|
||||
def pick_color(picktype, phase, quality=0):
|
||||
min_quality = 3
|
||||
bpc = base_phase_colors(picktype, phase)
|
||||
rgba = bpc['rgba']
|
||||
modifier = bpc['modifier']
|
||||
intensity = 255.*quality/min_quality
|
||||
rgba = modify_rgba(rgba, modifier, intensity)
|
||||
return rgba
|
||||
|
||||
|
||||
def pick_color_plt(picktype, phase, quality=0):
|
||||
rgba = list(pick_color(picktype, phase, quality))
|
||||
for index, val in enumerate(rgba):
|
||||
rgba[index] /= 255.
|
||||
return rgba
|
||||
|
||||
|
||||
def pick_linestyle_plt(picktype, key):
|
||||
linestyles_manu = {'mpp': ('solid', 2.),
|
||||
'epp': ('dashed', 1.),
|
||||
'lpp': ('dashed', 1.),
|
||||
'spe': ('dashed', 1.)}
|
||||
linestyles_auto = {'mpp': ('dotted', 2.),
|
||||
'epp': ('dashdot', 1.),
|
||||
'lpp': ('dashdot', 1.),
|
||||
'spe': ('dashdot', 1.)}
|
||||
linestyles = {'manual': linestyles_manu,
|
||||
'auto': linestyles_auto}
|
||||
return linestyles[picktype][key]
|
||||
|
||||
|
||||
def pick_linestyle_pg(picktype, key):
|
||||
linestyles_manu = {'mpp': (QtCore.Qt.SolidLine, 2.),
|
||||
'epp': (QtCore.Qt.DashLine, 1.),
|
||||
'lpp': (QtCore.Qt.DashLine, 1.),
|
||||
'spe': (QtCore.Qt.DashLine, 1.)}
|
||||
linestyles_auto = {'mpp': (QtCore.Qt.DotLine, 2.),
|
||||
'epp': (QtCore.Qt.DashDotLine, 1.),
|
||||
'lpp': (QtCore.Qt.DashDotLine, 1.),
|
||||
'spe': (QtCore.Qt.DashDotLine, 1.)}
|
||||
linestyles = {'manual': linestyles_manu,
|
||||
'auto': linestyles_auto}
|
||||
return linestyles[picktype][key]
|
||||
|
||||
|
||||
def modify_rgba(rgba, modifier, intensity):
|
||||
rgba = list(rgba)
|
||||
index = {'r': 0,
|
||||
'g': 1,
|
||||
'b': 2}
|
||||
val = rgba[index[modifier]] + intensity
|
||||
if val > 255.:
|
||||
val = 255.
|
||||
elif val < 0.:
|
||||
val = 0
|
||||
rgba[index[modifier]] = val
|
||||
return tuple(rgba)
|
||||
|
||||
|
||||
def base_phase_colors(picktype, phase):
|
||||
phasecolors = style_settings.phasecolors
|
||||
return phasecolors[picktype][phase]
|
||||
|
||||
def transform_colors_mpl_str(colors, no_alpha=False):
|
||||
colors = list(colors)
|
||||
colors_mpl = tuple([color / 255. for color in colors])
|
||||
if no_alpha:
|
||||
colors_mpl = '({}, {}, {})'.format(*colors_mpl)
|
||||
else:
|
||||
colors_mpl = '({}, {}, {}, {})'.format(*colors_mpl)
|
||||
return colors_mpl
|
||||
|
||||
def transform_colors_mpl(colors):
|
||||
colors = list(colors)
|
||||
colors_mpl = tuple([color / 255. for color in colors])
|
||||
return colors_mpl
|
||||
|
||||
def remove_underscores(data):
|
||||
"""
|
||||
takes a `obspy.core.stream.Stream` object and removes all underscores
|
||||
@ -427,6 +611,176 @@ def remove_underscores(data):
|
||||
return data
|
||||
|
||||
|
||||
def trim_station_components(data, trim_start=True, trim_end=True):
|
||||
'''
|
||||
cut a stream so only the part common to all three traces is kept to avoid dealing with offsets
|
||||
:param data: stream of seismic data
|
||||
:type data: `obspy.core.stream.Stream`
|
||||
:param trim_start: trim start of stream
|
||||
:type trim_start: bool
|
||||
:param trim_end: trim end of stream
|
||||
:type trim_end: bool
|
||||
:return: data stream
|
||||
'''
|
||||
starttime = {False: None}
|
||||
endtime = {False: None}
|
||||
|
||||
stations = get_stations(data)
|
||||
|
||||
print('trim_station_components: Will trim stream for trim_start: {} and for '
|
||||
'trim_end: {}.'.format(trim_start, trim_end))
|
||||
for station in stations:
|
||||
wf_station = data.select(station=station)
|
||||
starttime[True] = max([trace.stats.starttime for trace in wf_station])
|
||||
endtime[True] = min([trace.stats.endtime for trace in wf_station])
|
||||
wf_station.trim(starttime=starttime[trim_start], endtime=endtime[trim_end])
|
||||
|
||||
return data
|
||||
|
||||
|
||||
def check4gaps(data):
|
||||
'''
|
||||
check for gaps in Stream and remove them
|
||||
:param data: stream of seismic data
|
||||
:return: data stream
|
||||
'''
|
||||
stations = get_stations(data)
|
||||
|
||||
for station in stations:
|
||||
wf_station = data.select(station=station)
|
||||
if wf_station.get_gaps():
|
||||
for trace in wf_station:
|
||||
data.remove(trace)
|
||||
print('check4gaps: Found gaps and removed station {} from waveform data.'.format(station))
|
||||
|
||||
return data
|
||||
|
||||
|
||||
def check4doubled(data):
|
||||
'''
|
||||
check for doubled stations for same channel in Stream and take only the first one
|
||||
:param data: stream of seismic data
|
||||
:return: data stream
|
||||
'''
|
||||
stations = get_stations(data)
|
||||
|
||||
for station in stations:
|
||||
wf_station = data.select(station=station)
|
||||
# create list of all possible channels
|
||||
channels = []
|
||||
for trace in wf_station:
|
||||
channel = trace.stats.channel
|
||||
if not channel in channels:
|
||||
channels.append(channel)
|
||||
else:
|
||||
print('check4doubled: removed the following trace for station {}, as there is'
|
||||
' already a trace with the same channel given:\n{}'.format(
|
||||
station, trace
|
||||
))
|
||||
data.remove(trace)
|
||||
return data
|
||||
|
||||
|
||||
def get_stations(data):
|
||||
stations = []
|
||||
for tr in data:
|
||||
station = tr.stats.station
|
||||
if not station in stations:
|
||||
stations.append(station)
|
||||
|
||||
return stations
|
||||
|
||||
|
||||
def check4rotated(data, metadata=None, verbosity=1):
|
||||
|
||||
def rotate_components(wfstream, metadata=None):
|
||||
"""rotates components if orientation code is numeric.
|
||||
azimut and dip are fetched from metadata"""
|
||||
try:
|
||||
# indexing fails if metadata is None
|
||||
metadata[0]
|
||||
except:
|
||||
if verbosity:
|
||||
msg = 'Warning: could not rotate traces since no metadata was given\nset Inventory file!'
|
||||
print(msg)
|
||||
return wfstream
|
||||
if metadata[0] is None:
|
||||
# sometimes metadata is (None, (None,))
|
||||
if verbosity:
|
||||
msg = 'Warning: could not rotate traces since no metadata was given\nCheck inventory directory!'
|
||||
print(msg)
|
||||
return wfstream
|
||||
else:
|
||||
parser = metadata[1]
|
||||
|
||||
def get_dip_azimut(parser, trace_id):
|
||||
"""gets azimut and dip for a trace out of the metadata parser"""
|
||||
dip = None
|
||||
azimut = None
|
||||
try:
|
||||
blockettes = parser._select(trace_id)
|
||||
except SEEDParserException as e:
|
||||
print(e)
|
||||
raise ValueError
|
||||
for blockette_ in blockettes:
|
||||
if blockette_.id != 52:
|
||||
continue
|
||||
dip = blockette_.dip
|
||||
azimut = blockette_.azimuth
|
||||
break
|
||||
if dip is None or azimut is None:
|
||||
error_msg = 'Dip and azimuth not available for trace_id {}'.format(trace_id)
|
||||
raise ValueError(error_msg)
|
||||
return dip, azimut
|
||||
|
||||
trace_ids = [trace.id for trace in wfstream]
|
||||
for trace_id in trace_ids:
|
||||
orientation = trace_id[-1]
|
||||
if orientation.isnumeric():
|
||||
# misaligned channels have a number as orientation
|
||||
azimuts = []
|
||||
dips = []
|
||||
for trace_id in trace_ids:
|
||||
try:
|
||||
dip, azimut = get_dip_azimut(parser, trace_id)
|
||||
except ValueError as e:
|
||||
print(e)
|
||||
print('Failed to rotate station {}, no azimuth or dip available in metadata'.format(trace_id))
|
||||
return wfstream
|
||||
azimuts.append(azimut)
|
||||
dips.append(dip)
|
||||
# to rotate all traces must have same length
|
||||
wfstream = trim_station_components(wfstream, trim_start=True, trim_end=True)
|
||||
z, n, e = rotate2zne(wfstream[0], azimuts[0], dips[0],
|
||||
wfstream[1], azimuts[1], dips[1],
|
||||
wfstream[2], azimuts[2], dips[2])
|
||||
print('check4rotated: rotated station {} to ZNE'.format(trace_id))
|
||||
z_index = dips.index(min(dips)) # get z-trace index (dip is measured from 0 to -90
|
||||
wfstream[z_index].data = z
|
||||
wfstream[z_index].stats.channel = wfstream[z_index].stats.channel[0:-1] + 'Z'
|
||||
del trace_ids[z_index]
|
||||
for trace_id in trace_ids:
|
||||
dip, az = get_dip_azimut(parser, trace_id)
|
||||
trace = wfstream.select(id=trace_id)[0]
|
||||
if az > 315 and az <= 45 or az > 135 and az <= 225:
|
||||
trace.data = n
|
||||
trace.stats.channel = trace.stats.channel[0:-1] + 'N'
|
||||
elif az > 45 and az <= 135 or az > 225 and az <= 315:
|
||||
trace.data = e
|
||||
trace.stats.channel = trace.stats.channel[0:-1] + 'E'
|
||||
break
|
||||
else:
|
||||
continue
|
||||
return wfstream
|
||||
|
||||
stations = get_stations(data)
|
||||
|
||||
for station in stations:
|
||||
wf_station = data.select(station=station)
|
||||
wf_station = rotate_components(wf_station, metadata)
|
||||
return data
|
||||
|
||||
|
||||
def scaleWFData(data, factor=None, components='all'):
|
||||
"""
|
||||
produce scaled waveforms from given waveform data and a scaling factor,
|
||||
@ -477,6 +831,7 @@ def runProgram(cmd, parameter=None):
|
||||
|
||||
subprocess.check_output('{} | tee /dev/stderr'.format(cmd), shell=True)
|
||||
|
||||
|
||||
def which(program, infile=None):
|
||||
"""
|
||||
takes a program name and returns the full path to the executable or None
|
||||
@ -495,7 +850,7 @@ def which(program, infile=None):
|
||||
bpath = os.path.join(os.path.expanduser('~'), '.pylot', 'pylot.in')
|
||||
else:
|
||||
bpath = os.path.join(os.path.expanduser('~'), '.pylot', infile)
|
||||
|
||||
|
||||
if os.path.exists(bpath):
|
||||
nllocpath = ":" + PylotParameter(bpath).get('nllocbin')
|
||||
os.environ['PATH'] += nllocpath
|
||||
@ -523,6 +878,61 @@ def which(program, infile=None):
|
||||
|
||||
return None
|
||||
|
||||
|
||||
def loopIdentifyPhase(phase):
|
||||
'''
|
||||
Loop through phase string and try to recognize its type (P or S wave).
|
||||
Global variable ALTSUFFIX gives alternative suffix for phases if they do not end with P, p or S, s.
|
||||
If ALTSUFFIX is not given, the function will cut the last letter of the phase string until string ends
|
||||
with P or S.
|
||||
:param phase: phase name (str)
|
||||
:return:
|
||||
'''
|
||||
from pylot.core.util.defaults import ALTSUFFIX
|
||||
|
||||
phase_copy = phase
|
||||
while not identifyPhase(phase_copy):
|
||||
identified = False
|
||||
for alt_suf in ALTSUFFIX:
|
||||
if phase_copy.endswith(alt_suf):
|
||||
phase_copy = phase_copy.split(alt_suf)[0]
|
||||
identified = True
|
||||
if not identified:
|
||||
phase_copy = phase_copy[:-1]
|
||||
if len(phase_copy) < 1:
|
||||
print('Warning: Could not identify phase {}!'.format(phase))
|
||||
return
|
||||
return phase_copy
|
||||
|
||||
|
||||
def identifyPhase(phase):
|
||||
'''
|
||||
Returns capital P or S if phase string is identified by last letter. Else returns False.
|
||||
:param phase: phase name (str)
|
||||
:return: 'P', 'S' or False
|
||||
'''
|
||||
# common phase suffix for P and S
|
||||
common_P = ['P', 'p']
|
||||
common_S = ['S', 's']
|
||||
if phase[-1] in common_P:
|
||||
return 'P'
|
||||
if phase[-1] in common_S:
|
||||
return 'S'
|
||||
else:
|
||||
return False
|
||||
|
||||
|
||||
def identifyPhaseID(phase):
|
||||
return identifyPhase(loopIdentifyPhase(phase))
|
||||
|
||||
|
||||
def has_spe(pick):
|
||||
if not 'spe' in pick.keys():
|
||||
return None
|
||||
else:
|
||||
return pick['spe']
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
import doctest
|
||||
|
||||
|
84755
pylot/platform
1
pylot/styles/__init__.py
Normal file
@ -0,0 +1 @@
|
||||
# -*- coding: utf-8 -*-
|
259
pylot/styles/bright.qss
Normal file
@ -0,0 +1,259 @@
|
||||
QMainWindow{
|
||||
background-color: qlineargradient(spread:reflect, x1:0, y1:0, x2:0, y2:0.5, stop:0 rgba(230, 230, 230, 255), stop:1 rgba(255, 255, 255, 255));
|
||||
color: rgba(0, 0, 0, 255);
|
||||
}
|
||||
|
||||
QWidget{
|
||||
background-color: qlineargradient(spread:pad, x1:0, y1:0, x2:0, y2:1, stop:0 rgba(235, 235, 235, 255), stop:1 rgba(230, 230, 230, 255));
|
||||
color: rgba(0, 0, 0, 255);
|
||||
}
|
||||
|
||||
QToolBar QWidget:checked{
|
||||
background-color: transparent;
|
||||
border-color: rgba(230, 230, 230, 255);
|
||||
border-width: 2px;
|
||||
border-style:inset;
|
||||
}
|
||||
|
||||
QComboBox{
|
||||
background-color: rgba(255, 255, 255, 255);
|
||||
color: rgba(0, 0, 0, 255);
|
||||
min-height: 1.5em;
|
||||
|
||||
selection-background-color: qlineargradient(spread:pad, x1:0, y1:0, x2:1, y2:0, stop:0 rgba(0, 55, 140, 150), stop:1 rgba(0, 70, 180, 150));
|
||||
}
|
||||
|
||||
QComboBox *{
|
||||
background-color: rgba(255, 255, 255, 255);
|
||||
color: rgba(0, 0, 0, 255);
|
||||
|
||||
selection-background-color: qlineargradient(spread:pad, x1:0, y1:0, x2:1, y2:0, stop:0 rgba(0, 55, 140, 150), stop:1 rgba(0, 70, 180, 150));
|
||||
selection-color: rgba(255, 255, 255, 255);
|
||||
}
|
||||
|
||||
QMenuBar{
|
||||
background-color: qlineargradient(spread:pad, x1:0, y1:0, x2:0, y2:2, stop:0 rgba(240, 240, 240, 255), stop:1 rgba(230, 230, 230, 255));
|
||||
padding:1px;
|
||||
}
|
||||
|
||||
QMenuBar::item{
|
||||
background-color: qlineargradient(spread:pad, x1:0, y1:0, x2:0, y2:2, stop:0 rgba(240, 240, 240, 255), stop:1 rgba(230, 230, 230, 255));
|
||||
color: rgba(0, 0, 0, 255);
|
||||
padding:3px;
|
||||
padding-left:5px;
|
||||
padding-right:5px;
|
||||
}
|
||||
|
||||
QMenu{
|
||||
background-color: qlineargradient(spread:reflect, x1:0, y1:0, x2:0, y2:0.5, stop:0 rgba(230, 230, 230, 255), stop:1 rgba(230, 230, 230 255));
|
||||
color: rgba(0, 0, 0, 255);
|
||||
padding:0;
|
||||
}
|
||||
|
||||
*::item:selected{
|
||||
color: rgba(0, 0, 0, 255);
|
||||
background-color: qlineargradient(spread:pad, x1:0, y1:0, x2:1, y2:0, stop:0 rgba(0, 55, 140, 150), stop:1 rgba(0, 70, 180, 150));
|
||||
}
|
||||
|
||||
QToolBar{
|
||||
background-color: qlineargradient(spread:reflect, x1:0, y1:0, x2:0, y2:0.5, stop:0 rgba(230, 230, 230, 255), stop:1 rgba(255, 255, 255, 255));
|
||||
border-style:solid;
|
||||
border-color:rgba(200, 200, 200, 150);
|
||||
border-width:1px;
|
||||
}
|
||||
|
||||
QToolBar *{
|
||||
background-color: qlineargradient(spread:reflect, x1:0, y1:0, x2:0, y2:0.5, stop:0 rgba(230, 230, 230, 255), stop:1 rgba(255, 255, 255, 255));
|
||||
}
|
||||
|
||||
QMessageBox{
|
||||
background-color: rgba(255, 255, 255, 255);
|
||||
color: rgba(0, 0, 0, 255);
|
||||
}
|
||||
|
||||
QTableWidget{
|
||||
background-color: rgba(255, 255, 255, 255);
|
||||
color:rgba(0, 0, 0, 255);
|
||||
border-color:rgba(0, 0, 0, 255);
|
||||
selection-background-color: rgba(200, 210, 230, 255);
|
||||
}
|
||||
|
||||
QTableCornerButton::section{
|
||||
border: none;
|
||||
background-color: qlineargradient(spread:pad, x1:0, y1:0, x2:1, y2:0, stop:0 rgba(255, 255, 255, 255), stop:1 rgba(230, 230, 230, 255));
|
||||
}
|
||||
|
||||
QHeaderView::section{
|
||||
background-color:qlineargradient(spread:pad, x1:0, y1:0, x2:1, y2:0, stop:0 rgba(255, 255, 255, 255), stop:1 rgba(230, 230, 230, 255));
|
||||
border:none;
|
||||
border-top-style:solid;
|
||||
border-width:1px;
|
||||
border-top-color:qlineargradient(spread:pad, x1:0, y1:0, x2:1, y2:0, stop:0 rgba(255, 255, 255, 255), stop:1 rgba(230, 230, 230, 255));
|
||||
color:rgba(0, 0, 0, 255);
|
||||
padding:5px;
|
||||
}
|
||||
|
||||
QHeaderView::section:checked{
|
||||
background-color:qlineargradient(spread:pad, x1:0, y1:0, x2:1, y2:0, stop:0 rgba(0, 55, 140, 150), stop:1 rgba(0, 70, 180, 150));
|
||||
border-top-color:qlineargradient(spread:pad, x1:0, y1:0, x2:1, y2:0, stop:0 rgba(0, 55, 140, 150), stop:1 rgba(0, 70, 180, 150));
|
||||
}
|
||||
|
||||
QHeaderView{
|
||||
background-color:qlineargradient(spread:pad, x1:0, y1:0, x2:1, y2:0, stop:0 rgba(255, 255, 255, 255), stop:1 rgba(230, 230, 230, 255));
|
||||
|
||||
border:none;
|
||||
border-top-style:solid;
|
||||
border-width:1px;
|
||||
border-top-color:rgba(230, 230, 230, 255);
|
||||
color:rgba(0, 0, 0, 255);
|
||||
}
|
||||
|
||||
QListWidget{
|
||||
background-color:rgba(230, 230, 230, 255);
|
||||
color:rgba(0, 0, 0, 255);
|
||||
}
|
||||
|
||||
QStatusBar{
|
||||
background-color:rgba(255, 255, 255, 255);
|
||||
color:rgba(0, 0, 0, 255);
|
||||
}
|
||||
|
||||
QPushButton{
|
||||
background-color:qlineargradient(spread:reflect, x1:0, y1:0, x2:0, y2:0.5, stop:0 rgba(230, 230, 230, 255), stop:1 rgba(245, 245, 245, 255));
|
||||
color:rgba(0, 0, 0, 255);
|
||||
border-style: outset;
|
||||
border-width: 1px;
|
||||
border-color: rgba(100, 100, 120, 255);
|
||||
min-width: 6em;
|
||||
padding: 4px;
|
||||
padding-left:5px;
|
||||
padding-right:5px;
|
||||
border-radius: 2px;
|
||||
}
|
||||
|
||||
QPushButton:pressed{
|
||||
background-color: rgba(230, 230, 230, 255);
|
||||
border-style: inset;
|
||||
}
|
||||
|
||||
QPushButton:checked{
|
||||
background-color: rgba(230, 230, 230, 255);
|
||||
border-style: inset;
|
||||
}
|
||||
|
||||
*:disabled{
|
||||
color:rgba(100, 100, 120, 255);
|
||||
}
|
||||
|
||||
QTabBar{
|
||||
background-color:transparent;
|
||||
}
|
||||
|
||||
QTabBar::tab{
|
||||
background-color:qlineargradient(spread:pad, x1:0, y1:0, x2:0, y2:1, stop:0 rgba(230, 230, 230, 255), stop:1 rgba(210, 210, 210, 255));
|
||||
color: rgba(0, 0, 0, 255);
|
||||
border-style:solid;
|
||||
border-color:rgba(210, 210, 210 255);
|
||||
border-bottom-color: transparent;
|
||||
border-width:1px;
|
||||
padding:5px;
|
||||
}
|
||||
|
||||
QTabBar::tab:selected{
|
||||
background-color:qlineargradient(spread:pad, x1:0, y1:0, x2:0, y2:1, stop:0 rgba(255, 255, 255, 255), stop:1 rgba(245, 245, 245, 255));
|
||||
color: rgba(0, 0, 0, 255);
|
||||
border-style:solid;
|
||||
border-color:rgba(245, 245, 245, 255);
|
||||
border-bottom-color: transparent;
|
||||
border-width:1px;
|
||||
padding:5px;
|
||||
}
|
||||
|
||||
QTabBar::tab:disabled{
|
||||
background-color:qlineargradient(spread:pad, x1:0, y1:0, x2:0, y2:1, stop:0 rgba(230, 230, 230, 255), stop:1 rgba(210, 210, 210, 255));
|
||||
color: rgba(100, 100, 120, 255);
|
||||
}
|
||||
|
||||
QTabWidget{
|
||||
background-color:transparent;
|
||||
}
|
||||
|
||||
QTabWidget::pane{
|
||||
background-color:rgba(0, 0, 0, 255);
|
||||
border-style:solid;
|
||||
border-color:rgba(245, 245, 245, 255);
|
||||
border-width:1px;
|
||||
}
|
||||
|
||||
QTabWidget::tab{
|
||||
background-color:rgba(255, 255, 255, 255);
|
||||
}
|
||||
|
||||
QTabWidget > QWidget{
|
||||
background-color: rgba(245, 245, 245, 255);
|
||||
color: rgba(0, 0, 0, 255);
|
||||
}
|
||||
|
||||
QScrollArea{
|
||||
background: transparent;
|
||||
}
|
||||
|
||||
QScrollArea>QWidget>QWidget{
|
||||
background: transparent;
|
||||
}
|
||||
|
||||
QLabel{
|
||||
color: rgba(0, 0, 0, 255);
|
||||
background-color: transparent;
|
||||
}
|
||||
|
||||
QTextEdit{
|
||||
color: rgba(0, 0, 0, 255);
|
||||
background-color: rgba(255, 255, 255, 255);
|
||||
}
|
||||
|
||||
QSpinBox{
|
||||
color: rgba(0, 0, 0, 255);
|
||||
background-color: rgba(255, 255, 255, 255);
|
||||
}
|
||||
|
||||
QDoubleSpinBox{
|
||||
color: rgba(0, 0, 0, 255);
|
||||
background-color: rgba(255, 255, 255, 255);
|
||||
}
|
||||
|
||||
QCheckBox{
|
||||
background-color:transparent;
|
||||
border:none;
|
||||
}
|
||||
|
||||
QLineEdit{
|
||||
background-color: rgba(255, 255, 255, 255);
|
||||
border: 1px inset;
|
||||
border-radius:0;
|
||||
border-color: rgba(100, 100, 120, 255);
|
||||
}
|
||||
|
||||
QLineEdit:disabled{
|
||||
background-color: rgba(255, 255, 255, 255);
|
||||
border: 1px inset;
|
||||
border-radius:0;
|
||||
border-color: rgba(200, 200, 200, 255);
|
||||
}
|
||||
|
||||
QListWidget{
|
||||
background-color:rgba(255, 255, 255, 255)
|
||||
}
|
||||
|
||||
QProgressBar{
|
||||
background-color:rgba(230, 230, 230, 255);
|
||||
}
|
||||
|
||||
QProgressBar::chunk{
|
||||
background-color:qlineargradient(spread:reflect, x1:0, y1:0, x2:0.5, y2:0, stop:0 transparent, stop:1 rgba(0, 70, 180, 150));
|
||||
}
|
||||
|
||||
QStatusBar{
|
||||
background-color: qlineargradient(spread:pad, x1:0, y1:0, x2:0, y2:1, stop:0 rgba(235, 235, 235, 255), stop:1 rgba(230, 230, 230, 255));
|
||||
color: rgba(0, 0, 0, 255);
|
||||
}
|
258
pylot/styles/dark.qss
Normal file
@ -0,0 +1,258 @@
|
||||
QMainWindow{
|
||||
background-color: qlineargradient(spread:reflect, x1:0, y1:0, x2:0, y2:0.5, stop:0 rgba(70, 70, 80, 255), stop:1 rgba(60, 60, 70, 255));
|
||||
color: rgba(255, 255, 255, 255);
|
||||
}
|
||||
|
||||
QWidget{
|
||||
background-color: qlineargradient(spread:reflect, x1:0, y1:0, x2:0, y2:0.5, stop:0 rgba(70, 70, 80, 255), stop:1 rgba(60, 60, 70, 255));
|
||||
color: rgba(255, 255, 255, 255);
|
||||
}
|
||||
|
||||
QToolBar QWidget:checked{
|
||||
background-color: transparent;
|
||||
border-color: rgba(100, 100, 120, 255);
|
||||
border-width: 2px;
|
||||
border-style:inset;
|
||||
}
|
||||
|
||||
QComboBox{
|
||||
background-color: rgba(90, 90, 100, 255);
|
||||
color: rgba(255, 255, 255, 255);
|
||||
min-height: 1.5em;
|
||||
|
||||
selection-background-color: qlineargradient(spread:pad, x1:0, y1:0, x2:1, y2:0, stop:0 rgba(0, 144, 180, 255), stop:1 rgba(0, 150, 190, 255));
|
||||
}
|
||||
|
||||
QComboBox *{
|
||||
background-color: rgba(90, 90, 100, 255);
|
||||
color: rgba(255, 255, 255, 255);
|
||||
|
||||
selection-background-color: qlineargradient(spread:pad, x1:0, y1:0, x2:1, y2:0, stop:0 rgba(0, 144, 180, 255), stop:1 rgba(0, 150, 190, 255));
|
||||
selection-color: rgba(255, 255, 255, 255);
|
||||
}
|
||||
|
||||
QMenuBar{
|
||||
background-color: qlineargradient(spread:pad, x1:0, y1:0, x2:0, y2:1, stop:0 rgba(70, 70, 80, 255), stop:1 rgba(60, 60, 70, 255));
|
||||
padding:1px;
|
||||
}
|
||||
|
||||
QMenuBar::item{
|
||||
background-color: qlineargradient(spread:pad, x1:0, y1:0, x2:0, y2:1, stop:0 rgba(70, 70, 80, 255), stop:1 rgba(60, 60, 70, 255));
|
||||
color: rgba(255, 255, 255, 255);
|
||||
padding:3px;
|
||||
padding-left:5px;
|
||||
padding-right:5px;
|
||||
}
|
||||
QMenu{
|
||||
background-color: qlineargradient(spread:pad, x1:0, y1:0, x2:0, y2:1, stop:0 rgba(70, 70, 80, 255), stop:1 rgba(60, 60, 70, 255));
|
||||
color: rgba(255, 255, 255, 255);
|
||||
padding:0;
|
||||
}
|
||||
|
||||
*::item:selected{
|
||||
color: rgba(255, 255, 255, 255);
|
||||
background-color: qlineargradient(spread:pad, x1:0, y1:0, x2:1, y2:0, stop:0 rgba(0, 144, 180, 255), stop:1 rgba(0, 150, 190, 255));
|
||||
}
|
||||
|
||||
QToolBar{
|
||||
background-color: qlineargradient(spread:reflect, x1:0, y1:0, x2:0, y2:0.5, stop:0 rgba(70, 70, 80, 255), stop:1 rgba(60, 60, 70, 255));
|
||||
border-style:solid;
|
||||
border-color:rgba(80, 80, 90, 255);
|
||||
border-width:1px;
|
||||
}
|
||||
|
||||
QToolBar *{
|
||||
background-color: qlineargradient(spread:reflect, x1:0, y1:0, x2:0, y2:0.5, stop:0 rgba(70, 70, 80, 255), stop:1 rgba(60, 60, 70, 255));
|
||||
}
|
||||
|
||||
QMessageBox{
|
||||
background-color: rgba(60, 60, 70, 255);
|
||||
color: rgba(255, 255, 255, 255);
|
||||
}
|
||||
|
||||
QTableWidget{
|
||||
background-color: rgba(80, 80, 90, 255);
|
||||
color:rgba(255, 255, 255, 255);
|
||||
border-color:rgba(255, 255, 255, 255);
|
||||
selection-background-color: rgba(200, 210, 230, 255);
|
||||
}
|
||||
|
||||
QTableCornerButton::section{
|
||||
border: none;
|
||||
background-color: qlineargradient(spread:pad, x1:0, y1:0, x2:1, y2:0, stop:0 rgba(60, 60, 70, 255), stop:1 rgba(70, 70, 80, 255));
|
||||
}
|
||||
|
||||
QHeaderView::section{
|
||||
background-color:qlineargradient(spread:pad, x1:0, y1:0, x2:1, y2:0, stop:0 rgba(60, 60, 70, 255), stop:1 rgba(70, 70, 80, 255));
|
||||
border:none;
|
||||
border-top-style:solid;
|
||||
border-width:1px;
|
||||
border-top-color:qlineargradient(spread:pad, x1:0, y1:0, x2:1, y2:0, stop:0 rgba(60, 60, 70, 255), stop:1 rgba(70, 70, 80, 255));
|
||||
color:rgba(255, 255, 255, 255);
|
||||
padding:5px;
|
||||
}
|
||||
|
||||
QHeaderView::section:checked{
|
||||
background-color:qlineargradient(spread:pad, x1:0, y1:0, x2:1, y2:0, stop:0 rgba(0, 120, 150, 255), stop:1 rgba(0, 150, 190, 255));
|
||||
border-top-color:qlineargradient(spread:pad, x1:0, y1:0, x2:1, y2:0, stop:0 rgba(0, 120, 150, 255), stop:1 rgba(0, 150, 190, 255));
|
||||
}
|
||||
|
||||
QHeaderView{
|
||||
background-color:qlineargradient(spread:pad, x1:0, y1:0, x2:1, y2:0, stop:0 rgba(60, 60, 70, 255), stop:1 rgba(70, 70, 80, 255));
|
||||
|
||||
border:none;
|
||||
border-top-style:solid;
|
||||
border-width:1px;
|
||||
border-top-color:rgba(70, 70, 80, 255);
|
||||
color:rgba(255, 255, 255, 255);
|
||||
}
|
||||
|
||||
QListWidget{
|
||||
background-color:rgba(200, 200, 200, 255);
|
||||
color:rgba(255, 255, 255, 255);
|
||||
}
|
||||
|
||||
QStatusBar{
|
||||
background-color:rgba(60, 60, 70, 255);
|
||||
color:rgba(255, 255, 255, 255);
|
||||
}
|
||||
|
||||
QPushButton{
|
||||
background-color:qlineargradient(spread:reflect, x1:0, y1:0, x2:0, y2:0.5, stop:0 rgba(70, 70, 80, 255), stop:1 rgba(60, 60, 70, 255));
|
||||
color:rgba(255, 255, 255, 255);
|
||||
border-style: outset;
|
||||
border-width: 2px;
|
||||
border-color: rgba(50, 50, 60, 255);
|
||||
min-width: 6em;
|
||||
padding: 4px;
|
||||
padding-left:5px;
|
||||
padding-right:5px;
|
||||
border-radius: 2px;
|
||||
}
|
||||
|
||||
QPushButton:pressed{
|
||||
background-color: qlineargradient(spread:reflect, x1:0, y1:0, x2:0, y2:0.5, stop:0 rgba(80, 80, 90, 255), stop:1 rgba(70, 70, 80, 255));
|
||||
border-style: inset;
|
||||
}
|
||||
|
||||
QPushButton:checked{
|
||||
background-color: qlineargradient(spread:reflect, x1:0, y1:0, x2:0, y2:0.5, stop:0 rgba(80, 80, 90, 255), stop:1 rgba(70, 70, 80, 255));
|
||||
border-style: inset;
|
||||
}
|
||||
|
||||
*:disabled{
|
||||
color: rgba(130, 130, 130, 255);
|
||||
}
|
||||
|
||||
QTabBar{
|
||||
background-color:transparent;
|
||||
}
|
||||
|
||||
QTabBar::tab{
|
||||
background-color:qlineargradient(spread:pad, x1:0, y1:0, x2:0, y2:1, stop:0 rgba(70, 70, 80, 255), stop:1 rgba(60, 60, 70, 255));
|
||||
color: rgba(255, 255, 255, 255);
|
||||
border-style:solid;
|
||||
border-color:rgba(70, 70, 80, 255);
|
||||
border-bottom-color: transparent;
|
||||
border-width:1px;
|
||||
padding:5px;
|
||||
}
|
||||
|
||||
QTabBar::tab:selected{
|
||||
background-color:qlineargradient(spread:pad, x1:0, y1:0, x2:0, y2:1, stop:0 rgba(80, 80, 90, 255), stop:1 rgba(70, 70, 80, 255));
|
||||
color: rgba(255, 255, 255, 255);
|
||||
border-style:solid;
|
||||
border-color:rgba(70, 70, 80, 255);
|
||||
border-bottom-color: transparent;
|
||||
border-width:1px;
|
||||
padding:5px;
|
||||
}
|
||||
|
||||
QTabBar::tab:disabled{
|
||||
background-color:qlineargradient(spread:pad, x1:0, y1:0, x2:0, y2:1, stop:0 rgba(70, 70, 80, 255), stop:1 rgba(60, 60, 70, 255));
|
||||
color: rgba(100, 100, 120, 255);
|
||||
}
|
||||
|
||||
QTabWidget{
|
||||
background-color:transparent;
|
||||
}
|
||||
|
||||
QTabWidget::pane{
|
||||
background-color:rgba(70, 70, 80, 255);
|
||||
border-style:solid;
|
||||
border-color:rgba(70, 70, 80, 255);
|
||||
border-width:1px;
|
||||
}
|
||||
|
||||
QTabWidget::tab{
|
||||
background-color:rgba(70, 70, 80, 255);
|
||||
}
|
||||
|
||||
QTabWidget > QWidget{
|
||||
background-color: rgba(70, 70, 80, 255);
|
||||
color: rgba(255, 255, 255, 255);
|
||||
}
|
||||
|
||||
QScrollArea{
|
||||
background: transparent;
|
||||
}
|
||||
|
||||
QScrollArea>QWidget>QWidget{
|
||||
background: transparent;
|
||||
}
|
||||
|
||||
QLabel{
|
||||
color: rgba(255, 255, 255, 255);
|
||||
background-color: transparent;
|
||||
}
|
||||
|
||||
QTextEdit{
|
||||
color: rgba(255, 255, 255, 255);
|
||||
background-color: rgba(90, 90, 100, 255);
|
||||
}
|
||||
|
||||
QSpinBox{
|
||||
color: rgba(255, 255, 255, 255);
|
||||
background-color: rgba(90, 90, 100, 255);
|
||||
}
|
||||
|
||||
QDoubleSpinBox{
|
||||
color: rgba(255, 255, 255, 255);
|
||||
background-color: rgba(90, 90, 100, 255);
|
||||
}
|
||||
|
||||
QCheckBox{
|
||||
background-color:transparent;
|
||||
border:none;
|
||||
}
|
||||
|
||||
QLineEdit{
|
||||
background-color: rgba(90, 90, 100, 255);
|
||||
border: 1px inset;
|
||||
border-radius:0;
|
||||
border-color: rgba(100, 100, 120, 255);
|
||||
}
|
||||
|
||||
QLineEdit:disabled{
|
||||
background-color: rgba(90, 90, 100, 255);
|
||||
border: 1px inset;
|
||||
border-radius:0;
|
||||
border-color: rgba(200, 200, 200, 255);
|
||||
}
|
||||
|
||||
QListWidget{
|
||||
background-color:rgba(60, 60, 70, 255)
|
||||
}
|
||||
|
||||
QProgressBar{
|
||||
background-color:rgba(60, 60, 70, 255);
|
||||
}
|
||||
|
||||
QProgressBar::chunk{
|
||||
background-color:qlineargradient(spread:reflect, x1:0, y1:0, x2:0.5, y2:0, stop:0 transparent, stop:1 rgba(0, 150, 190, 255));
|
||||
}
|
||||
|
||||
QStatusBar{
|
||||
background-color: qlineargradient(spread:reflect, x1:0, y1:0, x2:0, y2:0.5, stop:0 rgba(70, 70, 80, 255), stop:1 rgba(60, 60, 70, 255));
|
||||
color: rgba(255, 255, 255, 255);
|
||||
}
|
70
pylot/styles/style_settings.py
Normal file
@ -0,0 +1,70 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# Set base phase colors for manual and automatic picks
|
||||
# together with a modifier (r, g, or b) used to alternate
|
||||
# the base color
|
||||
phasecolors = {
|
||||
'manual': {
|
||||
'P':{
|
||||
'rgba': (0, 0, 255, 255),
|
||||
'modifier': 'g'},
|
||||
'S':{
|
||||
'rgba': (255, 0, 0, 255),
|
||||
'modifier': 'b'}
|
||||
},
|
||||
'auto':{
|
||||
'P':{
|
||||
'rgba': (140, 0, 255, 255),
|
||||
'modifier': 'g'},
|
||||
'S':{
|
||||
'rgba': (255, 140, 0, 255),
|
||||
'modifier': 'b'}
|
||||
}
|
||||
}
|
||||
|
||||
# Set plot colors and stylesheet for each style
|
||||
stylecolors = {
|
||||
'default':{
|
||||
'linecolor':{
|
||||
'rgba': (0, 0, 0, 255)},
|
||||
'background': {
|
||||
'rgba': (255, 255, 255, 255)},
|
||||
'multicursor': {
|
||||
'rgba': (255, 190, 0, 255)},
|
||||
'ref': {
|
||||
'rgba': (200, 210, 230, 255)},
|
||||
'test': {
|
||||
'rgba': (200, 230, 200, 255)},
|
||||
'stylesheet': {
|
||||
'filename': None}
|
||||
},
|
||||
'dark': {
|
||||
'linecolor': {
|
||||
'rgba': (230, 230, 230, 255)},
|
||||
'background': {
|
||||
'rgba': (50, 50, 60, 255)},
|
||||
'multicursor': {
|
||||
'rgba': (0, 150, 190, 255)},
|
||||
'ref': {
|
||||
'rgba': (80, 110, 170, 255)},
|
||||
'test': {
|
||||
'rgba': (130, 190, 100, 255)},
|
||||
'stylesheet': {
|
||||
'filename': 'dark.qss'}
|
||||
},
|
||||
'bright': {
|
||||
'linecolor': {
|
||||
'rgba': (0, 0, 0, 255)},
|
||||
'background': {
|
||||
'rgba': (255, 255, 255, 255)},
|
||||
'multicursor': {
|
||||
'rgba': (100, 100, 190, 255)},
|
||||
'ref': {
|
||||
'rgba': (200, 210, 230, 255)},
|
||||
'test': {
|
||||
'rgba': (200, 230, 200, 255)},
|
||||
'stylesheet': {
|
||||
'filename': 'bright.qss'}
|
||||
}
|
||||
}
|
||||
|
@ -1,12 +0,0 @@
|
||||
#!/usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
import sys, time
|
||||
from PySide.QtGui import QApplication
|
||||
from pylot.core.util.widgets import HelpForm
|
||||
|
||||
app = QApplication(sys.argv)
|
||||
|
||||
win = HelpForm()
|
||||
win.show()
|
||||
app.exec_()
|
@ -1,20 +0,0 @@
|
||||
#!/usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
import sys
|
||||
import matplotlib
|
||||
|
||||
matplotlib.use('Qt4Agg')
|
||||
matplotlib.rcParams['backend.qt4'] = 'PySide'
|
||||
|
||||
from PySide.QtGui import QApplication
|
||||
from obspy.core import read
|
||||
from pylot.core.util.widgets import PickDlg
|
||||
import icons_rc
|
||||
|
||||
app = QApplication(sys.argv)
|
||||
|
||||
data = read()
|
||||
win = PickDlg(data=data)
|
||||
win.show()
|
||||
app.exec_()
|
@ -1,12 +0,0 @@
|
||||
#!/usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
import sys, time
|
||||
from PySide.QtGui import QApplication
|
||||
from pylot.core.util.widgets import PropertiesDlg
|
||||
|
||||
app = QApplication(sys.argv)
|
||||
|
||||
win = PropertiesDlg()
|
||||
win.show()
|
||||
app.exec_()
|
@ -1,17 +0,0 @@
|
||||
#!/usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
|
||||
import sys, time
|
||||
from PySide.QtGui import QApplication
|
||||
from pylot.core.util.widgets import FilterOptionsDialog, PropertiesDlg, HelpForm
|
||||
|
||||
dialogs = [FilterOptionsDialog, PropertiesDlg, HelpForm]
|
||||
|
||||
app = QApplication(sys.argv)
|
||||
|
||||
for dlg in dialogs:
|
||||
win = dlg()
|
||||
win.show()
|
||||
time.sleep(1)
|
||||
win.destroy()
|
@ -1,27 +0,0 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
'''
|
||||
Created on 10.11.2014
|
||||
|
||||
@author: sebastianw
|
||||
'''
|
||||
import unittest
|
||||
|
||||
|
||||
class Test(unittest.TestCase):
|
||||
|
||||
|
||||
def setUp(self):
|
||||
pass
|
||||
|
||||
|
||||
def tearDown(self):
|
||||
pass
|
||||
|
||||
|
||||
def testName(self):
|
||||
pass
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
#import sys;sys.argv = ['', 'Test.testName']
|
||||
unittest.main()
|
@ -1,19 +0,0 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
'''
|
||||
Created on 10.11.2014
|
||||
|
||||
@author: sebastianw
|
||||
'''
|
||||
import unittest
|
||||
|
||||
|
||||
class Test(unittest.TestCase):
|
||||
|
||||
|
||||
def testName(self):
|
||||
pass
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
#import sys;sys.argv = ['', 'Test.testName']
|
||||
unittest.main()
|
@ -1,303 +0,0 @@
|
||||
#!/usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
"""
|
||||
Script to run autoPyLoT-script "makeCF.py".
|
||||
Only for test purposes!
|
||||
"""
|
||||
|
||||
from obspy.core import read
|
||||
import matplotlib.pyplot as plt
|
||||
import numpy as np
|
||||
from pylot.core.pick.charfuns import *
|
||||
from pylot.core.pick.picker import *
|
||||
import glob
|
||||
import argparse
|
||||
|
||||
def run_makeCF(project, database, event, iplot, station=None):
|
||||
#parameters for CF calculation
|
||||
t2 = 7 #length of moving window for HOS calculation [sec]
|
||||
p = 4 #order of HOS
|
||||
cuttimes = [10, 50] #start and end time for CF calculation
|
||||
bpz = [2, 30] #corner frequencies of bandpass filter, vertical component
|
||||
bph = [2, 15] #corner frequencies of bandpass filter, horizontal components
|
||||
tdetz= 1.2 #length of AR-determination window [sec], vertical component
|
||||
tdeth= 0.8 #length of AR-determination window [sec], horizontal components
|
||||
tpredz = 0.4 #length of AR-prediction window [sec], vertical component
|
||||
tpredh = 0.4 #length of AR-prediction window [sec], horizontal components
|
||||
addnoise = 0.001 #add noise to seismogram for stable AR prediction
|
||||
arzorder = 2 #chosen order of AR process, vertical component
|
||||
arhorder = 4 #chosen order of AR process, horizontal components
|
||||
TSNRhos = [5, 0.5, 1, 0.1] #window lengths [s] for calculating SNR for earliest/latest pick and quality assessment
|
||||
#from HOS-CF [noise window, safety gap, signal window, slope determination window]
|
||||
TSNRarz = [5, 0.5, 1, 0.5] #window lengths [s] for calculating SNR for earliest/lates pick and quality assessment
|
||||
#from ARZ-CF
|
||||
#get waveform data
|
||||
if station:
|
||||
dpz = '/data/%s/EVENT_DATA/LOCAL/%s/%s/%s*HZ.msd' % (project, database, event, station)
|
||||
dpe = '/data/%s/EVENT_DATA/LOCAL/%s/%s/%s*HE.msd' % (project, database, event, station)
|
||||
dpn = '/data/%s/EVENT_DATA/LOCAL/%s/%s/%s*HN.msd' % (project, database, event, station)
|
||||
#dpz = '/DATA/%s/EVENT_DATA/LOCAL/%s/%s/%s*_z.gse' % (project, database, event, station)
|
||||
#dpe = '/DATA/%s/EVENT_DATA/LOCAL/%s/%s/%s*_e.gse' % (project, database, event, station)
|
||||
#dpn = '/DATA/%s/EVENT_DATA/LOCAL/%s/%s/%s*_n.gse' % (project, database, event, station)
|
||||
else:
|
||||
# dpz = '/DATA/%s/EVENT_DATA/LOCAL/%s/%s/*_z.gse' % (project, database, event)
|
||||
# dpe = '/DATA/%s/EVENT_DATA/LOCAL/%s/%s/*_e.gse' % (project, database, event)
|
||||
# dpn = '/DATA/%s/EVENT_DATA/LOCAL/%s/%s/*_n.gse' % (project, database, event)
|
||||
dpz = '/data/%s/EVENT_DATA/LOCAL/%s/%s/*HZ.msd' % (project, database, event)
|
||||
dpe = '/data/%s/EVENT_DATA/LOCAL/%s/%s/*HE.msd' % (project, database, event)
|
||||
dpn = '/data/%s/EVENT_DATA/LOCAL/%s/%s/*HN.msd' % (project, database, event)
|
||||
wfzfiles = glob.glob(dpz)
|
||||
wfefiles = glob.glob(dpe)
|
||||
wfnfiles = glob.glob(dpn)
|
||||
if wfzfiles:
|
||||
for i in range(len(wfzfiles)):
|
||||
print 'Vertical component data found ...'
|
||||
print wfzfiles[i]
|
||||
st = read('%s' % wfzfiles[i])
|
||||
st_copy = st.copy()
|
||||
#filter and taper data
|
||||
tr_filt = st[0].copy()
|
||||
tr_filt.filter('bandpass', freqmin=bpz[0], freqmax=bpz[1], zerophase=False)
|
||||
tr_filt.taper(max_percentage=0.05, type='hann')
|
||||
st_copy[0].data = tr_filt.data
|
||||
##############################################################
|
||||
#calculate HOS-CF using subclass HOScf of class CharacteristicFunction
|
||||
hoscf = HOScf(st_copy, cuttimes, t2, p) #instance of HOScf
|
||||
##############################################################
|
||||
#calculate AIC-HOS-CF using subclass AICcf of class CharacteristicFunction
|
||||
#class needs stream object => build it
|
||||
tr_aic = tr_filt.copy()
|
||||
tr_aic.data = hoscf.getCF()
|
||||
st_copy[0].data = tr_aic.data
|
||||
aiccf = AICcf(st_copy, cuttimes) #instance of AICcf
|
||||
##############################################################
|
||||
#get prelimenary onset time from AIC-HOS-CF using subclass AICPicker of class AutoPicking
|
||||
aicpick = AICPicker(aiccf, None, TSNRhos, 3, 10, None, 0.1)
|
||||
##############################################################
|
||||
#get refined onset time from HOS-CF using class Picker
|
||||
hospick = PragPicker(hoscf, None, TSNRhos, 2, 10, 0.001, 0.2, aicpick.getpick())
|
||||
#get earliest and latest possible picks
|
||||
hosELpick = EarlLatePicker(hoscf, 1.5, TSNRhos, None, 10, None, None, hospick.getpick())
|
||||
##############################################################
|
||||
#calculate ARZ-CF using subclass ARZcf of class CharcteristicFunction
|
||||
#get stream object of filtered data
|
||||
st_copy[0].data = tr_filt.data
|
||||
arzcf = ARZcf(st_copy, cuttimes, tpredz, arzorder, tdetz, addnoise) #instance of ARZcf
|
||||
##############################################################
|
||||
#calculate AIC-ARZ-CF using subclass AICcf of class CharacteristicFunction
|
||||
#class needs stream object => build it
|
||||
tr_arzaic = tr_filt.copy()
|
||||
tr_arzaic.data = arzcf.getCF()
|
||||
st_copy[0].data = tr_arzaic.data
|
||||
araiccf = AICcf(st_copy, cuttimes, tpredz, 0, tdetz) #instance of AICcf
|
||||
##############################################################
|
||||
#get onset time from AIC-ARZ-CF using subclass AICPicker of class AutoPicking
|
||||
aicarzpick = AICPicker(araiccf, 1.5, TSNRarz, 2, 10, None, 0.1)
|
||||
##############################################################
|
||||
#get refined onset time from ARZ-CF using class Picker
|
||||
arzpick = PragPicker(arzcf, 1.5, TSNRarz, 2.0, 10, 0.1, 0.05, aicarzpick.getpick())
|
||||
#get earliest and latest possible picks
|
||||
arzELpick = EarlLatePicker(arzcf, 1.5, TSNRarz, None, 10, None, None, arzpick.getpick())
|
||||
elif not wfzfiles:
|
||||
print 'No vertical component data found!'
|
||||
|
||||
if wfefiles and wfnfiles:
|
||||
for i in range(len(wfefiles)):
|
||||
print 'Horizontal component data found ...'
|
||||
print wfefiles[i]
|
||||
print wfnfiles[i]
|
||||
#merge streams
|
||||
H = read('%s' % wfefiles[i])
|
||||
H += read('%s' % wfnfiles[i])
|
||||
H_copy = H.copy()
|
||||
#filter and taper data
|
||||
trH1_filt = H[0].copy()
|
||||
trH2_filt = H[1].copy()
|
||||
trH1_filt.filter('bandpass', freqmin=bph[0], freqmax=bph[1], zerophase=False)
|
||||
trH2_filt.filter('bandpass', freqmin=bph[0], freqmax=bph[1], zerophase=False)
|
||||
trH1_filt.taper(max_percentage=0.05, type='hann')
|
||||
trH2_filt.taper(max_percentage=0.05, type='hann')
|
||||
H_copy[0].data = trH1_filt.data
|
||||
H_copy[1].data = trH2_filt.data
|
||||
|
||||
##############################################################
|
||||
#calculate ARH-CF using subclass ARHcf of class CharcteristicFunction
|
||||
arhcf = ARHcf(H_copy, cuttimes, tpredh, arhorder, tdeth, addnoise) #instance of ARHcf
|
||||
##############################################################
|
||||
#calculate AIC-ARH-CF using subclass AICcf of class CharacteristicFunction
|
||||
#class needs stream object => build it
|
||||
tr_arhaic = trH1_filt.copy()
|
||||
tr_arhaic.data = arhcf.getCF()
|
||||
H_copy[0].data = tr_arhaic.data
|
||||
#calculate ARH-AIC-CF
|
||||
arhaiccf = AICcf(H_copy, cuttimes, tpredh, 0, tdeth) #instance of AICcf
|
||||
##############################################################
|
||||
#get onset time from AIC-ARH-CF using subclass AICPicker of class AutoPicking
|
||||
aicarhpick = AICPicker(arhaiccf, 1.5, TSNRarz, 4, 10, None, 0.1)
|
||||
###############################################################
|
||||
#get refined onset time from ARH-CF using class Picker
|
||||
arhpick = PragPicker(arhcf, 1.5, TSNRarz, 2.5, 10, 0.1, 0.05, aicarhpick.getpick())
|
||||
#get earliest and latest possible picks
|
||||
arhELpick = EarlLatePicker(arhcf, 1.5, TSNRarz, None, 10, None, None, arhpick.getpick())
|
||||
|
||||
#create stream with 3 traces
|
||||
#merge streams
|
||||
AllC = read('%s' % wfefiles[i])
|
||||
AllC += read('%s' % wfnfiles[i])
|
||||
AllC += read('%s' % wfzfiles[i])
|
||||
#filter and taper data
|
||||
All1_filt = AllC[0].copy()
|
||||
All2_filt = AllC[1].copy()
|
||||
All3_filt = AllC[2].copy()
|
||||
All1_filt.filter('bandpass', freqmin=bph[0], freqmax=bph[1], zerophase=False)
|
||||
All2_filt.filter('bandpass', freqmin=bph[0], freqmax=bph[1], zerophase=False)
|
||||
All3_filt.filter('bandpass', freqmin=bpz[0], freqmax=bpz[1], zerophase=False)
|
||||
All1_filt.taper(max_percentage=0.05, type='hann')
|
||||
All2_filt.taper(max_percentage=0.05, type='hann')
|
||||
All3_filt.taper(max_percentage=0.05, type='hann')
|
||||
AllC[0].data = All1_filt.data
|
||||
AllC[1].data = All2_filt.data
|
||||
AllC[2].data = All3_filt.data
|
||||
#calculate AR3C-CF using subclass AR3Ccf of class CharacteristicFunction
|
||||
ar3ccf = AR3Ccf(AllC, cuttimes, tpredz, arhorder, tdetz, addnoise) #instance of AR3Ccf
|
||||
#get earliest and latest possible pick from initial ARH-pick
|
||||
ar3cELpick = EarlLatePicker(ar3ccf, 1.5, TSNRarz, None, 10, None, None, arhpick.getpick())
|
||||
##############################################################
|
||||
if iplot:
|
||||
#plot vertical trace
|
||||
plt.figure()
|
||||
tr = st[0]
|
||||
tdata = np.arange(0, tr.stats.npts / tr.stats.sampling_rate, tr.stats.delta)
|
||||
p1, = plt.plot(tdata, tr_filt.data/max(tr_filt.data), 'k')
|
||||
p2, = plt.plot(hoscf.getTimeArray(), hoscf.getCF() / max(hoscf.getCF()), 'r')
|
||||
p3, = plt.plot(aiccf.getTimeArray(), aiccf.getCF()/max(aiccf.getCF()), 'b')
|
||||
p4, = plt.plot(arzcf.getTimeArray(), arzcf.getCF()/max(arzcf.getCF()), 'g')
|
||||
p5, = plt.plot(araiccf.getTimeArray(), araiccf.getCF()/max(araiccf.getCF()), 'y')
|
||||
plt.plot([aicpick.getpick(), aicpick.getpick()], [-1, 1], 'b--')
|
||||
plt.plot([aicpick.getpick()-0.5, aicpick.getpick()+0.5], [1, 1], 'b')
|
||||
plt.plot([aicpick.getpick()-0.5, aicpick.getpick()+0.5], [-1, -1], 'b')
|
||||
plt.plot([hospick.getpick(), hospick.getpick()], [-1.3, 1.3], 'r', linewidth=2)
|
||||
plt.plot([hospick.getpick()-0.5, hospick.getpick()+0.5], [1.3, 1.3], 'r')
|
||||
plt.plot([hospick.getpick()-0.5, hospick.getpick()+0.5], [-1.3, -1.3], 'r')
|
||||
plt.plot([hosELpick.getLpick(), hosELpick.getLpick()], [-1.1, 1.1], 'r--')
|
||||
plt.plot([hosELpick.getEpick(), hosELpick.getEpick()], [-1.1, 1.1], 'r--')
|
||||
plt.plot([aicarzpick.getpick(), aicarzpick.getpick()], [-1.2, 1.2], 'y', linewidth=2)
|
||||
plt.plot([aicarzpick.getpick()-0.5, aicarzpick.getpick()+0.5], [1.2, 1.2], 'y')
|
||||
plt.plot([aicarzpick.getpick()-0.5, aicarzpick.getpick()+0.5], [-1.2, -1.2], 'y')
|
||||
plt.plot([arzpick.getpick(), arzpick.getpick()], [-1.4, 1.4], 'g', linewidth=2)
|
||||
plt.plot([arzpick.getpick()-0.5, arzpick.getpick()+0.5], [1.4, 1.4], 'g')
|
||||
plt.plot([arzpick.getpick()-0.5, arzpick.getpick()+0.5], [-1.4, -1.4], 'g')
|
||||
plt.plot([arzELpick.getLpick(), arzELpick.getLpick()], [-1.2, 1.2], 'g--')
|
||||
plt.plot([arzELpick.getEpick(), arzELpick.getEpick()], [-1.2, 1.2], 'g--')
|
||||
plt.yticks([])
|
||||
plt.ylim([-1.5, 1.5])
|
||||
plt.xlabel('Time [s]')
|
||||
plt.ylabel('Normalized Counts')
|
||||
plt.title('%s, %s, CF-SNR=%7.2f, CF-Slope=%12.2f' % (tr.stats.station, \
|
||||
tr.stats.channel, aicpick.getSNR(), aicpick.getSlope()))
|
||||
plt.suptitle(tr.stats.starttime)
|
||||
plt.legend([p1, p2, p3, p4, p5], ['Data', 'HOS-CF', 'HOSAIC-CF', 'ARZ-CF', 'ARZAIC-CF'])
|
||||
#plot horizontal traces
|
||||
plt.figure(2)
|
||||
plt.subplot(2,1,1)
|
||||
tsteph = tpredh / 4
|
||||
th1data = np.arange(0, trH1_filt.stats.npts / trH1_filt.stats.sampling_rate, trH1_filt.stats.delta)
|
||||
th2data = np.arange(0, trH2_filt.stats.npts / trH2_filt.stats.sampling_rate, trH2_filt.stats.delta)
|
||||
tarhcf = np.arange(0, len(arhcf.getCF()) * tsteph, tsteph) + cuttimes[0] + tdeth +tpredh
|
||||
p21, = plt.plot(th1data, trH1_filt.data/max(trH1_filt.data), 'k')
|
||||
p22, = plt.plot(arhcf.getTimeArray(), arhcf.getCF()/max(arhcf.getCF()), 'r')
|
||||
p23, = plt.plot(arhaiccf.getTimeArray(), arhaiccf.getCF()/max(arhaiccf.getCF()))
|
||||
plt.plot([aicarhpick.getpick(), aicarhpick.getpick()], [-1, 1], 'b')
|
||||
plt.plot([aicarhpick.getpick()-0.5, aicarhpick.getpick()+0.5], [1, 1], 'b')
|
||||
plt.plot([aicarhpick.getpick()-0.5, aicarhpick.getpick()+0.5], [-1, -1], 'b')
|
||||
plt.plot([arhpick.getpick(), arhpick.getpick()], [-1, 1], 'r')
|
||||
plt.plot([arhpick.getpick()-0.5, arhpick.getpick()+0.5], [1, 1], 'r')
|
||||
plt.plot([arhpick.getpick()-0.5, arhpick.getpick()+0.5], [-1, -1], 'r')
|
||||
plt.plot([arhELpick.getLpick(), arhELpick.getLpick()], [-0.8, 0.8], 'r--')
|
||||
plt.plot([arhELpick.getEpick(), arhELpick.getEpick()], [-0.8, 0.8], 'r--')
|
||||
plt.plot([arhpick.getpick() + arhELpick.getPickError(), arhpick.getpick() + arhELpick.getPickError()], \
|
||||
[-0.2, 0.2], 'r--')
|
||||
plt.plot([arhpick.getpick() - arhELpick.getPickError(), arhpick.getpick() - arhELpick.getPickError()], \
|
||||
[-0.2, 0.2], 'r--')
|
||||
plt.yticks([])
|
||||
plt.ylim([-1.5, 1.5])
|
||||
plt.ylabel('Normalized Counts')
|
||||
plt.title([trH1_filt.stats.station, trH1_filt.stats.channel])
|
||||
plt.suptitle(trH1_filt.stats.starttime)
|
||||
plt.legend([p21, p22, p23], ['Data', 'ARH-CF', 'ARHAIC-CF'])
|
||||
plt.subplot(2,1,2)
|
||||
plt.plot(th2data, trH2_filt.data/max(trH2_filt.data), 'k')
|
||||
plt.plot(arhcf.getTimeArray(), arhcf.getCF()/max(arhcf.getCF()), 'r')
|
||||
plt.plot(arhaiccf.getTimeArray(), arhaiccf.getCF()/max(arhaiccf.getCF()))
|
||||
plt.plot([aicarhpick.getpick(), aicarhpick.getpick()], [-1, 1], 'b')
|
||||
plt.plot([aicarhpick.getpick()-0.5, aicarhpick.getpick()+0.5], [1, 1], 'b')
|
||||
plt.plot([aicarhpick.getpick()-0.5, aicarhpick.getpick()+0.5], [-1, -1], 'b')
|
||||
plt.plot([arhpick.getpick(), arhpick.getpick()], [-1, 1], 'r')
|
||||
plt.plot([arhpick.getpick()-0.5, arhpick.getpick()+0.5], [1, 1], 'r')
|
||||
plt.plot([arhpick.getpick()-0.5, arhpick.getpick()+0.5], [-1, -1], 'r')
|
||||
plt.plot([arhELpick.getLpick(), arhELpick.getLpick()], [-0.8, 0.8], 'r--')
|
||||
plt.plot([arhELpick.getEpick(), arhELpick.getEpick()], [-0.8, 0.8], 'r--')
|
||||
plt.plot([arhpick.getpick() + arhELpick.getPickError(), arhpick.getpick() + arhELpick.getPickError()], \
|
||||
[-0.2, 0.2], 'r--')
|
||||
plt.plot([arhpick.getpick() - arhELpick.getPickError(), arhpick.getpick() - arhELpick.getPickError()], \
|
||||
[-0.2, 0.2], 'r--')
|
||||
plt.title([trH2_filt.stats.station, trH2_filt.stats.channel])
|
||||
plt.yticks([])
|
||||
plt.ylim([-1.5, 1.5])
|
||||
plt.xlabel('Time [s]')
|
||||
plt.ylabel('Normalized Counts')
|
||||
#plot 3-component window
|
||||
plt.figure(3)
|
||||
plt.subplot(3,1,1)
|
||||
p31, = plt.plot(tdata, tr_filt.data/max(tr_filt.data), 'k')
|
||||
p32, = plt.plot(ar3ccf.getTimeArray(), ar3ccf.getCF()/max(ar3ccf.getCF()), 'r')
|
||||
plt.plot([arhpick.getpick(), arhpick.getpick()], [-1, 1], 'b')
|
||||
plt.plot([arhpick.getpick()-0.5, arhpick.getpick()+0.5], [-1, -1], 'b')
|
||||
plt.plot([arhpick.getpick()-0.5, arhpick.getpick()+0.5], [1, 1], 'b')
|
||||
plt.plot([ar3cELpick.getLpick(), ar3cELpick.getLpick()], [-0.8, 0.8], 'b--')
|
||||
plt.plot([ar3cELpick.getEpick(), ar3cELpick.getEpick()], [-0.8, 0.8], 'b--')
|
||||
plt.yticks([])
|
||||
plt.xticks([])
|
||||
plt.ylabel('Normalized Counts')
|
||||
plt.title([tr.stats.station, tr.stats.channel])
|
||||
plt.suptitle(trH1_filt.stats.starttime)
|
||||
plt.legend([p31, p32], ['Data', 'AR3C-CF'])
|
||||
plt.subplot(3,1,2)
|
||||
plt.plot(th1data, trH1_filt.data/max(trH1_filt.data), 'k')
|
||||
plt.plot(ar3ccf.getTimeArray(), ar3ccf.getCF()/max(ar3ccf.getCF()), 'r')
|
||||
plt.plot([arhpick.getpick(), arhpick.getpick()], [-1, 1], 'b')
|
||||
plt.plot([arhpick.getpick()-0.5, arhpick.getpick()+0.5], [-1, -1], 'b')
|
||||
plt.plot([arhpick.getpick()-0.5, arhpick.getpick()+0.5], [1, 1], 'b')
|
||||
plt.plot([ar3cELpick.getLpick(), ar3cELpick.getLpick()], [-0.8, 0.8], 'b--')
|
||||
plt.plot([ar3cELpick.getEpick(), ar3cELpick.getEpick()], [-0.8, 0.8], 'b--')
|
||||
plt.yticks([])
|
||||
plt.xticks([])
|
||||
plt.ylabel('Normalized Counts')
|
||||
plt.title([trH1_filt.stats.station, trH1_filt.stats.channel])
|
||||
plt.subplot(3,1,3)
|
||||
plt.plot(th2data, trH2_filt.data/max(trH2_filt.data), 'k')
|
||||
plt.plot(ar3ccf.getTimeArray(), ar3ccf.getCF()/max(ar3ccf.getCF()), 'r')
|
||||
plt.plot([arhpick.getpick(), arhpick.getpick()], [-1, 1], 'b')
|
||||
plt.plot([arhpick.getpick()-0.5, arhpick.getpick()+0.5], [-1, -1], 'b')
|
||||
plt.plot([arhpick.getpick()-0.5, arhpick.getpick()+0.5], [1, 1], 'b')
|
||||
plt.plot([ar3cELpick.getLpick(), ar3cELpick.getLpick()], [-0.8, 0.8], 'b--')
|
||||
plt.plot([ar3cELpick.getEpick(), ar3cELpick.getEpick()], [-0.8, 0.8], 'b--')
|
||||
plt.yticks([])
|
||||
plt.ylabel('Normalized Counts')
|
||||
plt.title([trH2_filt.stats.station, trH2_filt.stats.channel])
|
||||
plt.xlabel('Time [s]')
|
||||
plt.show()
|
||||
raw_input()
|
||||
plt.close()
|
||||
|
||||
if __name__ == '__main__':
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument('--project', type=str, help='project name (e.g. Insheim)')
|
||||
parser.add_argument('--database', type=str, help='event data base (e.g. 2014.09_Insheim)')
|
||||
parser.add_argument('--event', type=str, help='event ID (e.g. e0010.015.14)')
|
||||
parser.add_argument('--iplot', help='anything, if set, figure occurs')
|
||||
parser.add_argument('--station', type=str, help='Station ID (e.g. INS3) (optional)')
|
||||
args = parser.parse_args()
|
||||
|
||||
run_makeCF(args.project, args.database, args.event, args.iplot, args.station)
|
@ -1,7 +0,0 @@
|
||||
#!/usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
from pylot.core.util.pdf import ProbabilityDensityFunction
|
||||
pdf = ProbabilityDensityFunction.from_pick(0.34, 0.5, 0.54, type='exp')
|
||||
pdf2 = ProbabilityDensityFunction.from_pick(0.34, 0.5, 0.54, type='exp')
|
||||
diff = pdf - pdf2
|
@ -1,15 +0,0 @@
|
||||
#!/usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
import argparse
|
||||
import numpy
|
||||
from pylot.core.pick.utils import getnoisewin
|
||||
|
||||
if __name__ == "__main__":
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument('--t', type=numpy.array, help='numpy array of time stamps')
|
||||
parser.add_argument('--t1', type=float, help='time from which relativ to it noise window is extracted')
|
||||
parser.add_argument('--tnoise', type=float, help='length of time window [s] for noise part extraction')
|
||||
parser.add_argument('--tgap', type=float, help='safety gap between signal (t1=onset) and noise')
|
||||
args = parser.parse_args()
|
||||
getnoisewin(args.t, args.t1, args.tnoise, args.tgap)
|
@ -1,28 +0,0 @@
|
||||
#!/usr/bin/python
|
||||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
Created Mar 2015
|
||||
Transcription of the rezipe of Diehl et al. (2009) for consistent phase
|
||||
picking. For a given inital (the most likely) pick, the corresponding earliest
|
||||
and latest possible pick is calculated based on noise measurements in front of
|
||||
the most likely pick and signal wavelength derived from zero crossings.
|
||||
|
||||
:author: Ludger Kueperkoch / MAGS2 EP3 working group
|
||||
"""
|
||||
|
||||
import argparse
|
||||
import obspy
|
||||
from pylot.core.pick.utils import earllatepicker
|
||||
|
||||
if __name__ == "__main__":
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument('--X', type=~obspy.core.stream.Stream,
|
||||
help='time series (seismogram) read with obspy module read')
|
||||
parser.add_argument('--nfac', type=int,
|
||||
help='(noise factor), nfac times noise level to calculate latest possible pick')
|
||||
parser.add_argument('--TSNR', type=tuple, help='length of time windows around pick used to determine SNR \
|
||||
[s] (Tnoise, Tgap, Tsignal)')
|
||||
parser.add_argument('--Pick1', type=float, help='Onset time of most likely pick')
|
||||
parser.add_argument('--iplot', type=int, help='if set, figure no. iplot occurs')
|
||||
args = parser.parse_args()
|
||||
earllatepicker(args.X, args.nfac, args.TSNR, args.Pick1, args.iplot)
|
@ -1,24 +0,0 @@
|
||||
#!/usr/bin/python
|
||||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
Created Mar 2015
|
||||
Function to derive first motion (polarity) for given phase onset based on zero crossings.
|
||||
|
||||
:author: MAGS2 EP3 working group / Ludger Kueperkoch
|
||||
"""
|
||||
|
||||
import argparse
|
||||
import obspy
|
||||
from pylot.core.pick.utils import fmpicker
|
||||
|
||||
if __name__ == "__main__":
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument('--Xraw', type=obspy.core.stream.Stream,
|
||||
help='unfiltered time series (seismogram) read with obspy module read')
|
||||
parser.add_argument('--Xfilt', type=obspy.core.stream.Stream,
|
||||
help='filtered time series (seismogram) read with obspy module read')
|
||||
parser.add_argument('--pickwin', type=float, help='length of pick window [s] for first motion determination')
|
||||
parser.add_argument('--Pick', type=float, help='Onset time of most likely pick')
|
||||
parser.add_argument('--iplot', type=int, help='if set, figure no. iplot occurs')
|
||||
args = parser.parse_args()
|
||||
fmpicker(args.Xraw, args.Xfilt, args.pickwin, args.Pick, args.iplot)
|
@ -1,41 +0,0 @@
|
||||
#!/usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
import argparse
|
||||
|
||||
from pylot.core.util.version import get_git_version as _getVersionString
|
||||
from pylot.core.io.phases import reassess_pilot_db
|
||||
|
||||
__version__ = _getVersionString()
|
||||
__author__ = 'S. Wehling-Benatelli'
|
||||
|
||||
if __name__ == '__main__':
|
||||
parser = argparse.ArgumentParser(
|
||||
description='reassess old PILOT event data base in terms of consistent '
|
||||
'automatic uncertainty estimation',
|
||||
epilog='Script written by {author} belonging to PyLoT version'
|
||||
' {version}\n'.format(author=__author__,
|
||||
version=__version__)
|
||||
)
|
||||
|
||||
parser.add_argument(
|
||||
'root', type=str, help='specifies the root directory'
|
||||
)
|
||||
parser.add_argument(
|
||||
'db', type=str, help='specifies the database name'
|
||||
)
|
||||
parser.add_argument(
|
||||
'--output', '-o', type=str, help='path to the output directory',
|
||||
dest='output'
|
||||
)
|
||||
parser.add_argument(
|
||||
'--parameterfile', '-p', type=str,
|
||||
help='full path to the parameterfile', dest='parfile'
|
||||
)
|
||||
parser.add_argument(
|
||||
'--verbosity', '-v', action='count', help='increase output verbosity',
|
||||
default=0, dest='verbosity'
|
||||
)
|
||||
|
||||
args = parser.parse_args()
|
||||
reassess_pilot_db(args.root, args.db, args.output, args.parfile, args.verbosity)
|
@ -1,38 +0,0 @@
|
||||
#!/usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
import argparse
|
||||
|
||||
from pylot.core.util.version import get_git_version as _getVersionString
|
||||
from pylot.core.io.phases import reassess_pilot_event
|
||||
|
||||
__version__ = _getVersionString()
|
||||
__author__ = 'S. Wehling-Benatelli'
|
||||
|
||||
if __name__ == '__main__':
|
||||
parser = argparse.ArgumentParser(
|
||||
description='reassess old PILOT event data in terms of consistent '
|
||||
'automatic uncertainty estimation',
|
||||
epilog='Script written by {author} belonging to PyLoT version'
|
||||
' {version}\n'.format(author=__author__,
|
||||
version=__version__)
|
||||
)
|
||||
|
||||
parser.add_argument(
|
||||
'root', type=str, help='specifies the root directory'
|
||||
)
|
||||
parser.add_argument(
|
||||
'db', type=str, help='specifies the database name'
|
||||
)
|
||||
parser.add_argument(
|
||||
'id', type=str, help='PILOT event identifier'
|
||||
)
|
||||
parser.add_argument(
|
||||
'--output', '-o', type=str, help='path to the output directory', dest='output'
|
||||
)
|
||||
parser.add_argument(
|
||||
'--parameterfile', '-p', type=str, help='full path to the parameterfile', dest='parfile'
|
||||
)
|
||||
|
||||
args = parser.parse_args()
|
||||
reassess_pilot_event(args.root, args.db, args.id, args.output, args.parfile)
|
@ -1,14 +0,0 @@
|
||||
#!/usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
import argparse
|
||||
import numpy
|
||||
from pylot.core.pick.utils import getsignalwin
|
||||
|
||||
if __name__ == "__main__":
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument('--t', type=numpy.array, help='numpy array of time stamps')
|
||||
parser.add_argument('--t1', type=float, help='time from which relativ to it signal window is extracted')
|
||||
parser.add_argument('--tsignal', type=float, help='length of time window [s] for signal part extraction')
|
||||
args = parser.parse_args()
|
||||
getsignalwin(args.t, args.t1, args.tsignal)
|
@ -1,30 +0,0 @@
|
||||
#!/usr/bin/python
|
||||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
Created Mar/Apr 2015
|
||||
Function to calculate SNR of certain part of seismogram relative
|
||||
to given time. Returns SNR and SNR [dB].
|
||||
|
||||
:author: Ludger Kueperkoch /MAGS EP3 working group
|
||||
"""
|
||||
|
||||
import argparse
|
||||
import obspy
|
||||
from pylot.core.pick.utils import getSNR
|
||||
|
||||
if __name__ == "__main__":
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument('--data', '-d', type=obspy.core.stream.Stream,
|
||||
help='time series (seismogram) read with obspy module '
|
||||
'read',
|
||||
dest='data')
|
||||
parser.add_argument('--tsnr', '-s', type=tuple,
|
||||
help='length of time windows around pick used to '
|
||||
'determine SNR [s] (Tnoise, Tgap, Tsignal)',
|
||||
dest='tsnr')
|
||||
parser.add_argument('--time', '-t', type=float,
|
||||
help='initial time from which noise and signal windows '
|
||||
'are calculated',
|
||||
dest='time')
|
||||
args = parser.parse_args()
|
||||
print getSNR(args.data, args.tsnr, args.time)
|
@ -1,307 +0,0 @@
|
||||
#!/usr/bin/python
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
"""
|
||||
Script to run autoPyLoT-script "run_makeCF.py".
|
||||
Only for test purposes!
|
||||
"""
|
||||
|
||||
from obspy.core import read
|
||||
import matplotlib.pyplot as plt
|
||||
import numpy as np
|
||||
from pylot.core.pick.charfuns import CharacteristicFunction
|
||||
from pylot.core.pick.picker import AutoPicker
|
||||
from pylot.core.pick.utils import *
|
||||
import glob
|
||||
import argparse
|
||||
|
||||
def run_makeCF(project, database, event, iplot, station=None):
|
||||
#parameters for CF calculation
|
||||
t2 = 7 #length of moving window for HOS calculation [sec]
|
||||
p = 4 #order of HOS
|
||||
cuttimes = [10, 50] #start and end time for CF calculation
|
||||
bpz = [2, 30] #corner frequencies of bandpass filter, vertical component
|
||||
bph = [2, 15] #corner frequencies of bandpass filter, horizontal components
|
||||
tdetz= 1.2 #length of AR-determination window [sec], vertical component
|
||||
tdeth= 0.8 #length of AR-determination window [sec], horizontal components
|
||||
tpredz = 0.4 #length of AR-prediction window [sec], vertical component
|
||||
tpredh = 0.4 #length of AR-prediction window [sec], horizontal components
|
||||
addnoise = 0.001 #add noise to seismogram for stable AR prediction
|
||||
arzorder = 2 #chosen order of AR process, vertical component
|
||||
arhorder = 4 #chosen order of AR process, horizontal components
|
||||
TSNRhos = [5, 0.5, 1, .6] #window lengths [s] for calculating SNR for earliest/latest pick and quality assessment
|
||||
#from HOS-CF [noise window, safety gap, signal window, slope determination window]
|
||||
TSNRarz = [5, 0.5, 1, 1.0] #window lengths [s] for calculating SNR for earliest/lates pick and quality assessment
|
||||
#from ARZ-CF
|
||||
#get waveform data
|
||||
if station:
|
||||
dpz = '/DATA/%s/EVENT_DATA/LOCAL/%s/%s/%s*HZ.msd' % (project, database, event, station)
|
||||
dpe = '/DATA/%s/EVENT_DATA/LOCAL/%s/%s/%s*HE.msd' % (project, database, event, station)
|
||||
dpn = '/DATA/%s/EVENT_DATA/LOCAL/%s/%s/%s*HN.msd' % (project, database, event, station)
|
||||
#dpz = '/DATA/%s/EVENT_DATA/LOCAL/%s/%s/%s*_z.gse' % (project, database, event, station)
|
||||
#dpe = '/DATA/%s/EVENT_DATA/LOCAL/%s/%s/%s*_e.gse' % (project, database, event, station)
|
||||
#dpn = '/DATA/%s/EVENT_DATA/LOCAL/%s/%s/%s*_n.gse' % (project, database, event, station)
|
||||
else:
|
||||
dpz = '/DATA/%s/EVENT_DATA/LOCAL/%s/%s/*HZ.msd' % (project, database, event)
|
||||
dpe = '/DATA/%s/EVENT_DATA/LOCAL/%s/%s/*HE.msd' % (project, database, event)
|
||||
dpn = '/DATA/%s/EVENT_DATA/LOCAL/%s/%s/*HN.msd' % (project, database, event)
|
||||
wfzfiles = glob.glob(dpz)
|
||||
wfefiles = glob.glob(dpe)
|
||||
wfnfiles = glob.glob(dpn)
|
||||
if wfzfiles:
|
||||
for i in range(len(wfzfiles)):
|
||||
print 'Vertical component data found ...'
|
||||
print wfzfiles[i]
|
||||
st = read('%s' % wfzfiles[i])
|
||||
st_copy = st.copy()
|
||||
#filter and taper data
|
||||
tr_filt = st[0].copy()
|
||||
tr_filt.filter('bandpass', freqmin=bpz[0], freqmax=bpz[1], zerophase=False)
|
||||
tr_filt.taper(max_percentage=0.05, type='hann')
|
||||
st_copy[0].data = tr_filt.data
|
||||
##############################################################
|
||||
#calculate HOS-CF using subclass HOScf of class CharacteristicFunction
|
||||
hoscf = HOScf(st_copy, cuttimes, t2, p) #instance of HOScf
|
||||
##############################################################
|
||||
#calculate AIC-HOS-CF using subclass AICcf of class CharacteristicFunction
|
||||
#class needs stream object => build it
|
||||
tr_aic = tr_filt.copy()
|
||||
tr_aic.data = hoscf.getCF()
|
||||
st_copy[0].data = tr_aic.data
|
||||
aiccf = AICcf(st_copy, cuttimes) #instance of AICcf
|
||||
##############################################################
|
||||
#get prelimenary onset time from AIC-HOS-CF using subclass AICPicker of class AutoPicking
|
||||
aicpick = AICPicker(aiccf, TSNRhos, 3, 10, None, 0.1)
|
||||
##############################################################
|
||||
#get refined onset time from HOS-CF using class Picker
|
||||
hospick = PragPicker(hoscf, TSNRhos, 2, 10, 0.001, 0.2, aicpick.getpick())
|
||||
#############################################################
|
||||
#get earliest and latest possible picks
|
||||
st_copy[0].data = tr_filt.data
|
||||
[lpickhos, epickhos, pickerrhos] = earllatepicker(st_copy, 1.5, TSNRhos, hospick.getpick(), 10)
|
||||
#############################################################
|
||||
#get SNR
|
||||
[SNR, SNRdB] = getSNR(st_copy, TSNRhos, hospick.getpick())
|
||||
print 'SNR:', SNR, 'SNR[dB]:', SNRdB
|
||||
##########################################################
|
||||
#get first motion of onset
|
||||
hosfm = fmpicker(st, st_copy, 0.2, hospick.getpick(), 11)
|
||||
##############################################################
|
||||
#calculate ARZ-CF using subclass ARZcf of class CharcteristicFunction
|
||||
arzcf = ARZcf(st, cuttimes, tpredz, arzorder, tdetz, addnoise) #instance of ARZcf
|
||||
##############################################################
|
||||
#calculate AIC-ARZ-CF using subclass AICcf of class CharacteristicFunction
|
||||
#class needs stream object => build it
|
||||
tr_arzaic = tr_filt.copy()
|
||||
tr_arzaic.data = arzcf.getCF()
|
||||
st_copy[0].data = tr_arzaic.data
|
||||
araiccf = AICcf(st_copy, cuttimes, tpredz, 0, tdetz) #instance of AICcf
|
||||
##############################################################
|
||||
#get onset time from AIC-ARZ-CF using subclass AICPicker of class AutoPicking
|
||||
aicarzpick = AICPicker(araiccf, TSNRarz, 2, 10, None, 0.1)
|
||||
##############################################################
|
||||
#get refined onset time from ARZ-CF using class Picker
|
||||
arzpick = PragPicker(arzcf, TSNRarz, 2.0, 10, 0.1, 0.05, aicarzpick.getpick())
|
||||
#get earliest and latest possible picks
|
||||
st_copy[0].data = tr_filt.data
|
||||
[lpickarz, epickarz, pickerrarz] = earllatepicker(st_copy, 1.5, TSNRarz, arzpick.getpick(), 10)
|
||||
elif not wfzfiles:
|
||||
print 'No vertical component data found!'
|
||||
|
||||
if wfefiles and wfnfiles:
|
||||
for i in range(len(wfefiles)):
|
||||
print 'Horizontal component data found ...'
|
||||
print wfefiles[i]
|
||||
print wfnfiles[i]
|
||||
#merge streams
|
||||
H = read('%s' % wfefiles[i])
|
||||
H += read('%s' % wfnfiles[i])
|
||||
H_copy = H.copy()
|
||||
#filter and taper data
|
||||
trH1_filt = H[0].copy()
|
||||
trH2_filt = H[1].copy()
|
||||
trH1_filt.filter('bandpass', freqmin=bph[0], freqmax=bph[1], zerophase=False)
|
||||
trH2_filt.filter('bandpass', freqmin=bph[0], freqmax=bph[1], zerophase=False)
|
||||
trH1_filt.taper(max_percentage=0.05, type='hann')
|
||||
trH2_filt.taper(max_percentage=0.05, type='hann')
|
||||
H_copy[0].data = trH1_filt.data
|
||||
H_copy[1].data = trH2_filt.data
|
||||
|
||||
##############################################################
|
||||
#calculate ARH-CF using subclass ARHcf of class CharcteristicFunction
|
||||
arhcf = ARHcf(H_copy, cuttimes, tpredh, arhorder, tdeth, addnoise) #instance of ARHcf
|
||||
##############################################################
|
||||
#calculate AIC-ARH-CF using subclass AICcf of class CharacteristicFunction
|
||||
#class needs stream object => build it
|
||||
tr_arhaic = trH1_filt.copy()
|
||||
tr_arhaic.data = arhcf.getCF()
|
||||
H_copy[0].data = tr_arhaic.data
|
||||
#calculate ARH-AIC-CF
|
||||
arhaiccf = AICcf(H_copy, cuttimes, tpredh, 0, tdeth) #instance of AICcf
|
||||
##############################################################
|
||||
#get onset time from AIC-ARH-CF using subclass AICPicker of class AutoPicking
|
||||
aicarhpick = AICPicker(arhaiccf, TSNRarz, 4, 10, None, 0.1)
|
||||
###############################################################
|
||||
#get refined onset time from ARH-CF using class Picker
|
||||
arhpick = PragPicker(arhcf, TSNRarz, 2.5, 10, 0.1, 0.05, aicarhpick.getpick())
|
||||
#get earliest and latest possible picks
|
||||
H_copy[0].data = trH1_filt.data
|
||||
[lpickarh1, epickarh1, pickerrarh1] = earllatepicker(H_copy, 1.5, TSNRarz, arhpick.getpick(), 10)
|
||||
H_copy[0].data = trH2_filt.data
|
||||
[lpickarh2, epickarh2, pickerrarh2] = earllatepicker(H_copy, 1.5, TSNRarz, arhpick.getpick(), 10)
|
||||
#get earliest pick of both earliest possible picks
|
||||
epick = [epickarh1, epickarh2]
|
||||
lpick = [lpickarh1, lpickarh2]
|
||||
pickerr = [pickerrarh1, pickerrarh2]
|
||||
ipick =np.argmin([epickarh1, epickarh2])
|
||||
epickarh = epick[ipick]
|
||||
lpickarh = lpick[ipick]
|
||||
pickerrarh = pickerr[ipick]
|
||||
|
||||
#create stream with 3 traces
|
||||
#merge streams
|
||||
AllC = read('%s' % wfefiles[i])
|
||||
AllC += read('%s' % wfnfiles[i])
|
||||
AllC += read('%s' % wfzfiles[i])
|
||||
#filter and taper data
|
||||
All1_filt = AllC[0].copy()
|
||||
All2_filt = AllC[1].copy()
|
||||
All3_filt = AllC[2].copy()
|
||||
All1_filt.filter('bandpass', freqmin=bph[0], freqmax=bph[1], zerophase=False)
|
||||
All2_filt.filter('bandpass', freqmin=bph[0], freqmax=bph[1], zerophase=False)
|
||||
All3_filt.filter('bandpass', freqmin=bpz[0], freqmax=bpz[1], zerophase=False)
|
||||
All1_filt.taper(max_percentage=0.05, type='hann')
|
||||
All2_filt.taper(max_percentage=0.05, type='hann')
|
||||
All3_filt.taper(max_percentage=0.05, type='hann')
|
||||
AllC[0].data = All1_filt.data
|
||||
AllC[1].data = All2_filt.data
|
||||
AllC[2].data = All3_filt.data
|
||||
#calculate AR3C-CF using subclass AR3Ccf of class CharacteristicFunction
|
||||
ar3ccf = AR3Ccf(AllC, cuttimes, tpredz, arhorder, tdetz, addnoise) #instance of AR3Ccf
|
||||
##############################################################
|
||||
if iplot:
|
||||
#plot vertical trace
|
||||
plt.figure()
|
||||
tr = st[0]
|
||||
tdata = np.arange(0, tr.stats.npts / tr.stats.sampling_rate, tr.stats.delta)
|
||||
p1, = plt.plot(tdata, tr_filt.data/max(tr_filt.data), 'k')
|
||||
p2, = plt.plot(hoscf.getTimeArray(), hoscf.getCF() / max(hoscf.getCF()), 'r')
|
||||
p3, = plt.plot(aiccf.getTimeArray(), aiccf.getCF()/max(aiccf.getCF()), 'b')
|
||||
p4, = plt.plot(arzcf.getTimeArray(), arzcf.getCF()/max(arzcf.getCF()), 'g')
|
||||
p5, = plt.plot(araiccf.getTimeArray(), araiccf.getCF()/max(araiccf.getCF()), 'y')
|
||||
plt.plot([aicpick.getpick(), aicpick.getpick()], [-1, 1], 'b--')
|
||||
plt.plot([aicpick.getpick()-0.5, aicpick.getpick()+0.5], [1, 1], 'b')
|
||||
plt.plot([aicpick.getpick()-0.5, aicpick.getpick()+0.5], [-1, -1], 'b')
|
||||
plt.plot([hospick.getpick(), hospick.getpick()], [-1.3, 1.3], 'r', linewidth=2)
|
||||
plt.plot([hospick.getpick()-0.5, hospick.getpick()+0.5], [1.3, 1.3], 'r')
|
||||
plt.plot([hospick.getpick()-0.5, hospick.getpick()+0.5], [-1.3, -1.3], 'r')
|
||||
plt.plot([lpickhos, lpickhos], [-1.1, 1.1], 'r--')
|
||||
plt.plot([epickhos, epickhos], [-1.1, 1.1], 'r--')
|
||||
plt.plot([aicarzpick.getpick(), aicarzpick.getpick()], [-1.2, 1.2], 'y', linewidth=2)
|
||||
plt.plot([aicarzpick.getpick()-0.5, aicarzpick.getpick()+0.5], [1.2, 1.2], 'y')
|
||||
plt.plot([aicarzpick.getpick()-0.5, aicarzpick.getpick()+0.5], [-1.2, -1.2], 'y')
|
||||
plt.plot([arzpick.getpick(), arzpick.getpick()], [-1.4, 1.4], 'g', linewidth=2)
|
||||
plt.plot([arzpick.getpick()-0.5, arzpick.getpick()+0.5], [1.4, 1.4], 'g')
|
||||
plt.plot([arzpick.getpick()-0.5, arzpick.getpick()+0.5], [-1.4, -1.4], 'g')
|
||||
plt.plot([lpickarz, lpickarz], [-1.2, 1.2], 'g--')
|
||||
plt.plot([epickarz, epickarz], [-1.2, 1.2], 'g--')
|
||||
plt.yticks([])
|
||||
plt.ylim([-1.5, 1.5])
|
||||
plt.xlabel('Time [s]')
|
||||
plt.ylabel('Normalized Counts')
|
||||
plt.title('%s, %s, CF-SNR=%7.2f, CF-Slope=%12.2f' % (tr.stats.station,
|
||||
tr.stats.channel, aicpick.getSNR(), aicpick.getSlope()))
|
||||
plt.suptitle(tr.stats.starttime)
|
||||
plt.legend([p1, p2, p3, p4, p5], ['Data', 'HOS-CF', 'HOSAIC-CF', 'ARZ-CF', 'ARZAIC-CF'])
|
||||
#plot horizontal traces
|
||||
plt.figure(2)
|
||||
plt.subplot(2,1,1)
|
||||
tsteph = tpredh / 4
|
||||
th1data = np.arange(0, trH1_filt.stats.npts / trH1_filt.stats.sampling_rate, trH1_filt.stats.delta)
|
||||
th2data = np.arange(0, trH2_filt.stats.npts / trH2_filt.stats.sampling_rate, trH2_filt.stats.delta)
|
||||
tarhcf = np.arange(0, len(arhcf.getCF()) * tsteph, tsteph) + cuttimes[0] + tdeth +tpredh
|
||||
p21, = plt.plot(th1data, trH1_filt.data/max(trH1_filt.data), 'k')
|
||||
p22, = plt.plot(arhcf.getTimeArray(), arhcf.getCF()/max(arhcf.getCF()), 'r')
|
||||
p23, = plt.plot(arhaiccf.getTimeArray(), arhaiccf.getCF()/max(arhaiccf.getCF()))
|
||||
plt.plot([aicarhpick.getpick(), aicarhpick.getpick()], [-1, 1], 'b')
|
||||
plt.plot([aicarhpick.getpick()-0.5, aicarhpick.getpick()+0.5], [1, 1], 'b')
|
||||
plt.plot([aicarhpick.getpick()-0.5, aicarhpick.getpick()+0.5], [-1, -1], 'b')
|
||||
plt.plot([arhpick.getpick(), arhpick.getpick()], [-1, 1], 'r')
|
||||
plt.plot([arhpick.getpick()-0.5, arhpick.getpick()+0.5], [1, 1], 'r')
|
||||
plt.plot([arhpick.getpick()-0.5, arhpick.getpick()+0.5], [-1, -1], 'r')
|
||||
plt.plot([lpickarh, lpickarh], [-0.8, 0.8], 'r--')
|
||||
plt.plot([epickarh, epickarh], [-0.8, 0.8], 'r--')
|
||||
plt.plot([arhpick.getpick() + pickerrarh, arhpick.getpick() + pickerrarh], [-0.2, 0.2], 'r--')
|
||||
plt.plot([arhpick.getpick() - pickerrarh, arhpick.getpick() - pickerrarh], [-0.2, 0.2], 'r--')
|
||||
plt.yticks([])
|
||||
plt.ylim([-1.5, 1.5])
|
||||
plt.ylabel('Normalized Counts')
|
||||
plt.title([trH1_filt.stats.station, trH1_filt.stats.channel])
|
||||
plt.suptitle(trH1_filt.stats.starttime)
|
||||
plt.legend([p21, p22, p23], ['Data', 'ARH-CF', 'ARHAIC-CF'])
|
||||
plt.subplot(2,1,2)
|
||||
plt.plot(th2data, trH2_filt.data/max(trH2_filt.data), 'k')
|
||||
plt.plot(arhcf.getTimeArray(), arhcf.getCF()/max(arhcf.getCF()), 'r')
|
||||
plt.plot(arhaiccf.getTimeArray(), arhaiccf.getCF()/max(arhaiccf.getCF()))
|
||||
plt.plot([aicarhpick.getpick(), aicarhpick.getpick()], [-1, 1], 'b')
|
||||
plt.plot([aicarhpick.getpick()-0.5, aicarhpick.getpick()+0.5], [1, 1], 'b')
|
||||
plt.plot([aicarhpick.getpick()-0.5, aicarhpick.getpick()+0.5], [-1, -1], 'b')
|
||||
plt.plot([arhpick.getpick(), arhpick.getpick()], [-1, 1], 'r')
|
||||
plt.plot([arhpick.getpick()-0.5, arhpick.getpick()+0.5], [1, 1], 'r')
|
||||
plt.plot([arhpick.getpick()-0.5, arhpick.getpick()+0.5], [-1, -1], 'r')
|
||||
plt.plot([lpickarh, lpickarh], [-0.8, 0.8], 'r--')
|
||||
plt.plot([epickarh, epickarh], [-0.8, 0.8], 'r--')
|
||||
plt.plot([arhpick.getpick() + pickerrarh, arhpick.getpick() + pickerrarh], [-0.2, 0.2], 'r--')
|
||||
plt.plot([arhpick.getpick() - pickerrarh, arhpick.getpick() - pickerrarh], [-0.2, 0.2], 'r--')
|
||||
plt.title([trH2_filt.stats.station, trH2_filt.stats.channel])
|
||||
plt.yticks([])
|
||||
plt.ylim([-1.5, 1.5])
|
||||
plt.xlabel('Time [s]')
|
||||
plt.ylabel('Normalized Counts')
|
||||
#plot 3-component window
|
||||
plt.figure(3)
|
||||
plt.subplot(3,1,1)
|
||||
p31, = plt.plot(tdata, tr_filt.data/max(tr_filt.data), 'k')
|
||||
p32, = plt.plot(ar3ccf.getTimeArray(), ar3ccf.getCF()/max(ar3ccf.getCF()), 'r')
|
||||
plt.plot([arhpick.getpick(), arhpick.getpick()], [-1, 1], 'b')
|
||||
plt.plot([arhpick.getpick()-0.5, arhpick.getpick()+0.5], [-1, -1], 'b')
|
||||
plt.plot([arhpick.getpick()-0.5, arhpick.getpick()+0.5], [1, 1], 'b')
|
||||
plt.yticks([])
|
||||
plt.xticks([])
|
||||
plt.ylabel('Normalized Counts')
|
||||
plt.title([tr.stats.station, tr.stats.channel])
|
||||
plt.suptitle(trH1_filt.stats.starttime)
|
||||
plt.legend([p31, p32], ['Data', 'AR3C-CF'])
|
||||
plt.subplot(3,1,2)
|
||||
plt.plot(th1data, trH1_filt.data/max(trH1_filt.data), 'k')
|
||||
plt.plot(ar3ccf.getTimeArray(), ar3ccf.getCF()/max(ar3ccf.getCF()), 'r')
|
||||
plt.plot([arhpick.getpick(), arhpick.getpick()], [-1, 1], 'b')
|
||||
plt.plot([arhpick.getpick()-0.5, arhpick.getpick()+0.5], [-1, -1], 'b')
|
||||
plt.plot([arhpick.getpick()-0.5, arhpick.getpick()+0.5], [1, 1], 'b')
|
||||
plt.yticks([])
|
||||
plt.xticks([])
|
||||
plt.ylabel('Normalized Counts')
|
||||
plt.title([trH1_filt.stats.station, trH1_filt.stats.channel])
|
||||
plt.subplot(3,1,3)
|
||||
plt.plot(th2data, trH2_filt.data/max(trH2_filt.data), 'k')
|
||||
plt.plot(ar3ccf.getTimeArray(), ar3ccf.getCF()/max(ar3ccf.getCF()), 'r')
|
||||
plt.plot([arhpick.getpick(), arhpick.getpick()], [-1, 1], 'b')
|
||||
plt.plot([arhpick.getpick()-0.5, arhpick.getpick()+0.5], [-1, -1], 'b')
|
||||
plt.plot([arhpick.getpick()-0.5, arhpick.getpick()+0.5], [1, 1], 'b')
|
||||
plt.yticks([])
|
||||
plt.ylabel('Normalized Counts')
|
||||
plt.title([trH2_filt.stats.station, trH2_filt.stats.channel])
|
||||
plt.xlabel('Time [s]')
|
||||
plt.show()
|
||||
raw_input()
|
||||
plt.close()
|
||||
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument('--project', type=str, help='project name (e.g. Insheim)')
|
||||
parser.add_argument('--database', type=str, help='event data base (e.g. 2014.09_Insheim)')
|
||||
parser.add_argument('--event', type=str, help='event ID (e.g. e0010.015.14)')
|
||||
parser.add_argument('--iplot', help='anything, if set, figure occurs')
|
||||
parser.add_argument('--station', type=str, help='Station ID (e.g. INS3) (optional)')
|
||||
args = parser.parse_args()
|
||||
|
||||
run_makeCF(args.project, args.database, args.event, args.iplot, args.station)
|
4
setup.py
@ -4,11 +4,11 @@ from distutils.core import setup
|
||||
|
||||
setup(
|
||||
name='PyLoT',
|
||||
version='0.1a1',
|
||||
version='0.2',
|
||||
packages=['pylot', 'pylot.core', 'pylot.core.loc', 'pylot.core.pick',
|
||||
'pylot.core.io', 'pylot.core.util', 'pylot.core.active',
|
||||
'pylot.core.analysis', 'pylot.testing'],
|
||||
requires=['obspy', 'PySide'],
|
||||
requires=['obspy', 'PySide', 'matplotlib', 'numpy'],
|
||||
url='dummy',
|
||||
license='LGPLv3',
|
||||
author='Sebastian Wehling-Benatelli',
|
||||
|