Merge branch 'develop'

This commit is contained in:
Marcel Paffrath 2017-09-21 16:18:53 +02:00
commit 472e5b3b9e
89 changed files with 216698 additions and 509615 deletions

1995
QtPyLoT.py → PyLoT.py Executable file → Normal file

File diff suppressed because it is too large Load Diff

186
README.md
View File

@ -1,90 +1,96 @@
# PyLoT # PyLoT
version: 0.1a version: 0.2
The Python picking and Localisation Tool The Python picking and Localisation Tool
This python library contains a graphical user interfaces for picking This python library contains a graphical user interfaces for picking
seismic phases. This software needs [ObsPy][ObsPy] seismic phases. This software needs [ObsPy][ObsPy]
and the PySide Qt4 bindings for python to be installed first. and the PySide Qt4 bindings for python to be installed first.
PILOT has originally been developed in Mathworks' MatLab. In order to PILOT has originally been developed in Mathworks' MatLab. In order to
distribute PILOT without facing portability problems, it has been decided distribute PILOT without facing portability problems, it has been decided
to redevelop the software package in Python. The great work of the ObsPy 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 group allows easy handling of a bunch of seismic data and PyLoT will
benefit a lot compared to the former MatLab version. benefit a lot compared to the former MatLab version.
The development of PyLoT is part of the joint research project MAGS2. The development of PyLoT is part of the joint research project MAGS2 and AlpArray.
## Installation ## Installation
At the moment there is no automatic installation procedure available for PyLoT. 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. Best way to install is to clone the repository and add the path to your Python path.
#### Prerequisites: #### Prerequisites:
In order to run PyLoT you need to install: In order to run PyLoT you need to install:
- python - python 2 or 3
- scipy - scipy
- numpy - numpy
- matplotlib - matplotlib
- obspy - obspy
- pyside - pyside
#### Some handwork: #### Some handwork:
PyLoT needs a properties folder on your system to work. It should be situated in your home directory: 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
mkdir ~/.pylot
In the next step you have to copy some files to this directory:
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*
for local distance seismicity
cp path-to-pylot/inputs/pylot_local.in ~/.pylot/pylot.in
cp path-to-pylot/inputs/autoPyLoT_local.in ~/.pylot/autoPyLoT.in
*for regional distance seismicity*
for regional distance seismicity
cp path-to-pylot/inputs/pylot_regional.in ~/.pylot/pylot.in
cp path-to-pylot/inputs/autoPyLoT_regional.in ~/.pylot/autoPyLoT.in
*for global distance seismicity*
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/pylot_global.in ~/.pylot/pylot.in
cp path-to-pylot/inputs/filter.in path-to-pylot/inputs/PILOT_TimeErrors.in path-to-pylot/inputs/richter_scaling.data ~/.pylot/
and some extra information on error estimates (just needed for reading old PILOT data) and the Richter magnitude scaling relation
You may need to do some modifications to these files. Especially folder names should be reviewed.
cp path-to-pylot/inputs/PILOT_TimeErrors.in path-to-pylot/inputs/richter_scaling.data ~/.pylot/
PyLoT has been tested on Mac OSX (10.11) and Debian Linux 8.
You may need to do some modifications to these files. Especially folder names should be reviewed.
## Release notes PyLoT has been tested on Mac OSX (10.11), Debian Linux 8 and on Windows 10.
#### Features:
## Release notes
- consistent manual phase picking through predefined SNR dependant zoom level
- uniform uncertainty estimation from waveform's properties for automatic and manual picks #### Features:
- pdf representation and comparison of picks taking the uncertainty intrinsically into account
- Richter and moment magnitude estimation - event organisation in project files and waveform visualisation
- location determination with external installation of [NonLinLoc](http://alomax.free.fr/nlloc/index.html) - consistent manual phase picking through predefined SNR dependant zoom level
- consistent automatic phase picking routines using Higher Order Statistics, AIC and Autoregression
#### Known issues: - interactive tuning of auto-pick parameters
- uniform uncertainty estimation from waveform's properties for automatic and manual picks
- Magnitude estimation from manual PyLoT takes some time (instrument correction) - pdf representation and comparison of picks taking the uncertainty intrinsically into account
- Richter and moment magnitude estimation
We hope to solve these with the next release. - location determination with external installation of [NonLinLoc](http://alomax.free.fr/nlloc/index.html)
## Staff #### Known issues:
Original author(s): L. Kueperkoch, S. Wehling-Benatelli, M. Bischoff (PILOT) - Sometimes an error might occur when using Qt
Developer(s): S. Wehling-Benatelli, L. Kueperkoch, K. Olbert, M. Bischoff, We hope to solve these with the next release.
C. Wollin, M. Rische, M. Paffrath
## Staff
Others: A. Bruestle, T. Meier, W. Friederich
Original author(s): L. Kueperkoch, S. Wehling-Benatelli, M. Bischoff (PILOT)
[ObsPy]: http://github.com/obspy/obspy/wiki Developer(s): S. Wehling-Benatelli, L. Kueperkoch, K. Olbert, M. Bischoff,
C. Wollin, M. Rische, M. Paffrath
October 2016
Others: A. Bruestle, T. Meier, W. Friederich
[ObsPy]: http://github.com/obspy/obspy/wiki
September 2017

View File

@ -4,31 +4,37 @@
from __future__ import print_function from __future__ import print_function
import argparse import argparse
import datetime
import glob import glob
import os 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.focmec as focmec
import pylot.core.loc.hash as hash 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 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.analysis.magnitude import MomentMagnitude, LocalMagnitude
from pylot.core.io.data import Data from pylot.core.io.data import Data
from pylot.core.io.inputs import PylotParameter from pylot.core.io.inputs import PylotParameter
from pylot.core.pick.autopick import autopickevent, iteratepicker from pylot.core.pick.autopick import autopickevent, iteratepicker
from pylot.core.util.dataprocessing import restitute_data, read_metadata, \ from pylot.core.util.dataprocessing import restitute_data, read_metadata
remove_underscores 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.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 from pylot.core.util.version import get_git_version as _getVersionString
__version__ = _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 Determine phase onsets automatically utilizing the automatic picking
algorithms by Kueperkoch et al. 2010/2012. 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 .. 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 splash = '''************************************\n
*********autoPyLoT starting*********\n *********autoPyLoT starting*********\n
The Python picking and Location Tool\n The Python picking and Location Tool\n
Version {version} 2015\n Version {version} 2017\n
\n \n
Authors:\n Authors:\n
S. Wehling-Benatelli (Ruhr-Universitaet Bochum)\n
L. Kueperkoch (BESTEC GmbH, Landau i. d. Pfalz)\n L. Kueperkoch (BESTEC GmbH, Landau i. d. Pfalz)\n
K. Olbert (Christian-Albrechts Universitaet zu Kiel)\n M. Paffrath (Ruhr-Universitaet Bochum)\n
***********************************'''.format(version=_getVersionString()) S. Wehling-Benatelli (Ruhr-Universitaet Bochum)\n
{sp}
***********************************'''.format(version=_getVersionString(),
sp=sp_info)
print(splash) print(splash)
parameter = real_None(parameter)
inputfile = real_None(inputfile)
eventid = real_None(eventid)
fig_dict = None
fig_dict_wadatijack = None
locflag = 1 locflag = 1
if input_dict and isinstance(input_dict, dict): if input_dict and isinstance(input_dict, dict):
if input_dict.has_key('parameter'): if 'parameter' in input_dict:
parameter = input_dict['parameter'] parameter = input_dict['parameter']
if input_dict.has_key('fig_dict'): if 'fig_dict' in input_dict:
fig_dict = input_dict['fig_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'] station = input_dict['station']
if input_dict.has_key('fnames'): if 'fnames' in input_dict:
fnames = input_dict['fnames'] 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'] iplot = input_dict['iplot']
if input_dict.has_key('locflag'): if 'locflag' in input_dict:
locflag = input_dict['locflag'] locflag = input_dict['locflag']
if 'savexml' in input_dict:
savexml = input_dict['savexml']
if not parameter: if not parameter:
if inputfile: if inputfile:
parameter = PylotParameter(inputfile) parameter = PylotParameter(inputfile)
iplot = parameter['iplot'] #iplot = parameter['iplot']
else: else:
print('No parameters set and no input file given. Choose either of both.') infile = os.path.join(os.path.expanduser('~'), '.pylot', 'pylot.in')
return print('Using default input file {}'.format(infile))
parameter = PylotParameter(infile)
else: else:
if not type(parameter) == PylotParameter: if not type(parameter) == PylotParameter:
print('Wrong input type for parameter: {}'.format(type(parameter))) 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: if inputfile:
print('Parameters set and input file given. Choose either of both.') print('Parameters set and input file given. Choose either of both.')
return return
data = Data()
evt = None evt = None
@ -97,7 +129,7 @@ def autoPyLoT(input_dict=None, parameter=None, inputfile=None, fnames=None, even
'dbase': parameter.get('database')} 'dbase': parameter.get('database')}
exf = ['root', 'dpath', 'dbase'] exf = ['root', 'dpath', 'dbase']
if parameter['eventID'] is not '*' and fnames == 'None': if parameter['eventID'] is not '*' and fnames == 'None':
dsfields['eventID'] = parameter['eventID'] dsfields['eventID'] = parameter['eventID']
exf.append('eventID') exf.append('eventID')
@ -106,7 +138,7 @@ def autoPyLoT(input_dict=None, parameter=None, inputfile=None, fnames=None, even
datastructure.setExpandFields(exf) datastructure.setExpandFields(exf)
# check if default location routine NLLoc is available # check if default location routine NLLoc is available
if parameter['nllocbin'] and locflag: if real_None(parameter['nllocbin']) and locflag:
# get NLLoc-root path # get NLLoc-root path
nllocroot = parameter.get('nllocroot') nllocroot = parameter.get('nllocroot')
# get path to NLLoc executable # get path to NLLoc executable
@ -137,9 +169,14 @@ def autoPyLoT(input_dict=None, parameter=None, inputfile=None, fnames=None, even
# multiple event processing # multiple event processing
# read each event in database # read each event in database
events = [events for events in glob.glob(os.path.join(datapath, '*')) if os.path.isdir(events)] 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 # single event processing
events = glob.glob(os.path.join(datapath, parameter['eventID'])) 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: else:
# autoPyLoT was initialized from GUI # autoPyLoT was initialized from GUI
events = [] events = []
@ -147,22 +184,41 @@ def autoPyLoT(input_dict=None, parameter=None, inputfile=None, fnames=None, even
evID = os.path.split(eventid)[-1] evID = os.path.split(eventid)[-1]
locflag = 2 locflag = 2
else: else:
# started in tune mode # started in tune or interactive mode
datapath = os.path.join(parameter['rootpath'], datapath = os.path.join(parameter['rootpath'],
parameter['datapath']) parameter['datapath'])
events = [] events = []
events.append(os.path.join(datapath, for eventID in eventid:
parameter['database'], events.append(os.path.join(datapath,
parameter['eventID'])) parameter['database'],
eventID))
if not events: if not events:
print('autoPyLoT: No events given. Return!') print('autoPyLoT: No events given. Return!')
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': if fnames == 'None':
data.setWFData(glob.glob(os.path.join(datapath, event, '*'))) data.setWFData(glob.glob(os.path.join(datapath, eventpath, '*')))
evID = os.path.split(event)[-1]
# the following is necessary because within # the following is necessary because within
# multiple event processing no event ID is provided # multiple event processing no event ID is provided
# in autopylot.in # in autopylot.in
@ -178,10 +234,10 @@ def autoPyLoT(input_dict=None, parameter=None, inputfile=None, fnames=None, even
parameter.setParam(eventID=eventID) parameter.setParam(eventID=eventID)
else: else:
data.setWFData(fnames) data.setWFData(fnames)
event = events[0] eventpath = events[0]
#now = datetime.datetime.now() # now = datetime.datetime.now()
#evID = '%d%02d%02d%02d%02d' % (now.year, # evID = '%d%02d%02d%02d%02d' % (now.year,
# now.month, # now.month,
# now.day, # now.day,
# now.hour, # now.hour,
@ -192,22 +248,31 @@ def autoPyLoT(input_dict=None, parameter=None, inputfile=None, fnames=None, even
wfdat = wfdat.select(station=station) wfdat = wfdat.select(station=station)
if not wfdat: if not wfdat:
print('Could not find station {}. STOP!'.format(station)) print('Could not find station {}. STOP!'.format(station))
return return
wfdat = remove_underscores(wfdat) wfdat = remove_underscores(wfdat)
metadata = read_metadata(parameter.get('invdir')) # trim components for each station to avoid problems with different trace starttimes for one station
print("Restitute data ...") wfdat = check4gaps(wfdat)
corr_dat = restitute_data(wfdat.copy(), *metadata) wfdat = check4doubled(wfdat)
wfdat = trim_station_components(wfdat, trim_start=True, trim_end=False)
print('Working on event %s. Stations: %s' % (event, station)) 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) print(wfdat)
########################################################## ##########################################################
# !automated picking starts here! # !automated picking starts here!
if input_dict: fdwj = None
if input_dict.has_key('fig_dict'): if fig_dict_wadatijack:
fig_dict = input_dict['fig_dict'] fdwj = fig_dict_wadatijack[evID]
picks = autopickevent(wfdat, parameter, iplot=iplot, fig_dict=fig_dict) picks = autopickevent(wfdat, parameter, iplot=iplot, fig_dict=fig_dict,
else: fig_dict_wadatijack=fdwj,
picks = autopickevent(wfdat, parameter, iplot=iplot) ncores=ncores, metadata=metadata, origin=data.get_evt_data().origins)
########################################################## ##########################################################
# locating # locating
if locflag > 0: 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 # calculate seismic moment Mo and moment magnitude Mw
moment_mag = MomentMagnitude(corr_dat, evt, parameter.get('vp'), moment_mag = MomentMagnitude(corr_dat, evt, parameter.get('vp'),
parameter.get('Qp'), parameter.get('Qp'),
parameter.get('rho'), True, \ parameter.get('rho'), True,
iplot) iplot)
# update pick with moment property values (w0, fc, Mo) # update pick with moment property values (w0, fc, Mo)
for station, props in moment_mag.moment_props.items(): for stats, props in moment_mag.moment_props.items():
picks[station]['P'].update(props) picks[stats]['P'].update(props)
evt = moment_mag.updated_event() evt = moment_mag.updated_event()
net_mw = moment_mag.net_magnitude() net_mw = moment_mag.net_magnitude()
print("Network moment magnitude: %4.1f" % net_mw.mag) 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') WAscaling = parameter.get('WAscaling')
magscaling = parameter.get('magscaling') magscaling = parameter.get('magscaling')
local_mag = LocalMagnitude(corr_dat, evt, local_mag = LocalMagnitude(corr_dat, evt,
parameter.get('sstop'), parameter.get('sstop'),
WAscaling, True, iplot) WAscaling, True, iplot)
for station, amplitude in local_mag.amplitudes.items(): for stats, amplitude in local_mag.amplitudes.items():
picks[station]['S']['Ao'] = amplitude.generic_amplitude picks[stats]['S']['Ao'] = amplitude.generic_amplitude
print("Local station magnitudes scaled with:") 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[1],
WAscaling[2])) WAscaling[2]))
evt = local_mag.updated_event(magscaling) evt = local_mag.updated_event(magscaling)
@ -289,9 +354,10 @@ def autoPyLoT(input_dict=None, parameter=None, inputfile=None, fnames=None, even
break break
print("autoPyLoT: Starting with iteration No. %d ..." % nlloccounter) print("autoPyLoT: Starting with iteration No. %d ..." % nlloccounter)
if input_dict: if input_dict:
if input_dict.has_key('fig_dict'): if 'fig_dict' in input_dict:
fig_dict = input_dict['fig_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: else:
picks = iteratepicker(wfdat, nllocfile, picks, badpicks, parameter) picks = iteratepicker(wfdat, nllocfile, picks, badpicks, parameter)
# write phases to NLLoc-phase file # 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: for key in picks:
if picks[key]['P']['weight'] >= 4 or picks[key]['S']['weight'] >= 4: if picks[key]['P']['weight'] >= 4 or picks[key]['S']['weight'] >= 4:
badpicks.append([key, picks[key]['P']['mpp']]) 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))) len(badpicks)))
if len(badpicks) == 0: if len(badpicks) == 0:
print("autoPyLoT: No more bad onsets found, stop iterative picking!") 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 # calculate seismic moment Mo and moment magnitude Mw
moment_mag = MomentMagnitude(corr_dat, evt, parameter.get('vp'), moment_mag = MomentMagnitude(corr_dat, evt, parameter.get('vp'),
parameter.get('Qp'), parameter.get('Qp'),
parameter.get('rho'), True, \ parameter.get('rho'), True,
iplot) iplot)
# update pick with moment property values (w0, fc, Mo) # update pick with moment property values (w0, fc, Mo)
for station, props in moment_mag.moment_props.items(): for stats, props in moment_mag.moment_props.items():
picks[station]['P'].update(props) if picks.has_key(stats):
picks[stats]['P'].update(props)
evt = moment_mag.updated_event() evt = moment_mag.updated_event()
net_mw = moment_mag.net_magnitude() net_mw = moment_mag.net_magnitude()
print("Network moment magnitude: %4.1f" % net_mw.mag) 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') WAscaling = parameter.get('WAscaling')
magscaling = parameter.get('magscaling') magscaling = parameter.get('magscaling')
local_mag = LocalMagnitude(corr_dat, evt, local_mag = LocalMagnitude(corr_dat, evt,
parameter.get('sstop'), parameter.get('sstop'),
WAscaling, True, iplot) WAscaling, True, iplot)
for station, amplitude in local_mag.amplitudes.items(): for stats, amplitude in local_mag.amplitudes.items():
picks[station]['S']['Ao'] = amplitude.generic_amplitude if picks.has_key(stats):
picks[stats]['S']['Ao'] = amplitude.generic_amplitude
print("Local station magnitudes scaled with:") 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[1],
WAscaling[2])) WAscaling[2]))
evt = local_mag.updated_event(magscaling) 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 # write phase files for various location
# and fault mechanism calculation routines # and fault mechanism calculation routines
# ObsPy event object # ObsPy event object
data.applyEVTData(picks)
if evt is not None: if evt is not None:
event_id = eventpath.split('/')[-1]
evt.resource_id = ResourceIdentifier('smi:local/' + event_id)
data.applyEVTData(evt, 'event') data.applyEVTData(evt, 'event')
fnqml = '%s/PyLoT_%s' % (event, evID) data.applyEVTData(picks)
data.exportEvent(fnqml, fnext='.xml', fcheck='manual') 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: if locflag == 1:
# HYPO71 # HYPO71
hypo71file = '%s/PyLoT_%s_HYPO71_phases' % (event, evID) hypo71file = '%s/PyLoT_%s_HYPO71_phases' % (eventpath, evID)
hypo71.export(picks, hypo71file, parameter) hypo71.export(picks, hypo71file, parameter)
# HYPOSAT # HYPOSAT
hyposatfile = '%s/PyLoT_%s_HYPOSAT_phases' % (event, evID) hyposatfile = '%s/PyLoT_%s_HYPOSAT_phases' % (eventpath, evID)
hyposat.export(picks, hyposatfile, parameter) hyposat.export(picks, hyposatfile, parameter)
# VELEST # VELEST
velestfile = '%s/PyLoT_%s_VELEST_phases.cnv' % (event, evID) velestfile = '%s/PyLoT_%s_VELEST_phases.cnv' % (eventpath, evID)
velest.export(picks, velestfile, parameter, evt) velest.export(picks, velestfile, evt, parameter)
# hypoDD # hypoDD
hypoddfile = '%s/PyLoT_%s_hypoDD_phases.pha' % (event, evID) hypoddfile = '%s/PyLoT_%s_hypoDD_phases.pha' % (eventpath, evID)
hypodd.export(picks, hypoddfile, parameter, evt) hypodd.export(picks, hypoddfile, parameter, evt)
# FOCMEC # FOCMEC
focmecfile = '%s/PyLoT_%s_FOCMEC.in' % (event, evID) focmecfile = '%s/PyLoT_%s_FOCMEC.in' % (eventpath, evID)
focmec.export(picks, focmecfile, parameter, evt) focmec.export(picks, focmecfile, parameter, evt)
# HASH # HASH
hashfile = '%s/PyLoT_%s_HASH' % (event, evID) hashfile = '%s/PyLoT_%s_HASH' % (eventpath, evID)
hash.export(picks, hashfile, parameter, evt) hash.export(picks, hashfile, parameter, evt)
endsplash = '''------------------------------------------\n' endsplash = '''------------------------------------------\n'
-----Finished event %s!-----\n' -----Finished event %s!-----\n'
------------------------------------------'''.format \ ------------------------------------------'''.format \
(version=_getVersionString()) % evID (version=_getVersionString()) % evID
print(endsplash) print(endsplash)
locflag = glocflag
if locflag == 0: if locflag == 0:
print("autoPyLoT was running in non-location mode!") print("autoPyLoT was running in non-location mode!")
# save picks for current event ID to dictionary with ALL picks
allpicks[evID] = picks
endsp = '''####################################\n endsp = '''####################################\n
************************************\n ************************************\n
*********autoPyLoT terminates*******\n *********autoPyLoT terminates*******\n
The Python picking and Location Tool\n The Python picking and Location Tool\n
************************************'''.format(version=_getVersionString()) ************************************'''.format(version=_getVersionString())
print(endsp) print(endsp)
return picks return allpicks
if __name__ == "__main__": if __name__ == "__main__":
@ -399,30 +478,28 @@ if __name__ == "__main__":
autoregressive prediction and AIC followed by locating the seismic events using autoregressive prediction and AIC followed by locating the seismic events using
NLLoc''') NLLoc''')
#parser.add_argument('-d', '-D', '--input_dict', type=str,
# action='store',
# help='''optional, dictionary containing processing parameters''')
#parser.add_argument('-p', '-P', '--parameter', type=str,
# action='store',
# help='''parameter file, default=None''')
parser.add_argument('-i', '-I', '--inputfile', type=str, parser.add_argument('-i', '-I', '--inputfile', type=str,
action='store', action='store',
help='''full path to the file containing the input help='''full path to the file containing the input
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, parser.add_argument('-f', '-F', '--fnames', type=str,
action='store', action='store',
help='''optional, list of data file names''') help='''optional, list of data file names''')
parser.add_argument('-e', '-E', '--eventid', type=str, parser.add_argument('-e', '--eventid', type=str,
action='store', action='store',
help='''optional, event path incl. event ID''') help='''optional, event path incl. event ID''')
parser.add_argument('-s', '-S', '--spath', type=str, parser.add_argument('-s', '-S', '--spath', type=str,
action='store', action='store',
help='''optional, save path for autoPyLoT output''') help='''optional, save path for autoPyLoT output''')
#parser.add_argument('-v', '-V', '--version', action='version', parser.add_argument('-c', '-C', '--ncores', type=int,
# version='autoPyLoT ' + __version__, action='store', default=0,
# help='show version information and exit') help='''optional, number of CPU cores used for parallel processing (default: all available(=0))''')
cla = parser.parse_args() cla = parser.parse_args()
picks = autoPyLoT(inputfile=str(cla.inputfile), fnames=str(cla.fnames), picks = autoPyLoT(inputfile=str(cla.inputfile), fnames=str(cla.fnames),
eventid=str(cla.eventid), savepath=str(cla.spath)) eventid=str(cla.eventid), savepath=str(cla.spath),
ncores=cla.ncores, iplot=int(cla.iplot))

View File

@ -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.

View File

@ -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> <body>
<p><b>PyLoT</b> is a program which is capable of picking seismic phases, <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 exporting these as numerous standard phase format and localize the corresponding
seismic event with external software as, e.g.:</p> seismic event with external software as, e.g.:</p>
<ul type="circle"> <ul type="circle">
<li><a href="http://alomax.free.fr/nlloc/index.html">NonLinLoc</a></li> <li><a href="http://alomax.free.fr/nlloc/index.html">NonLinLoc</a></li>
<li>HypoInvers</li> <li>HypoInvers</li>
<li>HypoSat</li> <li>HypoSat</li>
<li>whatever you want ...</li> <li>whatever you want ...</li>
</ul> </ul>
<p>Read more on the <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 <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 <a href="https://ariadne.geophysik.rub.de/trac/PyLoT">PyLoT TracPage</a> after
successful registration.</p> successful registration.</p>
</body></html> </body>
</html>

View File

@ -2,6 +2,8 @@
<qresource> <qresource>
<file>icons/pylot.ico</file> <file>icons/pylot.ico</file>
<file>icons/pylot.png</file> <file>icons/pylot.png</file>
<file>icons/back.png</file>
<file>icons/home.png</file>
<file>icons/newfile.png</file> <file>icons/newfile.png</file>
<file>icons/open.png</file> <file>icons/open.png</file>
<file>icons/openproject.png</file> <file>icons/openproject.png</file>
@ -23,6 +25,8 @@
<file>icons/savepicks.png</file> <file>icons/savepicks.png</file>
<file>icons/preferences.png</file> <file>icons/preferences.png</file>
<file>icons/parameter.png</file> <file>icons/parameter.png</file>
<file>icons/inventory.png</file>
<file>icons/map.png</file>
<file>icons/openloc.png</file> <file>icons/openloc.png</file>
<file>icons/compare_button.png</file> <file>icons/compare_button.png</file>
<file>icons/locate_button.png</file> <file>icons/locate_button.png</file>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 31 KiB

After

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 52 KiB

After

Width:  |  Height:  |  Size: 30 KiB

BIN
icons/back.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

BIN
icons/home.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 23 KiB

BIN
icons/inventory.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 25 KiB

After

Width:  |  Height:  |  Size: 22 KiB

BIN
icons/map.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 56 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 50 KiB

After

Width:  |  Height:  |  Size: 50 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 63 KiB

After

Width:  |  Height:  |  Size: 57 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 53 KiB

After

Width:  |  Height:  |  Size: 50 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 60 KiB

After

Width:  |  Height:  |  Size: 52 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 22 KiB

After

Width:  |  Height:  |  Size: 39 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 19 KiB

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 25 KiB

After

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 32 KiB

After

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 36 KiB

After

Width:  |  Height:  |  Size: 35 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 42 KiB

After

Width:  |  Height:  |  Size: 41 KiB

File diff suppressed because it is too large Load Diff

104841
icons_rc_3.py Normal file

File diff suppressed because it is too large Load Diff

View 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

View File

@ -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

View 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!
%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

View File

@ -1,2 +0,0 @@
P bandpass 4 2.0 20.0
S bandpass 4 2.0 15.0

View File

@ -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
View 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
View 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
View 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

View File

@ -158,24 +158,29 @@ def buildPyLoT(verbosity=None):
def installPyLoT(verbosity=None): def installPyLoT(verbosity=None):
files_to_copy = {'autoPyLoT_local.in':['~', '.pylot'], files_to_copy = {'pylot_local.in': ['~', '.pylot'],
'autoPyLoT_regional.in':['~', '.pylot'], 'pylot_regional.in': ['~', '.pylot'],
'filter.in':['~', '.pylot']} 'pylot_global.in': ['~', '.pylot']}
if verbosity > 0: if verbosity > 0:
print ('starting installation of PyLoT ...') print('starting installation of PyLoT ...')
if verbosity > 1: if verbosity > 1:
print ('copying input files into destination folder ...') print('copying input files into destination folder ...')
ans = input('please specify scope of interest ' 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): if not isinstance(ans, int):
ans = int(ans) 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 = [] link_dest = []
for file, destination in files_to_copy.items(): for file, destination in files_to_copy.items():
link_file = ans in file link_file = ans in file
if link_file: if link_file:
link_dest = copy.deepcopy(destination) link_dest = copy.deepcopy(destination)
link_dest.append('autoPyLoT.in') link_dest.append('pylot.in')
link_dest = os.path.join(*link_dest) link_dest = os.path.join(*link_dest)
destination.append(file) destination.append(file)
destination = os.path.join(*destination) destination = os.path.join(*destination)
@ -183,7 +188,7 @@ def installPyLoT(verbosity=None):
assert not os.path.isabs(srcfile), 'source files seem to be ' \ assert not os.path.isabs(srcfile), 'source files seem to be ' \
'corrupted ...' 'corrupted ...'
if verbosity > 1: 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) shutil.copyfile(srcfile, destination)
if link_file: if link_file:
if verbosity: if verbosity:
@ -191,8 +196,6 @@ def installPyLoT(verbosity=None):
os.symlink(destination, link_dest) os.symlink(destination, link_dest)
def cleanUp(verbosity=None): def cleanUp(verbosity=None):
if verbosity >= 1: if verbosity >= 1:
print('cleaning up build files...') print('cleaning up build files...')

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.2 KiB

View File

@ -6,27 +6,27 @@ Revised/extended summer 2017.
:author: Ludger Küperkoch / MAGS2 EP3 working group :author: Ludger Küperkoch / MAGS2 EP3 working group
""" """
import os
import matplotlib.pyplot as plt import matplotlib.pyplot as plt
import numpy as np import numpy as np
import obspy.core.event as ope import obspy.core.event as ope
from obspy.geodetics import degrees2kilometers 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, \ from pylot.core.pick.utils import getsignalwin, crossings_nonzero_all, \
select_for_phase select_for_phase
from pylot.core.util.utils import common_range, fit_curve 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): 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, 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, 260, 270, 280, 290, 300, 310, 320, 330, 340, 350, 360, 370, 380,
390, 400, 430, 470, 510, 560, 600, 700, 800, 900, 1000]) 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, 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, 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, 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, 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]) 5.1, 5.2, 5.4, 5.5, 5.7])
# prepare spline interpolation to calculate return value # prepare spline interpolation to calculate return value
func, params = fit_curve(distance, richter_scaling) func, params = fit_curve(distance, richter_scaling)
return func(delta, params) return func(delta, params)
@ -47,7 +47,7 @@ class Magnitude(object):
def __str__(self): def __str__(self):
print( 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') print('\tstation\tmagnitude')
for s, m in self.magnitudes.items(): print('\t{0}\t{1}'.format(s, m)) for s, m in self.magnitudes.items(): print('\t{0}\t{1}'.format(s, m))
@ -126,8 +126,8 @@ class Magnitude(object):
# scaling necessary # scaling necessary
print("Scaling network magnitude ...") print("Scaling network magnitude ...")
mag = ope.Magnitude( mag = ope.Magnitude(
mag=np.median([M.mag for M in self.magnitudes.values()]) *\ mag=np.median([M.mag for M in self.magnitudes.values()]) * \
magscaling[0] + magscaling[1], magscaling[0] + magscaling[1],
magnitude_type=self.type, magnitude_type=self.type,
origin_id=self.origin_id, origin_id=self.origin_id,
station_count=len(self.magnitudes), station_count=len(self.magnitudes),
@ -192,6 +192,14 @@ class LocalMagnitude(Magnitude):
def peak_to_peak(self, st, t0): 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 # simulate Wood-Anderson response
st.simulate(paz_remove=None, paz_simulate=self._paz) st.simulate(paz_remove=None, paz_simulate=self._paz)
@ -215,7 +223,7 @@ class LocalMagnitude(Magnitude):
th = np.arange(0, len(sqH) * dt, dt) th = np.arange(0, len(sqH) * dt, dt)
# get maximum peak within pick window # get maximum peak within pick window
iwin = getsignalwin(th, t0 - stime, self.calc_win) 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] iwin = iwin[0:ii]
wapp = np.max(sqH[iwin]) wapp = np.max(sqH[iwin])
if self.verbose: if self.verbose:
@ -224,7 +232,7 @@ class LocalMagnitude(Magnitude):
# check for plot flag (for debugging only) # check for plot flag (for debugging only)
fig = None fig = None
if self.plot_flag > 1: if iplot > 1:
st.plot() st.plot()
fig = plt.figure() fig = plt.figure()
ax = fig.add_subplot(111) ax = fig.add_subplot(111)
@ -250,8 +258,8 @@ class LocalMagnitude(Magnitude):
if not wf: if not wf:
if self.verbose: if self.verbose:
print( print(
'WARNING: no waveform data found for station {0}'.format( 'WARNING: no waveform data found for station {0}'.format(
station)) station))
continue continue
delta = degrees2kilometers(a.distance) delta = degrees2kilometers(a.distance)
onset = pick.time onset = pick.time
@ -270,13 +278,14 @@ class LocalMagnitude(Magnitude):
if str(self.wascaling) == '[0.0, 0.0, 0.0]': if str(self.wascaling) == '[0.0, 0.0, 0.0]':
print("Calculating original Richter magnitude ...") print("Calculating original Richter magnitude ...")
magnitude = ope.StationMagnitude(mag=np.log10(a0) \ magnitude = ope.StationMagnitude(mag=np.log10(a0) \
+ richter_magnitude_scaling(delta)) + richter_magnitude_scaling(delta))
else: else:
print("Calculating scaled local magnitude ...") 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) \ magnitude = ope.StationMagnitude(mag=np.log10(a0) \
+ self.wascaling[0] * np.log10(delta) + self.wascaling[1] + self.wascaling[0] * np.log10(delta) + self.wascaling[1]
* delta + self.wascaling[2]) * delta + self.wascaling[
2])
magnitude.origin_id = self.origin_id magnitude.origin_id = self.origin_id
magnitude.waveform_id = pick.waveform_id magnitude.waveform_id = pick.waveform_id
magnitude.amplitude_id = amplitude.resource_id magnitude.amplitude_id = amplitude.resource_id
@ -397,8 +406,8 @@ def calcMoMw(wfstream, w0, rho, vp, delta, verbosity=False):
if verbosity: if verbosity:
print( print(
"calcMoMw: Calculating seismic moment Mo and moment magnitude Mw for station {0} ...".format( "calcMoMw: Calculating seismic moment Mo and moment magnitude Mw for station {0} ...".format(
tr.stats.station)) tr.stats.station))
# additional common parameters for calculating Mo # additional common parameters for calculating Mo
rP = 2 / np.sqrt( rP = 2 / np.sqrt(
@ -412,8 +421,8 @@ def calcMoMw(wfstream, w0, rho, vp, delta, verbosity=False):
if verbosity: if verbosity:
print( print(
"calcMoMw: Calculated seismic moment Mo = {0} Nm => Mw = {1:3.1f} ".format( "calcMoMw: Calculated seismic moment Mo = {0} Nm => Mw = {1:3.1f} ".format(
Mo, Mw)) Mo, Mw))
return Mo, Mw return Mo, Mw
@ -452,7 +461,15 @@ def calcsourcespec(wfstream, onset, vp, delta, azimuth, incidence,
:type: integer :type: integer
''' '''
if verbosity: 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 # get Q value
Q, A = qp Q, A = qp
@ -509,9 +526,9 @@ def calcsourcespec(wfstream, onset, vp, delta, azimuth, incidence,
zc = crossings_nonzero_all(wfzc) zc = crossings_nonzero_all(wfzc)
if np.size(zc) == 0 or len(zc) <= 3: if np.size(zc) == 0 or len(zc) <= 3:
if verbosity: if verbosity:
print ("calcsourcespec: Something is wrong with the waveform, " print("calcsourcespec: Something is wrong with the waveform, "
"no zero crossings derived!\n") "no zero crossings derived!\n")
print ("No calculation of source spectrum possible!") print("No calculation of source spectrum possible!")
plotflag = 0 plotflag = 0
else: else:
plotflag = 1 plotflag = 1
@ -558,22 +575,22 @@ def calcsourcespec(wfstream, onset, vp, delta, azimuth, incidence,
[optspecfit, _] = curve_fit(synthsourcespec, F, YYcor, [w0in, Fcin]) [optspecfit, _] = curve_fit(synthsourcespec, F, YYcor, [w0in, Fcin])
w0 = optspecfit[0] w0 = optspecfit[0]
fc = optspecfit[1] fc = optspecfit[1]
#w01 = optspecfit[0] # w01 = optspecfit[0]
#fc1 = optspecfit[1] # fc1 = optspecfit[1]
if verbosity: if verbosity:
print ("calcsourcespec: Determined w0-value: %e m/Hz, \n" print("calcsourcespec: Determined w0-value: %e m/Hz, \n"
"calcsourcespec: Determined corner frequency: %f Hz" % (w0, fc)) "calcsourcespec: Determined corner frequency: %f Hz" % (w0, fc))
# use of conventional fitting # use of conventional fitting
# [w02, fc2] = fitSourceModel(F, YYcor, Fcin, iplot, verbosity) # [w02, fc2] = fitSourceModel(F, YYcor, Fcin, iplot, verbosity)
# get w0 and fc as median of both # get w0 and fc as median of both
# source spectrum fits # source spectrum fits
#w0 = np.median([w01, w02]) # w0 = np.median([w01, w02])
#fc = np.median([fc1, fc2]) # fc = np.median([fc1, fc2])
#if verbosity: # if verbosity:
# print("calcsourcespec: Using w0-value = %e m/Hz and fc = %f Hz" % ( # print("calcsourcespec: Using w0-value = %e m/Hz and fc = %f Hz" % (
# w0, fc)) # w0, fc))
if iplot > 1: if iplot > 1:
f1 = plt.figure() f1 = plt.figure()
@ -600,9 +617,9 @@ def calcsourcespec(wfstream, onset, vp, delta, azimuth, incidence,
p3, = plt.loglog(F, YYcor, 'r') p3, = plt.loglog(F, YYcor, 'r')
p4, = plt.loglog(F, fit, 'g') p4, = plt.loglog(F, fit, 'g')
plt.loglog([fc, fc], [w0 / 100, w0], 'g') plt.loglog([fc, fc], [w0 / 100, w0], 'g')
plt.legend([p1, p2, p3, p4], ['Raw Spectrum', \ plt.legend([p1, p2, p3, p4], ['Raw Spectrum',
'Used Raw Spectrum', \ 'Used Raw Spectrum',
'Q-Corrected Spectrum', \ 'Q-Corrected Spectrum',
'Fit to Spectrum']) 'Fit to Spectrum'])
plt.title('Source Spectrum from P Pulse, w0=%e m/Hz, fc=%6.2f Hz' \ plt.title('Source Spectrum from P Pulse, w0=%e m/Hz, fc=%6.2f Hz' \
% (w0, fc)) % (w0, fc))
@ -650,6 +667,14 @@ def fitSourceModel(f, S, fc0, iplot, verbosity=False):
:type: float :type: float
''' '''
try:
iplot = int(iplot)
except:
if iplot == True or iplot == 'True':
iplot = 2
else:
iplot = 0
w0 = [] w0 = []
stdw0 = [] stdw0 = []
fc = [] fc = []
@ -659,9 +684,9 @@ def fitSourceModel(f, S, fc0, iplot, verbosity=False):
# left side of initial corner frequency # left side of initial corner frequency
fcstopl = max(f[0], fc0 - max(1, fc0 / 2)) fcstopl = max(f[0], fc0 - max(1, fc0 / 2))
il = np.where(f <= fcstopl) 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 # 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) ir = np.where(f >= fcstopr)
# check, if fcstopr is available # check, if fcstopr is available
if np.size(ir) == 0: if np.size(ir) == 0:
@ -672,16 +697,16 @@ def fitSourceModel(f, S, fc0, iplot, verbosity=False):
# vary corner frequency around initial point # vary corner frequency around initial point
print("fitSourceModel: Varying corner frequency " print("fitSourceModel: Varying corner frequency "
"around initial corner frequency ...") "around initial corner frequency ...")
# check difference of il and ir in order to # check difference of il and ir in order to
# keep calculation time acceptable # keep calculation time acceptable
idiff = ir - il idiff = ir - il
if idiff > 10000: if idiff > 10000:
increment = 100 increment = 100
elif idiff <= 20: elif idiff <= 20:
increment = 1 increment = 1
else: else:
increment = 10 increment = 10
for i in range(il, ir, increment): for i in range(il, ir, increment):
FC = f[i] FC = f[i]
@ -707,10 +732,10 @@ def fitSourceModel(f, S, fc0, iplot, verbosity=False):
w0 = max(S) w0 = max(S)
if verbosity: if verbosity:
print( 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: if iplot > 1:
plt.figure()#iplot) plt.figure() # iplot)
plt.loglog(f, S, 'k') plt.loglog(f, S, 'k')
plt.loglog([f[0], fc], [w0, w0], 'g') plt.loglog([f[0], fc], [w0, w0], 'g')
plt.loglog([fc, fc], [w0 / 100, w0], 'g') plt.loglog([fc, fc], [w0 / 100, w0], 'g')
@ -719,7 +744,7 @@ def fitSourceModel(f, S, fc0, iplot, verbosity=False):
plt.xlabel('Frequency [Hz]') plt.xlabel('Frequency [Hz]')
plt.ylabel('Amplitude [m/Hz]') plt.ylabel('Amplitude [m/Hz]')
plt.grid() plt.grid()
plt.figure()#iplot + 1) plt.figure() # iplot + 1)
plt.subplot(311) plt.subplot(311)
plt.plot(f[il:ir], STD, '*') plt.plot(f[il:ir], STD, '*')
plt.title('Common Standard Deviations') plt.title('Common Standard Deviations')

View File

@ -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

View File

@ -3,15 +3,18 @@
import copy import copy
import os import os
from obspy import read_events from obspy import read_events
from obspy.core import read, Stream, UTCDateTime from obspy.core import read, Stream, UTCDateTime
from obspy.io.sac import SacIOError
from obspy.core.event import Event as ObsPyEvent from obspy.core.event import Event as ObsPyEvent
from obspy.io.sac import SacIOError
from pylot.core.io.phases import readPILOTEvent, picks_from_picksdict, \ from pylot.core.io.phases import readPILOTEvent, picks_from_picksdict, \
picksdict_from_pilot, merge_picks picksdict_from_pilot, merge_picks
from pylot.core.util.errors import FormatError, OverwriteError 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.event import Event
from pylot.core.util.utils import fnConstructor, full_range
import pylot.core.loc.velest as velest
class Data(object): class Data(object):
""" """
@ -39,7 +42,7 @@ class Data(object):
elif isinstance(evtdata, dict): elif isinstance(evtdata, dict):
evt = readPILOTEvent(**evtdata) evt = readPILOTEvent(**evtdata)
evtdata = evt evtdata = evt
elif isinstance(evtdata, basestring): elif isinstance(evtdata, str):
try: try:
cat = read_events(evtdata) cat = read_events(evtdata)
if len(cat) is not 1: if len(cat) is not 1:
@ -75,7 +78,7 @@ class Data(object):
def __add__(self, other): def __add__(self, other):
assert isinstance(other, Data), "operands must be of same type 'Data'" assert isinstance(other, Data), "operands must be of same type 'Data'"
rs_id = self.get_evt_data().get('resource_id') 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(): if other.isNew() and not self.isNew():
picks_to_add = other.get_evt_data().picks picks_to_add = other.get_evt_data().picks
old_picks = self.get_evt_data().picks old_picks = self.get_evt_data().picks
@ -98,7 +101,7 @@ class Data(object):
def getPicksStr(self): def getPicksStr(self):
picks_str = '' picks_str = ''
for pick in self.get_evt_data().picks: for pick in self.get_evt_data().picks:
picks_str += str(PyLoT) + '\n' picks_str += str(pick) + '\n'
return picks_str return picks_str
def getParent(self): def getParent(self):
@ -147,89 +150,158 @@ class Data(object):
# handle forbidden filenames especially on windows systems # handle forbidden filenames especially on windows systems
return fnConstructor(str(ID)) 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: basename of file
:param fnout: :param fnext: file extension
:param fnext: :param fcheck: check and delete existing information
:param fcheck: can be a str or a list of strings of ['manual', 'auto', 'origin', 'magnitude']
:raise KeyError:
""" """
from pylot.core.util.defaults import OUTPUTFORMATS from pylot.core.util.defaults import OUTPUTFORMATS
if not type(fcheck) == list:
fcheck = [fcheck]
try: try:
evtformat = OUTPUTFORMATS[fnext] evtformat = OUTPUTFORMATS[fnext]
except KeyError as e: except KeyError as e:
errmsg = '{0}; selected file extension {1} not ' \ errmsg = '{0}; selected file extension {1} not ' \
'supported'.format(e, fnext) 'supported'.format(e, fnext)
raise FormatError(errmsg) raise FormatError(errmsg)
# check for already existing xml-file # check for already existing xml-file
if fnext == '.xml': if fnext == '.xml':
if os.path.isfile(fnout + fnext): if os.path.isfile(fnout + fnext):
print("xml-file already exists! Check content ...") print("xml-file already exists! Check content ...")
cat_old = read_events(fnout + fnext) cat = read_events(fnout + fnext)
checkflag = 0 if len(cat) > 1:
for j in range(len(cat_old.events[0].picks)): raise IOError('Ambigious event information in file {}'.format(fnout + fnext))
if cat_old.events[0].picks[j].method_id.id.split('/')[1] == fcheck: if len(cat) < 1:
print("Found %s pick(s), append to new catalog." % fcheck) raise IOError('No event information in file {}'.format(fnout + fnext))
checkflag = 1 event = cat[0]
break if not event.resource_id == self.get_evt_data().resource_id:
if checkflag == 1: raise IOError("Missmatching event resource id's: {} and {}".format(event.resource_id,
self.get_evt_data().write(fnout + fnext, format=evtformat) self.get_evt_data().resource_id))
cat_new = read_events(fnout + fnext) self.checkEvent(event, fcheck)
cat_new.append(cat_old.events[0]) self.setEvtData(event)
cat_new.write(fnout + fnext, format=evtformat) self.get_evt_data().write(fnout + fnext, format=evtformat)
else: # try exporting event
self.get_evt_data().write(fnout + fnext, format=evtformat)
else:
self.get_evt_data().write(fnout + fnext, format=evtformat)
# try exporting event via ObsPy
else: 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 # check for stations picked automatically as well as manually
# Prefer manual picks! # Prefer manual picks!
evtdata_copy = self.get_evt_data().copy() for i in range(len(picks)):
evtdata_org = self.get_evt_data() if picks[i].method_id == 'manual':
for i in range(len(evtdata_org.picks)): mstation = picks[i].waveform_id.station_code
if evtdata_org.picks[i].method_id == 'manual': mstation_ext = mstation + '_'
mstation = evtdata_org.picks[i].waveform_id.station_code for k in range(len(picks_copy)):
mstation_ext = mstation + '_' if ((picks_copy[k].waveform_id.station_code == mstation) or
for k in range(len(evtdata_copy.picks)): (picks_copy[k].waveform_id.station_code == mstation_ext)) and \
if evtdata_copy.picks[k].waveform_id.station_code == mstation or \ (picks_copy[k].method_id == 'auto'):
evtdata_copy.picks[k].waveform_id.station_code == mstation_ext and \ del picks_copy[k]
evtdata_copy.picks[k].method_id == 'auto': break
del evtdata_copy.picks[k] lendiff = len(picks) - len(picks_copy)
break
lendiff = len(evtdata_org.picks) - len(evtdata_copy.picks)
if lendiff is not 0: 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': if fnext == '.obs':
try: try:
evtdata_copy.write(fnout + fnext, format=evtformat) evtdata_copy.write(fnout + fnext, format=evtformat)
# write header afterwards # write header afterwards
evid = str(evtdata_org.resource_id).split('/')[1] 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 header = '# EQEVENT: Label: EQ%s Loc: X 0.00 Y 0.00 Z 10.00 OT 0.00 \n' % evid
nllocfile = open(fnout + fnext) nllocfile = open(fnout + fnext)
l = nllocfile.readlines() l = nllocfile.readlines()
nllocfile.close() nllocfile.close()
l.insert(0, header) l.insert(0, header)
nllocfile = open(fnout + fnext, 'w') nllocfile = open(fnout + fnext, 'w')
nllocfile.write("".join(l)) nllocfile.write("".join(l))
nllocfile.close() nllocfile.close()
except KeyError as e: except KeyError as e:
raise KeyError('''{0} export format raise KeyError('''{0} export format
not implemented: {1}'''.format(evtformat, e)) not implemented: {1}'''.format(evtformat, e))
if fnext == '.cnv': if fnext == '.cnv':
try: try:
evtdata_org.write(fnout + fnext, format=evtformat) velest.export(picks_copy, fnout + fnext, eventinfo=self.get_evt_data())
except KeyError as e: except KeyError as e:
raise KeyError('''{0} export format raise KeyError('''{0} export format
not implemented: {1}'''.format(evtformat, e)) not implemented: {1}'''.format(evtformat, e))
def getComp(self): def getComp(self):
""" """
@ -294,7 +366,7 @@ class Data(object):
except Exception as e: except Exception as e:
warnmsg += '{0}\n{1}\n'.format(fname, e) warnmsg += '{0}\n{1}\n'.format(fname, e)
except SacIOError as se: except SacIOError as se:
warnmsg += '{0}\n{1}\n'.format(fname, se) warnmsg += '{0}\n{1}\n'.format(fname, se)
if warnmsg: if warnmsg:
warnmsg = 'WARNING: unable to read\n' + warnmsg warnmsg = 'WARNING: unable to read\n' + warnmsg
print(warnmsg) print(warnmsg)
@ -359,21 +431,20 @@ class Data(object):
:raise OverwriteError: raises an OverwriteError if the picks list is :raise OverwriteError: raises an OverwriteError if the picks list is
not empty. The GUI will then ask for a decision. not empty. The GUI will then ask for a decision.
""" """
#firstonset = find_firstonset(picks) # firstonset = find_firstonset(picks)
# check for automatic picks # check for automatic picks
print("Writing phases to ObsPy-quakeml file") print("Writing phases to ObsPy-quakeml file")
for key in picks: for key in picks:
if picks[key]['P']['picker'] == 'auto': if picks[key]['P']['picker'] == 'auto':
print("Existing picks will be overwritten!") print("Existing picks will be overwritten!")
picks = picks_from_picksdict(picks) picks = picks_from_picksdict(picks)
break break
else: else:
if self.get_evt_data().picks: if self.get_evt_data().picks:
raise OverwriteError('Existing picks would be overwritten!') raise OverwriteError('Existing picks would be overwritten!')
break else:
else: picks = picks_from_picksdict(picks)
picks = picks_from_picksdict(picks) break
break
self.get_evt_data().picks = picks self.get_evt_data().picks = picks
# if 'smi:local' in self.getID() and firstonset: # if 'smi:local' in self.getID() and firstonset:
# fonset_str = firstonset.strftime('%Y_%m_%d_%H_%M_%S') # fonset_str = firstonset.strftime('%Y_%m_%d_%H_%M_%S')
@ -381,7 +452,6 @@ class Data(object):
# ID.convertIDToQuakeMLURI(authority_id=authority_id) # ID.convertIDToQuakeMLURI(authority_id=authority_id)
# self.get_evt_data().resource_id = ID # self.get_evt_data().resource_id = ID
def applyEvent(event): def applyEvent(event):
""" """
takes an `obspy.core.event.Event` object and applies all new takes an `obspy.core.event.Event` object and applies all new
@ -393,13 +463,13 @@ class Data(object):
else: else:
# prevent overwriting original pick information # prevent overwriting original pick information
event_old = self.get_evt_data() event_old = self.get_evt_data()
print(event_old.resource_id, event.resource_id)
if not 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( print("WARNING: Missmatch in event resource id's: {} and {}".format(
event_old.resource_id, event_old.resource_id,
event.resource_id)) event.resource_id))
picks = copy.deepcopy(event_old.picks) else:
event = merge_picks(event, picks) picks = copy.deepcopy(event_old.picks)
event = merge_picks(event, picks)
# apply event information from location # apply event information from location
event_old.update(event) event_old.update(event)
@ -408,7 +478,6 @@ class Data(object):
applydata[typ](data) applydata[typ](data)
self._new = False self._new = False
class GenericDataStructure(object): class GenericDataStructure(object):

View File

@ -3,293 +3,401 @@
defaults = {'rootpath': {'type': str, defaults = {'rootpath': {'type': str,
'tooltip': 'project path', 'tooltip': 'project path',
'value': ''}, 'value': '',
'namestring': 'Root path'},
'datapath': {'type': str, 'datapath': {'type': str,
'tooltip': 'data path', 'tooltip': 'data path',
'value': ''}, 'value': '',
'namestring': 'Data path'},
'database': {'type': str, 'database': {'type': str,
'tooltip': 'name of data base', 'tooltip': 'name of data base',
'value': ''}, 'value': '',
'namestring': 'Database path'},
'eventID': {'type': str, 'eventID': {'type': str,
'tooltip': 'event ID for single event processing (* for all events found in database)', 'tooltip': 'event ID for single event processing (* for all events found in database)',
'value': ''}, 'value': '',
'namestring': 'Event ID'},
'extent': {'type': str, 'extent': {'type': str,
'tooltip': 'extent of array ("local", "regional" or "global")', 'tooltip': 'extent of array ("local", "regional" or "global")',
'value': 'local'}, 'value': 'local',
'namestring': 'Array extent'},
'invdir': {'type': str, 'invdir': {'type': str,
'tooltip': 'full path to inventory or dataless-seed file', 'tooltip': 'full path to inventory or dataless-seed file',
'value': ''}, 'value': '',
'namestring': 'Inversion dir'},
'datastructure': {'type': str, 'datastructure': {'type': str,
'tooltip': 'choose data structure', 'tooltip': 'choose data structure',
'value': 'PILOT'}, 'value': 'PILOT',
'namestring': 'Datastructure'},
'apverbose': {'type': bool, 'apverbose': {'type': bool,
'tooltip': "choose 'True' or 'False' for terminal output", 'tooltip': "choose 'True' or 'False' for terminal output",
'value': True}, 'value': True,
'namestring': 'App. verbosity'},
'nllocbin': {'type': str, 'nllocbin': {'type': str,
'tooltip': 'path to NLLoc executable', 'tooltip': 'path to NLLoc executable',
'value': ''}, 'value': '',
'namestring': 'NLLoc bin path'},
'nllocroot': {'type': str, 'nllocroot': {'type': str,
'tooltip': 'root of NLLoc-processing directory', 'tooltip': 'root of NLLoc-processing directory',
'value': ''}, 'value': '',
'namestring': 'NLLoc root path'},
'phasefile': {'type': str, 'phasefile': {'type': str,
'tooltip': 'name of autoPyLoT-output phase file for NLLoc', 'tooltip': 'name of autoPyLoT-output phase file for NLLoc',
'value': 'AUTOPHASES.obs'}, 'value': 'AUTOPHASES.obs',
'namestring': 'Phase filename'},
'ctrfile': {'type': str, 'ctrfile': {'type': str,
'tooltip': 'name of autoPyLoT-output control file for NLLoc', '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, 'ttpatter': {'type': str,
'tooltip': 'pattern of NLLoc ttimes from grid', 'tooltip': 'pattern of NLLoc ttimes from grid',
'value': 'ttime'}, 'value': 'ttime',
'namestring': 'Traveltime pattern'},
'outpatter': {'type': str, 'outpatter': {'type': str,
'tooltip': 'pattern of NLLoc-output file', 'tooltip': 'pattern of NLLoc-output file',
'value': 'AUTOLOC_nlloc'}, 'value': 'AUTOLOC_nlloc',
'namestring': 'NLLoc output pattern'},
'vp': {'type': float, 'vp': {'type': float,
'tooltip': 'average P-wave velocity', 'tooltip': 'average P-wave velocity',
'value': 3530.}, 'value': 3530.,
'namestring': 'P-velocity'},
'rho': {'type': float, 'rho': {'type': float,
'tooltip': 'average rock density [kg/m^3]', 'tooltip': 'average rock density [kg/m^3]',
'value': 2500.}, 'value': 2500.,
'namestring': 'Density'},
'Qp': {'type': (float, float), 'Qp': {'type': (float, float),
'tooltip': 'quality factor for P waves (Qp*f^a); list(Qp, a)', '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, 'pstart': {'type': float,
'tooltip': 'start time [s] for calculating CF for P-picking', 'tooltip': 'start time [s] for calculating CF for P-picking (if TauPy:'
'value': 15.0}, ' seconds relative to estimated onset)',
'value': 15.0,
'namestring': 'P start'},
'pstop': {'type': float, 'pstop': {'type': float,
'tooltip': 'end time [s] for calculating CF for P-picking', 'tooltip': 'end time [s] for calculating CF for P-picking (if TauPy:'
'value': 60.0}, ' seconds relative to estimated onset)',
'value': 60.0,
'namestring': 'P stop'},
'sstart': {'type': float, 'sstart': {'type': float,
'tooltip': 'start time [s] relative to P-onset for calculating CF for S-picking', '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, 'sstop': {'type': float,
'tooltip': 'end time [s] after P-onset for calculating CF for S-picking', '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), 'bpz1': {'type': (float, float),
'tooltip': 'lower/upper corner freq. of first band pass filter Z-comp. [Hz]', '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), 'bpz2': {'type': (float, float),
'tooltip': 'lower/upper corner freq. of second band pass filter Z-comp. [Hz]', '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), 'bph1': {'type': (float, float),
'tooltip': 'lower/upper corner freq. of first band pass filter H-comp. [Hz]', '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), 'bph2': {'type': (float, float),
'tooltip': 'lower/upper corner freq. of second band pass filter z-comp. [Hz]', '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, 'algoP': {'type': str,
'tooltip': 'choose algorithm for P-onset determination (HOS, ARZ, or AR3)', 'tooltip': 'choose algorithm for P-onset determination (HOS, ARZ, or AR3)',
'value': 'HOS'}, 'value': 'HOS',
'namestring': 'P algorithm'},
'tlta': {'type': float, 'tlta': {'type': float,
'tooltip': 'for HOS-/AR-AIC-picker, length of LTA window [s]', 'tooltip': 'for HOS-/AR-AIC-picker, length of LTA window [s]',
'value': 7.0}, 'value': 7.0,
'namestring': 'LTA window'},
'hosorder': {'type': int, 'hosorder': {'type': int,
'tooltip': 'for HOS-picker, order of Higher Order Statistics', 'tooltip': 'for HOS-picker, order of Higher Order Statistics',
'value': 4}, 'value': 4,
'namestring': 'HOS order'},
'Parorder': {'type': int, 'Parorder': {'type': int,
'tooltip': 'for AR-picker, order of AR process of Z-component', 'tooltip': 'for AR-picker, order of AR process of Z-component',
'value': 2}, 'value': 2,
'namestring': 'AR order P'},
'tdet1z': {'type': float, 'tdet1z': {'type': float,
'tooltip': 'for AR-picker, length of AR determination window [s] for Z-component, 1st pick', '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, 'tpred1z': {'type': float,
'tooltip': 'for AR-picker, length of AR prediction window [s] for Z-component, 1st pick', '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, 'tdet2z': {'type': float,
'tooltip': 'for AR-picker, length of AR determination window [s] for Z-component, 2nd pick', '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, 'tpred2z': {'type': float,
'tooltip': 'for AR-picker, length of AR prediction window [s] for Z-component, 2nd pick', '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, 'addnoise': {'type': float,
'tooltip': 'add noise to seismogram for stable AR prediction', 'tooltip': 'add noise to seismogram for stable AR prediction',
'value': 0.001}, 'value': 0.001,
'namestring': 'Add noise'},
'tsnrz': {'type': (float, float, float, float), 'tsnrz': {'type': (float, float, float, float),
'tooltip': 'for HOS/AR, window lengths for SNR-and slope estimation [tnoise, tsafetey, tsignal, tslope] [s]', '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, 'pickwinP': {'type': float,
'tooltip': 'for initial AIC pick, length of P-pick window [s]', 'tooltip': 'for initial AIC pick, length of P-pick window [s]',
'value': 3.0}, 'value': 3.0,
'namestring': 'AIC window P'},
'Precalcwin': {'type': float, 'Precalcwin': {'type': float,
'tooltip': 'for HOS/AR, window length [s] for recalculation of CF (relative to 1st pick)', '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, 'aictsmooth': {'type': float,
'tooltip': 'for HOS/AR, take average of samples for smoothing of AIC-function [s]', '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, 'tsmoothP': {'type': float,
'tooltip': 'for HOS/AR, take average of samples for smoothing CF [s]', '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, 'ausP': {'type': float,
'tooltip': 'for HOS/AR, artificial uplift of samples (aus) of CF (P)', '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, 'nfacP': {'type': float,
'tooltip': 'for HOS/AR, noise factor for noise level determination (P)', 'tooltip': 'for HOS/AR, noise factor for noise level determination (P)',
'value': 1.3}, 'value': 1.3,
'namestring': 'Noise factor P'},
'algoS': {'type': str, 'algoS': {'type': str,
'tooltip': 'choose algorithm for S-onset determination (ARH or AR3)', 'tooltip': 'choose algorithm for S-onset determination (ARH or AR3)',
'value': 'ARH'}, 'value': 'ARH',
'namestring': 'S algorithm'},
'tdet1h': {'type': float, 'tdet1h': {'type': float,
'tooltip': 'for HOS/AR, length of AR-determination window [s], H-components, 1st pick', '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, 'tpred1h': {'type': float,
'tooltip': 'for HOS/AR, length of AR-prediction window [s], H-components, 1st pick', '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, 'tdet2h': {'type': float,
'tooltip': 'for HOS/AR, length of AR-determinaton window [s], H-components, 2nd pick', '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, 'tpred2h': {'type': float,
'tooltip': 'for HOS/AR, length of AR-prediction window [s], H-components, 2nd pick', '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, 'Sarorder': {'type': int,
'tooltip': 'for AR-picker, order of AR process of H-components', 'tooltip': 'for AR-picker, order of AR process of H-components',
'value': 4}, 'value': 4,
'namestring': 'AR order S'},
'Srecalcwin': {'type': float, 'Srecalcwin': {'type': float,
'tooltip': 'for AR-picker, window length [s] for recalculation of CF (2nd pick) (H)', '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, 'pickwinS': {'type': float,
'tooltip': 'for initial AIC pick, length of S-pick window [s]', '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), 'tsnrh': {'type': (float, float, float, float),
'tooltip': 'for ARH/AR3, window lengths for SNR-and slope estimation [tnoise, tsafetey, tsignal, tslope] [s]', '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, 'aictsmoothS': {'type': float,
'tooltip': 'for AIC-picker, take average of samples for smoothing of AIC-function [s]', '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, 'tsmoothS': {'type': float,
'tooltip': 'for AR-picker, take average of samples for smoothing CF [s] (S)', '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, 'ausS': {'type': float,
'tooltip': 'for HOS/AR, artificial uplift of samples (aus) of CF (S)', '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, 'nfacS': {'type': float,
'tooltip': 'for AR-picker, noise factor for noise level determination (S)', 'tooltip': 'for AR-picker, noise factor for noise level determination (S)',
'value': 1.5}, 'value': 1.5,
'namestring': 'Noise factor S'},
'minfmweight': {'type': int, 'minfmweight': {'type': int,
'tooltip': 'minimum required P weight for first-motion determination', 'tooltip': 'minimum required P weight for first-motion determination',
'value': 1}, 'value': 1,
'namestring': 'Min. P weight'},
'minFMSNR': {'type': float, 'minFMSNR': {'type': float,
'tooltip': 'miniumum required SNR for first-motion determination', 'tooltip': 'miniumum required SNR for first-motion determination',
'value': 2.}, 'value': 2.,
'namestring': 'Min SNR'},
'fmpickwin': {'type': float, 'fmpickwin': {'type': float,
'tooltip': 'pick window around P onset for calculating zero crossings', '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), 'timeerrorsP': {'type': (float, float, float, float),
'tooltip': 'discrete time errors [s] corresponding to picking weights [0 1 2 3] for P', '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), 'timeerrorsS': {'type': (float, float, float, float),
'tooltip': 'discrete time errors [s] corresponding to picking weights [0 1 2 3] for S', '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, 'minAICPslope': {'type': float,
'tooltip': 'below this slope [counts/s] the initial P pick is rejected', '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, 'minAICPSNR': {'type': float,
'tooltip': 'below this SNR the initial P pick is rejected', 'tooltip': 'below this SNR the initial P pick is rejected',
'value': 1.1}, 'value': 1.1,
'namestring': 'Min. SNR P'},
'minAICSslope': {'type': float, 'minAICSslope': {'type': float,
'tooltip': 'below this slope [counts/s] the initial S pick is rejected', 'tooltip': 'below this slope [counts/s] the initial S pick is rejected',
'value': 1.}, 'value': 1.,
'namestring': 'Min. slope S'},
'minAICSSNR': {'type': float, 'minAICSSNR': {'type': float,
'tooltip': 'below this SNR the initial S pick is rejected', 'tooltip': 'below this SNR the initial S pick is rejected',
'value': 1.5}, 'value': 1.5,
'namestring': 'Min. SNR S'},
'minsiglength': {'type': float, 'minsiglength': {'type': float,
'tooltip': 'length of signal part for which amplitudes must exceed noiselevel [s]', 'tooltip': 'length of signal part for which amplitudes must exceed noiselevel [s]',
'value': 1.}, 'value': 1.,
'namestring': 'Min. signal length'},
'noisefactor': {'type': float, 'noisefactor': {'type': float,
'tooltip': 'noiselevel*noisefactor=threshold', 'tooltip': 'noiselevel*noisefactor=threshold',
'value': 1.0}, 'value': 1.0,
'namestring': 'Noise factor'},
'minpercent': {'type': float, 'minpercent': {'type': float,
'tooltip': 'required percentage of amplitudes exceeding threshold', 'tooltip': 'required percentage of amplitudes exceeding threshold',
'value': 10.}, 'value': 10.,
'namestring': 'Min amplitude [%]'},
'zfac': {'type': float, 'zfac': {'type': float,
'tooltip': 'P-amplitude must exceed at least zfac times RMS-S amplitude', 'tooltip': 'P-amplitude must exceed at least zfac times RMS-S amplitude',
'value': 1.5}, 'value': 1.5,
'namestring': 'Z factor'},
'mdttolerance': {'type': float, 'mdttolerance': {'type': float,
'tooltip': 'maximum allowed deviation of P picks from median [s]', 'tooltip': 'maximum allowed deviation of P picks from median [s]',
'value': 6.0}, 'value': 6.0,
'namestring': 'Median tolerance'},
'wdttolerance': {'type': float, 'wdttolerance': {'type': float,
'tooltip': 'maximum allowed deviation from Wadati-diagram', '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), 'WAscaling': {'type': (float, float, float),
'tooltip': 'Scaling relation (log(Ao)+Alog(r)+Br+C) of Wood-Anderson amplitude Ao [nm] \ 'tooltip': 'Scaling relation (log(Ao)+Alog(r)+Br+C) of Wood-Anderson amplitude Ao [nm] \
If zeros are set, original Richter magnitude is calculated!', If zeros are set, original Richter magnitude is calculated!',
'value': (0., 0., 0.)}, 'value': (0., 0., 0.),
'namestring': ('Wood-Anderson scaling', '', '', '')},
'magscaling': {'type': (float, float), 'magscaling': {'type': (float, float),
'tooltip': 'Scaling relation for derived local magnitude [a*Ml+b]. \ 'tooltip': 'Scaling relation for derived local magnitude [a*Ml+b]. \
If zeros are set, no scaling of network magnitude is applied!', If zeros are set, no scaling of network magnitude is applied!',
'value': (0., 0.)} 'value': (0., 0.),
} 'namestring': ('Local mag. scaling', '', '')},
settings_main={ 'minfreq': {'type': (float, float),
'dirs':[ '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', 'rootpath',
'datapath', 'datapath',
'database', 'database',
@ -297,34 +405,41 @@ settings_main={
'invdir', 'invdir',
'datastructure', 'datastructure',
'apverbose'], 'apverbose'],
'nlloc':[ 'nlloc': [
'nllocbin', 'nllocbin',
'nllocroot', 'nllocroot',
'phasefile', 'phasefile',
'ctrfile', 'ctrfile',
'ttpatter', 'ttpatter',
'outpatter'], 'outpatter'],
'smoment':[ 'smoment': [
'vp', 'vp',
'rho', 'rho',
'Qp'], 'Qp'],
'localmag':[ 'localmag': [
'WAscaling', 'WAscaling',
'magscaling'], 'magscaling'],
'pick':[ 'filter': [
'minfreq',
'maxfreq',
'filter_order',
'filter_type'],
'pick': [
'extent', 'extent',
'pstart', 'pstart',
'pstop', 'pstop',
'sstart', 'sstart',
'sstop', 'sstop',
'use_taup',
'taup_model',
'bpz1', 'bpz1',
'bpz2', 'bpz2',
'bph1', 'bph1',
'bph2'] 'bph2']
} }
settings_special_pick={ settings_special_pick = {
'z':[ 'z': [
'algoP', 'algoP',
'tlta', 'tlta',
'hosorder', 'hosorder',
@ -341,7 +456,7 @@ settings_special_pick={
'tsmoothP', 'tsmoothP',
'ausP', 'ausP',
'nfacP'], 'nfacP'],
'h':[ 'h': [
'algoS', 'algoS',
'tdet1h', 'tdet1h',
'tpred1h', 'tpred1h',
@ -355,11 +470,11 @@ settings_special_pick={
'tsmoothS', 'tsmoothS',
'ausS', 'ausS',
'nfacS'], 'nfacS'],
'fm':[ 'fm': [
'minfmweight', 'minfmweight',
'minFMSNR', 'minFMSNR',
'fmpickwin'], 'fmpickwin'],
'quality':[ 'quality': [
'timeerrorsP', 'timeerrorsP',
'timeerrorsS', 'timeerrorsS',
'minAICPslope', 'minAICPslope',
@ -371,5 +486,6 @@ settings_special_pick={
'minpercent', 'minpercent',
'zfac', 'zfac',
'mdttolerance', 'mdttolerance',
'wdttolerance'] 'wdttolerance',
'jackfactor'],
} }

View File

@ -1,8 +1,9 @@
#!/usr/bin/env python #!/usr/bin/env python
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
from pylot.core.io import default_parameters
from pylot.core.util.errors import ParameterError from pylot.core.util.errors import ParameterError
import default_parameters
class PylotParameter(object): class PylotParameter(object):
''' '''
@ -69,13 +70,13 @@ class PylotParameter(object):
# Set default values of parameter names # Set default values of parameter names
def __init_default_paras(self): def __init_default_paras(self):
parameters=default_parameters.defaults parameters = default_parameters.defaults
self.__defaults = parameters self.__defaults = parameters
def __init_subsettings(self): def __init_subsettings(self):
self._settings_main=default_parameters.settings_main self._settings_main = default_parameters.settings_main
self._settings_special_pick=default_parameters.settings_special_pick self._settings_special_pick = default_parameters.settings_special_pick
# String representation of the object # String representation of the object
def __repr__(self): def __repr__(self):
return "PylotParameter('%s')" % self.__filename return "PylotParameter('%s')" % self.__filename
@ -107,7 +108,7 @@ class PylotParameter(object):
yield key, value yield key, value
def hasParam(self, parameter): def hasParam(self, parameter):
if self.__parameter.has_key(parameter): if parameter in self.__parameter.keys():
return True return True
return False return False
@ -136,12 +137,13 @@ class PylotParameter(object):
return self._settings_special_pick return self._settings_special_pick
def get_all_para_names(self): 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()['dirs']
all_names += self.get_main_para_names()['nlloc'] all_names += self.get_main_para_names()['nlloc']
all_names += self.get_main_para_names()['smoment'] all_names += self.get_main_para_names()['smoment']
all_names += self.get_main_para_names()['localmag'] 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()['z']
all_names += self.get_special_para_names()['h'] all_names += self.get_special_para_names()['h']
all_names += self.get_special_para_names()['fm'] 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 = 'Type check failed for param: {}, is type: {}, expected type:{}'
message = message.format(param, is_type, expect_type) message = message.format(param, is_type, expect_type)
print(Warning(message)) print(Warning(message))
def setParamKV(self, param, value): def setParamKV(self, param, value):
self.__setitem__(param, value) self.__setitem__(param, value)
def setParam(self, **kwargs): def setParam(self, **kwargs):
for key in kwargs: for key in kwargs:
self.__setitem__(key, kwargs[key]) self.__setitem__(key, kwargs[key])
@staticmethod @staticmethod
def _printParameterError(errmsg): def _printParameterError(errmsg):
print('ParameterError:\n non-existent parameter %s' % errmsg) print('ParameterError:\n non-existent parameter %s' % errmsg)
@ -171,7 +173,7 @@ class PylotParameter(object):
defaults = self.get_defaults() defaults = self.get_defaults()
for param in defaults: for param in defaults:
self.setParamKV(param, defaults[param]['value']) self.setParamKV(param, defaults[param]['value'])
def from_file(self, fnin=None): def from_file(self, fnin=None):
if not fnin: if not fnin:
if self.__filename is not None: if self.__filename is not None:
@ -208,7 +210,10 @@ class PylotParameter(object):
vallist = value.strip().split(' ') vallist = value.strip().split(' ')
val = [] val = []
for val0 in vallist: for val0 in vallist:
val0 = float(val0) try:
val0 = float(val0)
except:
pass
val.append(val0) val.append(val0)
else: else:
val = str(value.strip()) val = str(value.strip())
@ -221,9 +226,9 @@ class PylotParameter(object):
# for key, value in self.iteritems(): # for key, value in self.iteritems():
# lines.append('{key}\t{value}\n'.format(key=key, value=value)) # lines.append('{key}\t{value}\n'.format(key=key, value=value))
# fid_out.writelines(lines) # fid_out.writelines(lines)
header = ('%This is a parameter input file for PyLoT/autoPyLoT.\n'+ header = ('%This is a parameter input file for PyLoT/autoPyLoT.\n' +
'%All main and special settings regarding data handling\n'+ '%All main and special settings regarding data handling\n' +
'%and picking are to be set here!\n'+ '%and picking are to be set here!\n' +
'%Parameters are optimized for %{} data sets!\n'.format(self.get_main_para_names()['pick'][0])) '%Parameters are optimized for %{} data sets!\n'.format(self.get_main_para_names()['pick'][0]))
separator = '%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n' separator = '%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n'
@ -236,16 +241,18 @@ class PylotParameter(object):
'parameters for seismic moment estimation', separator) 'parameters for seismic moment estimation', separator)
self.write_section(fid_out, self.get_main_para_names()['localmag'], self.write_section(fid_out, self.get_main_para_names()['localmag'],
'settings local magnitude', separator) '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'], self.write_section(fid_out, self.get_main_para_names()['pick'],
'common settings picker', separator) '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')) '%!!Edit the following only if you know what you are doing!!%\n'))
self.write_section(fid_out, self.get_special_para_names()['z'], self.write_section(fid_out, self.get_special_para_names()['z'],
'Z-component', None) 'Z-component', None)
self.write_section(fid_out, self.get_special_para_names()['h'], self.write_section(fid_out, self.get_special_para_names()['h'],
'H-components', None) 'H-components', None)
self.write_section(fid_out, self.get_special_para_names()['fm'], 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'], self.write_section(fid_out, self.get_special_para_names()['quality'],
'quality assessment', None) 'quality assessment', None)
@ -261,7 +268,7 @@ class PylotParameter(object):
if type(value) == list or type(value) == tuple: if type(value) == list or type(value) == tuple:
value_tmp = '' value_tmp = ''
for vl in value: for vl in value:
value_tmp+= '{} '.format(vl) value_tmp += '{} '.format(vl)
value = value_tmp value = value_tmp
tooltip = self.get_defaults()[name]['tooltip'] tooltip = self.get_defaults()[name]['tooltip']
if not len(str(value)) > l_val: if not len(str(value)) > l_val:
@ -277,7 +284,7 @@ class PylotParameter(object):
ttip = '%{:<{}}\n'.format(tooltip, l_ttip) ttip = '%{:<{}}\n'.format(tooltip, l_ttip)
else: else:
ttip = '%{}\n'.format(tooltip) ttip = '%{}\n'.format(tooltip)
line = value+name+ttip line = value + name + ttip
fid.write(line) fid.write(line)
@ -335,12 +342,13 @@ class FilterOptions(object):
def parseFilterOptions(self): def parseFilterOptions(self):
if self: if self:
robject = {'type': self.getFilterType(), 'corners': self.getOrder()} 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['freqmin'] = self.getFreq()[0]
robject['freqmax'] = self.getFreq()[1] robject['freqmax'] = self.getFreq()[1]
else: elif self.getFilterType() == 'highpass':
robject['freq'] = self.getFreq() if type(self.getFreq()) is \ robject['freq'] = self.getFreq()[0]
float else self.getFreq()[0] elif self.getFilterType() == 'lowpass':
robject['freq'] = self.getFreq()[1]
return robject return robject
return None return None

View File

@ -2,19 +2,23 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
import glob import glob
import obspy.core.event as ope
import os import os
import scipy.io as sio
import warnings 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.inputs import PylotParameter
from pylot.core.io.location import create_arrival, create_event, \ from pylot.core.io.location import create_event, \
create_magnitude, create_origin, create_pick create_magnitude
from pylot.core.pick.utils import select_for_phase from pylot.core.pick.utils import select_for_phase
from pylot.core.util.utils import getOwner, full_range, four_digits from pylot.core.util.utils import getOwner, full_range, four_digits
def add_amplitudes(event, amplitudes): def add_amplitudes(event, amplitudes):
amplitude_list = [] amplitude_list = []
for pick in event.picks: for pick in event.picks:
@ -33,6 +37,7 @@ def add_amplitudes(event, amplitudes):
event.amplitudes = amplitude_list event.amplitudes = amplitude_list
return event return event
def readPILOTEvent(phasfn=None, locfn=None, authority_id='RUB', **kwargs): def readPILOTEvent(phasfn=None, locfn=None, authority_id='RUB', **kwargs):
""" """
readPILOTEvent - function readPILOTEvent - function
@ -189,26 +194,35 @@ def picksdict_from_picks(evt):
PyLoT PyLoT
:param evt: Event object contain all available information :param evt: Event object contain all available information
:type evt: `~obspy.core.event.Event` :type evt: `~obspy.core.event.Event`
:return: pick dictionary :return: pick dictionary (auto and manual)
""" """
picks = {} picksdict = {
'manual': {},
'auto': {}
}
for pick in evt.picks: for pick in evt.picks:
phase = {} phase = {}
station = pick.waveform_id.station_code station = pick.waveform_id.station_code
channel = pick.waveform_id.channel_code channel = pick.waveform_id.channel_code
network = pick.waveform_id.network_code network = pick.waveform_id.network_code
try:
onsets = picks[station]
except KeyError as e:
#print(e)
onsets = {}
mpp = pick.time mpp = pick.time
spe = pick.time_errors.uncertainty 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: try:
lpp = mpp + pick.time_errors.upper_uncertainty lpp = mpp + pick.time_errors.upper_uncertainty
epp = mpp - pick.time_errors.lower_uncertainty epp = mpp - pick.time_errors.lower_uncertainty
except TypeError as e: except TypeError as e:
msg = e.message + ',\n falling back to symmetric uncertainties' msg = e + ',\n falling back to symmetric uncertainties'
warnings.warn(msg) warnings.warn(msg)
lpp = mpp + spe lpp = mpp + spe
epp = mpp - spe epp = mpp - spe
@ -218,17 +232,12 @@ def picksdict_from_picks(evt):
phase['spe'] = spe phase['spe'] = spe
phase['channel'] = channel phase['channel'] = channel
phase['network'] = network phase['network'] = network
try: phase['picker'] = picker
picker = str(pick.method_id)
if picker.startswith('smi:local/'):
picker = picker.split('smi:local/')[1]
phase['picker'] = picker
except IndexError:
pass
onsets[pick.phase_hint] = phase.copy() onsets[pick.phase_hint] = phase.copy()
picks[station] = onsets.copy() picksdict[picker][station] = onsets.copy()
return picks return picksdict
def picks_from_picksdict(picks, creation_info=None): def picks_from_picksdict(picks, creation_info=None):
picks_list = list() picks_list = list()
@ -238,8 +247,8 @@ def picks_from_picksdict(picks, creation_info=None):
continue continue
onset = phase['mpp'] onset = phase['mpp']
try: try:
ccode = phase['channel'] ccode = phase['channel']
ncode = phase['network'] ncode = phase['network']
except: except:
continue continue
pick = ope.Pick() pick = ope.Pick()
@ -253,8 +262,8 @@ def picks_from_picksdict(picks, creation_info=None):
lpp = phase['lpp'] lpp = phase['lpp']
pick.time_errors.lower_uncertainty = onset - epp pick.time_errors.lower_uncertainty = onset - epp
pick.time_errors.upper_uncertainty = lpp - onset pick.time_errors.upper_uncertainty = lpp - onset
except KeyError as e: except (KeyError, TypeError) as e:
warnings.warn(e.message, RuntimeWarning) warnings.warn(str(e), RuntimeWarning)
try: try:
picker = phase['picker'] picker = phase['picker']
except KeyError as e: except KeyError as e:
@ -263,8 +272,8 @@ def picks_from_picksdict(picks, creation_info=None):
pick.phase_hint = label pick.phase_hint = label
pick.method_id = ope.ResourceIdentifier(id=picker) pick.method_id = ope.ResourceIdentifier(id=picker)
pick.waveform_id = ope.WaveformStreamID(station_code=station, pick.waveform_id = ope.WaveformStreamID(station_code=station,
channel_code=ccode, channel_code=ccode,
network_code=ncode) network_code=ncode)
try: try:
polarity = phase['fm'] polarity = phase['fm']
if polarity == 'U' or '+': if polarity == 'U' or '+':
@ -274,7 +283,7 @@ def picks_from_picksdict(picks, creation_info=None):
else: else:
pick.polarity = 'undecidable' pick.polarity = 'undecidable'
except KeyError as e: 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 pass
else: else:
raise e raise e
@ -286,7 +295,7 @@ def reassess_pilot_db(root_dir, db_dir, out_dir=None, fn_param=None, verbosity=0
import glob import glob
db_root = os.path.join(root_dir, db_dir) 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: for evt in evt_list:
if verbosity > 0: 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) 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): def reassess_pilot_event(root_dir, db_dir, event_id, out_dir=None, fn_param=None, verbosity=0):
from obspy import read 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 from pylot.core.pick.utils import earllatepicker
if fn_param is None: if fn_param is None:
import pylot.core.util.defaults as defaults
fn_param = defaults.AUTOMATIC_DEFAULTS fn_param = defaults.AUTOMATIC_DEFAULTS
default = PylotParameter(fn_param, verbosity) 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: except Exception as e:
if 'No file matching file pattern:' in e.message: if 'No file matching file pattern:' in e.message:
if verbosity > 0: 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') datacheck.append(fn_pattern + ' (no data)\n')
continue continue
else: 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('nfac{0}'.format(phase)),
default.get('tsnrz' if phase == 'P' else 'tsnrh'), default.get('tsnrz' if phase == 'P' else 'tsnrh'),
Pick1=rel_pick, Pick1=rel_pick,
iplot=None, iplot=0,
verbosity=0) verbosity=0)
if epp is None or lpp is None: if epp is None or lpp is None:
continue 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) os.makedirs(out_dir)
fnout_prefix = os.path.join(out_dir, 'PyLoT_{0}.'.format(event_id)) fnout_prefix = os.path.join(out_dir, 'PyLoT_{0}.'.format(event_id))
evt.write(fnout_prefix + 'xml', format='QUAKEML') 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 Function of methods to write phases to the following standard file
formats used for locating earthquakes: 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 :param: eventinfo, optional, needed for VELEST-cnv file
and FOCMEC- and HASH-input files and FOCMEC- and HASH-input files
:type: `obspy.core.event.Event` object :type: `obspy.core.event.Event` object
""" """
if fformat == 'NLLoc': if fformat == 'NLLoc':
print ("Writing phases to %s for NLLoc" % filename) print("Writing phases to %s for NLLoc" % filename)
fid = open("%s" % filename, 'w') fid = open("%s" % filename, 'w')
# write header # write header
fid.write('# EQEVENT: %s Label: EQ%s Loc: X 0.00 Y 0.00 Z 10.00 OT 0.00 \n' % 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 ss = onset.second
ms = onset.microsecond ms = onset.microsecond
ss_ms = ss + ms / 1000000.0 ss_ms = ss + ms / 1000000.0
pweight = 1 # use pick pweight = 1 # use pick
try: try:
if arrivals[key]['P']['weight'] >= 4: if arrivals[key]['P']['weight'] >= 4:
pweight = 0 # do not use pick pweight = 0 # do not use pick
@ -475,7 +483,7 @@ def writephases(arrivals, fformat, filename, parameter, eventinfo=None):
ss = onset.second ss = onset.second
ms = onset.microsecond ms = onset.microsecond
ss_ms = ss + ms / 1000000.0 ss_ms = ss + ms / 1000000.0
sweight = 1 # use pick sweight = 1 # use pick
try: try:
if arrivals[key]['S']['weight'] >= 4: if arrivals[key]['S']['weight'] >= 4:
sweight = 0 # do not use pick sweight = 0 # do not use pick
@ -493,15 +501,15 @@ def writephases(arrivals, fformat, filename, parameter, eventinfo=None):
fid.close() fid.close()
elif fformat == 'HYPO71': elif fformat == 'HYPO71':
print ("Writing phases to %s for HYPO71" % filename) print("Writing phases to %s for HYPO71" % filename)
fid = open("%s" % filename, 'w') fid = open("%s" % filename, 'w')
# write header # write header
fid.write(' %s\n' % fid.write(' %s\n' %
parameter.get('eventID')) parameter.get('eventID'))
for key in arrivals: for key in arrivals:
if arrivals[key]['P']['weight'] < 4: if arrivals[key]['P']['weight'] < 4:
stat = key 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] stat = stat[1:5]
Ponset = arrivals[key]['P']['mpp'] Ponset = arrivals[key]['P']['mpp']
Sonset = arrivals[key]['S']['mpp'] Sonset = arrivals[key]['S']['mpp']
@ -541,41 +549,39 @@ def writephases(arrivals, fformat, filename, parameter, eventinfo=None):
elif sweight >= 2: elif sweight >= 2:
sstr = 'E' sstr = 'E'
fid.write('%-4s%sP%s%d %02d%02d%02d%02d%02d%5.2f %s%sS %d %s\n' % (stat, fid.write('%-4s%sP%s%d %02d%02d%02d%02d%02d%5.2f %s%sS %d %s\n' % (stat,
pstr, pstr,
fm, fm,
pweight, pweight,
year, year,
month, month,
day, day,
hh, hh,
mm, mm,
ss_ms, ss_ms,
Sss_ms, Sss_ms,
sstr, sstr,
sweight, sweight,
Ao)) Ao))
else: else:
fid.write('%-4s%sP%s%d %02d%02d%02d%02d%02d%5.2f %s\n' % (stat, fid.write('%-4s%sP%s%d %02d%02d%02d%02d%02d%5.2f %s\n' % (stat,
pstr, pstr,
fm, fm,
pweight, pweight,
year, year,
month, month,
day, day,
hh, hh,
mm, mm,
ss_ms, ss_ms,
Ao)) Ao))
fid.close() fid.close()
elif fformat == 'HYPOSAT': elif fformat == 'HYPOSAT':
print ("Writing phases to %s for HYPOSAT" % filename) print("Writing phases to %s for HYPOSAT" % filename)
fid = open("%s" % filename, 'w') fid = open("%s" % filename, 'w')
# write header # write header
fid.write('%s, event %s \n' % (parameter.get('database'), parameter.get('eventID'))) fid.write('%s, event %s \n' % (parameter.get('database'), parameter.get('eventID')))
errP = parameter.get('timeerrorsP')
errS = parameter.get('timeerrorsS')
for key in arrivals: for key in arrivals:
# P onsets # P onsets
if arrivals[key].has_key('P'): if arrivals[key].has_key('P'):
@ -592,7 +598,7 @@ def writephases(arrivals, fformat, filename, parameter, eventinfo=None):
# use symmetrized picking error as std # use symmetrized picking error as std
# (read the HYPOSAT manual) # (read the HYPOSAT manual)
pstd = arrivals[key]['P']['spe'] 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)) % (key, pyear, pmonth, pday, phh, pmm, Pss, pstd))
# S onsets # S onsets
if arrivals[key].has_key('S') and arrivals[key]['S']: 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 sms = Sonset.microsecond
Sss = sss + sms / 1000000.0 Sss = sss + sms / 1000000.0
sstd = arrivals[key]['S']['spe'] 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)) % (key, syear, smonth, sday, shh, smm, Sss, sstd))
fid.close() fid.close()
elif fformat == 'VELEST': elif fformat == 'VELEST':
print ("Writing phases to %s for VELEST" % filename) print("Writing phases to %s for VELEST" % filename)
fid = open("%s" % filename, 'w') fid = open("%s" % filename, 'w')
# get informations needed in cnv-file # get informations needed in cnv-file
# check, whether latitude is N or S and longitude is E or W # 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: if eventsource['latitude'] < 0:
cns = 'S' cns = 'S'
else: else:
@ -628,14 +638,14 @@ def writephases(arrivals, fformat, filename, parameter, eventinfo=None):
# get last two integers of origin year # get last two integers of origin year
stime = eventsource['time'] stime = eventsource['time']
if stime.year - 2000 >= 0: if stime.year - 2000 >= 0:
syear = stime.year - 2000 syear = stime.year - 2000
else: else:
syear = stime.year - 1900 syear = stime.year - 1900
ifx = 0 # default value, see VELEST manual, pp. 22-23 ifx = 0 # default value, see VELEST manual, pp. 22-23
# write header # 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' % ( 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'], syear, stime.month, stime.day, stime.hour, stime.minute, stime.second, eventsource['latitude'],
cns, eventsource['longitude'], cew, eventsource['depth'],eventinfo.magnitudes[0]['mag'], ifx)) cns, eventsource['longitude'], cew, eventsource['depth'], eventinfo.magnitudes[0]['mag'], ifx))
n = 0 n = 0
for key in arrivals: for key in arrivals:
# P onsets # P onsets
@ -643,33 +653,33 @@ def writephases(arrivals, fformat, filename, parameter, eventinfo=None):
if arrivals[key]['P']['weight'] < 4: if arrivals[key]['P']['weight'] < 4:
n += 1 n += 1
stat = key 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] stat = stat[1:5]
Ponset = arrivals[key]['P']['mpp'] Ponset = arrivals[key]['P']['mpp']
Pweight = arrivals[key]['P']['weight'] 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: 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: else:
fid.write('%-4sP%d%6.2f\n' % (stat, Pweight, Prt)) fid.write('%-4sP%d%6.2f\n' % (stat, Pweight, Prt))
# S onsets # S onsets
if arrivals[key].has_key('S'): if arrivals[key].has_key('S'):
if arrivals[key]['S']['weight'] < 4: if arrivals[key]['S']['weight'] < 4:
n += 1 n += 1
stat = key 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] stat = stat[1:5]
Sonset = arrivals[key]['S']['mpp'] Sonset = arrivals[key]['S']['mpp']
Sweight = arrivals[key]['S']['weight'] 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: 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: else:
fid.write('%-4sS%d%6.2f\n' % (stat, Sweight, Srt)) fid.write('%-4sS%d%6.2f\n' % (stat, Sweight, Srt))
fid.close() fid.close()
elif fformat == 'hypoDD': elif fformat == 'hypoDD':
print ("Writing phases to %s for hypoDD" % filename) print("Writing phases to %s for hypoDD" % filename)
fid = open("%s" % filename, 'w') fid = open("%s" % filename, 'w')
# get event information needed for hypoDD-phase file # get event information needed for hypoDD-phase file
eventsource = eventinfo.origins[0] eventsource = eventinfo.origins[0]
@ -678,59 +688,62 @@ def writephases(arrivals, fformat, filename, parameter, eventinfo=None):
hddID = event.split('.')[0][1:5] hddID = event.split('.')[0][1:5]
# write header # 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' % ( 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, stime.year, stime.month, stime.day, stime.hour, stime.minute, stime.second,
eventsource['latitude'], eventsource['longitude'], eventsource['depth'] / 1000, eventsource['latitude'], eventsource['longitude'], eventsource['depth'] / 1000,
eventinfo.magnitudes[0]['mag'], eventsource['quality']['standard_error'], hddID)) eventinfo.magnitudes[0]['mag'], eventsource['quality']['standard_error'], hddID))
for key in arrivals: for key in arrivals:
if arrivals[key].has_key('P'): if arrivals[key].has_key('P'):
# P onsets # P onsets
if arrivals[key]['P']['weight'] < 4: if arrivals[key]['P']['weight'] < 4:
Ponset = arrivals[key]['P']['mpp'] Ponset = arrivals[key]['P']['mpp']
Prt = Ponset - stime # onset time relative to source time Prt = Ponset - stime # onset time relative to source time
fid.write('%s %6.3f 1 P\n' % (key, Prt)) fid.write('%s %6.3f 1 P\n' % (key, Prt))
# S onsets # S onsets
if arrivals[key]['S']['weight'] < 4: if arrivals[key]['S']['weight'] < 4:
Sonset = arrivals[key]['S']['mpp'] Sonset = arrivals[key]['S']['mpp']
Srt = Sonset - stime # onset time relative to source time Srt = Sonset - stime # onset time relative to source time
fid.write('%-5s %6.3f 1 S\n' % (key, Srt)) fid.write('%-5s %6.3f 1 S\n' % (key, Srt))
fid.close() fid.close()
elif fformat == 'FOCMEC': elif fformat == 'FOCMEC':
print ("Writing phases to %s for FOCMEC" % filename) print("Writing phases to %s for FOCMEC" % filename)
fid = open("%s" % filename, 'w') fid = open("%s" % filename, 'w')
# get event information needed for FOCMEC-input file # get event information needed for FOCMEC-input file
eventsource = eventinfo.origins[0] eventsource = eventinfo.origins[0]
stime = eventsource['time'] stime = eventsource['time']
# write header line including event information # 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'), 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, stime.year, stime.month, stime.day,
eventsource['latitude'], eventsource['longitude'], eventsource['depth'] / 1000, stime.hour, stime.minute, stime.second,
eventinfo.magnitudes[0]['mag'])) eventsource['latitude'],
eventsource['longitude'],
eventsource['depth'] / 1000,
eventinfo.magnitudes[0]['mag']))
picks = eventinfo.picks picks = eventinfo.picks
for key in arrivals: for key in arrivals:
if arrivals[key].has_key('P'): if arrivals[key].has_key('P'):
if arrivals[key]['P']['weight'] < 4 and arrivals[key]['P']['fm'] is not None: if arrivals[key]['P']['weight'] < 4 and arrivals[key]['P']['fm'] is not None:
stat = key stat = key
for i in range(len(picks)): for i in range(len(picks)):
station = picks[i].waveform_id.station_code station = picks[i].waveform_id.station_code
if station == stat: if station == stat:
# get resource ID # get resource ID
resid_picks = picks[i].get('resource_id') resid_picks = picks[i].get('resource_id')
# find same ID in eventinfo # find same ID in eventinfo
# there it is the pick_id!! # there it is the pick_id!!
for j in range(len(eventinfo.origins[0].arrivals)): for j in range(len(eventinfo.origins[0].arrivals)):
resid_eventinfo = eventinfo.origins[0].arrivals[j].get('pick_id') resid_eventinfo = eventinfo.origins[0].arrivals[j].get('pick_id')
if resid_eventinfo == resid_picks and eventinfo.origins[0].arrivals[j].phase == 'P': if resid_eventinfo == resid_picks and eventinfo.origins[0].arrivals[j].phase == 'P':
if len(stat) > 4: # FOCMEC handles only 4-string station IDs if len(stat) > 4: # FOCMEC handles only 4-string station IDs
stat = stat[1:5] stat = stat[1:5]
az = eventinfo.origins[0].arrivals[j].get('azimuth') az = eventinfo.origins[0].arrivals[j].get('azimuth')
inz = eventinfo.origins[0].arrivals[j].get('takeoff_angle') inz = eventinfo.origins[0].arrivals[j].get('takeoff_angle')
fid.write('%-4s %6.2f %6.2f%s \n' % (stat, fid.write('%-4s %6.2f %6.2f%s \n' % (stat,
az, az,
inz, inz,
arrivals[key]['P']['fm'])) arrivals[key]['P']['fm']))
break break
fid.close() fid.close()
@ -739,9 +752,9 @@ def writephases(arrivals, fformat, filename, parameter, eventinfo=None):
# HASH-driver 1 and 2 (see HASH manual!) # HASH-driver 1 and 2 (see HASH manual!)
filename1 = filename + 'drv1' + '.phase' filename1 = filename + 'drv1' + '.phase'
filename2 = filename + 'drv2' + '.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') 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') fid2 = open("%s" % filename2, 'w')
# get event information needed for HASH-input file # get event information needed for HASH-input file
eventsource = eventinfo.origins[0] eventsource = eventinfo.origins[0]
@ -756,26 +769,32 @@ def writephases(arrivals, fformat, filename, parameter, eventinfo=None):
erz = eventsource.depth_errors['uncertainty'] erz = eventsource.depth_errors['uncertainty']
stime = eventsource['time'] stime = eventsource['time']
if stime.year - 2000 >= 0: if stime.year - 2000 >= 0:
syear = stime.year - 2000 syear = stime.year - 2000
else: else:
syear = stime.year - 1900 syear = stime.year - 1900
picks = eventinfo.picks picks = eventinfo.picks
# write header line including event information # write header line including event information
# for HASH-driver 1 # 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, 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, stime.month, stime.day,
latdeg, latmin, londeg, lonmin, eventsource['depth'], stime.hour, stime.minute,
eventinfo.magnitudes[0]['mag'], erh, erz, stime.second,
hashID)) latdeg, latmin, londeg,
lonmin, eventsource['depth'],
eventinfo.magnitudes[0][
'mag'], erh, erz,
hashID))
# write header line including event information # write header line including event information
# for HASH-driver 2 # 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, fid2.write(
stime.hour, stime.minute, stime.second, '%d%02d%02d%02d%02d%5.2f%dN%5.2f%3dE%6.2f%5.2f %d %5.2f %5.2f %4.2f %s \n' % (
latdeg,latmin,londeg, lonmin, syear, stime.month, stime.day,
eventsource['depth'], stime.hour, stime.minute, stime.second,
eventsource['quality']['used_phase_count'], latdeg, latmin, londeg, lonmin,
erh, erz, eventinfo.magnitudes[0]['mag'], eventsource['depth'],
hashID)) eventsource['quality']['used_phase_count'],
erh, erz, eventinfo.magnitudes[0]['mag'],
hashID))
# write phase lines # write phase lines
for key in arrivals: for key in arrivals:
@ -786,36 +805,38 @@ def writephases(arrivals, fformat, filename, parameter, eventinfo=None):
ncode = arrivals[key]['P']['network'] ncode = arrivals[key]['P']['network']
if arrivals[key]['P']['weight'] < 2: if arrivals[key]['P']['weight'] < 2:
Pqual='I' Pqual = 'I'
else: else:
Pqual='E' Pqual = 'E'
for i in range(len(picks)): for i in range(len(picks)):
station = picks[i].waveform_id.station_code station = picks[i].waveform_id.station_code
if station == stat: if station == stat:
# get resource ID # get resource ID
resid_picks = picks[i].get('resource_id') resid_picks = picks[i].get('resource_id')
# find same ID in eventinfo # find same ID in eventinfo
# there it is the pick_id!! # there it is the pick_id!!
for j in range(len(eventinfo.origins[0].arrivals)): for j in range(len(eventinfo.origins[0].arrivals)):
resid_eventinfo = eventinfo.origins[0].arrivals[j].get('pick_id') resid_eventinfo = eventinfo.origins[0].arrivals[j].get('pick_id')
if resid_eventinfo == resid_picks and eventinfo.origins[0].arrivals[j].phase == 'P': if resid_eventinfo == resid_picks and eventinfo.origins[0].arrivals[j].phase == 'P':
if len(stat) > 4: # HASH handles only 4-string station IDs if len(stat) > 4: # HASH handles only 4-string station IDs
stat = stat[1:5] stat = stat[1:5]
az = eventinfo.origins[0].arrivals[j].get('azimuth') az = eventinfo.origins[0].arrivals[j].get('azimuth')
inz = eventinfo.origins[0].arrivals[j].get('takeoff_angle') inz = eventinfo.origins[0].arrivals[j].get('takeoff_angle')
dist = eventinfo.origins[0].arrivals[j].get('distance') dist = eventinfo.origins[0].arrivals[j].get('distance')
# write phase line for HASH-driver 1 # 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'], fid1.write(
dist, inz, az, ccode)) '%-4s%sP%s%d 0 %3.1f %03d %03d 2 1 %s\n' % (
# write phase line for HASH-driver 2 stat, Pqual, arrivals[key]['P']['fm'], arrivals[key]['P']['weight'],
fid2.write('%-4s %s %s %s %s \n' % ( dist, inz, az, ccode))
stat, # write phase line for HASH-driver 2
ncode, fid2.write('%-4s %s %s %s %s \n' % (
ccode, stat,
Pqual, ncode,
arrivals[key]['P']['fm'])) ccode,
break Pqual,
arrivals[key]['P']['fm']))
break
fid1.write(' %s' % hashID) fid1.write(' %s' % hashID)
fid1.close() fid1.close()
@ -841,7 +862,155 @@ def merge_picks(event, picks):
network = pick.waveform_id.network_code network = pick.waveform_id.network_code
method = pick.method_id method = pick.method_id
for p in event.picks: for p in event.picks:
if p.waveform_id.station_code == station and p.phase_hint == phase: if p.waveform_id.station_code == station\
and p.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 p.time, p.time_errors, p.waveform_id.network_code, p.method_id = time, err, network, method
del time, err, phase, station, network, method del time, err, phase, station, network, method
return event 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()

View File

@ -6,6 +6,7 @@ from pylot.core.util.version import get_git_version as _getVersionString
__version__ = _getVersionString() __version__ = _getVersionString()
def export(picks, fnout, parameter, eventinfo): def export(picks, fnout, parameter, eventinfo):
''' '''
Take <picks> dictionary and exports picking data to a focmec Take <picks> dictionary and exports picking data to a focmec

View File

@ -6,6 +6,7 @@ from pylot.core.util.version import get_git_version as _getVersionString
__version__ = _getVersionString() __version__ = _getVersionString()
def export(picks, fnout, parameter, eventinfo): def export(picks, fnout, parameter, eventinfo):
''' '''
Take <picks> dictionary and exports picking data to a HASH Take <picks> dictionary and exports picking data to a HASH

View File

@ -6,6 +6,7 @@ from pylot.core.util.version import get_git_version as _getVersionString
__version__ = _getVersionString() __version__ = _getVersionString()
def export(picks, fnout, parameter): def export(picks, fnout, parameter):
''' '''
Take <picks> dictionary and exports picking data to a HYPO71 Take <picks> dictionary and exports picking data to a HYPO71

View File

@ -6,6 +6,7 @@ from pylot.core.util.version import get_git_version as _getVersionString
__version__ = _getVersionString() __version__ = _getVersionString()
def export(picks, fnout, parameter, eventinfo): def export(picks, fnout, parameter, eventinfo):
''' '''
Take <picks> dictionary and exports picking data to a hypoDD Take <picks> dictionary and exports picking data to a hypoDD

View File

@ -6,6 +6,7 @@ from pylot.core.util.version import get_git_version as _getVersionString
__version__ = _getVersionString() __version__ = _getVersionString()
def export(picks, fnout, parameter): def export(picks, fnout, parameter):
''' '''
Take <picks> dictionary and exports picking data to a HYPOSAT Take <picks> dictionary and exports picking data to a HYPOSAT

View File

@ -1,9 +1,10 @@
#!/usr/bin/env python #!/usr/bin/env python
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
import subprocess
import os
import glob import glob
import os
import subprocess
from obspy import read_events from obspy import read_events
from pylot.core.io.phases import writephases from pylot.core.io.phases import writephases
from pylot.core.util.utils import getPatternLine, runProgram, which 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() __version__ = _getVersionString()
class NLLocError(EnvironmentError): class NLLocError(EnvironmentError):
pass pass
def export(picks, fnout, parameter): def export(picks, fnout, parameter):
''' '''
Take <picks> dictionary and exports picking data to a NLLOC-obs 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) locfiles = 'LOCFILES %s NLLOC_OBS %s %s 0\n' % (phasefile, tttable, nllocout)
# modification of NLLoc-control file # modification of NLLoc-control file
print ("Modifying NLLoc-control file %s ..." % ctrfile) print("Modifying NLLoc-control file %s ..." % ctrfile)
curlocfiles = getPatternLine(ctrfile, 'LOCFILES') curlocfiles = getPatternLine(ctrfile, 'LOCFILES')
nllfile = open(ctrfile, 'r') nllfile = open(ctrfile, 'r')
filedata = nllfile.read() filedata = nllfile.read()
@ -94,7 +97,7 @@ def locate(fnin, infile=None):
def read_location(fn): def read_location(fn):
path, file = os.path.split(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: if len(file) > 1:
raise IOError('ambiguous location name {0}'.format(file)) raise IOError('ambiguous location name {0}'.format(file))
fn = os.path.join(path, file[0]) fn = os.path.join(path, file[0])

View File

@ -6,7 +6,8 @@ from pylot.core.util.version import get_git_version as _getVersionString
__version__ = _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 Take <picks> dictionary and exports picking data to a VELEST-cnv
<phasefile> without creating an ObsPy event object. <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 :param fnout: complete path to the exporting obs file
:type fnout: str :type fnout: str
:param: parameter, all input information
:type: object
:param: eventinfo, source time needed for VELEST-cnv format :param: eventinfo, source time needed for VELEST-cnv format
:type: list object :type: list object
:param: parameter, all input information
:type: object
''' '''
# write phases to VELEST-phase file # write phases to VELEST-phase file
writephases(picks, 'VELEST', fnout, parameter, eventinfo) writephases(picks, 'VELEST', fnout, parameter, eventinfo)

View File

@ -11,25 +11,37 @@ function conglomerate utils.
import matplotlib.pyplot as plt import matplotlib.pyplot as plt
import numpy as np import numpy as np
from pylot.core.io.data import Data
from pylot.core.io.inputs import PylotParameter 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 CharacteristicFunction
from pylot.core.pick.charfuns import HOScf, AICcf, ARZcf, ARHcf, AR3Ccf 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, \ from pylot.core.pick.utils import checksignallength, checkZ4S, earllatepicker, \
getSNR, fmpicker, checkPonsets, wadaticheck getSNR, fmpicker, checkPonsets, wadaticheck
from pylot.core.util.utils import getPatternLine, gen_Pool from pylot.core.util.utils import getPatternLine, gen_Pool,\
from pylot.core.io.data import Data 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 = [] stations = []
all_onsets = {} all_onsets = {}
input_tuples = [] 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 # get some parameters for quality control from
# parameter input file (usually autoPyLoT.in). # parameter input file (usually pylot.in).
wdttolerance = param.get('wdttolerance') wdttolerance = param.get('wdttolerance')
mdttolerance = param.get('mdttolerance') mdttolerance = param.get('mdttolerance')
jackfactor = param.get('jackfactor')
apverbose = param.get('apverbose') apverbose = param.get('apverbose')
for n in range(len(data)): for n in range(len(data)):
station = data[n].stats.station station = data[n].stats.station
@ -41,46 +53,67 @@ def autopickevent(data, param, iplot=0, fig_dict=None):
for station in stations: for station in stations:
topick = data.select(station=station) topick = data.select(station=station)
if not iplot: if iplot == None or iplot == 'None' or iplot == 0:
input_tuples.append((topick, param, apverbose)) input_tuples.append((topick, param, apverbose, metadata, origin))
if iplot>0: if iplot > 0:
all_onsets[station] = autopickstation(topick, param, verbose=apverbose, iplot=iplot, fig_dict=fig_dict) 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.') print('iPlot Flag active: NO MULTIPROCESSING possible.')
return all_onsets 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) result = pool.map(call_autopickstation, input_tuples)
pool.close() pool.close()
for pick in result: for pick in result:
station = pick['station'] if pick:
pick.pop('station') station = pick['station']
all_onsets[station] = pick pick.pop('station')
all_onsets[station] = pick
return all_onsets #return all_onsets
# quality control # quality control
# median check and jackknife on P-onset times # median check and jackknife on P-onset times
jk_checked_onsets = checkPonsets(all_onsets, mdttolerance, iplot) jk_checked_onsets = checkPonsets(all_onsets, mdttolerance, jackfactor, 1, fig_dict_wadatijack)
#return jk_checked_onsets
# check S-P times (Wadati) # 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): def call_autopickstation(input_tuple):
wfstream, pickparam, verbose = input_tuple wfstream, pickparam, verbose, metadata, origin = input_tuple
#multiprocessing not possible with interactive plotting # multiprocessing not possible with interactive plotting
return autopickstation(wfstream, pickparam, verbose, iplot=0) 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 :param wfstream: `~obspy.core.stream.Stream` containing waveform
:type wfstream: obspy.core.stream.Stream :type wfstream: obspy.core.stream.Stream
:param pickparam: container of picking parameters from input file, :param pickparam: container of picking parameters from input file,
usually autoPyLoT.in usually pylot.in
:type pickparam: PylotParameter :type pickparam: PylotParameter
:param verbose: :param verbose:
:type verbose: bool :type verbose: bool
@ -88,11 +121,10 @@ def autopickstation(wfstream, pickparam, verbose=False, iplot=0, fig_dict=None):
""" """
# declaring pickparam variables (only for convenience) # 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 # special parameters for P picking
iplot = iplot
algoP = pickparam.get('algoP') algoP = pickparam.get('algoP')
pstart = pickparam.get('pstart') pstart = pickparam.get('pstart')
pstop = pickparam.get('pstop') pstop = pickparam.get('pstop')
@ -102,6 +134,7 @@ def autopickstation(wfstream, pickparam, verbose=False, iplot=0, fig_dict=None):
bpz1 = pickparam.get('bpz1') bpz1 = pickparam.get('bpz1')
bpz2 = pickparam.get('bpz2') bpz2 = pickparam.get('bpz2')
pickwinP = pickparam.get('pickwinP') pickwinP = pickparam.get('pickwinP')
aictsmoothP = pickparam.get('aictsmooth')
tsmoothP = pickparam.get('tsmoothP') tsmoothP = pickparam.get('tsmoothP')
ausP = pickparam.get('ausP') ausP = pickparam.get('ausP')
nfacP = pickparam.get('nfacP') nfacP = pickparam.get('nfacP')
@ -117,6 +150,8 @@ def autopickstation(wfstream, pickparam, verbose=False, iplot=0, fig_dict=None):
algoS = pickparam.get('algoS') algoS = pickparam.get('algoS')
sstart = pickparam.get('sstart') sstart = pickparam.get('sstart')
sstop = pickparam.get('sstop') sstop = pickparam.get('sstop')
use_taup = real_Bool(pickparam.get('use_taup'))
taup_model = pickparam.get('taup_model')
bph1 = pickparam.get('bph1') bph1 = pickparam.get('bph1')
bph2 = pickparam.get('bph2') bph2 = pickparam.get('bph2')
tsnrh = pickparam.get('tsnrh') 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 if len(ndat) == 0: # check for other components
ndat = wfstream.select(component="1") 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: if algoP == 'HOS' or algoP == 'ARZ' and zdat is not None:
msg = '##################################################\nautopickstation:' \ msg = '##################################################\nautopickstation:' \
' Working on P onset of station {station}\nFiltering vertical ' \ ' 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)) data=str(zdat))
if verbose: print(msg) if verbose: print(msg)
z_copy = zdat.copy() z_copy = zdat.copy()
# filter and taper data
tr_filt = zdat[0].copy() 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], tr_filt.filter('bandpass', freqmin=bpz1[0], freqmax=bpz1[1],
zerophase=False) zerophase=False)
tr_filt.taper(max_percentage=0.05, type='hann') tr_filt.taper(max_percentage=0.05, type='hann')
z_copy[0].data = tr_filt.data z_copy[0].data = tr_filt.data
############################################################## ##############################################################
# check length of waveform and compare with cut times # 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 Lwf = zdat[0].stats.endtime - zdat[0].stats.starttime
Ldiff = Lwf - Lc if not Lwf > 0:
if Ldiff < 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 ' \ msg = 'autopickstation: Cutting times are too large for actual ' \
'waveform!\nUsing entire waveform instead!' 'waveform!\nUsing entire waveform instead!'
if verbose: print(msg) if verbose: print(msg)
@ -235,9 +327,17 @@ def autopickstation(wfstream, pickparam, verbose=False, iplot=0, fig_dict=None):
key = 'aicFig' key = 'aicFig'
if fig_dict: if fig_dict:
fig = fig_dict[key] fig = fig_dict[key]
linecolor = fig_dict['plot_style']['linecolor']['rgba_mpl']
else: else:
fig = None 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: if aicpick.getpick() is not None:
# check signal length to detect spuriously picked noise peaks # 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' key = 'slength'
if fig_dict: if fig_dict:
fig = fig_dict[key] fig = fig_dict[key]
linecolor = fig_dict['plot_style']['linecolor']['rgba_mpl']
else: else:
fig = None fig = None
linecolor = 'k'
Pflag = checksignallength(zne, aicpick.getpick(), tsnrz, Pflag = checksignallength(zne, aicpick.getpick(), tsnrz,
minsiglength / 2, minsiglength / 2,
nfacsl, minpercent, iplot, nfacsl, minpercent, iplot,
fig) fig, linecolor)
else: else:
# filter and taper horizontal traces # filter and taper horizontal traces
trH1_filt = edat.copy() trH1_filt = edat.copy()
trH2_filt = ndat.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], trH1_filt.filter('bandpass', freqmin=bph1[0],
freqmax=bph1[1], freqmax=bph1[1],
zerophase=False) zerophase=False)
@ -276,12 +381,14 @@ def autopickstation(wfstream, pickparam, verbose=False, iplot=0, fig_dict=None):
zne += trH2_filt zne += trH2_filt
if fig_dict: if fig_dict:
fig = fig_dict['slength'] fig = fig_dict['slength']
linecolor = fig_dict['plot_style']['linecolor']['rgba_mpl']
else: else:
fig = None fig = None
linecolor = 'k'
Pflag = checksignallength(zne, aicpick.getpick(), tsnrz, Pflag = checksignallength(zne, aicpick.getpick(), tsnrz,
minsiglength, minsiglength,
nfacsl, minpercent, iplot, nfacsl, minpercent, iplot,
fig) fig, linecolor)
if Pflag == 1: if Pflag == 1:
# check for spuriously picked S onset # 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.' 'Skipping control function checkZ4S.'
if verbose: print(msg) if verbose: print(msg)
else: else:
if iplot>1: if iplot > 1:
if fig_dict: if fig_dict:
fig = fig_dict['checkZ4s'] fig = fig_dict['checkZ4s']
linecolor = fig_dict['plot_style']['linecolor']['rgba_mpl']
else: else:
fig = None fig = None
linecolor = 'k'
Pflag = checkZ4S(zne, aicpick.getpick(), zfac, Pflag = checkZ4S(zne, aicpick.getpick(), zfac,
tsnrz[3], iplot, fig) tsnrz[2], iplot, fig, linecolor)
if Pflag == 0: if Pflag == 0:
Pmarker = 'SinsteadP' Pmarker = 'SinsteadP'
Pweight = 9 Pweight = 9
@ -306,8 +415,11 @@ def autopickstation(wfstream, pickparam, verbose=False, iplot=0, fig_dict=None):
Pweight = 9 Pweight = 9
############################################################## ##############################################################
# go on with processing if AIC onset passes quality control # go on with processing if AIC onset passes quality control
if (aicpick.getSlope() >= minAICPslope and slope = aicpick.getSlope()
aicpick.getSNR() >= minAICPSNR and Pflag == 1): if not slope:
slope = 0
if (slope >= minAICPslope and
aicpick.getSNR() >= minAICPSNR and Pflag == 1):
aicPflag = 1 aicPflag = 1
msg = 'AIC P-pick passes quality control: Slope: {0} counts/s, ' \ msg = 'AIC P-pick passes quality control: Slope: {0} counts/s, ' \
'SNR: {1}\nGo on with refined picking ...\n' \ '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 # re-filter waveform with larger bandpass
z_copy = zdat.copy() z_copy = zdat.copy()
tr_filt = zdat[0].copy() tr_filt = zdat[0].copy()
tr_filt.detrend(type='demean')
tr_filt.filter('bandpass', freqmin=bpz2[0], freqmax=bpz2[1], tr_filt.filter('bandpass', freqmin=bpz2[0], freqmax=bpz2[1],
zerophase=False) zerophase=False)
tr_filt.taper(max_percentage=0.05, type='hann') 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) algoP=algoP)
if fig_dict: if fig_dict:
fig = fig_dict['refPpick'] fig = fig_dict['refPpick']
linecolor = fig_dict['plot_style']['linecolor']['rgba_mpl']
else: else:
fig = None fig = None
linecolor = 'k'
refPpick = PragPicker(cf2, tsnrz, pickwinP, iplot, ausP, tsmoothP, refPpick = PragPicker(cf2, tsnrz, pickwinP, iplot, ausP, tsmoothP,
aicpick.getpick(), fig) aicpick.getpick(), fig, linecolor)
mpickP = refPpick.getpick() mpickP = refPpick.getpick()
############################################################# #############################################################
if mpickP is not None: if mpickP is not None:
@ -358,28 +473,34 @@ def autopickstation(wfstream, pickparam, verbose=False, iplot=0, fig_dict=None):
if iplot: if iplot:
if fig_dict: if fig_dict:
fig = fig_dict['el_Ppick'] fig = fig_dict['el_Ppick']
linecolor = fig_dict['plot_style']['linecolor']['rgba_mpl']
else: else:
fig = None fig = None
linecolor = 'k'
epickP, lpickP, Perror = earllatepicker(z_copy, nfacP, tsnrz, epickP, lpickP, Perror = earllatepicker(z_copy, nfacP, tsnrz,
mpickP, iplot, fig=fig) mpickP, iplot, fig=fig,
linecolor=linecolor)
else: else:
epickP, lpickP, Perror = earllatepicker(z_copy, nfacP, tsnrz, epickP, lpickP, Perror = earllatepicker(z_copy, nfacP, tsnrz,
mpickP, iplot) mpickP, iplot)
# get SNR # get SNR
[SNRP, SNRPdB, Pnoiselevel] = getSNR(z_copy, tsnrz, mpickP) [SNRP, SNRPdB, Pnoiselevel] = getSNR(z_copy, tsnrz, mpickP)
# weight P-onset using symmetric error # weight P-onset using symmetric error
if Perror <= timeerrorsP[0]: if Perror == None:
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 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 # get first motion of P onset
@ -388,11 +509,12 @@ def autopickstation(wfstream, pickparam, verbose=False, iplot=0, fig_dict=None):
if iplot: if iplot:
if fig_dict: if fig_dict:
fig = fig_dict['fm_picker'] fig = fig_dict['fm_picker']
linecolor = fig_dict['plot_style']['linecolor']['rgba_mpl']
else: else:
fig = None fig = None
FM = fmpicker(zdat, z_copy, fmpickwin, mpickP, iplot, fig) FM = fmpicker(zdat, z_copy, fmpickwin, mpickP, iplot, fig, linecolor)
else: else:
FM = fmpicker(zdat, z_copy, fmpickwin, mpickP, iplot) FM = fmpicker(zdat, z_copy, fmpickwin, mpickP, iplot)
else: else:
FM = 'N' FM = 'N'
@ -402,6 +524,8 @@ def autopickstation(wfstream, pickparam, verbose=False, iplot=0, fig_dict=None):
SNRPdB, SNRPdB,
FM) FM)
print(msg) print(msg)
msg = 'autopickstation: Refined P-Pick: {} s | P-Error: {} s'.format(mpickP, Perror)
print(msg)
Sflag = 1 Sflag = 1
else: else:
@ -419,16 +543,46 @@ def autopickstation(wfstream, pickparam, verbose=False, iplot=0, fig_dict=None):
print('autopickstation: No vertical component data available!, ' print('autopickstation: No vertical component data available!, '
'Skipping station!') 'Skipping station!')
if edat is not None and ndat is not None and len(edat) > 0 and len( if ((len(edat) > 0 and len(ndat) == 0) or (
ndat) > 0 and Pweight < 4: 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' \ msg = 'Go on picking S onset ...\n' \
'##################################################\n' \ '##################################################\n' \
'Working on S onset of station {0}\nFiltering horizontal ' \ 'Working on S onset of station {0}\nFiltering horizontal ' \
'traces ...'.format(edat[0].stats.station) 'traces ...'.format(edat[0].stats.station)
if verbose: print(msg) 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': if algoS == 'ARH':
# re-create stream object including both horizontal components # 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 # filter and taper data
trH1_filt = hdat[0].copy() trH1_filt = hdat[0].copy()
trH2_filt = hdat[1].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], trH1_filt.filter('bandpass', freqmin=bph1[0], freqmax=bph1[1],
zerophase=False) zerophase=False)
trH2_filt.filter('bandpass', freqmin=bph1[0], freqmax=bph1[1], 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() trH1_filt = hdat[0].copy()
trH2_filt = hdat[1].copy() trH2_filt = hdat[1].copy()
trH3_filt = hdat[2].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], trH1_filt.filter('bandpass', freqmin=bph1[0], freqmax=bph1[1],
zerophase=False) zerophase=False)
trH2_filt.filter('bandpass', freqmin=bph1[0], freqmax=bph1[1], 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 # of class AutoPicking
if fig_dict: if fig_dict:
fig = fig_dict['aicARHfig'] fig = fig_dict['aicARHfig']
linecolor = fig_dict['plot_style']['linecolor']['rgba_mpl']
else: else:
fig = None fig = None
linecolor = 'k'
aicarhpick = AICPicker(haiccf, tsnrh, pickwinS, iplot, None, 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 # go on with processing if AIC onset passes quality control
if (aicarhpick.getSlope() >= minAICSslope and slope = aicarhpick.getSlope()
aicarhpick.getSNR() >= minAICSSNR and if not slope:
aicarhpick.getpick() is not None): slope = 0
if (slope >= minAICSslope and
aicarhpick.getSNR() >= minAICSSNR and
aicarhpick.getpick() is not None):
aicSflag = 1 aicSflag = 1
msg = 'AIC S-pick passes quality control: Slope: {0} counts/s, ' \ msg = 'AIC S-pick passes quality control: Slope: {0} counts/s, ' \
'SNR: {1}\nGo on with refined picking ...\n' \ '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': if algoS == 'ARH':
trH1_filt = hdat[0].copy() trH1_filt = hdat[0].copy()
trH2_filt = hdat[1].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], trH1_filt.filter('bandpass', freqmin=bph2[0], freqmax=bph2[1],
zerophase=False) zerophase=False)
trH2_filt.filter('bandpass', freqmin=bph2[0], freqmax=bph2[1], 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() trH1_filt = hdat[0].copy()
trH2_filt = hdat[1].copy() trH2_filt = hdat[1].copy()
trH3_filt = hdat[2].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], trH1_filt.filter('bandpass', freqmin=bph2[0], freqmax=bph2[1],
zerophase=False) zerophase=False)
trH2_filt.filter('bandpass', freqmin=bph2[0], freqmax=bph2[1], 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 # get refined onset time from CF2 using class Picker
if fig_dict: if fig_dict:
fig = fig_dict['refSpick'] fig = fig_dict['refSpick']
linecolor = fig_dict['plot_style']['linecolor']['rgba_mpl']
else: else:
fig = None fig = None
linecolor = 'k'
refSpick = PragPicker(arhcf2, tsnrh, pickwinS, iplot, ausS, refSpick = PragPicker(arhcf2, tsnrh, pickwinS, iplot, ausS,
tsmoothS, aicarhpick.getpick(), fig) tsmoothS, aicarhpick.getpick(), fig, linecolor)
mpickS = refSpick.getpick() mpickS = refSpick.getpick()
############################################################# #############################################################
if mpickS is not None: if mpickS is not None:
@ -565,27 +736,33 @@ def autopickstation(wfstream, pickparam, verbose=False, iplot=0, fig_dict=None):
if iplot: if iplot:
if fig_dict: if fig_dict:
fig = fig_dict['el_S1pick'] fig = fig_dict['el_S1pick']
linecolor = fig_dict['plot_style']['linecolor']['rgba_mpl']
else: else:
fig = None fig = None
epickS1, lpickS1, Serror1 = earllatepicker(h_copy, nfacS, linecolor = 'k'
tsnrh, epickS1, lpickS1, Serror1 = earllatepicker(h_copy, nfacS,
mpickS, iplot, tsnrh,
fig=fig) mpickS, iplot,
fig=fig,
linecolor=linecolor)
else: else:
epickS1, lpickS1, Serror1 = earllatepicker(h_copy, nfacS, epickS1, lpickS1, Serror1 = earllatepicker(h_copy, nfacS,
tsnrh, tsnrh,
mpickS, iplot) mpickS, iplot)
h_copy[0].data = trH2_filt.data h_copy[0].data = trH2_filt.data
if iplot: if iplot:
if fig_dict: if fig_dict:
fig = fig_dict['el_S2pick'] fig = fig_dict['el_S2pick']
linecolor = fig_dict['plot_style']['linecolor']['rgba_mpl']
else: else:
fig = None fig = None
linecolor = ''
epickS2, lpickS2, Serror2 = earllatepicker(h_copy, nfacS, epickS2, lpickS2, Serror2 = earllatepicker(h_copy, nfacS,
tsnrh, tsnrh,
mpickS, iplot, mpickS, iplot,
fig=fig) fig=fig,
linecolor=linecolor)
else: else:
epickS2, lpickS2, Serror2 = earllatepicker(h_copy, nfacS, epickS2, lpickS2, Serror2 = earllatepicker(h_copy, nfacS,
tsnrh, tsnrh,
@ -629,6 +806,9 @@ def autopickstation(wfstream, pickparam, verbose=False, iplot=0, fig_dict=None):
lpickS = lpick[ipick] lpickS = lpick[ipick]
Serror = pickerr[ipick] Serror = pickerr[ipick]
msg = 'autopickstation: Refined S-Pick: {} s | S-Error: {} s'.format(mpickS, Serror)
print(msg)
# get SNR # get SNR
[SNRS, SNRSdB, Snoiselevel] = getSNR(h_copy, tsnrh, mpickS) [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 # get Wood-Anderson peak-to-peak amplitude
# initialize Data object # initialize Data object
data = Data()
# re-create stream object including both horizontal components # re-create stream object including both horizontal components
hdat = edat.copy() hdat = edat.copy()
hdat += ndat hdat += ndat
@ -670,21 +849,33 @@ def autopickstation(wfstream, pickparam, verbose=False, iplot=0, fig_dict=None):
############################################################ ############################################################
# get Wood-Anderson peak-to-peak amplitude # get Wood-Anderson peak-to-peak amplitude
# initialize Data object # initialize Data object
data = Data()
# re-create stream object including both horizontal components # re-create stream object including both horizontal components
hdat = edat.copy() hdat = edat.copy()
hdat += ndat hdat += ndat
else: else:
print('autopickstation: No horizontal component data available or ' \ print('autopickstation: No horizontal component data available or '
'bad P onset, skipping S picking!') '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: if iplot > 0:
# plot vertical trace # plot vertical trace
if not fig_dict: if fig_dict == None or fig_dict == 'None':
fig = plt.figure() fig = plt.figure()
plt_flag = 1
linecolor = 'k'
else: else:
fig = fig_dict['mainFig'] fig = fig_dict['mainFig']
linecolor = fig_dict['plot_style']['linecolor']['rgba_mpl']
fig._tight = True
ax1 = fig.add_subplot(311) ax1 = fig.add_subplot(311)
tdata = np.arange(0, zdat[0].stats.npts / tr_filt.stats.sampling_rate, tdata = np.arange(0, zdat[0].stats.npts / tr_filt.stats.sampling_rate,
tr_filt.stats.delta) tr_filt.stats.delta)
@ -692,7 +883,7 @@ def autopickstation(wfstream, pickparam, verbose=False, iplot=0, fig_dict=None):
wfldiff = len(tr_filt.data) - len(tdata) wfldiff = len(tr_filt.data) - len(tdata)
if wfldiff < 0: if wfldiff < 0:
tdata = tdata[0:len(tdata) - abs(wfldiff)] tdata = tdata[0:len(tdata) - abs(wfldiff)]
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: if Pweight < 4:
ax1.plot(cf1.getTimeArray(), cf1.getCF() / max(cf1.getCF()), ax1.plot(cf1.getTimeArray(), cf1.getCF() / max(cf1.getCF()),
'b', label='CF1') '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], ax1.plot([aicpick.getpick() - 0.5, aicpick.getpick() + 0.5],
[-1, -1], 'r') [-1, -1], 'r')
ax1.plot([refPpick.getpick(), refPpick.getpick()], 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], ax1.plot([refPpick.getpick() - 0.5, refPpick.getpick() + 0.5],
[1.3, 1.3], 'r', linewidth=2) [1.3, 1.3], 'r', linewidth=2)
ax1.plot([refPpick.getpick() - 0.5, refPpick.getpick() + 0.5], 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([lpickP, lpickP], [-1.1, 1.1], 'r--', label='lpp')
ax1.plot([epickP, epickP], [-1.1, 1.1], 'r--', label='epp') 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 ' ax1.set_title('%s, %s, P Weight=%d, SNR=%7.2f, SNR[dB]=%7.2f '
'Polarity: %s' % (tr_filt.stats.station, 'Polarity: %s' % (tr_filt.stats.station,
tr_filt.stats.channel, tr_filt.stats.channel,
Pweight, Pweight,
SNRP, SNRP,
SNRPdB, SNRPdB,
FM)) FM))
else: else:
ax1.set_title('%s, P Weight=%d, SNR=None, ' ax1.set_title('%s, P Weight=%d, SNR=None, '
'SNRdB=None' % (tr_filt.stats.channel, Pweight)) 'SNRdB=None' % (tr_filt.stats.channel, Pweight))
else: else:
ax1.set_title('%s, %s, P Weight=%d' % (tr_filt.stats.station, ax1.set_title('%s, %s, P Weight=%d' % (tr_filt.stats.station,
tr_filt.stats.channel, tr_filt.stats.channel,
Pweight)) Pweight))
ax1.legend() ax1.legend(loc=1)
ax1.set_yticks([]) ax1.set_yticks([])
ax1.set_ylim([-1.5, 1.5]) ax1.set_ylim([-1.5, 1.5])
ax1.set_ylabel('Normalized Counts') 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: if len(edat[0]) > 1 and len(ndat[0]) > 1 and Sflag == 1:
# plot horizontal traces # 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, th1data = np.arange(0,
trH1_filt.stats.npts / trH1_filt.stats.npts /
trH1_filt.stats.sampling_rate, 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) wfldiff = len(trH1_filt.data) - len(th1data)
if wfldiff < 0: if wfldiff < 0:
th1data = th1data[0:len(th1data) - abs(wfldiff)] th1data = th1data[0:len(th1data) - abs(wfldiff)]
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: if Pweight < 4:
ax2.plot(arhcf1.getTimeArray(), ax2.plot(arhcf1.getTimeArray(),
arhcf1.getCF() / max(arhcf1.getCF()), 'b', label='CF1') arhcf1.getCF() / max(arhcf1.getCF()), 'b', label='CF1')
if aicSflag == 1: if aicSflag == 1 and Sweight < 4:
ax2.plot(arhcf2.getTimeArray(), ax2.plot(arhcf2.getTimeArray(),
arhcf2.getCF() / max(arhcf2.getCF()), 'm', label='CF2') arhcf2.getCF() / max(arhcf2.getCF()), 'm', label='CF2')
ax2.plot( ax2.plot(
[aicarhpick.getpick(), aicarhpick.getpick()], [aicarhpick.getpick(), aicarhpick.getpick()],
[-1, 1], 'g', label='Initial S Onset') [-1, 1], 'g', label='Initial S Onset')
@ -778,13 +976,13 @@ def autopickstation(wfstream, pickparam, verbose=False, iplot=0, fig_dict=None):
else: else:
ax2.set_title('%s, S Weight=%d, SNR=None, SNRdB=None' % ( ax2.set_title('%s, S Weight=%d, SNR=None, SNRdB=None' % (
trH1_filt.stats.channel, Sweight)) trH1_filt.stats.channel, Sweight))
ax2.legend() ax2.legend(loc=1)
ax2.set_yticks([]) ax2.set_yticks([])
ax2.set_ylim([-1.5, 1.5]) ax2.set_ylim([-1.5, 1.5])
ax2.set_ylabel('Normalized Counts') 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, th2data = np.arange(0,
trH2_filt.stats.npts / trH2_filt.stats.npts /
trH2_filt.stats.sampling_rate, 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) wfldiff = len(trH2_filt.data) - len(th2data)
if wfldiff < 0: if wfldiff < 0:
th2data = th2data[0:len(th2data) - abs(wfldiff)] th2data = th2data[0:len(th2data) - abs(wfldiff)]
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: if Pweight < 4:
p22, = ax3.plot(arhcf1.getTimeArray(), p22, = ax3.plot(arhcf1.getTimeArray(),
arhcf1.getCF() / max(arhcf1.getCF()), 'b', label='CF1') 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) [-1.3, -1.3], 'g', linewidth=2)
ax3.plot([lpickS, lpickS], [-1.1, 1.1], 'g--', label='lpp') ax3.plot([lpickS, lpickS], [-1.1, 1.1], 'g--', label='lpp')
ax3.plot([epickS, epickS], [-1.1, 1.1], 'g--', label='epp') ax3.plot([epickS, epickS], [-1.1, 1.1], 'g--', label='epp')
ax3.legend() ax3.legend(loc=1)
ax3.set_yticks([]) ax3.set_yticks([])
ax3.set_ylim([-1.5, 1.5]) ax3.set_ylim([-1.5, 1.5])
ax3.set_xlabel('Time [s] after %s' % tr_filt.stats.starttime) ax3.set_xlabel('Time [s] after %s' % tr_filt.stats.starttime)
ax3.set_ylabel('Normalized Counts') ax3.set_ylabel('Normalized Counts')
ax3.set_title(trH2_filt.stats.channel) 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 # calculate "real" onset times
if lpickP is not None and lpickP == mpickP: if lpickP is not None and lpickP == mpickP:
lpickP += timeerrorsP[0] lpickP += zdat[0].stats.delta
if epickP is not None and epickP == mpickP: 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: if mpickP is not None and epickP is not None and lpickP is not None:
lpickP = zdat[0].stats.starttime + lpickP lpickP = zdat[0].stats.starttime + lpickP
epickP = zdat[0].stats.starttime + epickP 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] epickP = zdat[0].stats.starttime - timeerrorsP[3]
mpickP = zdat[0].stats.starttime 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: if lpickS is not None and lpickS == mpickS:
lpickS += timeerrorsS[0] lpickS += hdat.stats.delta
if epickS is not None and epickS == mpickS: 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: if mpickS is not None and epickS is not None and lpickS is not None:
lpickS = edat[0].stats.starttime + lpickS lpickS = hdat.stats.starttime + lpickS
epickS = edat[0].stats.starttime + epickS epickS = hdat.stats.starttime + epickS
mpickS = edat[0].stats.starttime + mpickS mpickS = hdat.stats.starttime + mpickS
else: else:
# dummy values (start of seismic trace) in order to derive # dummy values (start of seismic trace) in order to derive
# theoretical onset times for iteratve picking # theoretical onset times for iteratve picking
lpickS = edat[0].stats.starttime + timeerrorsS[3] lpickS = hdat.stats.starttime + timeerrorsS[3]
epickS = edat[0].stats.starttime - timeerrorsS[3] epickS = hdat.stats.starttime - timeerrorsS[3]
mpickS = edat[0].stats.starttime mpickS = hdat.stats.starttime
# create dictionary # create dictionary
# for P phase # 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, snrdb=SNRPdB, weight=Pweight, fm=FM, w0=None, fc=None, Mo=None,
Mw=None, picker=picker, marked=Pmarker) Mw=None, picker=picker, marked=Pmarker)
# add S phase # add S phase
ccode = edat[0].stats.channel ccode = hdat.stats.channel
ncode = edat[0].stats.network ncode = hdat.stats.network
spick = dict(channel=ccode, network=ncode, lpp=lpickS, epp=epickS, mpp=mpickS, spe=Serror, snr=SNRS, 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) snrdb=SNRSdB, weight=Sweight, fm=None, picker=picker, Ao=Ao)
# merge picks into returning dictionary # merge picks into returning dictionary
@ -923,17 +1133,21 @@ def iteratepicker(wf, NLLocfile, picks, badpicks, pickparameter, fig_dict=None):
Precalcwin_old = pickparameter.get('Precalcwin') Precalcwin_old = pickparameter.get('Precalcwin')
noisefactor_old = pickparameter.get('noisefactor') noisefactor_old = pickparameter.get('noisefactor')
zfac_old = pickparameter.get('zfac') zfac_old = pickparameter.get('zfac')
pickparameter.setParam( twindows = pickparameter.get('tsnrz')
pstart=max([0, badpicks[i][1] - wf2pick[0].stats.starttime \ tsafety = twindows[1]
- pickparameter.get('tlta')])) pstart = max([0, badpicks[i][1] - wf2pick[0].stats.starttime - pickparameter.get('tlta')])
pickparameter.setParam(pstop=pickparameter.get('pstart') + \ if abs(float(res)) <= tsafety / 2 or pstart == 0:
(3 * pickparameter.get('tlta'))) print("iteratepicker: Small residuum, leave parameters unchanged for this phase!")
pickparameter.setParam(sstop=pickparameter.get('sstop') / 2) else:
pickparameter.setParam(pickwinP=pickparameter.get('pickwinP') / 2) pickparameter.setParam(pstart=pstart)
pickparameter.setParam( pickparameter.setParam(pstop=pickparameter.get('pstart') + \
Precalcwin=pickparameter.get('Precalcwin') / 2) (pickparameter.get('Precalcwin')))
pickparameter.setParam(noisefactor=1.0) pickparameter.setParam(sstop=pickparameter.get('sstop') / 2)
pickparameter.setParam(zfac=1.0) 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( print(
"iteratepicker: The following picking parameters have been modified for iterative picking:") "iteratepicker: The following picking parameters have been modified for iterative picking:")
print( print(

View File

@ -17,7 +17,6 @@ autoregressive prediction: application ot local and regional distances, Geophys.
:author: MAGS2 EP3 working group :author: MAGS2 EP3 working group
""" """
import matplotlib.pyplot as plt
import numpy as np import numpy as np
from obspy.core import Stream from obspy.core import Stream
@ -27,7 +26,7 @@ class CharacteristicFunction(object):
SuperClass for different types of characteristic functions. 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 Initialize data type object with information from the original
Seismogram. Seismogram.
@ -64,7 +63,6 @@ class CharacteristicFunction(object):
self.calcCF(self.getDataArray()) self.calcCF(self.getDataArray())
self.arpara = np.array([]) self.arpara = np.array([])
self.xpred = np.array([]) self.xpred = np.array([])
self._stealthMode = stealthMode
def __str__(self): def __str__(self):
return '''\n\t{name} object:\n return '''\n\t{name} object:\n
@ -138,9 +136,6 @@ class CharacteristicFunction(object):
def getXCF(self): def getXCF(self):
return self.xcf return self.xcf
def _getStealthMode(self):
return self._stealthMode()
def getDataArray(self, cut=None): def getDataArray(self, cut=None):
''' '''
If cut times are given, time series is cut from cut[0] (start time) 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): def calcCF(self, data):
# if self._getStealthMode() is False:
# print 'Calculating AIC ...'
x = self.getDataArray() x = self.getDataArray()
xnp = x[0].data xnp = x[0].data
nn = np.isnan(xnp) ind = np.where(~np.isnan(xnp))[0]
if len(nn) > 1: if ind.size:
xnp[nn] = 0 xnp[:ind[0]] = xnp[ind[0]]
datlen = len(xnp) datlen = len(xnp)
k = np.arange(1, datlen) k = np.arange(1, datlen)
cf = np.zeros(datlen) cf = np.zeros(datlen)
@ -265,13 +258,9 @@ class HOScf(CharacteristicFunction):
if len(nn) > 1: if len(nn) > 1:
xnp[nn] = 0 xnp[nn] = 0
if self.getOrder() == 3: # this is skewness if self.getOrder() == 3: # this is skewness
# if self._getStealthMode() is False:
# print 'Calculating skewness ...'
y = np.power(xnp, 3) y = np.power(xnp, 3)
y1 = np.power(xnp, 2) y1 = np.power(xnp, 2)
elif self.getOrder() == 4: # this is kurtosis elif self.getOrder() == 4: # this is kurtosis
# if self._getStealthMode() is False:
# print 'Calculating kurtosis ...'
y = np.power(xnp, 4) y = np.power(xnp, 4)
y1 = np.power(xnp, 2) y1 = np.power(xnp, 2)
@ -297,9 +286,12 @@ class HOScf(CharacteristicFunction):
elif self.getOrder() == 4: elif self.getOrder() == 4:
LTA[j] = lta / np.power(lta1, 2) LTA[j] = lta / np.power(lta1, 2)
nn = np.isnan(LTA) # remove NaN's with first not-NaN-value,
if len(nn) > 1: # so autopicker doesnt pick discontinuity at start of the trace
LTA[nn] = 0 ind = np.where(~np.isnan(LTA))[0]
if ind.size:
first = ind[0]
LTA[:first] = LTA[first]
self.cf = LTA self.cf = LTA
self.xcf = x self.xcf = x
@ -307,7 +299,7 @@ class HOScf(CharacteristicFunction):
class ARZcf(CharacteristicFunction): class ARZcf(CharacteristicFunction):
def calcCF(self, data): 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()) x = self.getDataArray(self.getCut())
xnp = x[0].data xnp = x[0].data
nn = np.isnan(xnp) nn = np.isnan(xnp)
@ -343,7 +335,8 @@ class ARZcf(CharacteristicFunction):
cf = tap * cf cf = tap * cf
io = np.where(cf == 0) io = np.where(cf == 0)
ino = 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.cf = cf
self.xcf = x self.xcf = x
@ -430,7 +423,7 @@ class ARZcf(CharacteristicFunction):
class ARHcf(CharacteristicFunction): class ARHcf(CharacteristicFunction):
def calcCF(self, data): 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()) xnp = self.getDataArray(self.getCut())
n0 = np.isnan(xnp[0].data) n0 = np.isnan(xnp[0].data)
@ -466,7 +459,7 @@ class ARHcf(CharacteristicFunction):
# prediction error = CF # prediction error = CF
cf[i + lpred] = np.sqrt(np.sum(np.power(self.xpred[0][i:i + lpred] - xnp[0][i:i + lpred], 2) \ 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[1][i:i + lpred] - xnp[1][i:i + lpred], 2)) / (
2 * lpred)) 2 * lpred))
nn = np.isnan(cf) nn = np.isnan(cf)
if len(nn) > 1: if len(nn) > 1:
cf[nn] = 0 cf[nn] = 0
@ -475,7 +468,8 @@ class ARHcf(CharacteristicFunction):
cf = tap * cf cf = tap * cf
io = np.where(cf == 0) io = np.where(cf == 0)
ino = 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.cf = cf
self.xcf = xnp self.xcf = xnp
@ -567,7 +561,7 @@ class ARHcf(CharacteristicFunction):
class AR3Ccf(CharacteristicFunction): class AR3Ccf(CharacteristicFunction):
def calcCF(self, data): 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()) xnp = self.getDataArray(self.getCut())
n0 = np.isnan(xnp[0].data) 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) \ 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[1][i:i + lpred] - xnp[1][i:i + lpred], 2) \
+ np.power(self.xpred[2][i:i + lpred] - xnp[2][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) nn = np.isnan(cf)
if len(nn) > 1: if len(nn) > 1:
cf[nn] = 0 cf[nn] = 0
@ -617,7 +611,8 @@ class AR3Ccf(CharacteristicFunction):
cf = tap * cf cf = tap * cf
io = np.where(cf == 0) io = np.where(cf == 0)
ino = 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.cf = cf
self.xcf = xnp self.xcf = xnp

View File

@ -4,11 +4,11 @@
import copy import copy
import operator import operator
import os 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.io.phases import picksdict_from_picks
from pylot.core.util.pdf import ProbabilityDensityFunction from pylot.core.util.pdf import ProbabilityDensityFunction
from pylot.core.util.utils import find_in_list from pylot.core.util.utils import find_in_list
@ -27,16 +27,8 @@ class Comparison(object):
""" """
def __init__(self, **kwargs): def __init__(self, **kwargs):
names = list()
self._pdfs = dict() self._pdfs = dict()
for name, fn in kwargs.items(): names = self.iter_kwargs(kwargs)
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)
if len(names) > 2: if len(names) > 2:
raise ValueError('Comparison is only defined for two ' raise ValueError('Comparison is only defined for two '
'arguments!') 'arguments!')
@ -48,6 +40,40 @@ class Comparison(object):
return False return False
return True 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): def get(self, name):
return self._pdfs[name] return self._pdfs[name]
@ -92,8 +118,8 @@ class Comparison(object):
""" """
compare_pdfs = dict() compare_pdfs = dict()
pdf_a = self.get(self.names[0]).generate_pdf_data(type) pdf_a = self.get('auto').generate_pdf_data(type)
pdf_b = self.get(self.names[1]).generate_pdf_data(type) pdf_b = self.get('manu').generate_pdf_data(type)
for station, phases in pdf_a.items(): for station, phases in pdf_a.items():
if station in pdf_b.keys(): if station in pdf_b.keys():
@ -154,7 +180,7 @@ class Comparison(object):
def get_array(self, phase, method_name): def get_array(self, phase, method_name):
method = operator.methodcaller(method_name) method = operator.methodcaller(method_name)
pdf_list = self.get_all(phase) pdf_list = self.get_all(phase)
rarray = map(method, pdf_list) rarray = list(map(method, pdf_list))
return np.array(rarray) return np.array(rarray)
def get_expectation_array(self, phase): def get_expectation_array(self, phase):
@ -252,11 +278,7 @@ class PDFDictionary(object):
@classmethod @classmethod
def from_quakeml(self, fn): def from_quakeml(self, fn):
cat = read_events(fn) return PDFDictionary(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]))
def get_all(self, phase): def get_all(self, phase):
rlist = list() rlist = list()
@ -334,7 +356,7 @@ class PDFDictionary(object):
axarr[l].set_title(phase) axarr[l].set_title(phase)
if l is 0: if l is 0:
axann = axarr[l].annotate(station, xy=(.05, .5), axann = axarr[l].annotate(station, xy=(.05, .5),
xycoords='axes fraction') xycoords='axes fraction')
bbox_props = dict(boxstyle='round', facecolor='lightgrey', bbox_props = dict(boxstyle='round', facecolor='lightgrey',
alpha=.7) alpha=.7)
axann.set_bbox(bbox_props) axann.set_bbox(bbox_props)
@ -352,7 +374,6 @@ class PDFstatistics(object):
Takes a path as argument. Takes a path as argument.
""" """
def __init__(self, directory): def __init__(self, directory):
"""Initiates some values needed when dealing with pdfs later""" """Initiates some values needed when dealing with pdfs later"""
self._rootdir = directory self._rootdir = directory
@ -449,7 +470,7 @@ class PDFstatistics(object):
else: else:
raise ValueError("for call to method {0} value has to be " raise ValueError("for call to method {0} value has to be "
"defined but is 'None' ".format(method_options[ "defined but is 'None' ".format(method_options[
property.upper()])) property.upper()]))
for pdf_dict in self: for pdf_dict in self:
# create worklist # create worklist
@ -459,7 +480,7 @@ class PDFstatistics(object):
return rlist 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 Method to write array like data to file. Useful since acquiring can take
serious amount of time when dealing with large databases. serious amount of time when dealing with large databases.
@ -471,16 +492,16 @@ class PDFstatistics(object):
""" """
fid = open(os.path.join(out_dir), 'w') fid = open(os.path.join(out_dir), 'w')
for val in array: for val in array:
fid.write(str(val)+'\n') fid.write(str(val) + '\n')
fid.close() fid.close()
def main(): def main():
root_dir ='/home/sebastianp/Codetesting/xmls/' root_dir = '/home/sebastianp/Codetesting/xmls/'
Insheim = PDFstatistics(root_dir) Insheim = PDFstatistics(root_dir)
Insheim.curphase = 'p' Insheim.curphase = 'p'
qdlist = Insheim.get('qdf', 0.2) qdlist = Insheim.get('qdf', 0.2)
print qdlist print(qdlist)
if __name__ == "__main__": if __name__ == "__main__":

View File

@ -19,12 +19,14 @@ calculated after Diehl & Kissling (2009).
:author: MAGS2 EP3 working group / Ludger Kueperkoch :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 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): class AutoPicker(object):
''' '''
@ -34,7 +36,7 @@ class AutoPicker(object):
warnings.simplefilter('ignore') 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 :param: cf, characteristic function, on which the picking algorithm is applied
:type: `~pylot.core.pick.CharFuns.CharacteristicFunction` object :type: `~pylot.core.pick.CharFuns.CharacteristicFunction` object
@ -61,7 +63,8 @@ class AutoPicker(object):
''' '''
assert isinstance(cf, CharacteristicFunction), "%s is not a CharacteristicFunction object" % str(cf) assert isinstance(cf, CharacteristicFunction), "%s is not a CharacteristicFunction object" % str(cf)
self._linecolor = linecolor
self._pickcolor_p = 'b'
self.cf = cf.getCF() self.cf = cf.getCF()
self.Tcf = cf.getTimeArray() self.Tcf = cf.getTimeArray()
self.Data = cf.getXCF() self.Data = cf.getXCF()
@ -153,6 +156,15 @@ class AICPicker(AutoPicker):
self.Pick = None self.Pick = None
self.slope = None self.slope = None
self.SNR = 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 # find NaN's
nn = np.isnan(self.cf) nn = np.isnan(self.cf)
if len(nn) > 1: if len(nn) > 1:
@ -208,106 +220,146 @@ class AICPicker(AutoPicker):
inoise = getnoisewin(self.Tcf, self.Pick, self.TSNR[0], self.TSNR[1]) inoise = getnoisewin(self.Tcf, self.Pick, self.TSNR[0], self.TSNR[1])
# check, if these are counts or m/s, important for slope estimation! # check, if these are counts or m/s, important for slope estimation!
# this is quick and dirty, better solution? # this is quick and dirty, better solution?
if max(self.Data[0].data < 1e-3): 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 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 # get signal window
isignal = getsignalwin(self.Tcf, self.Pick, self.TSNR[2]) 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] isignal = isignal[0:ii]
try: try:
aic[isignal] self.Data[0].data[isignal]
except IndexError as e: except IndexError as e:
msg = "Time series out of bounds! {}".format(e) msg = "Time series out of bounds! {}".format(e)
print(msg) print(msg)
return return
# calculate SNR from CF # calculate SNR from CF
self.SNR = max(abs(aic[isignal] - np.mean(aic[isignal]))) / \ self.SNR = max(abs(self.Data[0].data[isignal] - np.mean(self.Data[0].data[isignal]))) / \
max(abs(aic[inoise] - np.mean(aic[inoise]))) max(abs(self.Data[0].data[inoise] - np.mean(self.Data[0].data[inoise])))
# calculate slope from CF after initial pick # calculate slope from CF after initial pick
# get slope window # get slope window
tslope = self.TSNR[3] # slope determination window tslope = self.TSNR[3] # slope determination window
islope = np.where((self.Tcf <= min([self.Pick + tslope, len(self.Data[0].data)])) \ islope = np.where((self.Tcf <= min([self.Pick + tslope, self.Tcf[-1]])) \
& (self.Tcf >= self.Pick)) & (self.Tcf >= self.Pick)) # TODO: put this in a seperate function like getsignalwin
# find maximum within slope determination window # find maximum within slope determination window
# 'cause slope should be calculated up to first local minimum only! # 'cause slope should be calculated up to first local minimum only!
imax = np.argmax(self.Data[0].data[islope]) try:
iislope = islope[0][0:imax] dataslope = self.Data[0].data[islope[0][0:-1]]
if len(iislope) <= 2: 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 # calculate slope from initial onset to maximum of AIC function
print("AICPicker: Not enough data samples left for slope calculation!") print("AICPicker: Not enough data samples left for slope calculation!")
print("Calculating slope from initial onset to maximum of AIC function ...") 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: if imax == 0:
print("AICPicker: Maximum for slope determination right at the beginning of the window!") print("AICPicker: Maximum for slope determination right at the beginning of the window!")
print("Choose longer slope determination window!") print("Choose longer slope determination window!")
if self.iplot > 1: if self.iplot > 1:
if not self.fig: if self.fig == None or self.fig == 'None':
fig = plt.figure() #self.iplot) ### WHY? MP MP fig = plt.figure()
plt_flag = 1
else: else:
fig = self.fig fig = self.fig
ax = fig.add_subplot(111) ax = fig.add_subplot(111)
x = self.Data[0].data 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.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_xlabel('Time [s] since %s' % self.Data[0].stats.starttime)
ax.set_yticks([]) ax.set_yticks([])
ax.set_title(self.Data[0].stats.station) ax.set_title(self.Data[0].stats.station)
if plt_flag == 1:
fig.show()
try: input()
except SyntaxError: pass
plt.close(fig)
return return
iislope = islope[0][0:imax] iislope = islope[0][0:imax+1]
dataslope = self.Data[0].data[iislope] dataslope = self.Data[0].data[iislope]
# calculate slope as polynomal fit of order 1 # calculate slope as polynomal fit of order 1
xslope = np.arange(0, len(dataslope), 1) xslope = np.arange(0, len(dataslope), 1)
P = np.polyfit(xslope, dataslope, 1) P = np.polyfit(xslope, dataslope, 1)
datafit = np.polyval(P, xslope) datafit = np.polyval(P, xslope)
if datafit[0] >= datafit[len(datafit) - 1]: if datafit[0] >= datafit[-1]:
print('AICPicker: Negative slope, bad onset skipped!') print('AICPicker: Negative slope, bad onset skipped!')
return 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: else:
self.SNR = None self.SNR = None
self.slope = None self.slope = None
if self.iplot > 1: if iplot > 1:
if not self.fig: if self.fig == None or self.fig == 'None':
fig = plt.figure()#self.iplot) fig = plt.figure() # self.iplot)
plt_flag = 1
else: else:
fig = self.fig fig = self.fig
fig._tight = True
ax1 = fig.add_subplot(211) ax1 = fig.add_subplot(211)
x = self.Data[0].data 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') ax1.plot(self.Tcf, aicsmooth / max(aicsmooth), 'r', label='Smoothed AIC-CF')
if self.Pick is not None: if self.Pick is not None:
ax1.plot([self.Pick, self.Pick], [-0.1, 0.5], 'b', linewidth=2, label='AIC-Pick') 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_xlabel('Time [s] since %s' % self.Data[0].stats.starttime)
ax1.set_yticks([]) ax1.set_yticks([])
ax1.legend() ax1.legend(loc=1)
if self.Pick is not None: if self.Pick is not None:
ax2 = fig.add_subplot(2,1,2, sharex=ax1) ax2 = fig.add_subplot(2, 1, 2, sharex=ax1)
ax2.plot(self.Tcf, x, 'k', label='Data') 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[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[isignal[0]], self.Tcf[isignal[-1]], color='b', alpha=0.2, lw=0,
ax1.axvspan(self.Tcf[iislope[0]],self.Tcf[iislope[-1]], color='g', alpha=0.2, lw=0, label='Slope Window') label='Signal Window')
ax1.axvspan(self.Tcf[iislope[0]], self.Tcf[iislope[-1]], color='g', alpha=0.2, lw=0,
ax2.axvspan(self.Tcf[inoise[0]],self.Tcf[inoise[-1]], color='y', alpha=0.2, lw=0, label='Noise Window') label='Slope 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.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') 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, 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_xlabel('Time [s] since %s' % self.Data[0].stats.starttime)
ax2.set_ylabel('Counts') ax2.set_ylabel('Counts')
ax2.set_yticks([]) ax2.set_yticks([])
ax2.legend() ax2.legend(loc=1)
if plt_flag == 1:
fig.show()
try: input()
except SyntaxError: pass
plt.close(fig)
else: else:
ax1.set_title(self.Data[0].stats.station) 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: if self.Pick == None:
print('AICPicker: Could not find minimum, picking window too short?') print('AICPicker: Could not find minimum, picking window too short?')
return return
@ -317,7 +369,15 @@ class PragPicker(AutoPicker):
''' '''
def calcPick(self): 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: if self.getpick1() is not None:
print('PragPicker: Get most likely pick from HOS- or AR-CF using pragmatic picking algorithm ...') print('PragPicker: Get most likely pick from HOS- or AR-CF using pragmatic picking algorithm ...')
@ -325,6 +385,7 @@ class PragPicker(AutoPicker):
self.SNR = None self.SNR = None
self.slope = None self.slope = None
pickflag = 0 pickflag = 0
plt_flag = 0
# smooth CF # smooth CF
ismooth = int(round(self.Tsmooth / self.dt)) ismooth = int(round(self.Tsmooth / self.dt))
cfsmooth = np.zeros(len(self.cf)) cfsmooth = np.zeros(len(self.cf))
@ -349,12 +410,19 @@ class PragPicker(AutoPicker):
ipick1 = np.argmin(abs(self.Tcf - self.getpick1())) ipick1 = np.argmin(abs(self.Tcf - self.getpick1()))
cfpick1 = 2 * self.cf[ipick1] 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 # prominent trend: decrease aus
# flat: use given aus # flat: use given aus
cfdiff = np.diff(cfipick) cfdiff = np.diff(cfipick)
if len(cfdiff)<20:
print('PragPicker: Very few samples for CF. Check LTA window dimensions!')
i0diff = np.where(cfdiff > 0) i0diff = np.where(cfdiff > 0)
cfdiff = cfdiff[i0diff] 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)) minaus = min(cfdiff * (1 + self.aus))
aus1 = max([minaus, self.aus]) aus1 = max([minaus, self.aus])
@ -375,15 +443,20 @@ class PragPicker(AutoPicker):
break break
# now we look to the left # now we look to the left
for i in range(ipick1, max([ipick1 - lpickwindow + 1, 2]), -1): if len(self.cf) > ipick1 +1:
if self.cf[i + 1] > self.cf[i] and self.cf[i - 1] >= self.cf[i]: for i in range(ipick1, max([ipick1 - lpickwindow + 1, 2]), -1):
if cfsmooth[i - 1] * (1 + aus1) >= cfsmooth[i]: if self.cf[i + 1] > self.cf[i] and self.cf[i - 1] >= self.cf[i]:
if cfpick1 >= self.cf[i]: if cfsmooth[i - 1] * (1 + aus1) >= cfsmooth[i]:
pick_l = self.Tcf[i] if cfpick1 >= self.cf[i]:
self.Pick = pick_l pick_l = self.Tcf[i]
flagpick_r = 1 self.Pick = pick_l
cfpick_l = self.cf[i] flagpick_r = 1
break 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? # now decide which pick: left or right?
if flagpick_l > 0 and flagpick_r > 0 and cfpick_l <= 3 * cfpick_r: 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 self.Pick = pick_l
pickflag = 1 pickflag = 1
else: else:
print('PragPicker: Could not find reliable onset!') print("PragPicker: Could not find reliable onset!")
self.Pick = None self.Pick = None
pickflag = 0 pickflag = 0
if self.getiplot() > 1: if iplot > 1:
if not self.fig: if self.fig == None or self.fig == 'None':
fig = plt.figure()#self.getiplot()) fig = plt.figure() # self.getiplot())
plt_flag = 1
else: else:
fig = self.fig fig = self.fig
fig._tight = True
ax = fig.add_subplot(111) 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') ax.plot(Tcfpick, cfsmoothipick, 'r', label='Smoothed CF')
if pickflag > 0: 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_xlabel('Time [s] since %s' % self.Data[0].stats.starttime)
ax.set_yticks([]) ax.set_yticks([])
ax.set_title(self.Data[0].stats.station) 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 return
else: else:
print('PragPicker: No initial onset time given! Check input!') print("PragPicker: No initial onset time given! Check input!")
self.Pick = None self.Pick = None
return return

View File

@ -9,12 +9,13 @@
""" """
import warnings import warnings
import matplotlib.pyplot as plt import matplotlib.pyplot as plt
import numpy as np import numpy as np
from obspy.core import Stream, UTCDateTime from obspy.core import Stream, UTCDateTime
def earllatepicker(X, nfac, TSNR, Pick1, iplot=None, 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) Function to derive earliest and latest possible pick after Diehl & Kissling (2009)
as reasonable uncertainties. Latest possible pick is based on noise level, as reasonable uncertainties. Latest possible pick is based on noise level,
@ -41,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) assert isinstance(X, Stream), "%s is not a stream object" % str(X)
if verbosity == 2: if verbosity == 2:
print('earllatepicker:') print('earllatepicker:')
print('nfac:', nfac) print('nfac:', nfac)
print('Init pick:', Pick1) print('Init pick:', Pick1)
print('TSNR (T_noise, T_gap, T_signal):', TSNR) print('TSNR (T_noise, T_gap, T_signal):', TSNR)
LPick = None LPick = None
EPick = None EPick = None
PickError = None PickError = None
plt_flag = 0
try:
iplot = int(iplot)
except:
if iplot == True or iplot == 'True':
iplot = 2
else:
iplot = 0
if verbosity: if verbosity:
print('earllatepicker: Get earliest and latest possible pick' print('earllatepicker: Get earliest and latest possible pick'
' relative to most likely pick ...') ' relative to most likely pick ...')
@ -69,14 +79,14 @@ def earllatepicker(X, nfac, TSNR, Pick1, iplot=None, verbosity=1, fig=None):
print('x_inoise:', x[inoise]) print('x_inoise:', x[inoise])
print('x_isignal:', x[isignal]) print('x_isignal:', x[isignal])
print('nlevel:', nlevel) print('nlevel:', nlevel)
# get time where signal exceeds nlevel # get time where signal exceeds nlevel
ilup, = np.where(x[isignal] > nlevel) ilup, = np.where(x[isignal] > nlevel)
ildown, = np.where(x[isignal] < -nlevel) ildown, = np.where(x[isignal] < -nlevel)
if not ilup.size and not ildown.size: if not ilup.size and not ildown.size:
if verbosity: if verbosity:
print ("earllatepicker: Signal lower than noise level!\n" print("earllatepicker: Signal lower than noise level!\n"
"Skip this trace!") "Skip this trace!")
return LPick, EPick, PickError return LPick, EPick, PickError
il = min(np.min(ilup) if ilup.size else float('inf'), il = min(np.min(ilup) if ilup.size else float('inf'),
np.min(ildown) if ildown.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 # get earliest possible pick
EPick = np.nan; EPick = np.nan
count = 0 count = 0
pis = isignal 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) PickError = symmetrize_error(diffti_te, diffti_tl)
if iplot > 1: if iplot > 1:
if not fig: if fig == None or fig == 'None':
fig = plt.figure()#iplot) fig = plt.figure() # iplot)
plt_flag = 1
fig._tight = True
ax = fig.add_subplot(111) 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[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.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[0], t[int(len(t)) - 1]], [nlevel, nlevel], color=linecolor, linewidth=0.7, linestyle='dashed', label='Noise Level')
ax.plot(t[isignal[zc]], np.zeros(len(zc)), '*g', ax.plot(t[pis[zc]], np.zeros(len(zc)), '*g',
markersize=14, label='Zero Crossings') 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([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([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], '--k', label='epp') 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], 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], 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_xlabel('Time [s] since %s' % X[0].stats.starttime)
ax.set_yticks([]) ax.set_yticks([])
ax.set_title( ax.set_title(
'Earliest-/Latest Possible/Most Likely Pick & Symmetric Pick Error, %s' % 'Earliest-/Latest Possible/Most Likely Pick & Symmetric Pick Error, %s' %
X[0].stats.station) X[0].stats.station)
ax.legend() ax.legend(loc=1)
if plt_flag == 1:
fig.show()
try: input()
except SyntaxError: pass
plt.close(fig)
return EPick, LPick, PickError 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. Function to derive first motion (polarity) of given phase onset Pick.
Calculation is based on zero crossings determined within time window pickwin Calculation is based on zero crossings determined within time window pickwin
@ -166,6 +183,15 @@ def fmpicker(Xraw, Xfilt, pickwin, Pick, iplot=None, fig=None):
:type: int :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) warnings.simplefilter('ignore', np.RankWarning)
assert isinstance(Xraw, Stream), "%s is not a stream object" % str(Xraw) 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 FM = None
if Pick is not 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 xraw = Xraw[0].data
xfilt = Xfilt[0].data xfilt = Xfilt[0].data
t = np.arange(0, Xraw[0].stats.npts / Xraw[0].stats.sampling_rate, t = np.arange(0, Xraw[0].stats.npts / Xraw[0].stats.sampling_rate,
Xraw[0].stats.delta) Xraw[0].stats.delta)
# get pick window # get pick window
ipick = np.where( ipick = np.where((t <= min([Pick + pickwin, len(Xraw[0])])) & (t >= Pick))
(t <= min([Pick + pickwin, len(Xraw[0])])) & (t >= Pick)) if len(ipick[0]) <= 1:
print('fmpicker: Zero crossings window to short!')
return
# remove mean # remove mean
xraw[ipick] = xraw[ipick] - np.mean(xraw[ipick]) xraw[ipick] = xraw[ipick] - np.mean(xraw[ipick])
xfilt[ipick] = xfilt[ipick] - np.mean(xfilt[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: if len(zc1) == 3:
break break
if len(zc1) < 3:
print('fmpicker: Could not determine zero crossings!')
return
# if time difference betweeen 1st and 2cnd zero crossing # if time difference betweeen 1st and 2cnd zero crossing
# is too short, get time difference between 1st and 3rd # is too short, get time difference between 1st and 3rd
# to derive maximum # to derive maximum
@ -211,16 +243,16 @@ def fmpicker(Xraw, Xfilt, pickwin, Pick, iplot=None, fig=None):
li1 = index1[1] li1 = index1[1]
else: else:
li1 = index1[0] li1 = index1[0]
if np.size(xraw[ipick[0][1]:ipick[0][li1]]) == 0: 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!") print("fmpicker: Onset on unfiltered trace too emergent for first motion determination!")
P1 = None P1 = None
else: else:
imax1 = np.argmax(abs(xraw[ipick[0][1]:ipick[0][li1]])) imax1 = np.argmax(abs(xraw[ipick[0][1]:ipick[0][li1]]))
if imax1 == 0: if imax1 == 0:
imax1 = np.argmax(abs(xraw[ipick[0][1]:ipick[0][index1[1]]])) imax1 = np.argmax(abs(xraw[ipick[0][1]:ipick[0][index1[1]]]))
if imax1 == 0: if imax1 == 0:
print ("fmpicker: Zero crossings too close!") print("fmpicker: Zero crossings too close!")
print ("Skip first motion determination!") print("Skip first motion determination!")
return FM return FM
islope1 = np.where((t >= Pick) & (t <= Pick + t[imax1])) 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] li2 = index2[1]
else: else:
li2 = index2[0] li2 = index2[0]
if np.size(xfilt[ipick[0][1]:ipick[0][li2]]) == 0: 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!") print("fmpicker: Onset on filtered trace too emergent for first motion determination!")
P2 = None P2 = None
else: else:
imax2 = np.argmax(abs(xfilt[ipick[0][1]:ipick[0][li2]])) imax2 = np.argmax(abs(xfilt[ipick[0][1]:ipick[0][li2]]))
if imax2 == 0: if imax2 == 0:
imax2 = np.argmax(abs(xfilt[ipick[0][1]:ipick[0][index2[1]]])) imax2 = np.argmax(abs(xfilt[ipick[0][1]:ipick[0][index2[1]]]))
if imax2 == 0: if imax2 == 0:
print ("fmpicker: Zero crossings too close!") print("fmpicker: Zero crossings too close!")
print ("Skip first motion determination!") print("Skip first motion determination!")
return FM return FM
islope2 = np.where((t >= Pick) & (t <= Pick + t[imax2])) 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]: elif P1[0] > 0 >= P2[0]:
FM = '+' FM = '+'
print ("fmpicker: Found polarity %s" % FM) print("fmpicker: Found polarity %s" % FM)
if iplot > 1: if iplot > 1:
if not fig: if fig == None or fig == 'None':
fig = plt.figure()#iplot) fig = plt.figure() # iplot)
plt_flag = 1
fig._tight = True
ax1 = fig.add_subplot(211) 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') ax1.plot([Pick, Pick], [max(xraw), -max(xraw)], 'b', linewidth=2, label='Pick')
if P1 is not None: if P1 is not None:
ax1.plot(t[islope1], xraw[islope1], label='Slope Window') ax1.plot(t[islope1], xraw[islope1], label='Slope Window')
ax1.plot(zc1, np.zeros(len(zc1)), '*g', markersize=14, label='Zero Crossings') ax1.plot(zc1, np.zeros(len(zc1)), '*g', markersize=14, label='Zero Crossings')
ax1.plot(t[islope1], datafit1, '--g', linewidth=2) 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.text(Pick + 0.02, max(xraw) / 2, '%s' % FM, fontsize=14)
ax1.set_yticks([]) ax1.set_yticks([])
ax1.set_title('First-Motion Determination, %s, Unfiltered Data' % Xraw[ ax1.set_title('First-Motion Determination, %s, Unfiltered Data' % Xraw[
0].stats.station) 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.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', ax2.plot([Pick, Pick], [max(xfilt), -max(xfilt)], 'b',
linewidth=2) linewidth=2)
if P2 is not None: if P2 is not None:
ax2.plot(t[islope2], xfilt[islope2]) ax2.plot(t[islope2], xfilt[islope2])
ax2.plot(zc2, np.zeros(len(zc2)), '*g', markersize=14) 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.text(Pick + 0.02, max(xraw) / 2, '%s' % FM, fontsize=14)
ax2.set_xlabel('Time [s] since %s' % Xraw[0].stats.starttime) ax2.set_xlabel('Time [s] since %s' % Xraw[0].stats.starttime)
ax2.set_yticks([]) ax2.set_yticks([])
if plt_flag == 1:
fig.show()
try: input()
except SyntaxError: pass
plt.close(fig)
return FM 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) assert isinstance(X, Stream), "%s is not a stream object" % str(X)
SNR = None SNR = None
SNRdb = None SNRdB = None
noiselevel = None noiselevel = None
x = X[tracenum].data x = X[tracenum].data
npts = X[tracenum].stats.npts npts = X[tracenum].stats.npts
sr = X[tracenum].stats.sampling_rate sr = X[tracenum].stats.sampling_rate
@ -372,7 +411,7 @@ def getSNR(X, TSNR, t1, tracenum=0):
# get signal window # get signal window
isignal = getsignalwin(t, t1, TSNR[2]) isignal = getsignalwin(t, t1, TSNR[2])
if np.size(inoise) < 1: if np.size(inoise) < 1:
print ("getSNR: Empty array inoise, check noise window!") print("getSNR: Empty array inoise, check noise window!")
return SNR, SNRdB, noiselevel return SNR, SNRdB, noiselevel
# demean over entire waveform # demean over entire waveform
@ -380,13 +419,13 @@ def getSNR(X, TSNR, t1, tracenum=0):
# calculate ratios # calculate ratios
noiselevel = np.sqrt(np.mean(np.square(x[inoise]))) noiselevel = np.sqrt(np.mean(np.square(x[inoise])))
#signallevel = np.sqrt(np.mean(np.square(x[isignal]))) # signallevel = np.sqrt(np.mean(np.square(x[isignal])))
if np.size(isignal) < 1: 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 return SNR, SNRdB, noiselevel
#noiselevel = np.abs(x[inoise]).max() # noiselevel = np.abs(x[inoise]).max()
signallevel = np.abs(x[isignal]).max() signallevel = np.abs(x[isignal]).max()
SNR = signallevel / noiselevel SNR = signallevel / noiselevel
@ -418,9 +457,9 @@ def getnoisewin(t, t1, tnoise, tgap):
inoise, = np.where((t <= max([t1 - tgap, 0])) \ inoise, = np.where((t <= max([t1 - tgap, 0])) \
& (t >= max([t1 - tnoise - tgap, 0]))) & (t >= max([t1 - tnoise - tgap, 0])))
if np.size(inoise) < 1: if np.size(inoise) < 1:
inoise, = np.where((t>=t[0]) & (t<=t1)) inoise, = np.where((t >= t[0]) & (t <= t1))
if np.size(inoise) < 1: if np.size(inoise) < 1:
print ("getnoisewin: Empty array inoise, check noise window!") print("getnoisewin: Empty array inoise, check noise window!")
return inoise return inoise
@ -441,10 +480,10 @@ def getsignalwin(t, t1, tsignal):
''' '''
# get signal window # get signal window
isignal, = np.where((t <= min([t1 + tsignal, len(t)])) \ isignal, = np.where((t <= min([t1 + tsignal, t[-1]])) \
& (t >= t1)) & (t >= t1))
if np.size(isignal) < 1: if np.size(isignal) < 1:
print ("getsignalwin: Empty array isignal, check signal window!") print("getsignalwin: Empty array isignal, check signal window!")
return isignal return isignal
@ -473,24 +512,25 @@ def getResolutionWindow(snr, extent):
>>> getResolutionWindow(2) >>> getResolutionWindow(2)
2.5 2.5
""" """
res_wins = { res_wins = {
'regional': {'HRW': 2., 'MRW': 5., 'LRW': 10., 'VLRW': 15.}, 'regional': {'HRW': 2., 'MRW': 5., 'LRW': 10., 'VLRW': 15.},
'local': {'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.} 'global': {'HRW': 40., 'MRW': 100., 'LRW': 200., 'VLRW': 300.}
} }
if snr < 1.5: if snr:
time_resolution = res_wins[extent]['VLRW'] if snr < 1.5:
elif snr < 2.: time_resolution = res_wins[extent]['VLRW']
time_resolution = res_wins[extent]['LRW'] elif snr < 2.:
elif snr < 3.: time_resolution = res_wins[extent]['LRW']
time_resolution = res_wins[extent]['MRW'] elif snr < 3.:
elif snr >3.: time_resolution = res_wins[extent]['MRW']
time_resolution = res_wins[extent]['HRW'] elif snr > 3.:
time_resolution = res_wins[extent]['HRW']
else: else:
time_resolution = res_wins[extent]['VLRW'] time_resolution = res_wins[extent]['VLRW']
return time_resolution / 2 return time_resolution / 2
@ -528,7 +568,7 @@ def select_for_phase(st, phase):
return sel_st 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 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 to detect S pick outliers. If a certain S-P time deviates by dttolerance
@ -551,7 +591,10 @@ def wadaticheck(pickdic, dttolerance, iplot):
Ppicks = [] Ppicks = []
Spicks = [] Spicks = []
SPtimes = [] 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: if pickdic[key]['P']['weight'] < 4 and pickdic[key]['S']['weight'] < 4:
# calculate S-P time # calculate S-P time
spt = pickdic[key]['S']['mpp'] - pickdic[key]['P']['mpp'] spt = pickdic[key]['S']['mpp'] - pickdic[key]['P']['mpp']
@ -572,25 +615,29 @@ def wadaticheck(pickdic, dttolerance, iplot):
# calculate vp/vs ratio before check # calculate vp/vs ratio before check
vpvsr = p1[0] + 1 vpvsr = p1[0] + 1
print ("###############################################") print("###############################################")
print ("wadaticheck: Average Vp/Vs ratio before check: %f" % vpvsr) print("wadaticheck: Average Vp/Vs ratio before check: %f" % vpvsr)
checkedPpicks = [] checkedPpicks = []
checkedSpicks = [] checkedSpicks = []
checkedSPtimes = [] checkedSPtimes = []
badstations = []
# calculate deviations from Wadati regression # calculate deviations from Wadati regression
ii = 0 ii = 0
ibad = 0 for key in list(pickdic.keys()):
for key in pickdic: if 'SPt' in pickdic[key]:
if pickdic[key].has_key('SPt'): stations.append(key)
wddiff = abs(pickdic[key]['SPt'] - wdfit[ii]) wddiff = abs(pickdic[key]['SPt'] - wdfit[ii])
ii += 1 ii += 1
# check, if deviation is larger than adjusted # check, if deviation is larger than adjusted
if wddiff > dttolerance: if wddiff > dttolerance:
# mark onset and downgrade S-weight to 9 # remove pick from dictionary
# (not used anymore) pickdic.pop(key)
marker = 'badWadatiCheck' # # mark onset and downgrade S-weight to 9
pickdic[key]['S']['weight'] = 9 # # (not used anymore)
# marker = 'badWadatiCheck'
# pickdic[key]['S']['weight'] = 9
badstations.append(key)
ibad += 1 ibad += 1
else: else:
marker = 'goodWadatiCheck' marker = 'goodWadatiCheck'
@ -601,7 +648,10 @@ def wadaticheck(pickdic, dttolerance, iplot):
checkedSPtime = pickdic[key]['S']['mpp'] - pickdic[key]['P']['mpp'] checkedSPtime = pickdic[key]['S']['mpp'] - pickdic[key]['P']['mpp']
checkedSPtimes.append(checkedSPtime) 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: if len(checkedPpicks) >= 3:
# calculate new slope # calculate new slope
@ -610,42 +660,67 @@ def wadaticheck(pickdic, dttolerance, iplot):
# calculate vp/vs ratio after check # calculate vp/vs ratio after check
cvpvsr = p2[0] + 1 cvpvsr = p2[0] + 1
print ("wadaticheck: Average Vp/Vs ratio after check: %f" % cvpvsr) print("wadaticheck: Average Vp/Vs ratio after check: %f" % cvpvsr)
print ("wadatacheck: Skipped %d S pick(s)" % ibad) print("wadatacheck: Skipped %d S pick(s)" % ibad)
else: else:
print ("###############################################") print("###############################################")
print ("wadatacheck: Not enough checked S-P times available!") print("wadaticheck: Not enough checked S-P times available!")
print ("Skip Wadati check!") print("Skip Wadati check!")
wfitflag = 1
wdfit2 = None
checkedonsets = pickdic checkedonsets = pickdic
else: else:
print ("wadaticheck: Not enough S-P times available for reliable regression!") print("wadaticheck: Not enough S-P times available for reliable regression!")
print ("Skip wadati check!") print("Skip wadati check!")
wfitflag = 1 wfitflag = 1
# plot results # plot results
if iplot > 0: if iplot > 0:
plt.figure()#iplot) if fig_dict:
f1, = plt.plot(Ppicks, SPtimes, 'ro') fig = fig_dict['wadati']
if wfitflag == 0: linecolor = fig_dict['plot_style']['linecolor']['rgba_mpl']
f2, = plt.plot(Ppicks, wdfit, 'k') plt_flag = 0
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')
else: 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]') ax.set_title('Wadati-Diagram, %d S-P Times, Vp/Vs(raw)=%5.2f,' \
plt.xlabel('P Times [s]') '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 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. Function to detect spuriously picked noise peaks.
Uses RMS trace of all 3 components (if available) to determine, Uses RMS trace of all 3 components (if available) to determine,
@ -676,9 +751,18 @@ def checksignallength(X, pick, TSNR, minsiglength, nfac, minpercent, iplot=0, fi
: type: int : 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) assert isinstance(X, Stream), "%s is not a stream object" % str(X)
print ("Checking signal length ...") print("Checking signal length ...")
if len(X) > 1: if len(X) > 1:
# all three components available # 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) rms = np.sqrt((np.power(x1, 2) + np.power(x2, 2) + np.power(x3, 2)) / 3)
else: else:
x1 = X[0].data 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, t = np.arange(0, ilen / X[0].stats.sampling_rate,
X[0].stats.delta) X[0].stats.delta)
# get noise window in front of pick plus saftey gap # 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 # get signal window
isignal = getsignalwin(t, pick, minsiglength) isignal = getsignalwin(t, pick, minsiglength)
# calculate minimum adjusted signal level # 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 # minimum adjusted number of samples over minimum signal level
minnum = len(isignal) * minpercent / 100 minnum = len(isignal) * minpercent / 100
# get number of samples above minimum adjusted signal level # get number of samples above minimum adjusted signal level
numoverthr = len(np.where(rms[isignal] >= minsiglevel)[0]) numoverthr = len(np.where(rms[isignal] >= minsiglevel)[0])
if numoverthr >= minnum: if numoverthr >= minnum:
print ("checksignallength: Signal reached required length.") print("checksignallength: Signal reached required length.")
returnflag = 1 returnflag = 1
else: else:
print ("checksignallength: Signal shorter than required minimum signal length!") print("checksignallength: Signal shorter than required minimum signal length!")
print ("Presumably picked noise peak, pick is rejected!") print("Presumably picked noise peak, pick is rejected!")
print ("(min. signal length required: %s s)" % minsiglength) print("(min. signal length required: %s s)" % minsiglength)
returnflag = 0 returnflag = 0
if iplot == 2: if iplot > 1:
if not fig: if fig == None or fig == 'None':
fig = plt.figure()#iplot) fig = plt.figure() # iplot)
plt_flag = 1
fig._tight = True
ax = fig.add_subplot(111) ax = fig.add_subplot(111)
ax.plot(t, rms, 'k', label='RMS Data') 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[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.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]]], ax.plot([t[isignal[0]], t[isignal[len(isignal) - 1]]],
[minsiglevel, minsiglevel], 'g', linewidth=2, label='Minimum Signal Level') [minsiglevel, minsiglevel], 'g', linewidth=2, label='Minimum Signal Level')
ax.plot([pick, pick], [min(rms), max(rms)], 'b', linewidth=2, label='Onset') 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_xlabel('Time [s] since %s' % X[0].stats.starttime)
ax.set_ylabel('Counts') ax.set_ylabel('Counts')
ax.set_title('Check for Signal Length, Station %s' % X[0].stats.station) ax.set_title('Check for Signal Length, Station %s' % X[0].stats.station)
ax.set_yticks([]) ax.set_yticks([])
if plt_flag == 1:
fig.show()
try: input()
except SyntaxError: pass
plt.close(fig)
return returnflag 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 Function to check statistics of P-onset times: Control deviation from
median (maximum adjusted deviation = dttolerance) and apply pseudo- median (maximum adjusted deviation = dttolerance) and apply pseudo-
@ -757,24 +849,26 @@ def checkPonsets(pickdic, dttolerance, iplot):
# search for good quality P picks # search for good quality P picks
Ppicks = [] Ppicks = []
stations = [] stations = []
for key in pickdic: for station in pickdic:
if pickdic[key]['P']['weight'] < 4: if pickdic[station]['P']['weight'] < 4:
# add P onsets to list # add P onsets to list
UTCPpick = UTCDateTime(pickdic[key]['P']['mpp']) UTCPpick = UTCDateTime(pickdic[station]['P']['mpp'])
Ppicks.append(UTCPpick.timestamp) Ppicks.append(UTCPpick.timestamp)
stations.append(key) stations.append(station)
# apply jackknife bootstrapping on variance of P onsets # apply jackknife bootstrapping on variance of P onsets
print ("###############################################") print("###############################################")
print ("checkPonsets: Apply jackknife bootstrapping on P-onset times ...") print("checkPonsets: Apply jackknife bootstrapping on P-onset times ...")
[xjack, PHI_pseudo, PHI_sub] = jackknife(Ppicks, 'VAR', 1) [xjack, PHI_pseudo, PHI_sub] = jackknife(Ppicks, 'VAR', 1)
if not xjack:
return
# get pseudo variances smaller than average variances # get pseudo variances smaller than average variances
# (times safety factor), these picks passed jackknife test # (times safety factor), these picks passed jackknife test
ij = np.where(PHI_pseudo <= 5 * xjack) ij = np.where(PHI_pseudo <= jackfactor * xjack)
# these picks did not pass jackknife test # 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] 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) print(badjkstations)
# calculate median from these picks # calculate median from these picks
@ -787,9 +881,10 @@ def checkPonsets(pickdic, dttolerance, iplot):
goodstations = np.array(stations)[igood] goodstations = np.array(stations)[igood]
badstations = np.array(stations)[ibad] badstations = np.array(stations)[ibad]
print ("checkPonsets: %d pick(s) deviate too much from median!" % len(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) \ print(badstations)
+ len(badjkstations), len(stations))) print("checkPonsets: Skipped %d P pick(s) out of %d" % (len(badstations) \
+ len(badjkstations), len(stations)))
goodmarker = 'goodPonsetcheck' goodmarker = 'goodPonsetcheck'
badmarker = 'badPonsetcheck' badmarker = 'badPonsetcheck'
@ -798,34 +893,52 @@ def checkPonsets(pickdic, dttolerance, iplot):
# mark P onset as checked and keep P weight # mark P onset as checked and keep P weight
pickdic[goodstations[i]]['P']['marked'] = goodmarker pickdic[goodstations[i]]['P']['marked'] = goodmarker
for i in range(0, len(badstations)): for i in range(0, len(badstations)):
# mark P onset and downgrade P weight to 9 # remove pick from dictionary
# (not used anymore) pickdic.pop(badstations[i])
pickdic[badstations[i]]['P']['marked'] = badmarker
pickdic[badstations[i]]['P']['weight'] = 9
for i in range(0, len(badjkstations)): for i in range(0, len(badjkstations)):
# mark P onset and downgrade P weight to 9 # remove pick from dictionary
# (not used anymore) pickdic.pop(badjkstations[i])
pickdic[badjkstations[i]]['P']['marked'] = badjkmarker # for i in range(0, len(badstations)):
pickdic[badjkstations[i]]['P']['weight'] = 9 # # 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 checkedonsets = pickdic
if iplot > 0: if iplot > 0:
p1, = plt.plot(np.arange(0, len(Ppicks)), Ppicks, 'ro', markersize=14) if fig_dict:
if len(badstations) < 1 and len(badjkstations) < 1: fig = fig_dict['jackknife']
p2, = plt.plot(np.arange(0, len(Ppicks)), Ppicks, 'go', markersize=14) plt_flag = 0
else: else:
p2, = plt.plot(igood, np.array(Ppicks)[igood], 'go', markersize=14) fig = plt.figure()
p3, = plt.plot([0, len(Ppicks) - 1], [pmedian, pmedian], 'g', plt_flag = 1
linewidth=2) ax = fig.add_subplot(111)
for i in range(0, len(Ppicks)):
plt.text(i, Ppicks[i] + 0.01, '{0}'.format(stations[i]))
plt.xlabel('Number of P Picks') if len(badstations) > 0:
plt.ylabel('Onset Time [s] from 1.1.1970') ax.plot(ibad, np.array(Ppicks)[ibad], marker ='o', markerfacecolor='orange', markersize=14,
plt.legend([p1, p2, p3], ['Skipped P Picks', 'Good P Picks', 'Median'], linestyle='None', label='Median Skipped P Picks')
loc='best') if len(badjkstations) > 0:
plt.title('Jackknifing and Median Tests on P Onsets') 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 return checkedonsets
@ -854,13 +967,13 @@ def jackknife(X, phi, h):
PHI_sub = None PHI_sub = None
# determine number of subgroups # determine number of subgroups
g = len(X) / h
if type(g) is not int: if len(X) % h:
print ("jackknife: Cannot divide quantity X in equal sized subgroups!") print("jackknife: Cannot divide quantity X in equal sized subgroups!")
print ("Choose another size for subgroups!") print("Choose another size for subgroups!")
return PHI_jack, PHI_pseudo, PHI_sub return PHI_jack, PHI_pseudo, PHI_sub
else: else:
g = int(len(X) / h)
# estimator of undisturbed spot check # estimator of undisturbed spot check
if phi == 'MEA': if phi == 'MEA':
phi_sc = np.mean(X) phi_sc = np.mean(X)
@ -894,7 +1007,7 @@ def jackknife(X, phi, h):
return PHI_jack, PHI_pseudo, PHI_sub return PHI_jack, PHI_pseudo, PHI_sub
def checkZ4S(X, pick, zfac, checkwin, iplot, fig=None): def checkZ4S(X, pick, zfac, checkwin, iplot, fig=None, linecolor='k'):
''' '''
Function to compare energy content of vertical trace with Function to compare energy content of vertical trace with
energy content of horizontal traces to detect spuriously energy content of horizontal traces to detect spuriously
@ -923,10 +1036,20 @@ def checkZ4S(X, pick, zfac, checkwin, iplot, fig=None):
are shown are shown
: type: int : 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) 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 returnflag = 0
@ -941,74 +1064,122 @@ def checkZ4S(X, pick, zfac, checkwin, iplot, fig=None):
if len(ndat) == 0: # check for other components if len(ndat) == 0: # check for other components
ndat = X.select(component="1") 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, tz = np.arange(0, zdat[0].stats.npts / zdat[0].stats.sampling_rate,
zdat[0].stats.delta) 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 zdiff = (zdat[0].stats.starttime - min_t)
absz = np.sqrt(np.power(z, 2)) ndiff = (ndat[0].stats.starttime - min_t)
# calculate RMS trace from both horizontal traces ediff = (edat[0].stats.starttime - min_t)
# 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))
# get signal window # get signal windows
isignal = getsignalwin(tz, pick, checkwin) isignalz = getsignalwin(tz, pick - zdiff, checkwin)
isignaln = getsignalwin(tn, pick - ndiff, checkwin)
isignale = getsignalwin(te, pick - ediff, checkwin)
# calculate energy levels # calculate RMS of traces
try: rmsz = RMS(zdat[0].data[isignalz])
zcodalevel = max(absz[isignal]) rmsn = RMS(ndat[0].data[isignaln])
except: rmse = RMS(edat[0].data[isignale])
ii = np.where(isignal <= len(absz))
isignal = isignal[ii]
zcodalevel = max(absz[isignal - 1])
try:
encodalevel = max(absen[isignal])
except:
ii = np.where(isignal <= len(absen))
isignal = isignal[ii]
encodalevel = max(absen[isignal - 1])
# calculate threshold # calculate threshold
minsiglevel = encodalevel * zfac minsiglevel = (rmsn + rmse) / 2 * zfac
# vertical P-coda level must exceed horizontal P-coda level # vertical P-coda level must exceed horizontal P-coda level
# zfac times encodalevel # zfac times encodalevel
if zcodalevel < minsiglevel: if rmsz < minsiglevel:
print ("checkZ4S: Maybe S onset? Skip this P pick!") print("checkZ4S: Maybe S onset? Skip this P pick!")
else: else:
print ("checkZ4S: P onset passes checkZ4S test!") print("checkZ4S: P onset passes checkZ4S test!")
returnflag = 1 returnflag = 1
if iplot > 1: if iplot > 1:
te = np.arange(0, edat[0].stats.npts / edat[0].stats.sampling_rate, rms_dict = {'Z': rmsz,
edat[0].stats.delta) 'N': rmsn,
tn = np.arange(0, ndat[0].stats.npts / ndat[0].stats.sampling_rate, 'E': rmse}
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()
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 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__': if __name__ == '__main__':
import doctest import doctest

File diff suppressed because it is too large Load Diff

View File

@ -1,13 +1,16 @@
#!/usr/bin/env python #!/usr/bin/env python
# -*- coding: utf-8 -*- # -*- 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: try:
urllib2.urlopen(url, timeout=1) urlopen(url, timeout=1)
return True return True
except urllib2.URLError: except:
pass pass
return False return False

View File

@ -1,13 +1,11 @@
#!/usr/bin/env python #!/usr/bin/env python
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
import os
import glob import glob
import os
import sys import sys
from obspy.io.xseed import Parser
import numpy as np import numpy as np
from obspy import UTCDateTime, read_inventory, read from obspy import UTCDateTime, read_inventory, read
from obspy.io.xseed import Parser from obspy.io.xseed import Parser
from pylot.core.util.utils import key_for_set_value, find_in_list, \ 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 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. 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. :param root_dir: a directory leading to the .gse files.
@ -170,7 +168,7 @@ def read_metadata(path_to_inventory):
invfile = list() invfile = list()
respfile = list() respfile = list()
# possible file extensions specified here: # 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): if os.path.isfile(path_to_inventory):
ext = os.path.splitext(path_to_inventory)[1].split('.')[1] ext = os.path.splitext(path_to_inventory)[1].split('.')[1]
inv[ext] += [path_to_inventory] inv[ext] += [path_to_inventory]
@ -184,7 +182,7 @@ def read_metadata(path_to_inventory):
print("Neither dataless-SEED file, inventory-xml file nor " print("Neither dataless-SEED file, inventory-xml file nor "
"RESP-file found!") "RESP-file found!")
print("!!WRONG CALCULATION OF SOURCE PARAMETERS!!") print("!!WRONG CALCULATION OF SOURCE PARAMETERS!!")
robj = None, robj = None,
elif invtype == 'dless': # prevent multiple read of large dlsv elif invtype == 'dless': # prevent multiple read of large dlsv
print("Reading metadata information from dataless-SEED file ...") print("Reading metadata information from dataless-SEED file ...")
if len(inv[invtype]) == 1: if len(inv[invtype]) == 1:
@ -202,7 +200,7 @@ def restitute_trace(input_tuple):
tr, invtype, inobj, unit, force = input_tuple tr, invtype, inobj, unit, force = input_tuple
remove_trace = False remove_trace = False
seed_id = tr.get_id() seed_id = tr.get_id()
# check, whether this trace has already been corrected # check, whether this trace has already been corrected
if 'processing' in tr.stats.keys() \ if 'processing' in tr.stats.keys() \
@ -245,14 +243,14 @@ def restitute_trace(input_tuple):
remove_trace = True remove_trace = True
# apply restitution to data # apply restitution to data
print("Correcting instrument at station %s, channel %s" \ print("Correcting instrument at station %s, channel %s" \
% (tr.stats.station, tr.stats.channel)) % (tr.stats.station, tr.stats.channel))
try: try:
if invtype in ['resp', 'dless']: if invtype in ['resp', 'dless']:
try: try:
tr.simulate(**kwargs) tr.simulate(**kwargs)
except ValueError as e: except ValueError as e:
vmsg = '{0}'.format(e) vmsg = '{0}'.format(e)
print(vmsg) print(vmsg)
else: else:
tr.attach_response(inventory) tr.attach_response(inventory)
@ -271,7 +269,7 @@ def restitute_trace(input_tuple):
return tr, remove_trace 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 takes a data stream and a path_to_inventory and returns the corrected
waveform data stream waveform data stream
@ -294,15 +292,15 @@ def restitute_data(data, invtype, inobj, unit='VEL', force=False):
for tr in data: for tr in data:
input_tuples.append((tr, invtype, inobj, unit, force)) input_tuples.append((tr, invtype, inobj, unit, force))
data.remove(tr) data.remove(tr)
pool = gen_Pool() pool = gen_Pool(ncores)
result = pool.map(restitute_trace, input_tuples) result = pool.map(restitute_trace, input_tuples)
pool.close() pool.close()
for tr, remove_trace in result: for tr, remove_trace in result:
if not remove_trace: if not remove_trace:
data.traces.append(tr) data.traces.append(tr)
# check if ALL traces could be restituted, take care of large datasets # check if ALL traces could be restituted, take care of large datasets
# better try restitution for smaller subsets of data (e.g. station by # better try restitution for smaller subsets of data (e.g. station by
# station) # 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)) trace.stats.station, trace.stats.channel))
# get corner frequencies for pre-filtering # get corner frequencies for pre-filtering
fny = trace.stats.sampling_rate / 2 fny = trace.stats.sampling_rate / 2
fc21 = fny - (fny * thi[0]/100.) fc21 = fny - (fny * thi[0] / 100.)
fc22 = fny - (fny * thi[1]/100.) fc22 = fny - (fny * thi[1] / 100.)
return (tlow[0], tlow[1], fc21, fc22) return (tlow[0], tlow[1], fc21, fc22)

View File

@ -7,43 +7,29 @@ Created on Wed Feb 26 12:31:25 2014
""" """
import os import os
from pylot.core.loc import nll import platform
from pylot.core.loc import hyposat
from pylot.core.util.utils import readDefaultFilterInformation
from pylot.core.loc import hypo71 from pylot.core.loc import hypo71
from pylot.core.loc import hypodd from pylot.core.loc import hypodd
from pylot.core.loc import hyposat
from pylot.core.loc import nll
from pylot.core.loc import velest from pylot.core.loc import velest
def readFilterInformation(fname): # determine system dependent path separator
def convert2FreqRange(*args): system_name = platform.system()
if len(args) > 1: if system_name in ["Linux", "Darwin"]:
return [float(arg) for arg in args] SEPARATOR = '/'
elif len(args) == 1: elif system_name == "Windows":
return float(args[0]) SEPARATOR = '\\'
return None
filter_file = open(fname, 'r') # suffix for phase name if not phase identified by last letter (P, p, etc.)
filter_information = dict() ALTSUFFIX = ['diff', 'n', 'g', '1', '2', '3']
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
FILTERDEFAULTS = readDefaultFilterInformation(os.path.join(os.path.expanduser('~'),
FILTERDEFAULTS = readFilterInformation(os.path.join(os.path.expanduser('~'), '.pylot',
'.pylot', 'pylot.in'))
'filter.in'))
TIMEERROR_DEFAULTS = os.path.join(os.path.expanduser('~'), TIMEERROR_DEFAULTS = os.path.join(os.path.expanduser('~'),
'.pylot', '.pylot',
@ -59,14 +45,14 @@ LOCTOOLS = dict(nll=nll, hyposat=hyposat, velest=velest, hypo71=hypo71, hypodd=h
class SetChannelComponents(object): class SetChannelComponents(object):
def __init__(self): def __init__(self):
self.setDefaultCompPosition() self.setDefaultCompPosition()
def setDefaultCompPosition(self): def setDefaultCompPosition(self):
# default component order # default component order
self.compPosition_Map = dict(Z=2, N=1, E=0) self.compPosition_Map = dict(Z=2, N=1, E=0)
self.compName_Map = {'3': 'Z', self.compName_Map = {'3': 'Z',
'1': 'N', '1': 'N',
'2': 'E'} '2': 'E'}
def _getCurrentPosition(self, component): def _getCurrentPosition(self, component):
for key, value in self.compName_Map.items(): for key, value in self.compName_Map.items():
if value == component: if value == component:
@ -85,10 +71,10 @@ class SetChannelComponents(object):
def setCompPosition(self, component_alter, component, switch=True): def setCompPosition(self, component_alter, component, switch=True):
component_alter = str(component_alter) component_alter = str(component_alter)
if not component_alter in self.compName_Map.keys(): 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())) raise ValueError(errMsg.format(component_alter, self.compName_Map.keys()))
if not component in self.compPosition_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())) raise ValueError(errMsg.format(component, self.compPosition_Map.keys()))
print('setCompPosition: set component {} to {}'.format(component_alter, component)) print('setCompPosition: set component {} to {}'.format(component_alter, component))
if switch: if switch:
@ -97,7 +83,7 @@ class SetChannelComponents(object):
def getCompPosition(self, component): def getCompPosition(self, component):
return self._getCurrentPosition(component)[0] return self._getCurrentPosition(component)[0]
def getPlotPosition(self, component): def getPlotPosition(self, component):
component = str(component) component = str(component)
if component in self.compPosition_Map.keys(): if component in self.compPosition_Map.keys():
@ -105,6 +91,5 @@ class SetChannelComponents(object):
elif component in self.compName_Map.keys(): elif component in self.compName_Map.keys():
return self.compPosition_Map[self.compName_Map[component]] return self.compPosition_Map[self.compName_Map[component]]
else: 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())) raise ValueError(errMsg.format(component, self.compPosition_Map.keys(), self.compName_Map.keys()))

View File

@ -25,5 +25,6 @@ class OverwriteError(IOError):
class ParameterError(Exception): class ParameterError(Exception):
pass pass
class ProcessingError(RuntimeError): class ProcessingError(RuntimeError):
pass pass

View File

@ -5,8 +5,7 @@ import os
from obspy import UTCDateTime from obspy import UTCDateTime
from obspy.core.event import Event as ObsPyEvent 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 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. Pickable class derived from ~obspy.core.event.Event containing information on a single event.
''' '''
def __init__(self, path): def __init__(self, path):
self.pylot_id = path.split('/')[-1] self.pylot_id = path.split('/')[-1]
# initialize super class # 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.path = path
self.database = path.split('/')[-2] self.database = path.split('/')[-2]
self.datapath = path.split('/')[-3] self.datapath = path.split('/')[-3]
@ -32,13 +32,13 @@ class Event(ObsPyEvent):
def get_notes_path(self): def get_notes_path(self):
notesfile = os.path.join(self.path, 'notes.txt') notesfile = os.path.join(self.path, 'notes.txt')
return notesfile return notesfile
def get_notes(self): def get_notes(self):
notesfile = self.get_notes_path() notesfile = self.get_notes_path()
if os.path.isfile(notesfile): if os.path.isfile(notesfile):
with open(notesfile) as infile: with open(notesfile) as infile:
path = str(infile.readlines()[0].split('\n')[0]) path = str(infile.readlines()[0].split('\n')[0])
text = '[eventInfo: '+path+']' text = '[eventInfo: ' + path + ']'
self.addNotes(text) self.addNotes(text)
try: try:
datetime = UTCDateTime(path.split('/')[-1]) datetime = UTCDateTime(path.split('/')[-1])
@ -67,31 +67,47 @@ class Event(ObsPyEvent):
self._testEvent = bool self._testEvent = bool
if bool: self._refEvent = False 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): def addPicks(self, picks):
''' '''
add pylot picks and overwrite existing add pylot picks and overwrite existing ones
''' '''
for station in picks: for station in picks:
self.pylot_picks[station] = picks[station] self.pylot_picks[station] = picks[station]
#add ObsPy picks # add ObsPy picks (clear old manual and copy all new manual from pylot)
self.picks = picks_from_picksdict(self.pylot_picks) self.clearObsPyPicks('manual')
self.picks += picks_from_picksdict(self.pylot_picks)
def addAutopicks(self, autopicks): def addAutopicks(self, autopicks):
for station in autopicks: for station in autopicks:
self.pylot_autopicks[station] = autopicks[station] 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): def setPick(self, station, pick):
if pick: if pick:
self.pylot_picks[station] = 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): def setPicks(self, picks):
''' '''
set pylot picks and delete and overwrite all existing set pylot picks and delete and overwrite all existing
''' '''
self.pylot_picks = picks 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): def getPick(self, station):
if station in self.pylot_picks.keys(): if station in self.pylot_picks.keys():
return self.pylot_picks[station] return self.pylot_picks[station]
@ -99,13 +115,25 @@ class Event(ObsPyEvent):
def getPicks(self): def getPicks(self):
return self.pylot_picks return self.pylot_picks
def setAutopick(self, station, autopick): def setAutopick(self, station, pick):
if autopick: if pick:
self.pylot_autopicks[station] = autopick 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): def getAutopick(self, station):
if station in self.pylot_autopicks.keys(): if station in self.pylot_autopicks.keys():
return self.pylot_autopicks[station] return self.pylot_autopicks[station]

View File

@ -1,24 +1,28 @@
from mpl_toolkits.basemap import Basemap #!/usr/bin/env python
# -*- coding: utf-8 -*-
import matplotlib.pyplot as plt import matplotlib.pyplot as plt
import numpy as np import numpy as np
import obspy import obspy
from matplotlib import cm from PySide import QtGui
from scipy.interpolate import griddata
from matplotlib.backends.backend_qt4agg import NavigationToolbar2QT as NavigationToolbar 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 pylot.core.util.widgets import PickDlg
from scipy.interpolate import griddata
plt.interactive(False) plt.interactive(False)
class map_projection(QtGui.QWidget): class map_projection(QtGui.QWidget):
def __init__(self, parent, figure=None): def __init__(self, parent, figure=None):
''' '''
:param: picked, can be False, auto, manual :param: picked, can be False, auto, manual
:value: str :value: str
''' '''
QtGui.QWidget.__init__(self) QtGui.QWidget.__init__(self)
self._parent = parent self._parent = parent
self.metadata = parent.metadata
self.parser = parent.metadata[1] self.parser = parent.metadata[1]
self.picks = None self.picks = None
self.picks_dict = None self.picks_dict = None
@ -28,7 +32,7 @@ class map_projection(QtGui.QWidget):
self.init_stations() self.init_stations()
self.init_basemap(resolution='l') self.init_basemap(resolution='l')
self.init_map() self.init_map()
#self.show() # self.show()
def init_map(self): def init_map(self):
self.init_lat_lon_dimensions() self.init_lat_lon_dimensions()
@ -36,7 +40,7 @@ class map_projection(QtGui.QWidget):
self.init_x_y_dimensions() self.init_x_y_dimensions()
self.connectSignals() self.connectSignals()
self.draw_everything() self.draw_everything()
def onpick(self, event): def onpick(self, event):
ind = event.ind ind = event.ind
button = event.mouseevent.button button = event.mouseevent.button
@ -44,7 +48,7 @@ class map_projection(QtGui.QWidget):
return return
data = self._parent.get_data().getWFData() data = self._parent.get_data().getWFData()
for index in ind: for index in ind:
station=str(self.station_names[index].split('.')[-1]) station = str(self.station_names[index].split('.')[-1])
try: try:
pickDlg = PickDlg(self, parameter=self._parent._inputs, pickDlg = PickDlg(self, parameter=self._parent._inputs,
data=data.select(station=station), data=data.select(station=station),
@ -89,7 +93,7 @@ class map_projection(QtGui.QWidget):
else: else:
self.figure = self._parent.am_figure self.figure = self._parent.am_figure
self.toolbar = self._parent.am_toolbar self.toolbar = self._parent.am_toolbar
self.main_ax = self.figure.add_subplot(111) self.main_ax = self.figure.add_subplot(111)
self.canvas = self.figure.canvas self.canvas = self.figure.canvas
@ -105,29 +109,29 @@ class map_projection(QtGui.QWidget):
self.comboBox_am = QtGui.QComboBox() self.comboBox_am = QtGui.QComboBox()
self.comboBox_am.insertItem(0, 'auto') 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(QtGui.QLabel('Select a phase: '))
self.top_row.addWidget(self.comboBox_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.canvas)
self.main_box.addWidget(self.toolbar) self.main_box.addWidget(self.toolbar)
def init_stations(self): def init_stations(self):
def get_station_names_lat_lon(parser): def get_station_names_lat_lon(parser):
station_names=[] station_names = []
lat=[] lat = []
lon=[] lon = []
for station in parser.stations: for station in parser.stations:
station_name=station[0].station_call_letters station_name = station[0].station_call_letters
network=station[0].network_code network = station[0].network_code
if not station_name in station_names: if not station_name in station_names:
station_names.append(network+'.'+station_name) station_names.append(network + '.' + station_name)
lat.append(station[0].latitude) lat.append(station[0].latitude)
lon.append(station[0].longitude) lon.append(station[0].longitude)
return station_names, lat, lon return station_names, lat, lon
station_names, lat, lon = get_station_names_lat_lon(self.parser) station_names, lat, lon = get_station_names_lat_lon(self.parser)
self.station_names = station_names self.station_names = station_names
self.lat = lat self.lat = lat
@ -135,52 +139,53 @@ class map_projection(QtGui.QWidget):
def init_picks(self): def init_picks(self):
phase = self.comboBox_phase.currentText() phase = self.comboBox_phase.currentText()
def get_picks(station_names): def get_picks(station_names):
picks=[] picks = []
for station in station_names: for station in station_names:
try: try:
station=station.split('.')[-1] station = station.split('.')[-1]
picks.append(self.picks_dict[station][phase]['mpp']) picks.append(self.picks_dict[station][phase]['mpp'])
except: except:
picks.append(np.nan) picks.append(np.nan)
return picks return picks
def get_picks_rel(picks): def get_picks_rel(picks):
picks_rel=[] picks_rel = []
picks_utc = [] picks_utc = []
for pick in picks: for pick in picks:
if type(pick) is obspy.core.utcdatetime.UTCDateTime: if type(pick) is obspy.core.utcdatetime.UTCDateTime:
picks_utc.append(pick) picks_utc.append(pick)
minp = min(picks_utc) minp = min(picks_utc)
for pick in picks: for pick in picks:
if type(pick) is obspy.core.utcdatetime.UTCDateTime: if type(pick) is obspy.core.utcdatetime.UTCDateTime:
pick -= minp pick -= minp
picks_rel.append(pick) picks_rel.append(pick)
return picks_rel return picks_rel
self.picks = get_picks(self.station_names) self.picks = get_picks(self.station_names)
self.picks_rel = get_picks_rel(self.picks) self.picks_rel = get_picks_rel(self.picks)
def init_picks_active(self): def init_picks_active(self):
def remove_nan_picks(picks): def remove_nan_picks(picks):
picks_no_nan=[] picks_no_nan = []
for pick in picks: for pick in picks:
if not np.isnan(pick): if not np.isnan(pick):
picks_no_nan.append(pick) picks_no_nan.append(pick)
return picks_no_nan return picks_no_nan
self.picks_no_nan = remove_nan_picks(self.picks_rel) self.picks_no_nan = remove_nan_picks(self.picks_rel)
def init_stations_active(self): def init_stations_active(self):
def remove_nan_lat_lon(picks, lat, lon): def remove_nan_lat_lon(picks, lat, lon):
lat_no_nan=[] lat_no_nan = []
lon_no_nan=[] lon_no_nan = []
for index, pick in enumerate(picks): for index, pick in enumerate(picks):
if not np.isnan(pick): if not np.isnan(pick):
lat_no_nan.append(lat[index]) lat_no_nan.append(lat[index])
lon_no_nan.append(lon[index]) lon_no_nan.append(lon[index])
return lat_no_nan, lon_no_nan 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) self.lat_no_nan, self.lon_no_nan = remove_nan_lat_lon(self.picks_rel, self.lat, self.lon)
def init_lat_lon_dimensions(self): def init_lat_lon_dimensions(self):
@ -188,7 +193,7 @@ class map_projection(QtGui.QWidget):
londim = max(lon) - min(lon) londim = max(lon) - min(lon)
latdim = max(lat) - min(lat) latdim = max(lat) - min(lat)
return londim, latdim return londim, latdim
self.londim, self.latdim = get_lon_lat_dim(self.lon, self.lat) self.londim, self.latdim = get_lon_lat_dim(self.lon, self.lat)
def init_x_y_dimensions(self): def init_x_y_dimensions(self):
@ -196,30 +201,30 @@ class map_projection(QtGui.QWidget):
xdim = max(x) - min(x) xdim = max(x) - min(x)
ydim = max(y) - min(y) ydim = max(y) - min(y)
return xdim, ydim return xdim, ydim
self.x, self.y = self.basemap(self.lon, self.lat) self.x, self.y = self.basemap(self.lon, self.lat)
self.xdim, self.ydim = get_x_y_dim(self.x, self.y) self.xdim, self.ydim = get_x_y_dim(self.x, self.y)
def init_basemap(self, resolution='l'): def init_basemap(self, resolution='l'):
#basemap = Basemap(projection=projection, 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, basemap = Basemap(projection='lcc', resolution=resolution, ax=self.main_ax,
width=5e6, height=2e6, width=5e6, height=2e6,
lat_0=(min(self.lat)+max(self.lat))/2., lat_0=(min(self.lat) + max(self.lat)) / 2.,
lon_0=(min(self.lon)+max(self.lon))/2.) lon_0=(min(self.lon) + max(self.lon)) / 2.)
#basemap.fillcontinents(color=None, lake_color='aqua',zorder=1) # basemap.fillcontinents(color=None, lake_color='aqua',zorder=1)
basemap.drawmapboundary(zorder=2)#fill_color='darkblue') basemap.drawmapboundary(zorder=2) # fill_color='darkblue')
basemap.shadedrelief(zorder=3) basemap.shadedrelief(zorder=3)
basemap.drawcountries(zorder=4) basemap.drawcountries(zorder=4)
basemap.drawstates(zorder=5) basemap.drawstates(zorder=5)
basemap.drawcoastlines(zorder=6) basemap.drawcoastlines(zorder=6)
self.basemap = basemap self.basemap = basemap
self.figure.tight_layout() self.figure.tight_layout()
def init_lat_lon_grid(self): def init_lat_lon_grid(self):
def get_lat_lon_axis(lat, lon): def get_lat_lon_axis(lat, lon):
steplat = (max(lat)-min(lat))/250 steplat = (max(lat) - min(lat)) / 250
steplon = (max(lon)-min(lon))/250 steplon = (max(lon) - min(lon)) / 250
lataxis = np.arange(min(lat), max(lat), steplat) lataxis = np.arange(min(lat), max(lat), steplat)
lonaxis = np.arange(min(lon), max(lon), steplon) lonaxis = np.arange(min(lon), max(lon), steplon)
@ -234,7 +239,8 @@ class map_projection(QtGui.QWidget):
def init_picksgrid(self): def init_picksgrid(self):
self.picksgrid_no_nan = griddata((self.lat_no_nan, self.lon_no_nan), 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'): def draw_contour_filled(self, nlevel='50'):
levels = np.linspace(min(self.picks_no_nan), max(self.picks_no_nan), nlevel) 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): def scatter_all_stations(self):
self.sc = self.basemap.scatter(self.lon, self.lat, s=50, facecolor='none', latlon=True, 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) self.cid = self.canvas.mpl_connect('pick_event', self.onpick)
if self.eventLoc: if self.eventLoc:
lat, lon = self.eventLoc lat, lon = self.eventLoc
@ -254,11 +260,11 @@ class map_projection(QtGui.QWidget):
lon = self.lon_no_nan lon = self.lon_no_nan
lat = self.lat_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: if len(lon) <= 2 and len(lat) <= 2:
self.sc_picked = self.basemap.scatter(lon[0], lat[0], s=50, facecolor='white', 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') 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', self.sc_picked = self.basemap.scatter(lon[1], lat[1], s=50, facecolor='white',
c=self.picks_no_nan[1], latlon=True, zorder=11) c=self.picks_no_nan[1], latlon=True, zorder=11)
else: else:
@ -266,11 +272,11 @@ class map_projection(QtGui.QWidget):
c=self.picks_no_nan, latlon=True, zorder=11, label='Picked') c=self.picks_no_nan, latlon=True, zorder=11, label='Picked')
def annotate_ax(self): def annotate_ax(self):
self.annotations=[] self.annotations = []
for index, name in enumerate(self.station_names): for index, name in enumerate(self.station_names):
self.annotations.append(self.main_ax.annotate(' %s' % name, xy=(self.x[index], self.y[index]), self.annotations.append(self.main_ax.annotate(' %s' % name, xy=(self.x[index], self.y[index]),
fontsize='x-small', color='white', zorder=12)) 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): def add_cbar(self, label):
cbar = self.main_ax.figure.colorbar(self.sc_picked, fraction=0.025) 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): def remove_drawings(self):
if hasattr(self, 'sc_picked'): if hasattr(self, 'sc_picked'):
self.sc_picked.remove() self.sc_picked.remove()
del(self.sc_picked) del (self.sc_picked)
if hasattr(self, 'sc_event'): if hasattr(self, 'sc_event'):
self.sc_event.remove() self.sc_event.remove()
del(self.sc_event) del (self.sc_event)
if hasattr(self, 'cbar'): if hasattr(self, 'cbar'):
self.cbar.remove() self.cbar.remove()
del(self.cbar) del (self.cbar)
if hasattr(self, 'contourf'): if hasattr(self, 'contourf'):
self.remove_contourf() self.remove_contourf()
del(self.contourf) del (self.contourf)
if hasattr(self, 'cid'): if hasattr(self, 'cid'):
self.canvas.mpl_disconnect(self.cid) self.canvas.mpl_disconnect(self.cid)
del(self.cid) del (self.cid)
try: try:
self.sc.remove() self.sc.remove()
except Exception as e: except Exception as e:
@ -342,18 +348,18 @@ class map_projection(QtGui.QWidget):
xlim = map.ax.get_xlim() xlim = map.ax.get_xlim()
ylim = map.ax.get_ylim() ylim = map.ax.get_ylim()
x, y = event.xdata, event.ydata x, y = event.xdata, event.ydata
zoom = {'up': 1./2., zoom = {'up': 1. / 2.,
'down': 2.} 'down': 2.}
if not event.xdata or not event.ydata: if not event.xdata or not event.ydata:
return return
if event.button in zoom: if event.button in zoom:
factor = zoom[event.button] factor = zoom[event.button]
xdiff = (xlim[1]-xlim[0])*factor xdiff = (xlim[1] - xlim[0]) * factor
xl = x - 0.5 * xdiff xl = x - 0.5 * xdiff
xr = 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 yb = y - 0.5 * ydiff
yt = 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_xlim(xl, xr)
map.ax.set_ylim(yb, yt) map.ax.set_ylim(yb, yt)
map.ax.figure.canvas.draw() map.ax.figure.canvas.draw()
def _warn(self, message): def _warn(self, message):
self.qmb = QtGui.QMessageBox(QtGui.QMessageBox.Icon.Warning, self.qmb = QtGui.QMessageBox(QtGui.QMessageBox.Icon.Warning,
'Warning', message) 'Warning', message)
self.qmb.show() self.qmb.show()

View File

@ -2,20 +2,23 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
import warnings import warnings
import numpy as np import numpy as np
from obspy import UTCDateTime 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 from pylot.core.util.version import get_git_version as _getVersionString
__version__ = _getVersionString() __version__ = _getVersionString()
__author__ = 'sebastianw' __author__ = 'sebastianw'
def create_axis(x0, incr, npts): def create_axis(x0, incr, npts):
ax = np.zeros(npts) ax = np.zeros(npts)
for i in range(npts): for i in range(npts):
ax[i] = x0 + incr * i ax[i] = x0 + incr * i
return ax return ax
def gauss_parameter(te, tm, tl, eta): def gauss_parameter(te, tm, tl, eta):
''' '''
takes three onset times and returns the parameters sig1, sig2, a1 and a2 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 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 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 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 :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): def _func(k, mu, sig1, sig2, a1, a2):
if k < mu: if k < mu:
rval = a1 * 1 / (np.sqrt(2 * np.pi) * sig1) * np.exp(-((k - mu) / sig1) ** 2 / 2) 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) 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 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 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: :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): def _func(k, mu, sig1, sig2, a):
mu = float(mu) mu = float(mu)
if k < mu: if k < mu:
@ -239,7 +248,7 @@ class ProbabilityDensityFunction(object):
self._x = np.array(x) self._x = np.array(x)
@classmethod @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'): type='exp'):
''' '''
Initialize a new ProbabilityDensityFunction object. Initialize a new ProbabilityDensityFunction object.
@ -307,14 +316,14 @@ class ProbabilityDensityFunction(object):
:return float: rval :return float: rval
''' '''
#rval = 0 # rval = 0
#for x in self.axis: # for x in self.axis:
# rval += x * self.data(x) # rval += x * self.data(x)
rval = self.mu rval = self.mu
# Not sure about this! That might not be the barycentre. # Not sure about this! That might not be the barycentre.
# However, for std calculation (next function) # However, for std calculation (next function)
# self.mu is also used!! (LK, 02/2017) # self.mu is also used!! (LK, 02/2017)
return rval return rval
def standard_deviation(self): def standard_deviation(self):
mu = self.mu mu = self.mu
@ -388,7 +397,6 @@ class ProbabilityDensityFunction(object):
qu = self.quantile(1 - prob_value) qu = self.quantile(1 - prob_value)
return qu - ql return qu - ql
def quantile_dist_frac(self, x): def quantile_dist_frac(self, x):
""" """
takes a probability value and returns the fraction of two takes a probability value and returns the fraction of two
@ -405,8 +413,7 @@ class ProbabilityDensityFunction(object):
""" """
if x <= 0 or x >= 0.25: if x <= 0 or x >= 0.25:
raise ValueError('Value out of range.') 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): def plot(self, label=None):
import matplotlib.pyplot as plt import matplotlib.pyplot as plt
@ -480,4 +487,3 @@ class ProbabilityDensityFunction(object):
x0, npts = self.commonlimits(incr, other) x0, npts = self.commonlimits(incr, other)
return x0, incr, npts return x0, incr, npts

View File

@ -3,6 +3,7 @@
import matplotlib.pyplot as plt import matplotlib.pyplot as plt
def create_bin_list(l_boundary, u_boundary, nbins=100): 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 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: if fnout:
plt.savefig(fnout) plt.savefig(fnout)
else: else:
plt.show() plt.show()

View File

@ -1,82 +1,167 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
import sys, os import sys, os, traceback
from PySide.QtCore import QThread, Signal, Qt import multiprocessing
from PySide.QtGui import QDialog, QProgressBar, QLabel, QHBoxLayout from PySide.QtCore import QThread, Signal, Qt, Slot, QRunnable, QObject
from PySide.QtGui import QDialog, QProgressBar, QLabel, QHBoxLayout, QPushButton
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
class Thread(QThread): class Thread(QThread):
message = Signal(str) 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) QThread.__init__(self, parent)
self.func = func self.func = func
self.arg = arg self.arg = arg
self.progressText = progressText self.progressText = progressText
self.pb_widget = pb_widget self.pb_widget = pb_widget
self.redirect_stdout = redirect_stdout self.redirect_stdout = redirect_stdout
self.abortButton = abortButton
self.finished.connect(self.hideProgressbar) self.finished.connect(self.hideProgressbar)
self.showProgressbar() self.showProgressbar()
def run(self): def run(self):
if self.redirect_stdout: if self.redirect_stdout:
sys.stdout = self sys.stdout = self
try: try:
if self.arg: if self.arg:
self.data = self.func(self.arg) self.data = self.func(self.arg)
else: else:
self.data = self.func() self.data = self.func()
self._executed = True 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: except Exception as e:
self._executed = False self._executed = False
self._executedError = e self._executedError = e
exc_type, exc_obj, exc_tb = sys.exc_info() exc_type, exc_obj, exc_tb = sys.exc_info()
fname = os.path.split(exc_tb.tb_frame.f_code.co_filename)[1] 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)) print('Exception: {}, file: {}, line: {}'.format(exc_type, fname, exc_tb.tb_lineno))
sys.stdout = sys.__stdout__ sys.stdout = sys.__stdout__
def __del__(self):
self.wait()
def showProgressbar(self): def showProgressbar(self):
if self.progressText: if self.progressText:
if not self.pb_widget: if not self.pb_widget:
self.pb_widget = QDialog(self.parent()) self.pb_widget = QDialog(self.parent())
self.pb_widget.setWindowFlags(Qt.SplashScreen) self.pb_widget.setWindowFlags(Qt.SplashScreen)
self.pb_widget.setModal(True) self.pb_widget.setModal(True)
hl = QHBoxLayout() hl = QHBoxLayout()
pb = QProgressBar() pb = QProgressBar()
@ -95,4 +180,8 @@ class Thread(QThread):
def flush(self): def flush(self):
pass pass
def emitDone(self, result):
print('emitDone!')
self.finished.emit('Done thread!')
self.hideProgressbar()

View File

@ -2,26 +2,57 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
import hashlib import hashlib
import numpy as np
from scipy.interpolate import splrep, splev
import os import os
import pwd import platform
import re import re
import warnings
import subprocess 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): def _pickle_method(m):
if m.im_self is None: if m.im_self is None:
return getattr, (m.im_class, m.im_func.func_name) return getattr, (m.im_class, m.im_func.func_name)
else: else:
return getattr, (m.im_self, m.im_func.func_name) 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): def fit_curve(x, y):
return splev, splrep(x, y) return splev, splrep(x, y)
def getindexbounds(f, eta): def getindexbounds(f, eta):
mi = f.argmax() mi = f.argmax()
m = max(f) m = max(f)
@ -31,16 +62,55 @@ def getindexbounds(f, eta):
return mi, l, u 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 import multiprocessing
if ncores=='max': if ncores == 0:
ncores=multiprocessing.cpu_count() ncores = multiprocessing.cpu_count()
print('gen_Pool: Generated multiprocessing Pool with {} cores\n'.format(ncores))
pool = multiprocessing.Pool(ncores) pool = multiprocessing.Pool(ncores)
return pool 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): def clims(lim1, lim2):
""" """
takes two pairs of limits and returns one pair of common limts 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 return combo_box.findText(val) if combo_box.findText(val) is not -1 else 0
def find_in_list(list, str): def find_in_list(list, str):
""" """
takes a list of strings and a string and returns the first list item 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 rlist[0]
return None return None
def find_nearest(array, value): def find_nearest(array, value):
''' '''
function find_nearest takes an array and a value and returns the function find_nearest takes an array and a value and returns the
@ -182,6 +254,22 @@ def fnConstructor(s):
return fn 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): def four_digits(year):
""" """
takes a two digit year integer and returns the correct four digit equivalent 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 returns the actual user's login ID
:return: login ID :return: login ID
''' '''
return pwd.getpwuid(os.getuid())[0] return os.getlogin()
def getOwner(fn): def getOwner(fn):
@ -268,7 +356,15 @@ def getOwner(fn):
:type fn: str :type fn: str
:return: login ID of the file's owner :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): def getPatternLine(fn, pattern):
@ -294,6 +390,7 @@ def getPatternLine(fn, pattern):
return None return None
def is_executable(fn): def is_executable(fn):
""" """
takes a filename and returns True if the file is executable on the system 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 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 takes a starttime and a trace object and returns a valid time axis for
plotting plotting
@ -376,16 +473,18 @@ def prepTimeAxis(stime, trace):
etime = stime + nsamp / srate etime = stime + nsamp / srate
time_ax = np.arange(stime, etime, tincr) time_ax = np.arange(stime, etime, tincr)
if len(time_ax) < nsamp: 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) time_ax = np.arange(stime, etime + tincr, tincr)
elif len(time_ax) > nsamp: 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) time_ax = np.arange(stime, etime - tincr, tincr)
if len(time_ax) != nsamp: if len(time_ax) != nsamp:
print('Station {0}, {1} samples of data \n ' print('Station {0}, {1} samples of data \n '
'{2} length of time vector \n' '{2} length of time vector \n'
'delta: {3}'.format(trace.stats.station, 'delta: {3}'.format(trace.stats.station,
nsamp, len(time_ax), tincr)) nsamp, len(time_ax), tincr))
time_ax = None time_ax = None
return time_ax return time_ax
@ -413,6 +512,91 @@ def find_horizontals(data):
return rval 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): def remove_underscores(data):
""" """
takes a `obspy.core.stream.Stream` object and removes all underscores takes a `obspy.core.stream.Stream` object and removes all underscores
@ -427,6 +611,176 @@ def remove_underscores(data):
return 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'): def scaleWFData(data, factor=None, components='all'):
""" """
produce scaled waveforms from given waveform data and a scaling factor, 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) subprocess.check_output('{} | tee /dev/stderr'.format(cmd), shell=True)
def which(program, infile=None): def which(program, infile=None):
""" """
takes a program name and returns the full path to the executable or 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') bpath = os.path.join(os.path.expanduser('~'), '.pylot', 'pylot.in')
else: else:
bpath = os.path.join(os.path.expanduser('~'), '.pylot', infile) bpath = os.path.join(os.path.expanduser('~'), '.pylot', infile)
if os.path.exists(bpath): if os.path.exists(bpath):
nllocpath = ":" + PylotParameter(bpath).get('nllocbin') nllocpath = ":" + PylotParameter(bpath).get('nllocbin')
os.environ['PATH'] += nllocpath os.environ['PATH'] += nllocpath
@ -523,6 +878,61 @@ def which(program, infile=None):
return 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__": if __name__ == "__main__":
import doctest import doctest

File diff suppressed because it is too large Load Diff

319295
pylot/os

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

1
pylot/styles/__init__.py Normal file
View File

@ -0,0 +1 @@
# -*- coding: utf-8 -*-

259
pylot/styles/bright.qss Normal file
View 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
View 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);
}

View 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'}
}
}

View File

@ -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_()

View File

@ -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_()

View File

@ -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_()

View File

@ -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()

View File

@ -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()

View File

@ -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()

View File

@ -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)

View File

@ -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

View File

@ -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)

View File

@ -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)

View File

@ -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)

View File

@ -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)

View File

@ -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)

View File

@ -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)

View File

@ -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)

View File

@ -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)

View File

@ -4,11 +4,11 @@ from distutils.core import setup
setup( setup(
name='PyLoT', name='PyLoT',
version='0.1a1', version='0.2',
packages=['pylot', 'pylot.core', 'pylot.core.loc', 'pylot.core.pick', packages=['pylot', 'pylot.core', 'pylot.core.loc', 'pylot.core.pick',
'pylot.core.io', 'pylot.core.util', 'pylot.core.active', 'pylot.core.io', 'pylot.core.util', 'pylot.core.active',
'pylot.core.analysis', 'pylot.testing'], 'pylot.core.analysis', 'pylot.testing'],
requires=['obspy', 'PySide'], requires=['obspy', 'PySide', 'matplotlib', 'numpy'],
url='dummy', url='dummy',
license='LGPLv3', license='LGPLv3',
author='Sebastian Wehling-Benatelli', author='Sebastian Wehling-Benatelli',