coppied files from Ludgers Laptop

This commit is contained in:
Marcel Paffrath 2017-04-06 13:16:28 +02:00
parent f5c06cd6b7
commit c90b061de9
56 changed files with 64030 additions and 244 deletions

View File

@ -15,7 +15,7 @@ Some icons are out of a free of charge icon set, which can be found here:
https://www.iconfinder.com/iconsets/flavour https://www.iconfinder.com/iconsets/flavour
:author: :author:
Sebastian Wehling-Benatelli Sebastian Wehling-Benatelli / Ludger Küperkoch
:copyright: :copyright:
The PyLoT Development Team (https://ariadne.geophysik.rub.de/trac/PyLoT) The PyLoT Development Team (https://ariadne.geophysik.rub.de/trac/PyLoT)
:license: :license:
@ -25,14 +25,13 @@ https://www.iconfinder.com/iconsets/flavour
import os import os
import sys import sys
import matplotlib import matplotlib
matplotlib.use('Qt4Agg') matplotlib.use('Qt4Agg')
matplotlib.rcParams['backend.qt4'] = 'PySide' matplotlib.rcParams['backend.qt4'] = 'PySide'
from PySide.QtCore import QCoreApplication, QSettings, Signal, QFile, \ from PySide.QtCore import QCoreApplication, QSettings, Signal, QFile, \
QFileInfo, Qt QFileInfo, Qt, QSize
from PySide.QtGui import QMainWindow, QInputDialog, QIcon, QFileDialog, \ from PySide.QtGui import QMainWindow, QInputDialog, QIcon, QFileDialog, \
QWidget, QHBoxLayout, QStyle, QKeySequence, QLabel, QFrame, QAction, \ QWidget, QHBoxLayout, QStyle, QKeySequence, QLabel, QFrame, QAction, \
QDialog, QErrorMessage, QApplication, QPixmap, QMessageBox, QSplashScreen, \ QDialog, QErrorMessage, QApplication, QPixmap, QMessageBox, QSplashScreen, \
@ -43,13 +42,13 @@ from obspy import UTCDateTime
from pylot.core.analysis.magnitude import RichterMagnitude, MomentMagnitude from pylot.core.analysis.magnitude import RichterMagnitude, MomentMagnitude
from pylot.core.io.data import Data from pylot.core.io.data import Data
from pylot.core.io.inputs import FilterOptions, AutoPickParameter from pylot.core.io.inputs import FilterOptions, AutoPickParameter
from pylot.core.pick.autopick import autopickevent #from pylot.core.pick.autopick import autopickevent
from autoPyLoT import autoPyLoT
from pylot.core.pick.compare import Comparison from pylot.core.pick.compare import Comparison
from pylot.core.pick.utils import symmetrize_error from pylot.core.pick.utils import symmetrize_error
from pylot.core.io.phases import picksdict_from_picks from pylot.core.io.phases import picksdict_from_picks
import pylot.core.loc.nll as nll import pylot.core.loc.nll as nll
from pylot.core.util.defaults import FILTERDEFAULTS, COMPNAME_MAP, \ from pylot.core.util.defaults import FILTERDEFAULTS, COMPNAME_MAP
AUTOMATIC_DEFAULTS
from pylot.core.util.errors import FormatError, DatastructureError, \ from pylot.core.util.errors import FormatError, DatastructureError, \
OverwriteError, ProcessingError OverwriteError, ProcessingError
from pylot.core.util.connection import checkurl from pylot.core.util.connection import checkurl
@ -78,15 +77,23 @@ class MainWindow(QMainWindow):
self.createAction = createAction self.createAction = createAction
# read settings # read settings
settings = QSettings() settings = QSettings()
# check for default pylot.in-file
infile = os.path.join(os.path.expanduser('~'), '.pylot', 'pylot.in') infile = os.path.join(os.path.expanduser('~'), '.pylot', 'pylot.in')
self._inputs = AutoPickParameter(infile) if os.path.isfile(infile)== False:
infile = QFileDialog().getOpenFileName(caption='Choose PyLoT-input file',
filter='*.in')
self.infile = infile[0]
else:
self.infile = infile
self._inputs = AutoPickParameter(self.infile)
if settings.value("user/FullName", None) is None: if settings.value("user/FullName", None) is None:
fulluser = QInputDialog.getText(self, "Enter Name:", "Full name") fulluser = QInputDialog.getText(self, "Enter Name:", "Full name")
settings.setValue("user/FullName", fulluser) settings.setValue("user/FullName", fulluser)
settings.setValue("user/Login", getLogin()) settings.setValue("user/Login", getLogin())
if settings.value("agency_id", None) is None: if settings.value("agency_id", None) is None:
agency = QInputDialog.getText(self, agency = QInputDialog.getText(self,
"Enter authority name (e.g. BUG):", "Enter authority/institution name:",
"Authority") "Authority")
settings.setValue("agency_id", agency) settings.setValue("agency_id", agency)
self.recentfiles = settings.value("data/recentEvents", []) self.recentfiles = settings.value("data/recentEvents", [])
@ -164,16 +171,20 @@ class MainWindow(QMainWindow):
lambda event: self.tutor_user()) lambda event: self.tutor_user())
_layout.addWidget(self.DataPlot) _layout.addWidget(self.DataPlot)
manupicksicon = self.style().standardIcon(QStyle.SP_DialogYesButton)
autopicksicon = self.style().standardIcon(QStyle.SP_DialogNoButton)
locactionicon = self.style().standardIcon(QStyle.SP_DirOpenIcon)
loadpiloticon = self.style().standardIcon(QStyle.SP_ComputerIcon)
quitIcon = self.style().standardIcon(QStyle.SP_MediaStop) quitIcon = self.style().standardIcon(QStyle.SP_MediaStop)
saveIcon = self.style().standardIcon(QStyle.SP_DriveHDIcon) saveIcon = self.style().standardIcon(QStyle.SP_DriveHDIcon)
helpIcon = self.style().standardIcon(QStyle.SP_DialogHelpButton) helpIcon = self.style().standardIcon(QStyle.SP_DialogHelpButton)
newIcon = self.style().standardIcon(QStyle.SP_FileIcon) newIcon = self.style().standardIcon(QStyle.SP_FileIcon)
# create resource icons # create resource icons
locactionicon = QIcon()
locactionicon.addPixmap(QPixmap(':/icons/locactionicon.png'))
manupicksicon = QIcon()
manupicksicon.addPixmap(QPixmap(':/icons/manupicsicon.png'))
autopicksicon = QIcon()
autopicksicon.addPixmap(QPixmap(':/icons/autopicsicon.png'))
loadpiloticon = QIcon()
loadpiloticon.addPixmap(QPixmap(':/icons/Matlab_PILOT_icon.png'))
p_icon = QIcon() p_icon = QIcon()
p_icon.addPixmap(QPixmap(':/icons/key_P.png')) p_icon.addPixmap(QPixmap(':/icons/key_P.png'))
s_icon = QIcon() s_icon = QIcon()
@ -189,12 +200,11 @@ class MainWindow(QMainWindow):
e_icon = QIcon() e_icon = QIcon()
e_icon.addPixmap(QPixmap(':/icons/key_E.png')) e_icon.addPixmap(QPixmap(':/icons/key_E.png'))
auto_icon = QIcon() auto_icon = QIcon()
auto_icon.addPixmap(QPixmap(':/icons/sync.png')) auto_icon.addPixmap(QPixmap(':/icons/autopick_button.png'))
locate_icon = QIcon() locate_icon = QIcon()
locate_icon.addPixmap(QPixmap(':/icons/locate.png')) locate_icon.addPixmap(QPixmap(':/icons/locate_button.png'))
compare_icon = QIcon() compare_icon = QIcon()
compare_icon.addPixmap(QPixmap(':/icons/compare.png')) compare_icon.addPixmap(QPixmap(':/icons/compare_button.png'))
newEventAction = self.createAction(self, "&New event ...", newEventAction = self.createAction(self, "&New event ...",
self.createNewEvent, self.createNewEvent,
QKeySequence.New, newIcon, QKeySequence.New, newIcon,
@ -203,28 +213,29 @@ class MainWindow(QMainWindow):
self.load_data, self.load_data,
QKeySequence.Open, QKeySequence.Open,
manupicksicon, manupicksicon,
"Load pick data for " "Load manual picks for "
"the actual event.") "the displayed event.")
openmanualpicksaction.setData(None) openmanualpicksaction.setData(None)
openautopicksaction = self.createAction(self, "Load &automatic picks " openautopicksaction = self.createAction(self, "Load &automatic picks "
"...", "...",
self.load_autopicks, self.load_autopicks,
"Ctrl+A", "Ctrl+A",
autopicksicon, autopicksicon,
"Load automatic pick data " "Load automatic picks "
"for the actual event.") "for the displayed event.")
openautopicksaction.setData(None) openautopicksaction.setData(None)
loadlocationaction = self.createAction(self, "Load &location ...", loadlocationaction = self.createAction(self, "Load &location ...",
self.load_loc, "Ctrl+L", self.load_loc, "Ctrl+L",
locactionicon, locactionicon,
"Load location information on " "Load location information on "
"the actual event.") "the displayed event.")
loadpilotevent = self.createAction(self, "Load PILOT &event ...", loadpilotevent = self.createAction(self, "Load PILOT &event ...",
self.load_pilotevent, "Ctrl+E", self.load_pilotevent, "Ctrl+E",
loadpiloticon, loadpiloticon,
"Load PILOT event from information " "Load PILOT event from information "
"Matlab binary collections.") "MatLab binary collections (created"
" in former MatLab based version).")
saveEventAction = self.createAction(self, "&Save event ...", saveEventAction = self.createAction(self, "&Save event ...",
self.saveData, QKeySequence.Save, self.saveData, QKeySequence.Save,
saveIcon, "Save actual event data.") saveIcon, "Save actual event data.")
@ -269,7 +280,7 @@ class MainWindow(QMainWindow):
printAction = self.createAction(self, "&Print event ...", printAction = self.createAction(self, "&Print event ...",
self.show_event_information, QKeySequence.Print, self.show_event_information, QKeySequence.Print,
print_icon, print_icon,
"Print waveform overview.") "Print waveform section.")
helpAction = self.createAction(self, "&Help ...", self.helpHelp, helpAction = self.createAction(self, "&Help ...", self.helpHelp,
QKeySequence.HelpContents, helpIcon, QKeySequence.HelpContents, helpIcon,
"""Show either the documentation """Show either the documentation
@ -347,13 +358,12 @@ class MainWindow(QMainWindow):
# pickToolActions = (selectStation, ) # pickToolActions = (selectStation, )
# pickToolBar.setObjectName("PickTools") # pickToolBar.setObjectName("PickTools")
# self.addActions(pickToolBar, pickToolActions) # self.addActions(pickToolBar, pickToolActions)
locateEvent = self.createAction(parent=self, text='locate the event',
locateEvent = self.createAction(parent=self, text='locate_event',
slot=self.locate_event, slot=self.locate_event,
shortcut='Alt+Ctrl+L', shortcut='Alt+Ctrl+L',
icon=locate_icon, icon=locate_icon,
tip='Locate the event using ' tip='Locate the event using '
'the picked arrivals.') 'the displayed manual arrivals.')
locationToolBar = self.addToolBar("LocationTools") locationToolBar = self.addToolBar("LocationTools")
locationToolActions = (locateEvent,) locationToolActions = (locateEvent,)
@ -586,8 +596,7 @@ class MainWindow(QMainWindow):
ans = QMessageBox.question(self, self.tr("Overwrite file..."), ans = QMessageBox.question(self, self.tr("Overwrite file..."),
self.tr("File already exists: {0}\n".format(fbasename + exform) + \ self.tr("File already exists: {0}\n".format(fbasename + exform) + \
"Overwrite file anyway?"), "Overwrite file anyway?"),
QMessageBox.Cancel, QMessageBox.Yes | QMessageBox.No, QMessageBox.Yes | QMessageBox.No | QMessageBox.Cancel)
QMessageBox.Cancel)
# only negative answers have to be caught # only negative answers have to be caught
if ans == QMessageBox.No: if ans == QMessageBox.No:
self.saveData() self.saveData()
@ -601,6 +610,9 @@ class MainWindow(QMainWindow):
self.update_status('Event saved as %s' % (fbasename + exform)) self.update_status('Event saved as %s' % (fbasename + exform))
return True return True
def getinfile(self):
return self.infile
def getComponent(self): def getComponent(self):
return self.dispComponent return self.dispComponent
@ -804,7 +816,8 @@ class MainWindow(QMainWindow):
station = self.getStationName(wfID) station = self.getStationName(wfID)
self.update_status('picking on station {0}'.format(station)) self.update_status('picking on station {0}'.format(station))
data = self.get_data().getWFData() data = self.get_data().getWFData()
pickDlg = PickDlg(self, data=data.select(station=station), pickDlg = PickDlg(self, infile=self.getinfile(),
data=data.select(station=station),
station=station, station=station,
picks=self.getPicksOnStation(station)) picks=self.getPicksOnStation(station))
if pickDlg.exec_(): if pickDlg.exec_():
@ -830,6 +843,7 @@ class MainWindow(QMainWindow):
self.listWidget.scrollToBottom() self.listWidget.scrollToBottom()
def autoPick(self): def autoPick(self):
self.autosave = QFileDialog().getExistingDirectory(caption='Select autoPyLoT output')
self.listWidget = QListWidget() self.listWidget = QListWidget()
self.setDirty(True) self.setDirty(True)
self.logDockWidget = QDockWidget("AutoPickLog", self) self.logDockWidget = QDockWidget("AutoPickLog", self)
@ -838,18 +852,17 @@ class MainWindow(QMainWindow):
Qt.LeftDockWidgetArea | Qt.RightDockWidgetArea) Qt.LeftDockWidgetArea | Qt.RightDockWidgetArea)
self.logDockWidget.setWidget(self.listWidget) self.logDockWidget.setWidget(self.listWidget)
self.addDockWidget(Qt.LeftDockWidgetArea, self.logDockWidget) self.addDockWidget(Qt.LeftDockWidgetArea, self.logDockWidget)
self.addListItem('loading default values for local data ...') self.addListItem('Loading default values from PyLoT-input file %s'
# may become obsolete if generalized input parameter a read from disc % self.infile)
# during initialization autopick_parameter = self._inputs
# TODO double check for obsolete read in of parameters
autopick_parameter = AutoPickParameter(AUTOMATIC_DEFAULTS)
self.addListItem(str(autopick_parameter)) self.addListItem(str(autopick_parameter))
# Create the worker thread and run it
self.thread = AutoPickThread(parent=self, self.thread = AutoPickThread(parent=self,
func=autopickevent, func=autoPyLoT,
data=self.get_data().getWFData(), infile = self.infile,
param=autopick_parameter) fnames=self.fnames,
savepath=self.autosave)
self.thread.message.connect(self.addListItem) self.thread.message.connect(self.addListItem)
self.thread.start() self.thread.start()
self.thread.finished.connect(self.finalizeAutoPick) self.thread.finished.connect(self.finalizeAutoPick)
@ -1128,7 +1141,7 @@ class MainWindow(QMainWindow):
QMainWindow.closeEvent(self, event) QMainWindow.closeEvent(self, event)
def PyLoTprefs(self): def PyLoTprefs(self):
props = PropertiesDlg(self) props = PropertiesDlg(self, infile=self.getinfile())
if props.exec_(): if props.exec_():
return return
@ -1153,11 +1166,15 @@ def main():
# create the main window # create the main window
pylot_form = MainWindow() pylot_form = MainWindow()
icon = QIcon()
pylot_form.setWindowIcon(icon)
pylot_form.setIconSize(QSize(60, 60))
splash.showMessage('Loading. Please wait ...') splash.showMessage('Loading. Please wait ...')
pylot_app.processEvents() pylot_app.processEvents()
# set Application Information # set Application Information
pylot_app.setOrganizationName("Ruhr-University Bochum / MAGS2") pylot_app.setOrganizationName("Ruhr-University Bochum / BESTEC")
pylot_app.setOrganizationDomain("rub.de") pylot_app.setOrganizationDomain("rub.de")
pylot_app.processEvents() pylot_app.processEvents()
pylot_app.setApplicationName("PyLoT") pylot_app.setApplicationName("PyLoT")

View File

@ -16,12 +16,12 @@ 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.
##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:
@ -32,7 +32,7 @@ In order to run PyLoT you need to install:
- 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:
@ -59,10 +59,9 @@ You may need to do some modifications to these files. Especially folder names sh
PyLoT has been tested on Mac OSX (10.11) and Debian Linux 8. PyLoT has been tested on Mac OSX (10.11) and Debian Linux 8.
##release notes: ## Release notes
==============
#### Features #### Features:
- consistent manual phase picking through predefined SNR dependant zoom level - consistent manual phase picking through predefined SNR dependant zoom level
- uniform uncertainty estimation from waveform's properties for automatic and manual picks - uniform uncertainty estimation from waveform's properties for automatic and manual picks
@ -70,21 +69,20 @@ PyLoT has been tested on Mac OSX (10.11) and Debian Linux 8.
- Richter and moment magnitude estimation - Richter and moment magnitude estimation
- location determination with external installation of [NonLinLoc](http://alomax.free.fr/nlloc/index.html) - location determination with external installation of [NonLinLoc](http://alomax.free.fr/nlloc/index.html)
#### Known issues #### Known issues:
- Magnitude estimation from manual PyLoT takes some time (instrument correction) - Magnitude estimation from manual PyLoT takes some time (instrument correction)
We hope to solve these with the next release. We hope to solve these with the next release.
####staff: ## Staff
======
original author(s): L. Kueperkoch, S. Wehling-Benatelli, M. Bischoff (PILOT) Original author(s): L. Kueperkoch, S. Wehling-Benatelli, M. Bischoff (PILOT)
developer(s): S. Wehling-Benatelli, L. Kueperkoch, K. Olbert, M. Bischoff, Developer(s): S. Wehling-Benatelli, L. Kueperkoch, K. Olbert, M. Bischoff,
C. Wollin, M. Rische, M. Paffrath C. Wollin, M. Rische, M. Paffrath
others: A. Bruestle, T. Meier, W. Friederich Others: A. Bruestle, T. Meier, W. Friederich
[ObsPy]: http://github.com/obspy/obspy/wiki [ObsPy]: http://github.com/obspy/obspy/wiki

124
autoPyLoT.py Executable file → Normal file
View File

@ -6,11 +6,17 @@ from __future__ import print_function
import argparse import argparse
import glob import glob
import os import os
import datetime
from obspy import read_events from obspy import read_events
import pylot.core.loc.hsat as hsat import pylot.core.loc.hyposat as hyposat
import pylot.core.loc.hypo71 as hypo71
import pylot.core.loc.velest as velest
import pylot.core.loc.hypodd as hypodd
import pylot.core.loc.focmec as focmec
import pylot.core.loc.hash as hash
import pylot.core.loc.nll as nll import pylot.core.loc.nll as nll
#from PySide.QtGui import QWidget, QInputDialog
from pylot.core.analysis.magnitude import MomentMagnitude, RichterMagnitude from pylot.core.analysis.magnitude import MomentMagnitude, RichterMagnitude
from pylot.core.io.data import Data from pylot.core.io.data import Data
from pylot.core.io.inputs import AutoPickParameter from pylot.core.io.inputs import AutoPickParameter
@ -23,7 +29,7 @@ from pylot.core.util.version import get_git_version as _getVersionString
__version__ = _getVersionString() __version__ = _getVersionString()
def autoPyLoT(inputfile): def autoPyLoT(inputfile, fnames=None, savepath=None):
""" """
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.
@ -43,14 +49,13 @@ def autoPyLoT(inputfile):
Version {version} 2015\n Version {version} 2015\n
\n \n
Authors:\n Authors:\n
S. Wehling-Benatelli (Ruhr-Universität Bochum)\n S. Wehling-Benatelli (Ruhr-Universitaet Bochum)\n
L. Küperkoch (BESTEC GmbH, Landau i. d. Pfalz)\n L. Kueperkoch (BESTEC GmbH, Landau i. d. Pfalz)\n
K. Olbert (Christian-Albrechts Universität zu Kiel)\n K. Olbert (Christian-Albrechts Universitaet zu Kiel)\n
***********************************'''.format(version=_getVersionString()) ***********************************'''.format(version=_getVersionString())
print(splash) print(splash)
# reading parameter file # reading parameter file
parameter = AutoPickParameter(inputfile) parameter = AutoPickParameter(inputfile)
data = Data() data = Data()
@ -65,8 +70,8 @@ def autoPyLoT(inputfile):
'dbase': parameter.get('database')} 'dbase': parameter.get('database')}
exf = ['root', 'dpath', 'dbase'] exf = ['root', 'dpath', 'dbase']
if parameter.hasParam('eventID'): if parameter.hasParam('eventID') and fnames == 'None':
dsfields['eventID'] = parameter.get('eventID') dsfields['eventID'] = parameter.get('eventID')
exf.append('eventID') exf.append('eventID')
@ -100,22 +105,51 @@ def autoPyLoT(inputfile):
print(" !!! ") print(" !!! ")
datapath = datastructure.expandDataPath() datapath = datastructure.expandDataPath()
if not parameter.hasParam('eventID'): if fnames == 'None' and not parameter.hasParam('eventID'):
# 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)]
else: elif fnames == 'None' and parameter.hasParam('eventID'):
# single event processing # single event processing
events = glob.glob(os.path.join(datapath, parameter.get('eventID'))) events = glob.glob(os.path.join(datapath, parameter.get('eventID')))
else:
# autoPyLoT was initialized from GUI
events = fnames
for event in events: for event in events:
data.setWFData(glob.glob(os.path.join(datapath, event, '*'))) if fnames == 'None':
evID = os.path.split(event)[-1] data.setWFData(glob.glob(os.path.join(datapath, event, '*')))
print('Working on event %s' % event) evID = os.path.split(event)[-1]
print(data) # the following is necessary because within
# multiple event processing no event ID is provided
# in autopylot.in
try:
parameter.get('eventID')
except:
now = datetime.datetime.now()
eventID = '%d%02d%02d%02d%02d' % (now.year,
now.month,
now.day,
now.hour,
now.minute)
parameter.setParam(eventID=eventID)
else:
data.setWFData(fnames)
event = savepath
now = datetime.datetime.now()
evID = '%d%02d%02d%02d%02d' % (now.year,
now.month,
now.day,
now.hour,
now.minute)
parameter.setParam(eventID=evID)
wfdat = data.getWFData() # all available streams wfdat = data.getWFData() # all available streams
wfdat = remove_underscores(wfdat) wfdat = remove_underscores(wfdat)
metadata = read_metadata(parameter.get('invdir')) metadata = read_metadata(parameter.get('invdir'))
corr_dat, rest_flag = restitute_data(wfdat.copy(), *metadata) corr_dat, rest_flag = restitute_data(wfdat.copy(), *metadata)
print('Working on event %s' % event)
print(data)
########################################################## ##########################################################
# !automated picking starts here! # !automated picking starts here!
picks = autopickevent(wfdat, parameter) picks = autopickevent(wfdat, parameter)
@ -123,7 +157,7 @@ def autoPyLoT(inputfile):
# locating # locating
if locflag == 1: if locflag == 1:
# write phases to NLLoc-phase file # write phases to NLLoc-phase file
nll.export(picks, phasefile) nll.export(picks, phasefile, parameter)
# For locating the event the NLLoc-control file has to be modified! # For locating the event the NLLoc-control file has to be modified!
nllocout = '%s_%s' % (evID, nllocoutpatter) nllocout = '%s_%s' % (evID, nllocoutpatter)
@ -132,7 +166,7 @@ def autoPyLoT(inputfile):
ttpat) ttpat)
# locate the event # locate the event
nll.locate(ctrfile) nll.locate(ctrfile, inputfile)
# !iterative picking if traces remained unpicked or occupied with bad picks! # !iterative picking if traces remained unpicked or occupied with bad picks!
# get theoretical onset times for picks with weights >= 4 # get theoretical onset times for picks with weights >= 4
@ -157,13 +191,15 @@ def autoPyLoT(inputfile):
# calculating seismic moment Mo and moment magnitude Mw # calculating 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, 0) parameter.get('rho'), True, \
parameter.get('iplot'))
# update pick with moment property values (w0, fc, Mo) # update pick with moment property values (w0, fc, Mo)
for station, props in moment_mag.moment_props.items(): for station, props in moment_mag.moment_props.items():
picks[station]['P'].update(props) picks[station]['P'].update(props)
evt = moment_mag.updated_event() evt = moment_mag.updated_event()
local_mag = RichterMagnitude(corr_dat, evt, local_mag = RichterMagnitude(corr_dat, evt,
parameter.get('sstop'), True, 0) parameter.get('sstop'), True,\
parameter.get('iplot'))
for station, amplitude in local_mag.amplitudes.items(): for station, amplitude in local_mag.amplitudes.items():
picks[station]['S']['Ao'] = amplitude.generic_amplitude picks[station]['S']['Ao'] = amplitude.generic_amplitude
evt = local_mag.updated_event() evt = local_mag.updated_event()
@ -185,11 +221,11 @@ def autoPyLoT(inputfile):
print("autoPyLoT: Starting with iteration No. %d ..." % nlloccounter) print("autoPyLoT: Starting with iteration No. %d ..." % nlloccounter)
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
nll.export(picks, phasefile) nll.export(picks, phasefile, parameter)
# remove actual NLLoc-location file to keep only the last # remove actual NLLoc-location file to keep only the last
os.remove(nllocfile) os.remove(nllocfile)
# locate the event # locate the event
nll.locate(ctrfile) nll.locate(ctrfile, inputfile)
print("autoPyLoT: Iteration No. %d finished." % nlloccounter) print("autoPyLoT: Iteration No. %d finished." % nlloccounter)
# get updated NLLoc-location file # get updated NLLoc-location file
nllocfile = max(glob.glob(locsearch), key=os.path.getctime) nllocfile = max(glob.glob(locsearch), key=os.path.getctime)
@ -207,13 +243,15 @@ def autoPyLoT(inputfile):
# calculating seismic moment Mo and moment magnitude Mw # calculating 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, 0) parameter.get('rho'), True, \
parameter.get('iplot'))
# update pick with moment property values (w0, fc, Mo) # update pick with moment property values (w0, fc, Mo)
for station, props in moment_mag.moment_props.items(): for station, props in moment_mag.moment_props.items():
picks[station]['P'].update(props) picks[station]['P'].update(props)
evt = moment_mag.updated_event() evt = moment_mag.updated_event()
local_mag = RichterMagnitude(corr_dat, evt, local_mag = RichterMagnitude(corr_dat, evt,
parameter.get('sstop'), True, 0) parameter.get('sstop'), True, \
parameter.get('iplot'))
for station, amplitude in local_mag.amplitudes.items(): for station, amplitude in local_mag.amplitudes.items():
picks[station]['S']['Ao'] = amplitude.generic_amplitude picks[station]['S']['Ao'] = amplitude.generic_amplitude
evt = local_mag.updated_event() evt = local_mag.updated_event()
@ -221,16 +259,35 @@ def autoPyLoT(inputfile):
print("Network moment magnitude: %4.1f" % net_mw.mag) print("Network moment magnitude: %4.1f" % net_mw.mag)
else: else:
print("autoPyLoT: No NLLoc-location file available! Stop iteration!") print("autoPyLoT: No NLLoc-location file available! Stop iteration!")
locflag = 9
########################################################## ##########################################################
# write phase files for various location routines # write phase files for various location
# HYPO71 # and fault mechanism calculation routines
hypo71file = '%s/autoPyLoT_HYPO71.pha' % event # ObsPy event object
hsat.export(picks, hypo71file)
data.applyEVTData(picks) data.applyEVTData(picks)
if evt is not None: if evt is not None:
data.applyEVTData(evt, 'event') data.applyEVTData(evt, 'event')
fnqml = '%s/autoPyLoT' % event fnqml = '%s/autoPyLoT' % event
data.exportEvent(fnqml) data.exportEvent(fnqml)
# HYPO71
hypo71file = '%s/autoPyLoT_HYPO71_phases' % event
hypo71.export(picks, hypo71file, parameter)
# HYPOSAT
hyposatfile = '%s/autoPyLoT_HYPOSAT_phases' % event
hyposat.export(picks, hyposatfile, parameter)
if locflag == 1:
# VELEST
velestfile = '%s/autoPyLoT_VELEST_phases.cnv' % event
velest.export(picks, velestfile, parameter, evt)
# hypoDD
hypoddfile = '%s/autoPyLoT_hypoDD_phases.pha' % event
hypodd.export(picks, hypoddfile, parameter, evt)
# FOCMEC
focmecfile = '%s/autoPyLoT_FOCMEC.in' % event
focmec.export(picks, focmecfile, parameter, evt)
# HASH
hashfile = '%s/autoPyLoT_HASH' % event
hash.export(picks, hashfile, parameter, evt)
endsplash = '''------------------------------------------\n' endsplash = '''------------------------------------------\n'
-----Finished event %s!-----\n' -----Finished event %s!-----\n'
@ -249,7 +306,6 @@ def autoPyLoT(inputfile):
if __name__ == "__main__": if __name__ == "__main__":
from pylot.core.util.defaults import AUTOMATIC_DEFAULTS
# parse arguments # parse arguments
parser = argparse.ArgumentParser( parser = argparse.ArgumentParser(
description='''autoPyLoT automatically picks phase onset times using higher order statistics, description='''autoPyLoT automatically picks phase onset times using higher order statistics,
@ -258,13 +314,17 @@ if __name__ == "__main__":
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''')
default=AUTOMATIC_DEFAULTS parser.add_argument('-f', '-F', '--fnames', type=str,
) action='store',
help='''optional, list of data file names''')
parser.add_argument('-s', '-S', '--spath', type=str,
action=store,
help='''optional, save path for autoPyLoT output''')
parser.add_argument('-v', '-V', '--version', action='version', parser.add_argument('-v', '-V', '--version', action='version',
version='autoPyLoT ' + __version__, version='autoPyLoT ' + __version__,
help='show version information and exit') help='show version information and exit')
cla = parser.parse_args() cla = parser.parse_args()
autoPyLoT(str(cla.inputfile)) autoPyLoT(str(cla.inputfile), str(cla.fnames), str(cla.spath))

View File

@ -2,10 +2,15 @@
<qresource> <qresource>
<file>icons/pylot.ico</file> <file>icons/pylot.ico</file>
<file>icons/pylot.png</file> <file>icons/pylot.png</file>
<file>icons/locate.png</file> <file>icons/manupicsicon.png</file>
<file>icons/autopicsicon.png</file>
<file>icons/autopick_button.png</file>
<file>icons/locactionicon.png</file>
<file>icons/compare_button.png</file>
<file>icons/locate_button.png</file>
<file>icons/Matlab_PILOT_icon.png</file>
<file>icons/printer.png</file> <file>icons/printer.png</file>
<file>icons/delete.png</file> <file>icons/delete.png</file>
<file>icons/compare.png</file>
<file>icons/key_E.png</file> <file>icons/key_E.png</file>
<file>icons/key_N.png</file> <file>icons/key_N.png</file>
<file>icons/key_P.png</file> <file>icons/key_P.png</file>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.0 KiB

0
icons/delete.png Executable file → Normal file
View File

Before

Width:  |  Height:  |  Size: 5.0 KiB

After

Width:  |  Height:  |  Size: 5.0 KiB

0
icons/key_E.png Executable file → Normal file
View File

Before

Width:  |  Height:  |  Size: 3.9 KiB

After

Width:  |  Height:  |  Size: 3.9 KiB

0
icons/key_N.png Executable file → Normal file
View File

Before

Width:  |  Height:  |  Size: 4.0 KiB

After

Width:  |  Height:  |  Size: 4.0 KiB

0
icons/key_P.png Executable file → Normal file
View File

Before

Width:  |  Height:  |  Size: 3.9 KiB

After

Width:  |  Height:  |  Size: 3.9 KiB

0
icons/key_Q.png Executable file → Normal file
View File

Before

Width:  |  Height:  |  Size: 4.1 KiB

After

Width:  |  Height:  |  Size: 4.1 KiB

0
icons/key_R.png Executable file → Normal file
View File

Before

Width:  |  Height:  |  Size: 4.0 KiB

After

Width:  |  Height:  |  Size: 4.0 KiB

0
icons/key_S.png Executable file → Normal file
View File

Before

Width:  |  Height:  |  Size: 4.0 KiB

After

Width:  |  Height:  |  Size: 4.0 KiB

BIN
icons/key_T.png Executable file → Normal file

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.8 KiB

After

Width:  |  Height:  |  Size: 0 B

0
icons/key_U.png Executable file → Normal file
View File

Before

Width:  |  Height:  |  Size: 3.9 KiB

After

Width:  |  Height:  |  Size: 3.9 KiB

0
icons/key_V.png Executable file → Normal file
View File

Before

Width:  |  Height:  |  Size: 4.0 KiB

After

Width:  |  Height:  |  Size: 4.0 KiB

0
icons/key_W.png Executable file → Normal file
View File

Before

Width:  |  Height:  |  Size: 4.1 KiB

After

Width:  |  Height:  |  Size: 4.1 KiB

0
icons/key_Z.png Executable file → Normal file
View File

Before

Width:  |  Height:  |  Size: 3.9 KiB

After

Width:  |  Height:  |  Size: 3.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.1 KiB

0
icons/sync.png Executable file → Normal file
View File

Before

Width:  |  Height:  |  Size: 4.2 KiB

After

Width:  |  Height:  |  Size: 4.2 KiB

0
icons/zoom_0.png Executable file → Normal file
View File

Before

Width:  |  Height:  |  Size: 6.9 KiB

After

Width:  |  Height:  |  Size: 6.9 KiB

0
icons/zoom_in.png Executable file → Normal file
View File

Before

Width:  |  Height:  |  Size: 7.0 KiB

After

Width:  |  Height:  |  Size: 7.0 KiB

0
icons/zoom_out.png Executable file → Normal file
View File

Before

Width:  |  Height:  |  Size: 6.9 KiB

After

Width:  |  Height:  |  Size: 6.9 KiB

63325
icons_rc.py

File diff suppressed because one or more lines are too long

View File

@ -1 +1 @@
0.1a f5c0-dirty

0
pylot/__init__.py Executable file → Normal file
View File

0
pylot/core/__init__.py Executable file → Normal file
View File

View File

@ -6,19 +6,16 @@ Created autumn/winter 2015.
:author: Ludger Küperkoch / MAGS2 EP3 working group :author: Ludger Küperkoch / MAGS2 EP3 working group
""" """
import os 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 import integrate, signal
from scipy.optimize import curve_fit 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
def richter_magnitude_scaling(delta): def richter_magnitude_scaling(delta):
relation = np.loadtxt(os.path.join(os.path.expanduser('~'), relation = np.loadtxt(os.path.join(os.path.expanduser('~'),
'.pylot', 'richter_scaling.data')) '.pylot', 'richter_scaling.data'))
@ -200,8 +197,8 @@ class RichterMagnitude(Magnitude):
iwin = getsignalwin(th, t0 - stime, self.calc_win) iwin = getsignalwin(th, t0 - stime, self.calc_win)
wapp = np.max(sqH[iwin]) wapp = np.max(sqH[iwin])
if self.verbose: if self.verbose:
print("Determined Wood-Anderson peak-to-peak amplitude: {0} " print("Determined Wood-Anderson peak-to-peak amplitude for station {0}: {1} "
"mm".format(wapp)) "mm".format(st[0].stats.station, wapp))
# check for plot flag (for debugging only) # check for plot flag (for debugging only)
if self.plot_flag > 1: if self.plot_flag > 1:
@ -317,8 +314,8 @@ class MomentMagnitude(Magnitude):
continue continue
pick = a.pick_id.get_referred_object() pick = a.pick_id.get_referred_object()
station = pick.waveform_id.station_code station = pick.waveform_id.station_code
wf = select_for_phase(self.stream.select( scopy = self.stream.copy()
station=station), a.phase) wf = scopy.select(station=station)
if not wf: if not wf:
continue continue
onset = pick.time onset = pick.time
@ -326,15 +323,16 @@ class MomentMagnitude(Magnitude):
azimuth = a.azimuth azimuth = a.azimuth
incidence = a.takeoff_angle incidence = a.takeoff_angle
w0, fc = calcsourcespec(wf, onset, self.p_velocity, distance, w0, fc = calcsourcespec(wf, onset, self.p_velocity, distance,
azimuth, azimuth, incidence, self.p_attenuation,
incidence, self.p_attenuation,
self.plot_flag, self.verbose) self.plot_flag, self.verbose)
if w0 is None or fc is None: if w0 is None or fc is None:
if self.verbose: if self.verbose:
print("WARNING: insufficient frequency information") print("WARNING: insufficient frequency information")
continue continue
wf = select_for_phase(wf, "P") WF = select_for_phase(self.stream.select(
m0, mw = calcMoMw(wf, w0, self.rock_density, self.p_velocity, station=station), a.phase)
WF = select_for_phase(WF, "P")
m0, mw = calcMoMw(WF, w0, self.rock_density, self.p_velocity,
distance, self.verbose) distance, self.verbose)
self.moment_props = (station, dict(w0=w0, fc=fc, Mo=m0)) self.moment_props = (station, dict(w0=w0, fc=fc, Mo=m0))
magnitude = ope.StationMagnitude(mag=mw) magnitude = ope.StationMagnitude(mag=mw)
@ -426,7 +424,7 @@ def calcsourcespec(wfstream, onset, vp, delta, azimuth, incidence,
:type: integer :type: integer
''' '''
if verbosity: if verbosity:
print ("Calculating source spectrum ....") print ("Calculating source spectrum for station %s ...." % wfstream[0].stats.station)
# get Q value # get Q value
Q, A = qp Q, A = qp
@ -453,18 +451,21 @@ def calcsourcespec(wfstream, onset, vp, delta, azimuth, incidence,
LQT = wfstream.rotate('ZNE->LQT', azimuth, incidence) LQT = wfstream.rotate('ZNE->LQT', azimuth, incidence)
ldat = LQT.select(component="L") ldat = LQT.select(component="L")
if len(ldat) == 0: if len(ldat) == 0:
# if horizontal channels are 2 and 3 # if horizontal channels are 1 and 2
# no azimuth information is available and thus no # no azimuth information is available and thus no
# rotation is possible! # rotation is possible!
if verbosity: if verbosity:
print("calcsourcespec: Azimuth information is missing, " print("calcsourcespec: Azimuth information is missing, "
"no rotation of components possible!") "no rotation of components possible!")
ldat = LQT.select(component="Z") # instead, use component 3
ldat = LQT.select(component="3")
if len(ldat) == 0:
# maybe component z available
ldat = LQT.select(component="Z")
# integrate to displacement # integrate to displacement
# unrotated vertical component (for comparison) # unrotated vertical component (for comparison)
inttrz = signal.detrend(integrate.cumtrapz(zdat[0].data, None, dt)) inttrz = signal.detrend(integrate.cumtrapz(zdat[0].data, None, dt))
# rotated component Z => L # rotated component Z => L
Ldat = signal.detrend(integrate.cumtrapz(ldat[0].data, None, dt)) Ldat = signal.detrend(integrate.cumtrapz(ldat[0].data, None, dt))
@ -527,22 +528,24 @@ def calcsourcespec(wfstream, onset, vp, delta, azimuth, incidence,
# use of implicit scipy otimization function # use of implicit scipy otimization function
fit = synthsourcespec(F, w0in, Fcin) fit = synthsourcespec(F, w0in, Fcin)
[optspecfit, _] = curve_fit(synthsourcespec, F, YYcor, [w0in, Fcin]) [optspecfit, _] = curve_fit(synthsourcespec, F, YYcor, [w0in, Fcin])
w01 = optspecfit[0] w0 = optspecfit[0]
fc1 = optspecfit[1] fc = optspecfit[1]
#w01 = optspecfit[0]
#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"
"Determined corner frequency: %f Hz" % (w01, fc1)) "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()
@ -627,18 +630,35 @@ def fitSourceModel(f, S, fc0, iplot, verbosity=False):
fc = [] fc = []
stdfc = [] stdfc = []
STD = [] STD = []
# get window around initial corner frequency for trials # get window around initial corner frequency for trials
fcstopl = fc0 - max(1, len(f) / 10) # left side of initial corner frequency
il = np.argmin(abs(f - fcstopl)) fcstopl = max(f[0], fc0 - max(1, fc0 / 2))
fcstopl = f[il] il = np.where(f <= fcstopl)
fcstopr = fc0 + min(len(f), len(f) / 10) il = il[0][np.size(il) - 1]
ir = np.argmin(abs(f - fcstopr)) # right side of initial corner frequency
fcstopr = f[ir] fcstopr = min(fc0 + (fc0 / 2), f[len(f) - 1])
iF = np.where((f >= fcstopl) & (f <= fcstopr)) ir = np.where(f >= fcstopr)
# check, if fcstopr is available
if np.size(ir) == 0:
fcstopr = fc0
ir = len(f) - 1
else:
ir = ir[0][0]
# vary corner frequency around initial point # vary corner frequency around initial point
for i in range(il, ir): print("fitSourceModel: Varying corner frequency "
"around initial corner frequency ...")
# check difference of il and ir in order to
# keep calculation time acceptable
idiff = ir - il
if idiff > 10000:
increment = 100
elif idiff <= 20:
increment = 1
else:
increment = 10
for i in range(il, ir, increment):
FC = f[i] FC = f[i]
indexdc = np.where((f > 0) & (f <= FC)) indexdc = np.where((f > 0) & (f <= FC))
dc = np.mean(S[indexdc]) dc = np.mean(S[indexdc])

View File

@ -6,13 +6,11 @@ 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.core.event import Event from obspy.core.event import Event
from pylot.core.io.phases import readPILOTEvent, picks_from_picksdict, \ from pylot.core.io.phases import readPILOTEvent, picks_from_picksdict, \
picksdict_from_pilot, merge_picks picksdict_from_pilot, merge_picks
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.utils import fnConstructor, full_range
class Data(object): class Data(object):
""" """
Data container with attributes wfdata holding ~obspy.core.stream. Data container with attributes wfdata holding ~obspy.core.stream.
@ -298,10 +296,20 @@ class Data(object):
""" """
#firstonset = find_firstonset(picks) #firstonset = find_firstonset(picks)
if self.get_evt_data().picks: # check for automatic picks
raise OverwriteError('Actual picks would be overwritten!') print("Writing phases to ObsPy-quakeml file")
else: for key in picks:
picks = picks_from_picksdict(picks) if picks[key]['P']['picker'] == 'auto':
print("Existing picks will be overwritten!")
picks = picks_from_picksdict(picks)
break
else:
if self.get_evt_data().picks:
raise OverwriteError('Existing picks would be overwritten!')
break
else:
picks = picks_from_picksdict(picks)
break
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')

View File

@ -14,7 +14,6 @@ from pylot.core.io.location import create_arrival, create_event, \
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:
@ -233,6 +232,8 @@ def picks_from_picksdict(picks, creation_info=None):
if not isinstance(phase, dict): if not isinstance(phase, dict):
continue continue
onset = phase['mpp'] onset = phase['mpp']
ccode = phase['channel']
ncode = phase['network']
pick = ope.Pick() pick = ope.Pick()
if creation_info: if creation_info:
pick.creation_info = creation_info pick.creation_info = creation_info
@ -253,7 +254,9 @@ def picks_from_picksdict(picks, creation_info=None):
picker = 'Unknown' picker = 'Unknown'
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,
network_code=ncode)
try: try:
polarity = phase['fm'] polarity = phase['fm']
if polarity == 'U' or '+': if polarity == 'U' or '+':
@ -384,7 +387,7 @@ def reassess_pilot_event(root_dir, db_dir, event_id, out_dir=None, fn_param=None
#evt.write(fnout_prefix + 'cnv', format='VELEST') #evt.write(fnout_prefix + 'cnv', format='VELEST')
def writephases(arrivals, fformat, filename): def writephases(arrivals, fformat, filename, parameter, 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:
@ -402,17 +405,25 @@ def writephases(arrivals, fformat, filename):
HYPOINVERSE, and hypoDD HYPOINVERSE, and hypoDD
:param: filename, full path and name of phase file :param: filename, full path and name of phase file
:type: string :type: string
"""
:param: parameter, all input information
:type: object
:param: eventinfo, optional, needed for VELEST-cnv file
and FOCMEC- and HASH-input files
: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: Label: EQ001 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' %
(parameter.get('database'), parameter.get('eventID')))
for key in arrivals: for key in arrivals:
# P onsets # P onsets
if arrivals[key]['P']: if arrivals[key].has_key('P'):
try: try:
fm = arrivals[key]['P']['fm'] fm = arrivals[key]['P']['fm']
except KeyError as e: except KeyError as e:
@ -477,9 +488,13 @@ def writephases(arrivals, fformat, filename):
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(' EQ001\n') fid.write(' %s\n' %
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
if len(stat) > 4: # HYPO71 handles only 4-string station IDs
stat = stat[1:5]
Ponset = arrivals[key]['P']['mpp'] Ponset = arrivals[key]['P']['mpp']
Sonset = arrivals[key]['S']['mpp'] Sonset = arrivals[key]['S']['mpp']
pweight = arrivals[key]['P']['weight'] pweight = arrivals[key]['P']['weight']
@ -517,7 +532,7 @@ def writephases(arrivals, fformat, filename):
sstr = 'I' sstr = 'I'
elif sweight >= 2: elif sweight >= 2:
sstr = 'E' sstr = 'E'
fid.write('%s%sP%s%d %02d%02d%02d%02d%02d%5.2f %s%sS %d %s\n' % (key, 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,
@ -532,7 +547,7 @@ def writephases(arrivals, fformat, filename):
sweight, sweight,
Ao)) Ao))
else: else:
fid.write('%s%sP%s%d %02d%02d%02d%02d%02d%5.2f %s\n' % (key, fid.write('%-4s%sP%s%d %02d%02d%02d%02d%02d%5.2f %s\n' % (stat,
pstr, pstr,
fm, fm,
pweight, pweight,
@ -546,6 +561,258 @@ def writephases(arrivals, fformat, filename):
fid.close() fid.close()
elif fformat == 'HYPOSAT':
print ("Writing phases to %s for HYPOSAT" % filename)
fid = open("%s" % filename, 'w')
# write header
fid.write('%s, event %s \n' % (parameter.get('database'), parameter.get('eventID')))
errP = parameter.get('timeerrorsP')
errS = parameter.get('timeerrorsS')
for key in arrivals:
# P onsets
if arrivals[key].has_key('P'):
if arrivals[key]['P']['weight'] < 4:
Ponset = arrivals[key]['P']['mpp']
pyear = Ponset.year
pmonth = Ponset.month
pday = Ponset.day
phh = Ponset.hour
pmm = Ponset.minute
pss = Ponset.second
pms = Ponset.microsecond
Pss = pss + pms / 1000000.0
# use symmetrized picking error as std
# (read the HYPOSAT manual)
pstd = arrivals[key]['P']['spe']
fid.write('%-5s P1 %4.0f %02d %02d %02d %02d %05.02f %5.3f -999. 0.00 -999. 0.00\n'
% (key, pyear, pmonth, pday, phh, pmm, Pss, pstd))
# S onsets
if arrivals[key].has_key('S') and arrivals[key]['S']:
if arrivals[key]['S']['weight'] < 4:
Sonset = arrivals[key]['S']['mpp']
syear = Sonset.year
smonth = Sonset.month
sday = Sonset.day
shh = Sonset.hour
smm = Sonset.minute
sss = Sonset.second
sms = Sonset.microsecond
Sss = sss + sms / 1000000.0
sstd = arrivals[key]['S']['spe']
fid.write('%-5s S1 %4.0f %02d %02d %02d %02d %05.02f %5.3f -999. 0.00 -999. 0.00\n'
% (key, syear, smonth, sday, shh, smm, Sss, sstd))
fid.close()
elif fformat == 'VELEST':
print ("Writing phases to %s for VELEST" % filename)
fid = open("%s" % filename, 'w')
# get informations needed in cnv-file
# check, whether latitude is N or S and longitude is E or W
eventsource = eventinfo.origins[0]
if eventsource['latitude'] < 0:
cns = 'S'
else:
cns = 'N'
if eventsource['longitude'] < 0:
cew = 'W'
else:
cew = 'E'
# get last two integers of origin year
stime = eventsource['time']
if stime.year - 2000 >= 0:
syear = stime.year - 2000
else:
syear = stime.year - 1900
ifx = 0 # default value, see VELEST manual, pp. 22-23
# write header
fid.write('%s%02d%02d %02d%02d %05.2f %7.4f%c %8.4f%c %7.2f %6.2f %02.0f 0.0 0.03 1.0 1.0\n' % (
syear, stime.month, stime.day, stime.hour, stime.minute, stime.second, eventsource['latitude'],
cns, eventsource['longitude'], cew, eventsource['depth'],eventinfo.magnitudes[0]['mag'], ifx))
n = 0
for key in arrivals:
# P onsets
if arrivals[key].has_key('P'):
if arrivals[key]['P']['weight'] < 4:
n += 1
stat = key
if len(stat) > 4: # VELEST handles only 4-string station IDs
stat = stat[1:5]
Ponset = arrivals[key]['P']['mpp']
Pweight = arrivals[key]['P']['weight']
Prt = Ponset - stime # onset time relative to source time
if n % 6 is not 0:
fid.write('%-4sP%d%6.2f' % (stat, Pweight, Prt))
else:
fid.write('%-4sP%d%6.2f\n' % (stat, Pweight, Prt))
# S onsets
if arrivals[key].has_key('S'):
if arrivals[key]['S']['weight'] < 4:
n += 1
stat = key
if len(stat) > 4: # VELEST handles only 4-string station IDs
stat = stat[1:5]
Sonset = arrivals[key]['S']['mpp']
Sweight = arrivals[key]['S']['weight']
Srt = Ponset - stime # onset time relative to source time
if n % 6 is not 0:
fid.write('%-4sS%d%6.2f' % (stat, Sweight, Srt))
else:
fid.write('%-4sS%d%6.2f\n' % (stat, Sweight, Srt))
fid.close()
elif fformat == 'hypoDD':
print ("Writing phases to %s for hypoDD" % filename)
fid = open("%s" % filename, 'w')
# get event information needed for hypoDD-phase file
eventsource = eventinfo.origins[0]
stime = eventsource['time']
event = parameter.get('eventID')
hddID = event.split('.')[0][1:5]
# write header
fid.write('# %d %d %d %d %d %5.2f %7.4f +%6.4f %7.4f %4.2f 0.1 0.5 %4.2f %s\n' % (
stime.year, stime.month, stime.day, stime.hour, stime.minute, stime.second,
eventsource['latitude'], eventsource['longitude'], eventsource['depth'] / 1000,
eventinfo.magnitudes[0]['mag'], eventsource['quality']['standard_error'], hddID))
for key in arrivals:
if arrivals[key].has_key('P'):
# P onsets
if arrivals[key]['P']['weight'] < 4:
Ponset = arrivals[key]['P']['mpp']
Prt = Ponset - stime # onset time relative to source time
fid.write('%s %6.3f 1 P\n' % (key, Prt))
# S onsets
if arrivals[key]['S']['weight'] < 4:
Sonset = arrivals[key]['S']['mpp']
Srt = Sonset - stime # onset time relative to source time
fid.write('%-5s %6.3f 1 S\n' % (key, Srt))
fid.close()
elif fformat == 'FOCMEC':
print ("Writing phases to %s for FOCMEC" % filename)
fid = open("%s" % filename, 'w')
# get event information needed for FOCMEC-input file
eventsource = eventinfo.origins[0]
stime = eventsource['time']
# write header line including event information
fid.write('%s %d%02d%02d%02d%02d%02.0f %7.4f %6.4f %3.1f %3.1f\n' % (parameter.get('eventID'),
stime.year, stime.month, stime.day, stime.hour, stime.minute, stime.second,
eventsource['latitude'], eventsource['longitude'], eventsource['depth'] / 1000,
eventinfo.magnitudes[0]['mag']))
picks = eventinfo.picks
for key in arrivals:
if arrivals[key].has_key('P'):
if arrivals[key]['P']['weight'] < 4 and arrivals[key]['P']['fm'] is not None:
stat = key
for i in range(len(picks)):
station = picks[i].waveform_id.station_code
if station == stat:
# get resource ID
resid_picks = picks[i].get('resource_id')
# find same ID in eventinfo
# there it is the pick_id!!
for j in range(len(eventinfo.origins[0].arrivals)):
resid_eventinfo = eventinfo.origins[0].arrivals[j].get('pick_id')
if resid_eventinfo == resid_picks and eventinfo.origins[0].arrivals[j].phase == 'P':
if len(stat) > 4: # FOCMEC handles only 4-string station IDs
stat = stat[1:5]
az = eventinfo.origins[0].arrivals[j].get('azimuth')
inz = eventinfo.origins[0].arrivals[j].get('takeoff_angle')
fid.write('%-4s %6.2f %6.2f%s \n' % (stat,
az,
inz,
arrivals[key]['P']['fm']))
break
fid.close()
elif fformat == 'HASH':
# two different input files for
# HASH-driver 1 and 2 (see HASH manual!)
filename1 = filename + 'drv1' + '.phase'
filename2 = filename + 'drv2' + '.phase'
print ("Writing phases to %s for HASH for HASH-driver 1" % filename1)
fid1 = open("%s" % filename1, 'w')
print ("Writing phases to %s for HASH for HASH-driver 2" % filename2)
fid2 = open("%s" % filename2, 'w')
# get event information needed for HASH-input file
eventsource = eventinfo.origins[0]
event = parameter.get('eventID')
hashID = event.split('.')[0][1:5]
latdeg = eventsource['latitude']
latmin = eventsource['latitude'] * 60 / 10000
londeg = eventsource['longitude']
lonmin = eventsource['longitude'] * 60 / 10000
erh = 1 / 2 * (eventsource.origin_uncertainty['min_horizontal_uncertainty'] +
eventsource.origin_uncertainty['max_horizontal_uncertainty']) / 1000
erz = eventsource.depth_errors['uncertainty']
stime = eventsource['time']
if stime.year - 2000 >= 0:
syear = stime.year - 2000
else:
syear = stime.year - 1900
picks = eventinfo.picks
# write header line including event information
# for HASH-driver 1
fid1.write('%s%02d%02d%02d%02d%5.2f%2dN%5.2f%3dE%5.2f%6.3f%4.2f%5.2f%5.2f%s\n' % (syear,
stime.month, stime.day, stime.hour, stime.minute, stime.second,
latdeg, latmin, londeg, lonmin, eventsource['depth'],
eventinfo.magnitudes[0]['mag'], erh, erz,
hashID))
# write header line including event information
# for HASH-driver 2
fid2.write('%d%02d%02d%02d%02d%5.2f%dN%5.2f%3dE%6.2f%5.2f %d %5.2f %5.2f %4.2f %s \n' % (syear, stime.month, stime.day,
stime.hour, stime.minute, stime.second,
latdeg,latmin,londeg, lonmin,
eventsource['depth'],
eventsource['quality']['used_phase_count'],
erh, erz, eventinfo.magnitudes[0]['mag'],
hashID))
# write phase lines
for key in arrivals:
if arrivals[key].has_key('P'):
if arrivals[key]['P']['weight'] < 4 and arrivals[key]['P']['fm'] is not None:
stat = key
ccode = arrivals[key]['P']['channel']
ncode = arrivals[key]['P']['network']
if arrivals[key]['P']['weight'] < 2:
Pqual='I'
else:
Pqual='E'
for i in range(len(picks)):
station = picks[i].waveform_id.station_code
if station == stat:
# get resource ID
resid_picks = picks[i].get('resource_id')
# find same ID in eventinfo
# there it is the pick_id!!
for j in range(len(eventinfo.origins[0].arrivals)):
resid_eventinfo = eventinfo.origins[0].arrivals[j].get('pick_id')
if resid_eventinfo == resid_picks and eventinfo.origins[0].arrivals[j].phase == 'P':
if len(stat) > 4: # HASH handles only 4-string station IDs
stat = stat[1:5]
az = eventinfo.origins[0].arrivals[j].get('azimuth')
inz = eventinfo.origins[0].arrivals[j].get('takeoff_angle')
dist = eventinfo.origins[0].arrivals[j].get('distance')
# write phase line for HASH-driver 1
fid1.write('%-4s%sP%s%d 0 %3.1f %03d %03d 2 1 %s\n' % (stat, Pqual, arrivals[key]['P']['fm'], arrivals[key]['P']['weight'],
dist, inz, az, ccode))
# write phase line for HASH-driver 2
fid2.write('%-4s %s %s %s %s \n' % (
stat,
ncode,
ccode,
Pqual,
arrivals[key]['P']['fm']))
break
fid1.write(' %s' % hashID)
fid1.close()
fid2.close()
def merge_picks(event, picks): def merge_picks(event, picks):
""" """

View File

@ -1,21 +0,0 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
from pylot.core.io.phases import writephases
from pylot.core.util.version import get_git_version as _getVersionString
__version__ = _getVersionString()
def export(picks, fnout):
'''
Take <picks> dictionary and exports picking data to a NLLOC-obs
<phasefile> without creating an ObsPy event object.
:param picks: picking data dictionary
:type picks: dict
:param fnout: complete path to the exporting obs file
:type fnout: str
'''
# write phases to NLLoc-phase file
writephases(picks, 'HYPO71', fnout)

View File

@ -14,7 +14,7 @@ __version__ = _getVersionString()
class NLLocError(EnvironmentError): class NLLocError(EnvironmentError):
pass pass
def export(picks, fnout): 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
<phasefile> without creating an ObsPy event object. <phasefile> without creating an ObsPy event object.
@ -24,9 +24,12 @@ def export(picks, fnout):
: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
''' '''
# write phases to NLLoc-phase file # write phases to NLLoc-phase file
writephases(picks, 'NLLoc', fnout) writephases(picks, 'NLLoc', fnout, parameter)
def modify_inputs(ctrfn, root, nllocoutn, phasefn, tttn): def modify_inputs(ctrfn, root, nllocoutn, phasefn, tttn):
@ -67,14 +70,17 @@ def modify_inputs(ctrfn, root, nllocoutn, phasefn, tttn):
nllfile.close() nllfile.close()
def locate(fnin): def locate(fnin, infile=None):
""" """
takes an external program name takes an external program name
:param fnin: :param fnin:
:return: :return:
""" """
exe_path = which('NLLoc') if infile is None:
exe_path = which('NLLoc')
else:
exe_path = which('NLLoc', infile)
if exe_path is None: if exe_path is None:
raise NLLocError('NonLinLoc executable not found; check your ' raise NLLocError('NonLinLoc executable not found; check your '
'environment variables') 'environment variables')

View File

@ -1,2 +1,27 @@
#!/usr/bin/env python #!/usr/bin/env python
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
from pylot.core.io.phases import writephases
from pylot.core.util.version import get_git_version as _getVersionString
__version__ = _getVersionString()
def export(picks, fnout, parameter, eventinfo):
'''
Take <picks> dictionary and exports picking data to a VELEST-cnv
<phasefile> without creating an ObsPy event object.
:param picks: picking data dictionary
:type picks: dict
:param fnout: complete path to the exporting obs file
:type fnout: str
:param: parameter, all input information
:type: object
:param: eventinfo, source time needed for VELEST-cnv format
:type: list object
'''
# write phases to VELEST-phase file
writephases(picks, 'VELEST', fnout, parameter, eventinfo)

20
pylot/core/pick/autopick.py Executable file → Normal file
View File

@ -143,7 +143,7 @@ def autopickstation(wfstream, pickparam, verbose=False):
Sflag = 0 Sflag = 0
Pmarker = [] Pmarker = []
Ao = None # Wood-Anderson peak-to-peak amplitude Ao = None # Wood-Anderson peak-to-peak amplitude
picker = 'autoPyLoT' # name of the picking programm picker = 'auto' # type of picks
# split components # split components
zdat = wfstream.select(component="Z") zdat = wfstream.select(component="Z")
@ -157,7 +157,7 @@ def autopickstation(wfstream, pickparam, verbose=False):
ndat = wfstream.select(component="1") ndat = wfstream.select(component="1")
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=zdat[0].stats.station,
data=str(zdat)) data=str(zdat))
@ -552,7 +552,7 @@ def autopickstation(wfstream, pickparam, verbose=False):
print('autopickstation: S-weight: {0}, SNR: {1}, ' print('autopickstation: S-weight: {0}, SNR: {1}, '
'SNR[dB]: {2}\n' 'SNR[dB]: {2}\n'
'################################################' '##################################################'
''.format(Sweight, SNRS, SNRSdB)) ''.format(Sweight, SNRS, SNRSdB))
################################################################ ################################################################
# get Wood-Anderson peak-to-peak amplitude # get Wood-Anderson peak-to-peak amplitude
@ -566,7 +566,7 @@ def autopickstation(wfstream, pickparam, verbose=False):
'AIC-SNR={0}, AIC-Slope={1}counts/s\n' \ 'AIC-SNR={0}, AIC-Slope={1}counts/s\n' \
'(min. AIC-SNR={2}, ' \ '(min. AIC-SNR={2}, ' \
'min. AIC-Slope={3}counts/s)\n' \ 'min. AIC-Slope={3}counts/s)\n' \
'################################################' \ '##################################################' \
''.format(aicarhpick.getSNR(), ''.format(aicarhpick.getSNR(),
aicarhpick.getSlope(), aicarhpick.getSlope(),
minAICSSNR, minAICSSNR,
@ -778,11 +778,15 @@ def autopickstation(wfstream, pickparam, verbose=False):
# create dictionary # create dictionary
# for P phase # for P phase
ppick = dict(lpp=lpickP, epp=epickP, mpp=mpickP, spe=Perror, snr=SNRP, ccode = zdat[0].stats.channel
ncode = zdat[0].stats.network
ppick = dict(channel=ccode, network=ncode, lpp=lpickP, epp=epickP, mpp=mpickP, spe=Perror, snr=SNRP,
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
spick = dict(lpp=lpickS, epp=epickS, mpp=mpickS, spe=Serror, snr=SNRS, ccode = edat[0].stats.channel
ncode = edat[0].stats.network
spick = dict(channel=ccode, network=ncode, lpp=lpickS, epp=epickS, mpp=mpickS, spe=Serror, snr=SNRS,
snrdb=SNRSdB, weight=Sweight, fm=None, picker=picker, Ao=Ao) snrdb=SNRSdB, weight=Sweight, fm=None, picker=picker, Ao=Ao)
# merge picks into returning dictionary # merge picks into returning dictionary
picks = dict(P=ppick, S=spick) picks = dict(P=ppick, S=spick)
@ -804,7 +808,7 @@ def iteratepicker(wf, NLLocfile, picks, badpicks, pickparameter):
:param pickparameter: picking parameters from autoPyLoT-input file :param pickparameter: picking parameters from autoPyLoT-input file
''' '''
msg = '#######################################################\n' \ msg = '##################################################\n' \
'autoPyLoT: Found {0} bad onsets at station(s) {1}, ' \ 'autoPyLoT: Found {0} bad onsets at station(s) {1}, ' \
'starting re-picking them ...'.format(len(badpicks), badpicks) 'starting re-picking them ...'.format(len(badpicks), badpicks)
print(msg) print(msg)
@ -823,7 +827,7 @@ def iteratepicker(wf, NLLocfile, picks, badpicks, pickparameter):
badpicks[i][1] = picks[badpicks[i][0]]['P']['mpp'] - float(res) badpicks[i][1] = picks[badpicks[i][0]]['P']['mpp'] - float(res)
# get corresponding waveform stream # get corresponding waveform stream
msg = '#######################################################\n' \ msg = '##################################################\n' \
'iteratepicker: Re-picking station {0}'.format(badpicks[i][0]) 'iteratepicker: Re-picking station {0}'.format(badpicks[i][0])
print(msg) print(msg)
wf2pick = wf.select(station=badpicks[i][0]) wf2pick = wf.select(station=badpicks[i][0])

View File

@ -7,7 +7,6 @@ import os
import numpy as np import numpy as np
import glob import glob
import matplotlib.pyplot as plt import matplotlib.pyplot as plt
from obspy import read_events from obspy import read_events
from pylot.core.io.phases import picksdict_from_picks from pylot.core.io.phases import picksdict_from_picks
@ -289,7 +288,6 @@ class PDFDictionary(object):
values['mpp'], values['mpp'],
values['lpp'], values['lpp'],
type=type) type=type)
return pdf_picks return pdf_picks
def plot(self, stations=None): def plot(self, stations=None):
@ -493,4 +491,4 @@ if __name__ == "__main__":
main() main()
pr.disable() pr.disable()
# after your program ends # after your program ends
pr.print_stats(sort="calls") pr.print_stats(sort="calls")

View File

@ -1,12 +1,11 @@
#!/usr/bin/env python #!/usr/bin/env python
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# #
# -*- coding: utf-8 -*-
""" """
Created Mar/Apr 2015 Created Mar/Apr 2015
Collection of helpful functions for manual and automatic picking. Collection of helpful functions for manual and automatic picking.
:author: Ludger Kueperkoch / MAGS2 EP3 working group :author: Ludger Kueperkoch, BESTEC GmbH
""" """
import warnings import warnings

0
pylot/core/util/__init__.py Executable file → Normal file
View File

View File

@ -180,8 +180,10 @@ def read_metadata(path_to_inventory):
invtype = key_for_set_value(inv) invtype = key_for_set_value(inv)
if invtype is None: if invtype is None:
raise IOError("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!!")
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:
@ -250,13 +252,23 @@ def restitute_data(data, invtype, inobj, unit='VEL', force=False):
else: else:
finv = invlist[0] finv = invlist[0]
inventory = read_inventory(finv, format='STATIONXML') inventory = read_inventory(finv, format='STATIONXML')
elif invtype == None:
print("No restitution possible, as there are no station-meta data available!")
break
else: else:
data.remove(tr) data.remove(tr)
continue continue
# apply restitution to data # apply restitution to data
print("Correcting instrument at station %s, channel %s" \
% (tr.stats.station, tr.stats.channel))
try: try:
if invtype in ['resp', 'dless']: if invtype in ['resp', 'dless']:
tr.simulate(**kwargs) try:
tr.simulate(**kwargs)
except ValueError as e:
vmsg = '{0}'.format(e)
print(vmsg)
else: else:
tr.attach_response(inventory) tr.attach_response(inventory)
tr.remove_response(output=unit, tr.remove_response(output=unit,

View File

@ -8,7 +8,9 @@ Created on Wed Feb 26 12:31:25 2014
import os import os
from pylot.core.loc import nll from pylot.core.loc import nll
from pylot.core.loc import hsat from pylot.core.loc import hyposat
from pylot.core.loc import hypo71
from pylot.core.loc import hypodd
from pylot.core.loc import velest from pylot.core.loc import velest
@ -43,10 +45,6 @@ FILTERDEFAULTS = readFilterInformation(os.path.join(os.path.expanduser('~'),
'.pylot', '.pylot',
'filter.in')) 'filter.in'))
AUTOMATIC_DEFAULTS = os.path.join(os.path.expanduser('~'),
'.pylot',
'autoPyLoT.in')
TIMEERROR_DEFAULTS = os.path.join(os.path.expanduser('~'), TIMEERROR_DEFAULTS = os.path.join(os.path.expanduser('~'),
'.pylot', '.pylot',
'PILOT_TimeErrors.in') 'PILOT_TimeErrors.in')
@ -55,7 +53,7 @@ OUTPUTFORMATS = {'.xml': 'QUAKEML',
'.cnv': 'CNV', '.cnv': 'CNV',
'.obs': 'NLLOC_OBS'} '.obs': 'NLLOC_OBS'}
LOCTOOLS = dict(nll=nll, hsat=hsat, velest=velest) LOCTOOLS = dict(nll=nll, hyposat=hyposat, velest=velest, hypo71=hypo71, hypodd=hypodd)
COMPPOSITION_MAP = dict(Z=2, N=1, E=0) COMPPOSITION_MAP = dict(Z=2, N=1, E=0)
COMPPOSITION_MAP['1'] = 1 COMPPOSITION_MAP['1'] = 1

View File

@ -51,8 +51,11 @@ def exp_parameter(te, tm, tl, eta):
sig1 = np.log(eta) / (te - tm) sig1 = np.log(eta) / (te - tm)
sig2 = np.log(eta) / (tm - tl) sig2 = np.log(eta) / (tm - tl)
if np.isinf(sig1) == True:
sig1 = np.log(eta) / (tm - tl)
if np.isinf(sig2) == True:
sig2 = np.log(eta) / (te - tm)
a = 1 / (1 / sig1 + 1 / sig2) a = 1 / (1 / sig1 + 1 / sig2)
return tm, sig1, sig2, a return tm, sig1, sig2, a
@ -237,7 +240,7 @@ class ProbabilityDensityFunction(object):
@classmethod @classmethod
def from_pick(self, lbound, barycentre, rbound, incr=0.001, decfact=0.01, def from_pick(self, lbound, barycentre, rbound, incr=0.001, decfact=0.01,
type='gauss'): type='exp'):
''' '''
Initialize a new ProbabilityDensityFunction object. Initialize a new ProbabilityDensityFunction object.
Takes incr, lbound, barycentre and rbound to derive x0 and the number Takes incr, lbound, barycentre and rbound to derive x0 and the number
@ -304,10 +307,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)
return rval * self.incr rval = self.mu
# Not sure about this! That might not be the barycentre.
# However, for std calculation (next function)
# self.mu is also used!! (LK, 02/2017)
return rval
def standard_deviation(self): def standard_deviation(self):
mu = self.mu mu = self.mu

View File

@ -7,17 +7,18 @@ class AutoPickThread(QThread):
message = Signal(str) message = Signal(str)
finished = Signal() finished = Signal()
def __init__(self, parent, func, data, param): def __init__(self, parent, func, infile, fnames, savepath):
super(AutoPickThread, self).__init__() super(AutoPickThread, self).__init__()
self.setParent(parent) self.setParent(parent)
self.func = func self.func = func
self.data = data self.infile = infile
self.param = param self.fnames = fnames
self.savepath = savepath
def run(self): def run(self):
sys.stdout = self sys.stdout = self
picks = self.func(self.data, self.param) picks = self.func(self.infile, self.fnames, self.savepath)
print("Autopicking finished!\n") print("Autopicking finished!\n")

View File

@ -477,7 +477,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): 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
modified after: http://stackoverflow.com/questions/377017/test-if-executable-exists-in-python modified after: http://stackoverflow.com/questions/377017/test-if-executable-exists-in-python
@ -490,7 +490,12 @@ def which(program):
for key in settings.allKeys(): for key in settings.allKeys():
if 'binPath' in key: if 'binPath' in key:
os.environ['PATH'] += ':{0}'.format(settings.value(key)) os.environ['PATH'] += ':{0}'.format(settings.value(key))
bpath = os.path.join(os.path.expanduser('~'), '.pylot', 'autoPyLoT.in') if infile is None:
# use default parameter-file name
bpath = os.path.join(os.path.expanduser('~'), '.pylot', 'pylot.in')
else:
bpath = os.path.join(os.path.expanduser('~'), '.pylot', infile)
if os.path.exists(bpath): if os.path.exists(bpath):
nllocpath = ":" + AutoPickParameter(bpath).get('nllocbin') nllocpath = ":" + AutoPickParameter(bpath).get('nllocbin')
os.environ['PATH'] += nllocpath os.environ['PATH'] += nllocpath

0
pylot/core/util/version.py Executable file → Normal file
View File

View File

@ -5,12 +5,15 @@ Created on Wed Mar 19 11:27:35 2014
@author: sebastianw @author: sebastianw
""" """
import os
import getpass
import warnings import warnings
import copy import copy
import datetime import datetime
import numpy as np import numpy as np
from matplotlib.figure import Figure from matplotlib.figure import Figure
from pylot.core.util.utils import find_horizontals
try: try:
from matplotlib.backends.backend_qt4agg import FigureCanvas from matplotlib.backends.backend_qt4agg import FigureCanvas
@ -26,7 +29,7 @@ from PySide.QtGui import QAction, QApplication, QCheckBox, QComboBox, \
from PySide.QtCore import QSettings, Qt, QUrl, Signal, Slot from PySide.QtCore import QSettings, Qt, QUrl, Signal, Slot
from PySide.QtWebKit import QWebView from PySide.QtWebKit import QWebView
from obspy import Stream, UTCDateTime from obspy import Stream, UTCDateTime
from pylot.core.io.inputs import FilterOptions from pylot.core.io.inputs import FilterOptions, AutoPickParameter
from pylot.core.pick.utils import getSNR, earllatepicker, getnoisewin, \ from pylot.core.pick.utils import getSNR, earllatepicker, getnoisewin, \
getResolutionWindow getResolutionWindow
from pylot.core.pick.compare import Comparison from pylot.core.pick.compare import Comparison
@ -49,7 +52,12 @@ def getDataType(parent):
def plot_pdf(_axes, x, y, annotation, bbox_props, xlabel=None, ylabel=None, def plot_pdf(_axes, x, y, annotation, bbox_props, xlabel=None, ylabel=None,
title=None): title=None):
_axes.plot(x, y) # try method or data
try:
_axes.plot(x, y()) # y provided as method
except:
_axes.plot(x, y) # y provided as data
if title: if title:
_axes.set_title(title) _axes.set_title(title)
if xlabel: if xlabel:
@ -235,23 +243,23 @@ class ComparisonDialog(QDialog):
x, y, std, exp = pdf.axis, pdf.data, pdf.standard_deviation(), \ x, y, std, exp = pdf.axis, pdf.data, pdf.standard_deviation(), \
pdf.expectation() pdf.expectation()
annotation = "{phase} difference on {station}\n" \ annotation = "%s difference on %s\n" \
"expectation: {exp}\n" \ "expectation: %7.4f s\n" \
"std: {std}".format(station=station, phase=phase, "std: %7.4f s" % (phase, station,
std=std, exp=exp) exp, std)
bbox_props = dict(boxstyle='round', facecolor='lightgrey', alpha=.7) bbox_props = dict(boxstyle='round', facecolor='lightgrey', alpha=.7)
plot_pdf(_axes, x, y, annotation, bbox_props, 'time difference [s]', plot_pdf(_axes, x, y, annotation, bbox_props, 'time difference [s]',
'propability density [-]', phase) 'propability density [-]', phase)
pdf_a = copy.deepcopy(self.data.get('auto')[station][phase]) pdf_a = copy.deepcopy(self.data.get('auto')[station][phase])
pdf_m = copy.deepcopy(self.data.get('manu')[station][phase]) pdf_m = copy.deepcopy(self.data.get('manu')[station][phase])
xauto, yauto, stdauto, expauto, alim = pdf_a.axis, pdf_a.data, \ xauto, yauto, stdauto, expauto, alim = pdf_a.axis, pdf_a.data(), \
pdf_a.standard_deviation(), \ pdf_a.standard_deviation(), \
pdf_a.expectation(), \ pdf_a.expectation(), \
pdf_a.limits() pdf_a.limits()
xmanu, ymanu, stdmanu, expmanu, mlim = pdf_m.axis, pdf_m.data, \ xmanu, ymanu, stdmanu, expmanu, mlim = pdf_m.axis, pdf_m.data(), \
pdf_m.standard_deviation(), \ pdf_m.standard_deviation(), \
pdf_m.expectation(), \ pdf_m.expectation(), \
pdf_m.limits() pdf_m.limits()
@ -259,21 +267,19 @@ class ComparisonDialog(QDialog):
lims = clims(alim, mlim) lims = clims(alim, mlim)
# relative x axis # relative x axis
x0 = lims[0] x0 = lims[0]
xmanu -= x0 xmanu -= x0
xauto -= x0 xauto -= x0
lims = [lim - x0 for lim in lims] lims = [lim - x0 for lim in lims]
x0 = UTCDateTime(x0) x0 = UTCDateTime(x0)
# set annotation text # set annotation text
mannotation = "probability density for manual pick\n" \ mannotation = "probability density of manual pick\n" \
"expectation: {exp}\n" \ "expectation: %7.4f s\n" \
"std: {std}".format(std=stdmanu, "std: %7.4f s" % (expmanu-x0.timestamp, stdmanu)
exp=expmanu-x0.timestamp)
aannotation = "probability density for automatic pick\n" \ aannotation = "probability density of automatic pick\n" \
"expectation: {exp}\n" \ "expectation: %7.4f s\n" \
"std: {std}".format(std=stdauto, "std: %7.4f s" % (expauto-x0.timestamp, stdauto)
exp=expauto-x0.timestamp)
_ax1 = plot_pdf(_ax1, xmanu, ymanu, mannotation, _ax1 = plot_pdf(_ax1, xmanu, ymanu, mannotation,
bbox_props=bbox_props, xlabel='seconds since ' bbox_props=bbox_props, xlabel='seconds since '
@ -504,15 +510,17 @@ class WaveformWidget(FigureCanvas):
class PickDlg(QDialog): class PickDlg(QDialog):
def __init__(self, parent=None, data=None, station=None, picks=None, def __init__(self, parent=None, data=None, station=None, picks=None,
rotate=False): rotate=False, infile=None):
super(PickDlg, self).__init__(parent) super(PickDlg, self).__init__(parent)
# initialize attributes # initialize attributes
self.infile = infile
self.station = station self.station = station
self.rotate = rotate self.rotate = rotate
self.components = 'ZNE' self.components = 'ZNE'
settings = QSettings() settings = QSettings()
self._user = settings.value('user/Login', 'anonymous') pylot_user = getpass.getuser()
self._user = settings.value('user/Login', pylot_user)
if picks: if picks:
self.picks = picks self.picks = picks
else: else:
@ -704,6 +712,9 @@ class PickDlg(QDialog):
self.cidrelease = self.connectReleaseEvent(self.panRelease) self.cidrelease = self.connectReleaseEvent(self.panRelease)
self.cidscroll = self.connectScrollEvent(self.scrollZoom) self.cidscroll = self.connectScrollEvent(self.scrollZoom)
def getinfile(self):
return self.infile
def getStartTime(self): def getStartTime(self):
return self.stime return self.stime
@ -806,6 +817,7 @@ class PickDlg(QDialog):
self.disconnectMotionEvent() self.disconnectMotionEvent()
self.cidpress = self.connectPressEvent(self.setPick) self.cidpress = self.connectPressEvent(self.setPick)
print(self.selectPhase.currentText())
if self.selectPhase.currentText().upper().startswith('P'): if self.selectPhase.currentText().upper().startswith('P'):
self.setIniPickP(gui_event, wfdata, trace_number) self.setIniPickP(gui_event, wfdata, trace_number)
elif self.selectPhase.currentText().upper().startswith('S'): elif self.selectPhase.currentText().upper().startswith('S'):
@ -819,14 +831,14 @@ class PickDlg(QDialog):
def setIniPickP(self, gui_event, wfdata, trace_number): def setIniPickP(self, gui_event, wfdata, trace_number):
parameter = AutoPickParameter(self.getinfile())
ini_pick = gui_event.xdata ini_pick = gui_event.xdata
settings = QSettings() nfac = parameter.get('nfacP')
twins = parameter.get('tsnrz')
nfac = settings.value('picking/nfac_P', 1.3) noise_win = twins[0]
noise_win = settings.value('picking/noise_win_P', 5.) gap_win = twins[1]
gap_win = settings.value('picking/gap_win_P', .2) signal_win = twins[2]
signal_win = settings.value('picking/signal_win_P', 3.)
itrace = int(trace_number) itrace = int(trace_number)
while itrace > len(wfdata) - 1: while itrace > len(wfdata) - 1:
@ -868,14 +880,14 @@ class PickDlg(QDialog):
def setIniPickS(self, gui_event, wfdata): def setIniPickS(self, gui_event, wfdata):
parameter = AutoPickParameter(self.getinfile())
ini_pick = gui_event.xdata ini_pick = gui_event.xdata
settings = QSettings() nfac = parameter.get('nfacS')
twins = parameter.get('tsnrh')
nfac = settings.value('picking/nfac_S', 1.5) noise_win = twins[0]
noise_win = settings.value('picking/noise_win_S', 5.) gap_win = twins[1]
gap_win = settings.value('picking/gap_win_S', .2) signal_win = twins[2]
signal_win = settings.value('picking/signal_win_S', 3.)
# copy data for plotting # copy data for plotting
data = self.getWFData().copy() data = self.getWFData().copy()
@ -922,6 +934,8 @@ class PickDlg(QDialog):
def setPick(self, gui_event): def setPick(self, gui_event):
parameter = AutoPickParameter(self.getinfile())
# get axes limits # get axes limits
self.updateCurrentLimits() self.updateCurrentLimits()
@ -941,7 +955,14 @@ class PickDlg(QDialog):
wfdata.filter(**filteroptions) wfdata.filter(**filteroptions)
# get earliest and latest possible pick and symmetric pick error # get earliest and latest possible pick and symmetric pick error
[epp, lpp, spe] = earllatepicker(wfdata, 1.5, (5., .5, 2.), pick) if wfdata[0].stats.channel[2] == 'Z' or wfdata[0].stats.channel[2] == '3':
nfac = parameter.get('nfacP')
TSNR = parameter.get('tsnrz')
else:
nfac = parameter.get('nfacS')
TSNR = parameter.get('tsnrh')
[epp, lpp, spe] = earllatepicker(wfdata, nfac, (TSNR[0], TSNR[1], TSNR[2]), pick)
# return absolute time values for phases # return absolute time values for phases
stime = self.getStartTime() stime = self.getStartTime()
@ -951,7 +972,8 @@ class PickDlg(QDialog):
# save pick times for actual phase # save pick times for actual phase
phasepicks = dict(epp=epp, lpp=lpp, mpp=mpp, spe=spe, phasepicks = dict(epp=epp, lpp=lpp, mpp=mpp, spe=spe,
picker=self.getUser()) picker='manual', channel=channel,
network=wfdata[0].stats.network)
try: try:
oldphasepick = self.picks[phase] oldphasepick = self.picks[phase]
@ -1171,13 +1193,15 @@ class PickDlg(QDialog):
class PropertiesDlg(QDialog): class PropertiesDlg(QDialog):
def __init__(self, parent=None): def __init__(self, parent=None, infile=None):
super(PropertiesDlg, self).__init__(parent) super(PropertiesDlg, self).__init__(parent)
self.infile = infile
appName = QApplication.applicationName() appName = QApplication.applicationName()
self.setWindowTitle("{0} Properties".format(appName)) self.setWindowTitle("{0} Properties".format(appName))
self.tabWidget = QTabWidget() self.tabWidget = QTabWidget()
self.tabWidget.addTab(InputsTab(self), "Inputs") self.tabWidget.addTab(InputsTab(self), "Inputs")
self.tabWidget.addTab(OutputsTab(self), "Outputs") self.tabWidget.addTab(OutputsTab(self), "Outputs")
@ -1186,7 +1210,8 @@ class PropertiesDlg(QDialog):
self.tabWidget.addTab(LocalisationTab(self), "Loc Tools") self.tabWidget.addTab(LocalisationTab(self), "Loc Tools")
self.buttonBox = QDialogButtonBox(QDialogButtonBox.Ok | self.buttonBox = QDialogButtonBox(QDialogButtonBox.Ok |
QDialogButtonBox.Apply | QDialogButtonBox.Apply |
QDialogButtonBox.Close) QDialogButtonBox.Close |
QDialogButtonBox.RestoreDefaults)
layout = QVBoxLayout() layout = QVBoxLayout()
layout.addWidget(self.tabWidget) layout.addWidget(self.tabWidget)
@ -1195,8 +1220,11 @@ class PropertiesDlg(QDialog):
self.buttonBox.accepted.connect(self.accept) self.buttonBox.accepted.connect(self.accept)
self.buttonBox.rejected.connect(self.reject) self.buttonBox.rejected.connect(self.reject)
self.buttonBox.button(QDialogButtonBox.Apply).clicked.connect( self.buttonBox.button(QDialogButtonBox.Apply).clicked.connect(self.apply)
self.apply) self.buttonBox.button(QDialogButtonBox.RestoreDefaults).clicked.connect(self.restore)
def getinfile(self):
return self.infile
def accept(self, *args, **kwargs): def accept(self, *args, **kwargs):
self.apply() self.apply()
@ -1209,6 +1237,14 @@ class PropertiesDlg(QDialog):
if values is not None: if values is not None:
self.setValues(values) self.setValues(values)
def restore(self):
for widint in range(self.tabWidget.count()):
curwid = self.tabWidget.widget(widint)
values = curwid.resetValues(self.getinfile())
if values is not None:
self.setValues(values)
@staticmethod @staticmethod
def setValues(tabValues): def setValues(tabValues):
settings = QSettings() settings = QSettings()
@ -1224,16 +1260,19 @@ class PropTab(QWidget):
def getValues(self): def getValues(self):
return None return None
def resetValues(self, infile=None):
return None
class InputsTab(PropTab): class InputsTab(PropTab):
def __init__(self, parent): def __init__(self, parent, infile=None):
super(InputsTab, self).__init__(parent) super(InputsTab, self).__init__(parent)
settings = QSettings() settings = QSettings()
pylot_user = getpass.getuser()
fulluser = settings.value("user/FullName") fulluser = settings.value("user/FullName")
login = settings.value("user/Login") login = settings.value("user/Login")
fullNameLabel = QLabel("Full name for user '{0}': ".format(login)) fullNameLabel = QLabel("Full name for user '{0}': ".format(pylot_user))
# get the full name of the actual user # get the full name of the actual user
self.fullNameEdit = QLineEdit() self.fullNameEdit = QLineEdit()
@ -1276,9 +1315,24 @@ class InputsTab(PropTab):
"data/Structure": self.structureSelect.currentText()} "data/Structure": self.structureSelect.currentText()}
return values return values
def resetValues(self, infile):
para = AutoPickParameter(infile)
datstruct = para.get('datastructure')
if datstruct == 'SeisComp':
index = 0
else:
index = 2
datapath = para.get('datapath')
rootpath = para.get('rootpath')
database = para.get('database')
path = os.path.join(os.path.expanduser('~'), rootpath, datapath, database)
values = {"data/dataRoot": self.dataDirEdit.setText("%s" % path),
"user/FullName": self.fullNameEdit.text(),
"data/Structure": self.structureSelect.setCurrentIndex(index)}
return values
class OutputsTab(PropTab): class OutputsTab(PropTab):
def __init__(self, parent=None): def __init__(self, parent=None, infile=None):
super(OutputsTab, self).__init__(parent) super(OutputsTab, self).__init__(parent)
settings = QSettings() settings = QSettings()
@ -1302,6 +1356,9 @@ class OutputsTab(PropTab):
values = {"output/Format": self.eventOutputComboBox.currentText()} values = {"output/Format": self.eventOutputComboBox.currentText()}
return values return values
def resetValues(self, infile):
values = {"output/Format": self.eventOutputComboBox.setCurrentIndex(1)}
return values
class PhasesTab(PropTab): class PhasesTab(PropTab):
def __init__(self, parent=None): def __init__(self, parent=None):
@ -1318,7 +1375,7 @@ class GraphicsTab(PropTab):
class LocalisationTab(PropTab): class LocalisationTab(PropTab):
def __init__(self, parent=None): def __init__(self, parent=None, infile=None):
super(LocalisationTab, self).__init__(parent) super(LocalisationTab, self).__init__(parent)
settings = QSettings() settings = QSettings()
@ -1388,6 +1445,13 @@ class LocalisationTab(PropTab):
"loc/tool": loctool} "loc/tool": loctool}
return values return values
def resetValues(self, infile):
para = AutoPickParameter(infile)
nllocroot = para.get('nllocroot')
nllocbin = para.get('nllocbin')
loctool = self.locToolComboBox.setCurrentIndex(3)
values = {"nll/rootPath": self.rootedit.setText("%s" % nllocroot),
"nll/binPath": self.binedit.setText("%s" % nllocbin)}
class NewEventDlg(QDialog): class NewEventDlg(QDialog):
def __init__(self, parent=None, titleString="Create a new event"): def __init__(self, parent=None, titleString="Create a new event"):

0
pylot/testing/testHelpForm.py Executable file → Normal file
View File

0
pylot/testing/testPickDlg.py Executable file → Normal file
View File

0
pylot/testing/testPropDlg.py Executable file → Normal file
View File

0
pylot/testing/testUIcomponents.py Executable file → Normal file
View File

0
pylot/testing/test_autopick.py Executable file → Normal file
View File

0
scripts/pylot-noisewindow.py Executable file → Normal file
View File

0
scripts/pylot-pick-earliest-latest.py Executable file → Normal file
View File

0
scripts/pylot-pick-firstmotion.py Executable file → Normal file
View File

0
scripts/pylot-reasses-pilot-db.py Executable file → Normal file
View File

0
scripts/pylot-reasses-pilot-event.py Executable file → Normal file
View File

0
scripts/pylot-signalwindow.py Executable file → Normal file
View File

0
scripts/pylot-snr.py Executable file → Normal file
View File

0
scripts/run_makeCF.py Executable file → Normal file
View File