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
:author:
Sebastian Wehling-Benatelli
Sebastian Wehling-Benatelli / Ludger Küperkoch
:copyright:
The PyLoT Development Team (https://ariadne.geophysik.rub.de/trac/PyLoT)
:license:
@ -25,14 +25,13 @@ https://www.iconfinder.com/iconsets/flavour
import os
import sys
import matplotlib
matplotlib.use('Qt4Agg')
matplotlib.rcParams['backend.qt4'] = 'PySide'
from PySide.QtCore import QCoreApplication, QSettings, Signal, QFile, \
QFileInfo, Qt
QFileInfo, Qt, QSize
from PySide.QtGui import QMainWindow, QInputDialog, QIcon, QFileDialog, \
QWidget, QHBoxLayout, QStyle, QKeySequence, QLabel, QFrame, QAction, \
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.io.data import Data
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.utils import symmetrize_error
from pylot.core.io.phases import picksdict_from_picks
import pylot.core.loc.nll as nll
from pylot.core.util.defaults import FILTERDEFAULTS, COMPNAME_MAP, \
AUTOMATIC_DEFAULTS
from pylot.core.util.defaults import FILTERDEFAULTS, COMPNAME_MAP
from pylot.core.util.errors import FormatError, DatastructureError, \
OverwriteError, ProcessingError
from pylot.core.util.connection import checkurl
@ -78,15 +77,23 @@ class MainWindow(QMainWindow):
self.createAction = createAction
# read settings
settings = QSettings()
# check for default pylot.in-file
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:
fulluser = QInputDialog.getText(self, "Enter Name:", "Full name")
settings.setValue("user/FullName", fulluser)
settings.setValue("user/Login", getLogin())
if settings.value("agency_id", None) is None:
agency = QInputDialog.getText(self,
"Enter authority name (e.g. BUG):",
"Enter authority/institution name:",
"Authority")
settings.setValue("agency_id", agency)
self.recentfiles = settings.value("data/recentEvents", [])
@ -164,16 +171,20 @@ class MainWindow(QMainWindow):
lambda event: self.tutor_user())
_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)
saveIcon = self.style().standardIcon(QStyle.SP_DriveHDIcon)
helpIcon = self.style().standardIcon(QStyle.SP_DialogHelpButton)
newIcon = self.style().standardIcon(QStyle.SP_FileIcon)
# 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.addPixmap(QPixmap(':/icons/key_P.png'))
s_icon = QIcon()
@ -189,12 +200,11 @@ class MainWindow(QMainWindow):
e_icon = QIcon()
e_icon.addPixmap(QPixmap(':/icons/key_E.png'))
auto_icon = QIcon()
auto_icon.addPixmap(QPixmap(':/icons/sync.png'))
auto_icon.addPixmap(QPixmap(':/icons/autopick_button.png'))
locate_icon = QIcon()
locate_icon.addPixmap(QPixmap(':/icons/locate.png'))
locate_icon.addPixmap(QPixmap(':/icons/locate_button.png'))
compare_icon = QIcon()
compare_icon.addPixmap(QPixmap(':/icons/compare.png'))
compare_icon.addPixmap(QPixmap(':/icons/compare_button.png'))
newEventAction = self.createAction(self, "&New event ...",
self.createNewEvent,
QKeySequence.New, newIcon,
@ -203,28 +213,29 @@ class MainWindow(QMainWindow):
self.load_data,
QKeySequence.Open,
manupicksicon,
"Load pick data for "
"the actual event.")
"Load manual picks for "
"the displayed event.")
openmanualpicksaction.setData(None)
openautopicksaction = self.createAction(self, "Load &automatic picks "
"...",
self.load_autopicks,
"Ctrl+A",
autopicksicon,
"Load automatic pick data "
"for the actual event.")
"Load automatic picks "
"for the displayed event.")
openautopicksaction.setData(None)
loadlocationaction = self.createAction(self, "Load &location ...",
self.load_loc, "Ctrl+L",
locactionicon,
"Load location information on "
"the actual event.")
"the displayed event.")
loadpilotevent = self.createAction(self, "Load PILOT &event ...",
self.load_pilotevent, "Ctrl+E",
loadpiloticon,
"Load PILOT event from information "
"Matlab binary collections.")
"MatLab binary collections (created"
" in former MatLab based version).")
saveEventAction = self.createAction(self, "&Save event ...",
self.saveData, QKeySequence.Save,
saveIcon, "Save actual event data.")
@ -269,7 +280,7 @@ class MainWindow(QMainWindow):
printAction = self.createAction(self, "&Print event ...",
self.show_event_information, QKeySequence.Print,
print_icon,
"Print waveform overview.")
"Print waveform section.")
helpAction = self.createAction(self, "&Help ...", self.helpHelp,
QKeySequence.HelpContents, helpIcon,
"""Show either the documentation
@ -347,13 +358,12 @@ class MainWindow(QMainWindow):
# pickToolActions = (selectStation, )
# pickToolBar.setObjectName("PickTools")
# self.addActions(pickToolBar, pickToolActions)
locateEvent = self.createAction(parent=self, text='locate_event',
locateEvent = self.createAction(parent=self, text='locate the event',
slot=self.locate_event,
shortcut='Alt+Ctrl+L',
icon=locate_icon,
tip='Locate the event using '
'the picked arrivals.')
'the displayed manual arrivals.')
locationToolBar = self.addToolBar("LocationTools")
locationToolActions = (locateEvent,)
@ -586,8 +596,7 @@ class MainWindow(QMainWindow):
ans = QMessageBox.question(self, self.tr("Overwrite file..."),
self.tr("File already exists: {0}\n".format(fbasename + exform) + \
"Overwrite file anyway?"),
QMessageBox.Cancel, QMessageBox.Yes | QMessageBox.No,
QMessageBox.Cancel)
QMessageBox.Yes | QMessageBox.No | QMessageBox.Cancel)
# only negative answers have to be caught
if ans == QMessageBox.No:
self.saveData()
@ -601,6 +610,9 @@ class MainWindow(QMainWindow):
self.update_status('Event saved as %s' % (fbasename + exform))
return True
def getinfile(self):
return self.infile
def getComponent(self):
return self.dispComponent
@ -804,7 +816,8 @@ class MainWindow(QMainWindow):
station = self.getStationName(wfID)
self.update_status('picking on station {0}'.format(station))
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,
picks=self.getPicksOnStation(station))
if pickDlg.exec_():
@ -830,6 +843,7 @@ class MainWindow(QMainWindow):
self.listWidget.scrollToBottom()
def autoPick(self):
self.autosave = QFileDialog().getExistingDirectory(caption='Select autoPyLoT output')
self.listWidget = QListWidget()
self.setDirty(True)
self.logDockWidget = QDockWidget("AutoPickLog", self)
@ -838,18 +852,17 @@ class MainWindow(QMainWindow):
Qt.LeftDockWidgetArea | Qt.RightDockWidgetArea)
self.logDockWidget.setWidget(self.listWidget)
self.addDockWidget(Qt.LeftDockWidgetArea, self.logDockWidget)
self.addListItem('loading default values for local data ...')
# may become obsolete if generalized input parameter a read from disc
# during initialization
# TODO double check for obsolete read in of parameters
autopick_parameter = AutoPickParameter(AUTOMATIC_DEFAULTS)
self.addListItem('Loading default values from PyLoT-input file %s'
% self.infile)
autopick_parameter = self._inputs
self.addListItem(str(autopick_parameter))
# Create the worker thread and run it
self.thread = AutoPickThread(parent=self,
func=autopickevent,
data=self.get_data().getWFData(),
param=autopick_parameter)
func=autoPyLoT,
infile = self.infile,
fnames=self.fnames,
savepath=self.autosave)
self.thread.message.connect(self.addListItem)
self.thread.start()
self.thread.finished.connect(self.finalizeAutoPick)
@ -1128,7 +1141,7 @@ class MainWindow(QMainWindow):
QMainWindow.closeEvent(self, event)
def PyLoTprefs(self):
props = PropertiesDlg(self)
props = PropertiesDlg(self, infile=self.getinfile())
if props.exec_():
return
@ -1153,11 +1166,15 @@ def main():
# create the main window
pylot_form = MainWindow()
icon = QIcon()
pylot_form.setWindowIcon(icon)
pylot_form.setIconSize(QSize(60, 60))
splash.showMessage('Loading. Please wait ...')
pylot_app.processEvents()
# set Application Information
pylot_app.setOrganizationName("Ruhr-University Bochum / MAGS2")
pylot_app.setOrganizationName("Ruhr-University Bochum / BESTEC")
pylot_app.setOrganizationDomain("rub.de")
pylot_app.processEvents()
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.
##Installation
## Installation
At the moment there is no automatic installation procedure available for PyLoT.
Best way to install is to clone the repository and add the path to your Python path.
####prerequisites:
#### Prerequisites:
In order to run PyLoT you need to install:
@ -32,7 +32,7 @@ In order to run PyLoT you need to install:
- obspy
- pyside
####some handwork
#### Some handwork:
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.
##release notes:
==============
## Release notes
#### Features
#### Features:
- consistent manual phase picking through predefined SNR dependant zoom level
- 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
- 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)
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
others: A. Bruestle, T. Meier, W. Friederich
Others: A. Bruestle, T. Meier, W. Friederich
[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 glob
import os
import datetime
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
#from PySide.QtGui import QWidget, QInputDialog
from pylot.core.analysis.magnitude import MomentMagnitude, RichterMagnitude
from pylot.core.io.data import Data
from pylot.core.io.inputs import AutoPickParameter
@ -23,7 +29,7 @@ from pylot.core.util.version import get_git_version as _getVersionString
__version__ = _getVersionString()
def autoPyLoT(inputfile):
def autoPyLoT(inputfile, fnames=None, savepath=None):
"""
Determine phase onsets automatically utilizing the automatic picking
algorithms by Kueperkoch et al. 2010/2012.
@ -43,14 +49,13 @@ def autoPyLoT(inputfile):
Version {version} 2015\n
\n
Authors:\n
S. Wehling-Benatelli (Ruhr-Universität Bochum)\n
L. Küperkoch (BESTEC GmbH, Landau i. d. Pfalz)\n
K. Olbert (Christian-Albrechts Universität zu Kiel)\n
S. Wehling-Benatelli (Ruhr-Universitaet Bochum)\n
L. Kueperkoch (BESTEC GmbH, Landau i. d. Pfalz)\n
K. Olbert (Christian-Albrechts Universitaet zu Kiel)\n
***********************************'''.format(version=_getVersionString())
print(splash)
# reading parameter file
parameter = AutoPickParameter(inputfile)
data = Data()
@ -65,8 +70,8 @@ def autoPyLoT(inputfile):
'dbase': parameter.get('database')}
exf = ['root', 'dpath', 'dbase']
if parameter.hasParam('eventID'):
if parameter.hasParam('eventID') and fnames == 'None':
dsfields['eventID'] = parameter.get('eventID')
exf.append('eventID')
@ -100,22 +105,51 @@ def autoPyLoT(inputfile):
print(" !!! ")
datapath = datastructure.expandDataPath()
if not parameter.hasParam('eventID'):
if fnames == 'None' and not parameter.hasParam('eventID'):
# multiple event processing
# read each event in database
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
events = glob.glob(os.path.join(datapath, parameter.get('eventID')))
else:
# autoPyLoT was initialized from GUI
events = fnames
for event in events:
data.setWFData(glob.glob(os.path.join(datapath, event, '*')))
evID = os.path.split(event)[-1]
print('Working on event %s' % event)
print(data)
if fnames == 'None':
data.setWFData(glob.glob(os.path.join(datapath, event, '*')))
evID = os.path.split(event)[-1]
# 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 = remove_underscores(wfdat)
metadata = read_metadata(parameter.get('invdir'))
corr_dat, rest_flag = restitute_data(wfdat.copy(), *metadata)
print('Working on event %s' % event)
print(data)
##########################################################
# !automated picking starts here!
picks = autopickevent(wfdat, parameter)
@ -123,7 +157,7 @@ def autoPyLoT(inputfile):
# locating
if locflag == 1:
# 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!
nllocout = '%s_%s' % (evID, nllocoutpatter)
@ -132,7 +166,7 @@ def autoPyLoT(inputfile):
ttpat)
# locate the event
nll.locate(ctrfile)
nll.locate(ctrfile, inputfile)
# !iterative picking if traces remained unpicked or occupied with bad picks!
# get theoretical onset times for picks with weights >= 4
@ -157,13 +191,15 @@ def autoPyLoT(inputfile):
# calculating seismic moment Mo and moment magnitude Mw
moment_mag = MomentMagnitude(corr_dat, evt, parameter.get('vp'),
parameter.get('Qp'),
parameter.get('rho'), True, 0)
parameter.get('rho'), True, \
parameter.get('iplot'))
# update pick with moment property values (w0, fc, Mo)
for station, props in moment_mag.moment_props.items():
picks[station]['P'].update(props)
evt = moment_mag.updated_event()
local_mag = RichterMagnitude(corr_dat, evt,
parameter.get('sstop'), True, 0)
parameter.get('sstop'), True,\
parameter.get('iplot'))
for station, amplitude in local_mag.amplitudes.items():
picks[station]['S']['Ao'] = amplitude.generic_amplitude
evt = local_mag.updated_event()
@ -185,11 +221,11 @@ def autoPyLoT(inputfile):
print("autoPyLoT: Starting with iteration No. %d ..." % nlloccounter)
picks = iteratepicker(wfdat, nllocfile, picks, badpicks, parameter)
# 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
os.remove(nllocfile)
# locate the event
nll.locate(ctrfile)
nll.locate(ctrfile, inputfile)
print("autoPyLoT: Iteration No. %d finished." % nlloccounter)
# get updated NLLoc-location file
nllocfile = max(glob.glob(locsearch), key=os.path.getctime)
@ -207,13 +243,15 @@ def autoPyLoT(inputfile):
# calculating seismic moment Mo and moment magnitude Mw
moment_mag = MomentMagnitude(corr_dat, evt, parameter.get('vp'),
parameter.get('Qp'),
parameter.get('rho'), True, 0)
parameter.get('rho'), True, \
parameter.get('iplot'))
# update pick with moment property values (w0, fc, Mo)
for station, props in moment_mag.moment_props.items():
picks[station]['P'].update(props)
evt = moment_mag.updated_event()
local_mag = RichterMagnitude(corr_dat, evt,
parameter.get('sstop'), True, 0)
parameter.get('sstop'), True, \
parameter.get('iplot'))
for station, amplitude in local_mag.amplitudes.items():
picks[station]['S']['Ao'] = amplitude.generic_amplitude
evt = local_mag.updated_event()
@ -221,16 +259,35 @@ def autoPyLoT(inputfile):
print("Network moment magnitude: %4.1f" % net_mw.mag)
else:
print("autoPyLoT: No NLLoc-location file available! Stop iteration!")
locflag = 9
##########################################################
# write phase files for various location routines
# HYPO71
hypo71file = '%s/autoPyLoT_HYPO71.pha' % event
hsat.export(picks, hypo71file)
# write phase files for various location
# and fault mechanism calculation routines
# ObsPy event object
data.applyEVTData(picks)
if evt is not None:
data.applyEVTData(evt, 'event')
fnqml = '%s/autoPyLoT' % event
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'
-----Finished event %s!-----\n'
@ -249,7 +306,6 @@ def autoPyLoT(inputfile):
if __name__ == "__main__":
from pylot.core.util.defaults import AUTOMATIC_DEFAULTS
# parse arguments
parser = argparse.ArgumentParser(
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,
action='store',
help='''full path to the file containing the input
parameters for autoPyLoT''',
default=AUTOMATIC_DEFAULTS
)
parameters for autoPyLoT''')
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',
version='autoPyLoT ' + __version__,
help='show version information and exit')
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>
<file>icons/pylot.ico</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/delete.png</file>
<file>icons/compare.png</file>
<file>icons/key_E.png</file>
<file>icons/key_N.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
"""
import os
import matplotlib.pyplot as plt
import numpy as np
import obspy.core.event as ope
from obspy.geodetics import degrees2kilometers
from scipy import integrate, signal
from scipy.optimize import curve_fit
from pylot.core.pick.utils import getsignalwin, crossings_nonzero_all, \
select_for_phase
from pylot.core.util.utils import common_range, fit_curve
def richter_magnitude_scaling(delta):
relation = np.loadtxt(os.path.join(os.path.expanduser('~'),
'.pylot', 'richter_scaling.data'))
@ -200,8 +197,8 @@ class RichterMagnitude(Magnitude):
iwin = getsignalwin(th, t0 - stime, self.calc_win)
wapp = np.max(sqH[iwin])
if self.verbose:
print("Determined Wood-Anderson peak-to-peak amplitude: {0} "
"mm".format(wapp))
print("Determined Wood-Anderson peak-to-peak amplitude for station {0}: {1} "
"mm".format(st[0].stats.station, wapp))
# check for plot flag (for debugging only)
if self.plot_flag > 1:
@ -317,8 +314,8 @@ class MomentMagnitude(Magnitude):
continue
pick = a.pick_id.get_referred_object()
station = pick.waveform_id.station_code
wf = select_for_phase(self.stream.select(
station=station), a.phase)
scopy = self.stream.copy()
wf = scopy.select(station=station)
if not wf:
continue
onset = pick.time
@ -326,15 +323,16 @@ class MomentMagnitude(Magnitude):
azimuth = a.azimuth
incidence = a.takeoff_angle
w0, fc = calcsourcespec(wf, onset, self.p_velocity, distance,
azimuth,
incidence, self.p_attenuation,
azimuth, incidence, self.p_attenuation,
self.plot_flag, self.verbose)
if w0 is None or fc is None:
if self.verbose:
print("WARNING: insufficient frequency information")
continue
wf = select_for_phase(wf, "P")
m0, mw = calcMoMw(wf, w0, self.rock_density, self.p_velocity,
WF = select_for_phase(self.stream.select(
station=station), a.phase)
WF = select_for_phase(WF, "P")
m0, mw = calcMoMw(WF, w0, self.rock_density, self.p_velocity,
distance, self.verbose)
self.moment_props = (station, dict(w0=w0, fc=fc, Mo=m0))
magnitude = ope.StationMagnitude(mag=mw)
@ -426,7 +424,7 @@ def calcsourcespec(wfstream, onset, vp, delta, azimuth, incidence,
:type: integer
'''
if verbosity:
print ("Calculating source spectrum ....")
print ("Calculating source spectrum for station %s ...." % wfstream[0].stats.station)
# get Q value
Q, A = qp
@ -453,18 +451,21 @@ def calcsourcespec(wfstream, onset, vp, delta, azimuth, incidence,
LQT = wfstream.rotate('ZNE->LQT', azimuth, incidence)
ldat = LQT.select(component="L")
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
# rotation is possible!
if verbosity:
print("calcsourcespec: Azimuth information is missing, "
"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
# unrotated vertical component (for comparison)
inttrz = signal.detrend(integrate.cumtrapz(zdat[0].data, None, dt))
# rotated component Z => L
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
fit = synthsourcespec(F, w0in, Fcin)
[optspecfit, _] = curve_fit(synthsourcespec, F, YYcor, [w0in, Fcin])
w01 = optspecfit[0]
fc1 = optspecfit[1]
w0 = optspecfit[0]
fc = optspecfit[1]
#w01 = optspecfit[0]
#fc1 = optspecfit[1]
if verbosity:
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
[w02, fc2] = fitSourceModel(F, YYcor, Fcin, iplot, verbosity)
# [w02, fc2] = fitSourceModel(F, YYcor, Fcin, iplot, verbosity)
# get w0 and fc as median of both
# source spectrum fits
w0 = np.median([w01, w02])
fc = np.median([fc1, fc2])
if verbosity:
print("calcsourcespec: Using w0-value = %e m/Hz and fc = %f Hz" % (
w0, fc))
#w0 = np.median([w01, w02])
#fc = np.median([fc1, fc2])
#if verbosity:
# print("calcsourcespec: Using w0-value = %e m/Hz and fc = %f Hz" % (
# w0, fc))
if iplot > 1:
f1 = plt.figure()
@ -627,18 +630,35 @@ def fitSourceModel(f, S, fc0, iplot, verbosity=False):
fc = []
stdfc = []
STD = []
# get window around initial corner frequency for trials
fcstopl = fc0 - max(1, len(f) / 10)
il = np.argmin(abs(f - fcstopl))
fcstopl = f[il]
fcstopr = fc0 + min(len(f), len(f) / 10)
ir = np.argmin(abs(f - fcstopr))
fcstopr = f[ir]
iF = np.where((f >= fcstopl) & (f <= fcstopr))
# left side of initial corner frequency
fcstopl = max(f[0], fc0 - max(1, fc0 / 2))
il = np.where(f <= fcstopl)
il = il[0][np.size(il) - 1]
# right side of initial corner frequency
fcstopr = min(fc0 + (fc0 / 2), f[len(f) - 1])
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
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]
indexdc = np.where((f > 0) & (f <= FC))
dc = np.mean(S[indexdc])

View File

@ -6,13 +6,11 @@ import os
from obspy import read_events
from obspy.core import read, Stream, UTCDateTime
from obspy.core.event import Event
from pylot.core.io.phases import readPILOTEvent, picks_from_picksdict, \
picksdict_from_pilot, merge_picks
from pylot.core.util.errors import FormatError, OverwriteError
from pylot.core.util.utils import fnConstructor, full_range
class Data(object):
"""
Data container with attributes wfdata holding ~obspy.core.stream.
@ -298,10 +296,20 @@ class Data(object):
"""
#firstonset = find_firstonset(picks)
if self.get_evt_data().picks:
raise OverwriteError('Actual picks would be overwritten!')
else:
picks = picks_from_picksdict(picks)
# check for automatic picks
print("Writing phases to ObsPy-quakeml file")
for key in picks:
if picks[key]['P']['picker'] == 'auto':
print("Existing picks will be overwritten!")
picks = picks_from_picksdict(picks)
break
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
# if 'smi:local' in self.getID() and firstonset:
# 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.util.utils import getOwner, full_range, four_digits
def add_amplitudes(event, amplitudes):
amplitude_list = []
for pick in event.picks:
@ -233,6 +232,8 @@ def picks_from_picksdict(picks, creation_info=None):
if not isinstance(phase, dict):
continue
onset = phase['mpp']
ccode = phase['channel']
ncode = phase['network']
pick = ope.Pick()
if creation_info:
pick.creation_info = creation_info
@ -253,7 +254,9 @@ def picks_from_picksdict(picks, creation_info=None):
picker = 'Unknown'
pick.phase_hint = label
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:
polarity = phase['fm']
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')
def writephases(arrivals, fformat, filename):
def writephases(arrivals, fformat, filename, parameter, eventinfo=None):
"""
Function of methods to write phases to the following standard file
formats used for locating earthquakes:
@ -402,17 +405,25 @@ def writephases(arrivals, fformat, filename):
HYPOINVERSE, and hypoDD
: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':
print ("Writing phases to %s for NLLoc" % filename)
fid = open("%s" % filename, 'w')
# 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:
# P onsets
if arrivals[key]['P']:
if arrivals[key].has_key('P'):
try:
fm = arrivals[key]['P']['fm']
except KeyError as e:
@ -477,9 +488,13 @@ def writephases(arrivals, fformat, filename):
print ("Writing phases to %s for HYPO71" % filename)
fid = open("%s" % filename, 'w')
# write header
fid.write(' EQ001\n')
fid.write(' %s\n' %
parameter.get('eventID'))
for key in arrivals:
if arrivals[key]['P']['weight'] < 4:
stat = key
if len(stat) > 4: # HYPO71 handles only 4-string station IDs
stat = stat[1:5]
Ponset = arrivals[key]['P']['mpp']
Sonset = arrivals[key]['S']['mpp']
pweight = arrivals[key]['P']['weight']
@ -517,7 +532,7 @@ def writephases(arrivals, fformat, filename):
sstr = 'I'
elif sweight >= 2:
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,
fm,
pweight,
@ -532,7 +547,7 @@ def writephases(arrivals, fformat, filename):
sweight,
Ao))
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,
fm,
pweight,
@ -546,6 +561,258 @@ def writephases(arrivals, fformat, filename):
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):
"""

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):
pass
def export(picks, fnout):
def export(picks, fnout, parameter):
'''
Take <picks> dictionary and exports picking data to a NLLOC-obs
<phasefile> without creating an ObsPy event object.
@ -24,9 +24,12 @@ def export(picks, fnout):
:param fnout: complete path to the exporting obs file
:type fnout: str
:param: parameter, all input information
:type: object
'''
# write phases to NLLoc-phase file
writephases(picks, 'NLLoc', fnout)
writephases(picks, 'NLLoc', fnout, parameter)
def modify_inputs(ctrfn, root, nllocoutn, phasefn, tttn):
@ -67,14 +70,17 @@ def modify_inputs(ctrfn, root, nllocoutn, phasefn, tttn):
nllfile.close()
def locate(fnin):
def locate(fnin, infile=None):
"""
takes an external program name
:param fnin:
:return:
"""
exe_path = which('NLLoc')
if infile is None:
exe_path = which('NLLoc')
else:
exe_path = which('NLLoc', infile)
if exe_path is None:
raise NLLocError('NonLinLoc executable not found; check your '
'environment variables')

View File

@ -1,2 +1,27 @@
#!/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, 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
Pmarker = []
Ao = None # Wood-Anderson peak-to-peak amplitude
picker = 'autoPyLoT' # name of the picking programm
picker = 'auto' # type of picks
# split components
zdat = wfstream.select(component="Z")
@ -157,7 +157,7 @@ def autopickstation(wfstream, pickparam, verbose=False):
ndat = wfstream.select(component="1")
if algoP == 'HOS' or algoP == 'ARZ' and zdat is not None:
msg = '##########################################\nautopickstation:' \
msg = '##################################################\nautopickstation:' \
' Working on P onset of station {station}\nFiltering vertical ' \
'trace ...\n{data}'.format(station=zdat[0].stats.station,
data=str(zdat))
@ -552,7 +552,7 @@ def autopickstation(wfstream, pickparam, verbose=False):
print('autopickstation: S-weight: {0}, SNR: {1}, '
'SNR[dB]: {2}\n'
'################################################'
'##################################################'
''.format(Sweight, SNRS, SNRSdB))
################################################################
# 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' \
'(min. AIC-SNR={2}, ' \
'min. AIC-Slope={3}counts/s)\n' \
'################################################' \
'##################################################' \
''.format(aicarhpick.getSNR(),
aicarhpick.getSlope(),
minAICSSNR,
@ -778,11 +778,15 @@ def autopickstation(wfstream, pickparam, verbose=False):
# create dictionary
# 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,
Mw=None, picker=picker, marked=Pmarker)
# 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)
# merge picks into returning dictionary
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
'''
msg = '#######################################################\n' \
msg = '##################################################\n' \
'autoPyLoT: Found {0} bad onsets at station(s) {1}, ' \
'starting re-picking them ...'.format(len(badpicks), badpicks)
print(msg)
@ -823,7 +827,7 @@ def iteratepicker(wf, NLLocfile, picks, badpicks, pickparameter):
badpicks[i][1] = picks[badpicks[i][0]]['P']['mpp'] - float(res)
# get corresponding waveform stream
msg = '#######################################################\n' \
msg = '##################################################\n' \
'iteratepicker: Re-picking station {0}'.format(badpicks[i][0])
print(msg)
wf2pick = wf.select(station=badpicks[i][0])

View File

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

View File

@ -1,12 +1,11 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
#
# -*- coding: utf-8 -*-
"""
Created Mar/Apr 2015
Collection of helpful functions for manual and automatic picking.
:author: Ludger Kueperkoch / MAGS2 EP3 working group
:author: Ludger Kueperkoch, BESTEC GmbH
"""
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)
if invtype is None:
raise IOError("Neither dataless-SEED file, inventory-xml file nor "
"RESP-file found!")
print("Neither dataless-SEED file, inventory-xml file nor "
"RESP-file found!")
print("!!WRONG CALCULATION OF SOURCE PARAMETERS!!")
robj = None,
elif invtype == 'dless': # prevent multiple read of large dlsv
print("Reading metadata information from dataless-SEED file ...")
if len(inv[invtype]) == 1:
@ -250,13 +252,23 @@ def restitute_data(data, invtype, inobj, unit='VEL', force=False):
else:
finv = invlist[0]
inventory = read_inventory(finv, format='STATIONXML')
elif invtype == None:
print("No restitution possible, as there are no station-meta data available!")
break
else:
data.remove(tr)
continue
# apply restitution to data
print("Correcting instrument at station %s, channel %s" \
% (tr.stats.station, tr.stats.channel))
try:
if invtype in ['resp', 'dless']:
tr.simulate(**kwargs)
try:
tr.simulate(**kwargs)
except ValueError as e:
vmsg = '{0}'.format(e)
print(vmsg)
else:
tr.attach_response(inventory)
tr.remove_response(output=unit,

View File

@ -8,7 +8,9 @@ Created on Wed Feb 26 12:31:25 2014
import os
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
@ -43,10 +45,6 @@ FILTERDEFAULTS = readFilterInformation(os.path.join(os.path.expanduser('~'),
'.pylot',
'filter.in'))
AUTOMATIC_DEFAULTS = os.path.join(os.path.expanduser('~'),
'.pylot',
'autoPyLoT.in')
TIMEERROR_DEFAULTS = os.path.join(os.path.expanduser('~'),
'.pylot',
'PILOT_TimeErrors.in')
@ -55,7 +53,7 @@ OUTPUTFORMATS = {'.xml': 'QUAKEML',
'.cnv': 'CNV',
'.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['1'] = 1

View File

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

View File

@ -7,17 +7,18 @@ class AutoPickThread(QThread):
message = Signal(str)
finished = Signal()
def __init__(self, parent, func, data, param):
def __init__(self, parent, func, infile, fnames, savepath):
super(AutoPickThread, self).__init__()
self.setParent(parent)
self.func = func
self.data = data
self.param = param
self.infile = infile
self.fnames = fnames
self.savepath = savepath
def run(self):
sys.stdout = self
picks = self.func(self.data, self.param)
picks = self.func(self.infile, self.fnames, self.savepath)
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)
def which(program):
def which(program, infile=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
@ -490,7 +490,12 @@ def which(program):
for key in settings.allKeys():
if 'binPath' in 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):
nllocpath = ":" + AutoPickParameter(bpath).get('nllocbin')
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
"""
import os
import getpass
import warnings
import copy
import datetime
import numpy as np
from matplotlib.figure import Figure
from pylot.core.util.utils import find_horizontals
try:
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.QtWebKit import QWebView
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, \
getResolutionWindow
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,
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:
_axes.set_title(title)
if xlabel:
@ -235,23 +243,23 @@ class ComparisonDialog(QDialog):
x, y, std, exp = pdf.axis, pdf.data, pdf.standard_deviation(), \
pdf.expectation()
annotation = "{phase} difference on {station}\n" \
"expectation: {exp}\n" \
"std: {std}".format(station=station, phase=phase,
std=std, exp=exp)
annotation = "%s difference on %s\n" \
"expectation: %7.4f s\n" \
"std: %7.4f s" % (phase, station,
exp, std)
bbox_props = dict(boxstyle='round', facecolor='lightgrey', alpha=.7)
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_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.expectation(), \
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.expectation(), \
pdf_m.limits()
@ -259,21 +267,19 @@ class ComparisonDialog(QDialog):
lims = clims(alim, mlim)
# relative x axis
x0 = lims[0]
xmanu -= x0
xmanu -= x0
xauto -= x0
lims = [lim - x0 for lim in lims]
x0 = UTCDateTime(x0)
# set annotation text
mannotation = "probability density for manual pick\n" \
"expectation: {exp}\n" \
"std: {std}".format(std=stdmanu,
exp=expmanu-x0.timestamp)
mannotation = "probability density of manual pick\n" \
"expectation: %7.4f s\n" \
"std: %7.4f s" % (expmanu-x0.timestamp, stdmanu)
aannotation = "probability density for automatic pick\n" \
"expectation: {exp}\n" \
"std: {std}".format(std=stdauto,
exp=expauto-x0.timestamp)
aannotation = "probability density of automatic pick\n" \
"expectation: %7.4f s\n" \
"std: %7.4f s" % (expauto-x0.timestamp, stdauto)
_ax1 = plot_pdf(_ax1, xmanu, ymanu, mannotation,
bbox_props=bbox_props, xlabel='seconds since '
@ -504,15 +510,17 @@ class WaveformWidget(FigureCanvas):
class PickDlg(QDialog):
def __init__(self, parent=None, data=None, station=None, picks=None,
rotate=False):
rotate=False, infile=None):
super(PickDlg, self).__init__(parent)
# initialize attributes
self.infile = infile
self.station = station
self.rotate = rotate
self.components = 'ZNE'
settings = QSettings()
self._user = settings.value('user/Login', 'anonymous')
pylot_user = getpass.getuser()
self._user = settings.value('user/Login', pylot_user)
if picks:
self.picks = picks
else:
@ -704,6 +712,9 @@ class PickDlg(QDialog):
self.cidrelease = self.connectReleaseEvent(self.panRelease)
self.cidscroll = self.connectScrollEvent(self.scrollZoom)
def getinfile(self):
return self.infile
def getStartTime(self):
return self.stime
@ -806,6 +817,7 @@ class PickDlg(QDialog):
self.disconnectMotionEvent()
self.cidpress = self.connectPressEvent(self.setPick)
print(self.selectPhase.currentText())
if self.selectPhase.currentText().upper().startswith('P'):
self.setIniPickP(gui_event, wfdata, trace_number)
elif self.selectPhase.currentText().upper().startswith('S'):
@ -819,14 +831,14 @@ class PickDlg(QDialog):
def setIniPickP(self, gui_event, wfdata, trace_number):
parameter = AutoPickParameter(self.getinfile())
ini_pick = gui_event.xdata
settings = QSettings()
nfac = settings.value('picking/nfac_P', 1.3)
noise_win = settings.value('picking/noise_win_P', 5.)
gap_win = settings.value('picking/gap_win_P', .2)
signal_win = settings.value('picking/signal_win_P', 3.)
nfac = parameter.get('nfacP')
twins = parameter.get('tsnrz')
noise_win = twins[0]
gap_win = twins[1]
signal_win = twins[2]
itrace = int(trace_number)
while itrace > len(wfdata) - 1:
@ -868,14 +880,14 @@ class PickDlg(QDialog):
def setIniPickS(self, gui_event, wfdata):
parameter = AutoPickParameter(self.getinfile())
ini_pick = gui_event.xdata
settings = QSettings()
nfac = settings.value('picking/nfac_S', 1.5)
noise_win = settings.value('picking/noise_win_S', 5.)
gap_win = settings.value('picking/gap_win_S', .2)
signal_win = settings.value('picking/signal_win_S', 3.)
nfac = parameter.get('nfacS')
twins = parameter.get('tsnrh')
noise_win = twins[0]
gap_win = twins[1]
signal_win = twins[2]
# copy data for plotting
data = self.getWFData().copy()
@ -922,6 +934,8 @@ class PickDlg(QDialog):
def setPick(self, gui_event):
parameter = AutoPickParameter(self.getinfile())
# get axes limits
self.updateCurrentLimits()
@ -941,7 +955,14 @@ class PickDlg(QDialog):
wfdata.filter(**filteroptions)
# 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
stime = self.getStartTime()
@ -951,7 +972,8 @@ class PickDlg(QDialog):
# save pick times for actual phase
phasepicks = dict(epp=epp, lpp=lpp, mpp=mpp, spe=spe,
picker=self.getUser())
picker='manual', channel=channel,
network=wfdata[0].stats.network)
try:
oldphasepick = self.picks[phase]
@ -1171,13 +1193,15 @@ class PickDlg(QDialog):
class PropertiesDlg(QDialog):
def __init__(self, parent=None):
def __init__(self, parent=None, infile=None):
super(PropertiesDlg, self).__init__(parent)
self.infile = infile
appName = QApplication.applicationName()
self.setWindowTitle("{0} Properties".format(appName))
self.tabWidget = QTabWidget()
self.tabWidget.addTab(InputsTab(self), "Inputs")
self.tabWidget.addTab(OutputsTab(self), "Outputs")
@ -1186,7 +1210,8 @@ class PropertiesDlg(QDialog):
self.tabWidget.addTab(LocalisationTab(self), "Loc Tools")
self.buttonBox = QDialogButtonBox(QDialogButtonBox.Ok |
QDialogButtonBox.Apply |
QDialogButtonBox.Close)
QDialogButtonBox.Close |
QDialogButtonBox.RestoreDefaults)
layout = QVBoxLayout()
layout.addWidget(self.tabWidget)
@ -1195,8 +1220,11 @@ class PropertiesDlg(QDialog):
self.buttonBox.accepted.connect(self.accept)
self.buttonBox.rejected.connect(self.reject)
self.buttonBox.button(QDialogButtonBox.Apply).clicked.connect(
self.apply)
self.buttonBox.button(QDialogButtonBox.Apply).clicked.connect(self.apply)
self.buttonBox.button(QDialogButtonBox.RestoreDefaults).clicked.connect(self.restore)
def getinfile(self):
return self.infile
def accept(self, *args, **kwargs):
self.apply()
@ -1209,6 +1237,14 @@ class PropertiesDlg(QDialog):
if values is not None:
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
def setValues(tabValues):
settings = QSettings()
@ -1224,16 +1260,19 @@ class PropTab(QWidget):
def getValues(self):
return None
def resetValues(self, infile=None):
return None
class InputsTab(PropTab):
def __init__(self, parent):
def __init__(self, parent, infile=None):
super(InputsTab, self).__init__(parent)
settings = QSettings()
pylot_user = getpass.getuser()
fulluser = settings.value("user/FullName")
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
self.fullNameEdit = QLineEdit()
@ -1276,9 +1315,24 @@ class InputsTab(PropTab):
"data/Structure": self.structureSelect.currentText()}
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):
def __init__(self, parent=None):
def __init__(self, parent=None, infile=None):
super(OutputsTab, self).__init__(parent)
settings = QSettings()
@ -1302,6 +1356,9 @@ class OutputsTab(PropTab):
values = {"output/Format": self.eventOutputComboBox.currentText()}
return values
def resetValues(self, infile):
values = {"output/Format": self.eventOutputComboBox.setCurrentIndex(1)}
return values
class PhasesTab(PropTab):
def __init__(self, parent=None):
@ -1318,7 +1375,7 @@ class GraphicsTab(PropTab):
class LocalisationTab(PropTab):
def __init__(self, parent=None):
def __init__(self, parent=None, infile=None):
super(LocalisationTab, self).__init__(parent)
settings = QSettings()
@ -1388,6 +1445,13 @@ class LocalisationTab(PropTab):
"loc/tool": loctool}
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):
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