31 Commits
Author SHA1 Message Date
Darius Arnold cfe59cc264 Merge remote-tracking branch 'origin/develop' into darius 2017-09-07 17:03:18 +02:00
Darius Arnold 11fb9bfa52 Merge remote-tracking branch 'origin/develop' into darius 2017-09-07 13:00:47 +02:00
Darius Arnold f06d11ab07 Merge remote-tracking branch 'origin/develop' into darius 2017-08-31 22:49:44 +02:00
Darius Arnold 591743240c Merge branch 'develop' into darius 2017-08-31 10:57:23 +02:00
Darius Arnold f65b5efe41 [bugfix] for #240, tune autopicker not showing plots for some stations
this is probably just a workaround. Why was the program trying to access picks that were removed from the pick-dictionary?
2017-08-27 17:51:04 +02:00
Darius Arnold bb54f2843e [experimental] enable tight layout option on tune autopicker
Seems to work if autopicker is called from the GUI. No further testing done
2017-08-27 16:52:21 +02:00
Darius Arnold 8293d63d28 [change] show more stations in stationbox of tune autopicker dialog 2017-08-27 16:34:00 +02:00
Darius Arnold 85e1e45552 [change] wadaticheck and jackknife print excluded stations 2017-08-26 19:41:26 +02:00
Darius Arnold 66d091197a [minor] change axis label for comparison dialog 2017-08-26 19:30:46 +02:00
Darius Arnold 6de5ebfe52 [minor] only show a single point in legends of wadati-/jacknife-plot 2017-08-26 19:20:43 +02:00
Darius Arnold 2b7ff9fd3a [change] include safetygap in check for other maxima in front of first one
And some changes to improve readability/understandability
2017-08-26 19:19:55 +02:00
Darius Arnold 01dc489569 [bugfix] avoid indexing an empty array when there are no NaNs at start of CF 2017-08-26 17:26:35 +02:00
Darius Arnold efd2621db9 [add] jackknife safety factor no longer hardcoded, GUI parameter added 2017-08-26 17:22:28 +02:00
Darius Arnold fde3f251fb [bugfix] Earllate-Picker would use wrong timearray for plotting
signal-timearray gets doubled if not enough zero crossings are found to calculate valid signal period. Plotting would then use the old "single" timearray.
2017-08-26 12:14:44 +02:00
Darius Arnold 2db6fde709 [add] check second maximum of HOS/AR-CF
Use the second maximum if it is larger than first maximum * minfactor. This helps when two onsets are close together (eg. S and SKS at 90°) and the second onset is stronger.
2017-08-26 02:12:31 +02:00
Darius Arnold cd83c99034 [bugfix] wdfit2 referenced before set if wadaticheck had < 3 good picks 2017-08-26 01:55:16 +02:00
Darius Arnold c760ea394c [add] remove picks with weight > 3 from pickdictionary after autopicking 2017-08-26 01:53:38 +02:00
Darius Arnold 1afc6bdcf1 readd imports of check4rotated that got lost during merge 2017-08-26 01:49:18 +02:00
Darius Arnold 63293c6f93 gitignore file update 2017-08-26 01:43:21 +02:00
Darius Arnold 1dab754811 Merge branch 'develop' into darius 2017-08-26 01:42:18 +02:00
Darius Arnold 17da0b9ddb [bugfix] check4rotated unable to access metadata in TuneAutopicker 2017-08-26 01:10:17 +02:00
Darius Arnold 2a2c4d7a37 [change] replace NaN's in HOScf by first NaN value instead of zero 2017-08-24 15:42:12 +02:00
Darius Arnold 9dfb4f37a5 [change] calculate slope from two or more samples 2017-08-21 13:20:05 +02:00
Darius Arnold c454640619 [bugfix] handle to short zero crossings window 2017-08-21 13:19:22 +02:00
Darius Arnold 6223c4b5e1 [change] more readable indexing during slope determination 2017-08-21 13:18:31 +02:00
Darius Arnold 2e094fb0b5 [bugfix] catch empty index array during slope determination 2017-08-21 13:17:33 +02:00
Darius Arnold f6ae77d4d2 [add] tune autopicker displays picked onset time and error in seconds 2017-08-21 13:16:22 +02:00
Darius Arnold 08ce54e890 [add] enabled jackknife function fpr P onsets 2017-08-21 13:15:38 +02:00
Darius Arnold f2a6228e83 [bugfix] error in if check during load of eventliste.csv file 2017-08-21 13:14:10 +02:00
Darius Arnold 3e3b00b304 [add] function to rotate back traces if metadata is available 2017-08-21 13:13:03 +02:00
Darius Arnold f1b64bb314 [add] possible models displayed in taupy tooltip 2017-08-21 13:09:54 +02:00
60 changed files with 417107 additions and 15975 deletions
+4
View File
@@ -0,0 +1,4 @@
\.idea/
*.pyc
Regular → Executable
+115 -253
View File
@@ -39,7 +39,7 @@ from PySide.QtCore import QCoreApplication, QSettings, Signal, QFile, \
from PySide.QtGui import QMainWindow, QInputDialog, QIcon, QFileDialog, \
QWidget, QHBoxLayout, QVBoxLayout, QStyle, QKeySequence, QLabel, QFrame, QAction, \
QDialog, QErrorMessage, QApplication, QPixmap, QMessageBox, QSplashScreen, \
QActionGroup, QListWidget, QLineEdit, QListView, QAbstractItemView, \
QActionGroup, QListWidget, QDockWidget, QLineEdit, QListView, QAbstractItemView, \
QTreeView, QComboBox, QTabWidget, QPushButton, QGridLayout
import numpy as np
from obspy import UTCDateTime
@@ -49,7 +49,7 @@ from obspy.core.util import AttribDict
try:
import pyqtgraph as pg
except Exception as e:
print('PyLoT: Could not import pyqtgraph. {}'.format(e))
print('QtPyLoT: Could not import pyqtgraph. {}'.format(e))
pg = None
try:
@@ -64,18 +64,18 @@ from pylot.core.io.data import Data
from pylot.core.io.inputs import FilterOptions, PylotParameter
from autoPyLoT import autoPyLoT
from pylot.core.pick.compare import Comparison
from pylot.core.pick.utils import symmetrize_error, getQualityFromUncertainty
from pylot.core.pick.utils import symmetrize_error, getQualityFromUncertainty, removePicksAbove
from pylot.core.io.phases import picksdict_from_picks
import pylot.core.loc.nll as nll
from pylot.core.util.defaults import FILTERDEFAULTS, SetChannelComponents
from pylot.core.util.errors import DatastructureError, \
from pylot.core.util.errors import FormatError, DatastructureError, \
OverwriteError
from pylot.core.util.connection import checkurl
from pylot.core.util.dataprocessing import read_metadata, restitute_data
from pylot.core.util.utils import fnConstructor, getLogin, \
full_range, readFilterInformation, trim_station_components, check4gaps, make_pen, pick_color_plt, \
pick_linestyle_plt, remove_underscores, check4doubled, identifyPhaseID, excludeQualityClasses, has_spe, \
check4rotated, transform_colors_mpl, transform_colors_mpl_str
check4rotated
from pylot.core.util.event import Event
from pylot.core.io.location import create_creation_info, create_event
from pylot.core.util.widgets import FilterOptionsDialog, NewEventDlg, \
@@ -87,8 +87,6 @@ from pylot.core.util.structure import DATASTRUCTURE
from pylot.core.util.thread import Thread, Worker
from pylot.core.util.version import get_git_version as _getVersionString
from pylot.styles import style_settings
if sys.version_info.major == 3:
import icons_rc_3 as icons_rc
elif sys.version_info.major == 2:
@@ -112,7 +110,6 @@ class MainWindow(QMainWindow):
print('Using default input file {}'.format(infile))
if os.path.isfile(infile) == False:
infile = QFileDialog().getOpenFileName(caption='Choose PyLoT-input file')
if not os.path.exists(infile[0]):
QMessageBox.warning(self, "PyLoT Warning",
"No PyLoT-input file declared!")
@@ -127,7 +124,6 @@ class MainWindow(QMainWindow):
self.project = Project()
self.project.parameter = self._inputs
self.tap = None
self.apw = None
self.paraBox = None
self.array_map = None
self._metadata = None
@@ -144,6 +140,12 @@ class MainWindow(QMainWindow):
# default factor for dataplot e.g. enabling/disabling scrollarea
self.height_factor = 12
# default colors for ref/test event
self._colors = {
'ref': QtGui.QColor(200, 210, 230, 255),
'test': QtGui.QColor(200, 230, 200, 255)
}
# UI has to be set up before(!) children widgets are about to show up
self.createAction = createAction
# read settings
@@ -172,8 +174,6 @@ class MainWindow(QMainWindow):
self.fnames = None
self._stime = None
structure_setting = settings.value("data/Structure", "PILOT")
if not structure_setting:
structure_setting = 'PILOT'
self.dataStructure = DATASTRUCTURE[structure_setting]()
self.seismicPhase = str(settings.value("phase", "P"))
if settings.value("data/dataRoot", None) is None:
@@ -210,8 +210,6 @@ class MainWindow(QMainWindow):
except:
self.startTime = UTCDateTime()
self.init_styles()
pylot_icon = QIcon()
pylot_icon.addPixmap(QPixmap(':/icons/pylot.png'))
@@ -553,13 +551,6 @@ class MainWindow(QMainWindow):
self.addActions(toolbars["autoPyLoT"], pickActions)
self.addActions(toolbars["LocationTools"], locationToolActions)
# init pyqtgraph
self.pg = pg
# init style
settings = QSettings()
style = settings.value('style')
self.set_style(style)
# add event combo box and ref/test buttons
self.eventBox = self.createEventBox()
@@ -576,24 +567,21 @@ class MainWindow(QMainWindow):
self.eventBox.activated.connect(self.refreshEvents)
# add main tab widget
self.tabs = QTabWidget(self)
self.tabs = QTabWidget()
self._main_layout.addWidget(self.tabs)
self.tabs.currentChanged.connect(self.refreshTabs)
# add progressbar
self.mainProgressBarWidget = QtGui.QWidget()
self._main_layout.addWidget(self.mainProgressBarWidget)
# add scroll area used in case number of traces gets too high
self.wf_scroll_area = QtGui.QScrollArea(self)
self.wf_scroll_area = QtGui.QScrollArea()
# create central matplotlib figure canvas widget
self.pg = pg
self.init_wfWidget()
# init main widgets for main tabs
wf_tab = QtGui.QWidget(self)
array_tab = QtGui.QWidget(self)
events_tab = QtGui.QWidget(self)
wf_tab = QtGui.QWidget()
array_tab = QtGui.QWidget()
events_tab = QtGui.QWidget()
# init main widgets layouts
self.wf_layout = QtGui.QVBoxLayout()
@@ -636,8 +624,8 @@ class MainWindow(QMainWindow):
self.dataPlot = PylotCanvas(parent=self, connect_events=False, multicursor=True)
self.dataPlot.updateWidget(xlab, None, plottitle)
else:
self.pg = pg
self.dataPlot = WaveformWidgetPG(parent=self,
self.pg = True
self.dataPlot = WaveformWidgetPG(parent=self, xlabel=xlab, ylabel=None,
title=plottitle)
self.dataPlot.setCursor(Qt.CrossCursor)
self.wf_scroll_area.setWidget(self.dataPlot)
@@ -648,7 +636,7 @@ class MainWindow(QMainWindow):
'''
Initiate/create buttons for assigning events containing manual picks to reference or test set.
'''
self.ref_event_button = QtGui.QPushButton('Tune')
self.ref_event_button = QtGui.QPushButton('Ref')
self.test_event_button = QtGui.QPushButton('Test')
self.ref_event_button.setToolTip('Set manual picks of current ' +
'event as reference picks for autopicker tuning.')
@@ -656,8 +644,8 @@ class MainWindow(QMainWindow):
'event as test picks for autopicker testing.')
self.ref_event_button.setCheckable(True)
self.test_event_button.setCheckable(True)
self.set_button_border_color(self.ref_event_button, self._style['ref']['rgba'])
self.set_button_border_color(self.test_event_button, self._style['test']['rgba'])
self.set_button_color(self.ref_event_button, self._colors['ref'])
self.set_button_color(self.test_event_button, self._colors['test'])
self.ref_event_button.clicked.connect(self.toggleRef)
self.test_event_button.clicked.connect(self.toggleTest)
self.ref_event_button.setEnabled(False)
@@ -675,86 +663,6 @@ class MainWindow(QMainWindow):
if event.key() == QtCore.Qt.Key.Key_Shift:
self._shift = False
def init_styles(self):
self._styles = {}
styles = ['default', 'dark', 'bright']
stylecolors = style_settings.stylecolors
for style in styles:
if style in stylecolors.keys():
self._styles[style] = stylecolors[style]
self._phasecolors = style_settings.phasecolors
styles_dir = os.path.dirname(style_settings.__file__)
for style, stylecolors in self._styles.items():
stylesheet = stylecolors['stylesheet']['filename']
if stylesheet:
stylesheet_file = open(os.path.join(styles_dir, stylesheet), 'r')
stylesheet = stylesheet_file.read()
stylesheet_file.close()
else:
stylesheet = self.styleSheet()
bg_color = stylecolors['background']['rgba']
line_color = stylecolors['linecolor']['rgba']
multcursor_color = stylecolors['multicursor']['rgba']
# transform to 0-1 values for mpl and update dict
stylecolors['background']['rgba_mpl'] = transform_colors_mpl(bg_color)
stylecolors['linecolor']['rgba_mpl'] = transform_colors_mpl(line_color)
multcursor_color = stylecolors['multicursor']['rgba_mpl'] = transform_colors_mpl(multcursor_color)
stylecolors['stylesheet'] = stylesheet
def set_style(self, stylename=None):
if not stylename:
stylename = 'default'
if not stylename in self._styles:
qmb = QMessageBox.warning(self, 'Could not find style',
'Could not find style with name {}. Using default.'.format(stylename))
self.set_style('default')
return
style = self._styles[stylename]
self._style = style
self._stylename = stylename
self.setStyleSheet(style['stylesheet'])
# colors for ref/test event
self._ref_test_colors = {
'ref': QtGui.QColor(*style['ref']['rgba']),
'test': QtGui.QColor(*style['test']['rgba']),
}
# plot colors
bg_color = style['background']['rgba']
bg_color_mpl_na = transform_colors_mpl_str(bg_color, no_alpha=True)
line_color = style['linecolor']['rgba']
line_color_mpl_na = transform_colors_mpl_str(line_color, no_alpha=True)
for param in matplotlib.rcParams:
if 'color' in param and matplotlib.rcParams[param] in ['k', 'black']:
matplotlib.rcParams[param] = line_color_mpl_na
matplotlib.rc('axes',
edgecolor=line_color_mpl_na,
facecolor=bg_color_mpl_na,
labelcolor=line_color_mpl_na)
matplotlib.rc('xtick',
color=line_color_mpl_na)
matplotlib.rc('ytick',
color=line_color_mpl_na)
matplotlib.rc('figure',
facecolor=bg_color_mpl_na)
if self.pg:
pg.setConfigOption('background', bg_color)
pg.setConfigOption('foreground', line_color)
settings = QSettings()
settings.setValue('style', stylename)
settings.sync()
@property
def metadata(self):
return self._metadata
@@ -806,8 +714,12 @@ class MainWindow(QMainWindow):
settings = QSettings()
return settings.value("data/dataRoot")
def load_autopicks(self, fname=None):
self.load_data(fname, type='auto')
def load_loc(self, fname=None):
self.load_data(fname, loc=True)
type = getDataType(self)
self.load_data(fname, type=type, loc=True)
def load_pilotevent(self):
filt = "PILOT location files (*LOC*.mat)"
@@ -822,8 +734,10 @@ class MainWindow(QMainWindow):
filter=filt, dir=loc_dir)
fn_phases = fn_phases[0]
type = getDataType(self)
fname_dict = dict(phasfn=fn_phases, locfn=fn_loc)
self.load_data(fname_dict)
self.load_data(fname_dict, type=type)
def load_multiple_data(self):
if not self.okToContinue():
@@ -888,27 +802,20 @@ class MainWindow(QMainWindow):
def add_recentfile(self, event):
self.recentfiles.insert(0, event)
def set_button_border_color(self, button, color=None):
def set_button_color(self, button, color=None):
'''
Set background color of a button.
button: type = QtGui.QAbstractButton
color: type = QtGui.QColor or type = str (RGBA)
'''
if type(color) == QtGui.QColor:
button.setStyleSheet({'QPushButton{background-color:transparent}'})
palette = button.palette()
role = button.backgroundRole()
palette.setColor(role, color)
button.setPalette(palette)
button.setAutoFillBackground(True)
elif type(color) == str:
button.setStyleSheet('QPushButton{border-color: %s}'
'QPushButton:checked{background-color: rgba%s}'% (color, color))
elif type(color) == tuple:
button.setStyleSheet('QPushButton{border-color: rgba%s}'
'QPushButton:checked{background-color: rgba%s}' % (str(color), str(color)))
elif not color:
button.setStyleSheet(self.orig_parent._style['stylesheet'])
elif type(color) == str or not color:
button.setStyleSheet("background-color: {}".format(color))
def getWFFnames(self):
try:
@@ -964,7 +871,7 @@ class MainWindow(QMainWindow):
def get_current_event(self, eventbox=None):
'''
Return event (type PyLoT.Event) currently selected in eventbox.
Return event (type QtPylot.Event) currently selected in eventbox.
'''
if not eventbox:
eventbox = self.eventBox
@@ -973,7 +880,7 @@ class MainWindow(QMainWindow):
def get_current_event_path(self, eventbox=None):
'''
Return event path of event (type PyLoT.Event) currently selected in eventbox.
Return event path of event (type QtPylot.Event) currently selected in eventbox.
'''
event = self.get_current_event(eventbox)
if event:
@@ -981,7 +888,7 @@ class MainWindow(QMainWindow):
def get_current_event_name(self, eventbox=None):
'''
Return event path of event (type PyLoT.Event) currently selected in eventbox.
Return event path of event (type QtPylot.Event) currently selected in eventbox.
'''
path = self.get_current_event_path(eventbox)
if path:
@@ -1122,7 +1029,7 @@ class MainWindow(QMainWindow):
'''
# if pick widget is open, refresh tooltips as well
if self.apw:
if hasattr(self, 'apw'):
self.apw.refresh_tooltips()
if hasattr(self, 'cmpw'):
self.cmpw.refresh_tooltips()
@@ -1184,9 +1091,9 @@ class MainWindow(QMainWindow):
item_ref = QtGui.QStandardItem() # str(event_ref))
item_test = QtGui.QStandardItem() # str(event_test))
if event_ref:
item_ref.setBackground(self._ref_test_colors['ref'])
item_ref.setBackground(self._colors['ref'])
if event_test:
item_test.setBackground(self._ref_test_colors['test'])
item_test.setBackground(self._colors['test'])
item_notes = QtGui.QStandardItem(event.notes)
openIcon = self.style().standardIcon(QStyle.SP_DirOpenIcon)
@@ -1342,11 +1249,10 @@ class MainWindow(QMainWindow):
if len(eventdict) < 1:
return
# init event selection options for autopick
self.compareoptions =[('tune events', self.get_ref_events, self._style['ref']['rgba']),
('test events', self.get_test_events, self._style['test']['rgba']),
('all (picked) events', self.get_manu_picked_events, None)]
self.compareoptions =[('tune events', self.get_ref_events),
('test events', self.get_test_events),
('all (picked) events', self.get_manu_picked_events)]
self.cmpw = CompareEventsWidget(self, self.compareoptions, eventdict, comparisons)
self.cmpw.start.connect(self.compareMulti)
@@ -1354,9 +1260,7 @@ class MainWindow(QMainWindow):
self.cmpw.show()
def compareMulti(self):
if not self.compareoptions:
return
for key, func, color in self.compareoptions:
for key, func in self.compareoptions:
if self.cmpw.rb_dict[key].isChecked():
# if radio button is checked break for loop and use func
break
@@ -1370,10 +1274,7 @@ class MainWindow(QMainWindow):
def buildMultiCompareWidget(self, eventlist):
global_comparison = Comparison(eventlist=eventlist)
compare_widget = ComparisonWidget(global_comparison, self)
for events_name, rb in self.cmpw.rb_dict.items():
if rb.isChecked():
break
compare_widget.setWindowTitle('Histograms for {}'.format(events_name))
compare_widget.setWindowTitle('Histograms for all selected events')
compare_widget.hideToolbar()
compare_widget.setHistboxChecked(True)
return compare_widget
@@ -1531,8 +1432,7 @@ class MainWindow(QMainWindow):
'''
if load:
self.wfd_thread = Thread(self, self.loadWaveformData,
progressText='Reading data input...',
pb_widget=self.mainProgressBarWidget)
progressText='Reading data input...')
if load and plot:
self.wfd_thread.finished.connect(self.plotWaveformDataThread)
@@ -1562,7 +1462,7 @@ class MainWindow(QMainWindow):
check4gaps(wfdat)
check4doubled(wfdat)
# check for stations with rotated components
wfdat = check4rotated(wfdat, self.metadata, verbosity=0)
wfdat = check4rotated(wfdat, self.metadata)
# trim station components to same start value
trim_station_components(wfdat, trim_start=True, trim_end=False)
self._stime = full_range(self.get_data().getWFData())[0]
@@ -1622,8 +1522,7 @@ class MainWindow(QMainWindow):
self.getPlotWidget().updateWidget()
plots = self.wfp_thread.data
for times, data in plots:
self.dataPlot.plotWidget.getPlotItem().plot(times, data,
pen=self.dataPlot.pen_linecolor)
self.dataPlot.plotWidget.getPlotItem().plot(times, data, pen='k')
self.dataPlot.reinitMoveProxy()
self.dataPlot.plotWidget.showAxis('left')
self.dataPlot.plotWidget.showAxis('bottom')
@@ -1633,7 +1532,7 @@ class MainWindow(QMainWindow):
if self.pg:
self.finish_pg_plot()
else:
self._max_xlims = self.dataPlot.getXLims(self.dataPlot.axes[0])
self._max_xlims = self.dataPlot.getXLims()
plotWidget = self.getPlotWidget()
plotDict = plotWidget.getPlotDict()
pos = plotDict.keys()
@@ -1671,22 +1570,10 @@ class MainWindow(QMainWindow):
if event.pylot_picks and event.pylot_autopicks:
for station in event.pylot_picks:
if station in event.pylot_autopicks:
try:
autopick_p = event.pylot_autopicks[station]['P']['spe']
except KeyError:
autopick_p = None
try:
manupick_p = event.pylot_picks[station]['P']['spe']
except KeyError:
manupick_p = None
try:
autopick_s = event.pylot_autopicks[station]['S']['spe']
except KeyError:
autopick_s = None
try:
manupick_s = event.pylot_picks[station]['S']['spe']
except KeyError:
manupick_s = None
if autopick_p and manupick_p:
return True
elif autopick_s and manupick_s:
@@ -1707,7 +1594,7 @@ class MainWindow(QMainWindow):
self.dataPlot.plotWidget.hideAxis('bottom')
self.dataPlot.plotWidget.hideAxis('left')
else:
self.dataPlot.axes[0].cla()
self.dataPlot.getAxes().cla()
self.loadlocationaction.setEnabled(False)
self.auto_tune.setEnabled(False)
self.auto_pick.setEnabled(False)
@@ -1729,8 +1616,7 @@ class MainWindow(QMainWindow):
'''
self.clearWaveformDataPlot()
self.wfp_thread = Thread(self, self.plotWaveformData,
progressText='Plotting waveform data...',
pb_widget=self.mainProgressBarWidget)
progressText='Plotting waveform data...')
self.wfp_thread.finished.connect(self.finishWaveformDataPlot)
self.wfp_thread.start()
@@ -1866,27 +1752,27 @@ class MainWindow(QMainWindow):
self.checkFilterOptions()
# def updateFilterOptions(self):
# try:
# settings = QSettings()
# if settings.value("filterdefaults",
# None) is None and not self.getFilters():
# for key, value in FILTERDEFAULTS.items():
# self.setFilterOptions(FilterOptions(**value), key)
# elif settings.value("filterdefaults", None) is not None:
# for key, value in settings.value("filterdefaults"):
# self.setFilterOptions(FilterOptions(**value), key)
# except Exception as e:
# self.update_status('Error ...')
# emsg = QErrorMessage(self)
# emsg.showMessage('Error: {0}'.format(e))
# else:
# self.update_status('Filter loaded ... '
# '[{0}: {1} Hz]'.format(
# self.getFilterOptions().getFilterType(),
# self.getFilterOptions().getFreq()))
# if self.filterAction.isChecked():
# self.filterWaveformData()
def updateFilterOptions(self):
try:
settings = QSettings()
if settings.value("filterdefaults",
None) is None and not self.getFilters():
for key, value in FILTERDEFAULTS.items():
self.setFilterOptions(FilterOptions(**value), key)
elif settings.value("filterdefaults", None) is not None:
for key, value in settings.value("filterdefaults"):
self.setFilterOptions(FilterOptions(**value), key)
except Exception as e:
self.update_status('Error ...')
emsg = QErrorMessage(self)
emsg.showMessage('Error: {0}'.format(e))
else:
self.update_status('Filter loaded ... '
'[{0}: {1} Hz]'.format(
self.getFilterOptions().getFilterType(),
self.getFilterOptions().getFreq()))
if self.filterAction.isChecked():
self.filterWaveformData()
def getSeismicPhase(self):
return self.seismicPhase
@@ -2020,35 +1906,26 @@ class MainWindow(QMainWindow):
'el_S1pick',
'el_S2pick',
'refSpick',
'aicARHfig',
'plot_style'
'aicARHfig'
]
for key in self.fig_keys:
if key == 'plot_style':
fig = self._style
else:
fig = Figure()
self.fig_dict[key] = fig
def init_canvas_dict(self):
self.canvas_dict = {}
for key in self.fig_keys:
if not key == 'plot_style':
self.canvas_dict[key] = PylotCanvas(self.fig_dict[key], parent=self)
self.canvas_dict[key] = PylotCanvas(self.fig_dict[key])
def init_fig_dict_wadatijack(self, eventIDs):
self.fig_dict_wadatijack = {}
self.fig_keys_wadatijack = [
'jackknife',
'wadati',
'plot_style'
'wadati'
]
for eventID in eventIDs:
self.fig_dict_wadatijack[eventID] = {}
for key in self.fig_keys_wadatijack:
if key == 'plot_style':
fig = self._style
else:
fig = Figure()
self.fig_dict_wadatijack[eventID][key] = fig
@@ -2057,9 +1934,7 @@ class MainWindow(QMainWindow):
for eventID in self.fig_dict_wadatijack.keys():
self.canvas_dict_wadatijack[eventID] = {}
for key in self.fig_keys_wadatijack:
if not key == 'plot_style':
self.canvas_dict_wadatijack[eventID][key] = PylotCanvas(self.fig_dict_wadatijack[eventID][key],
parent=self)
self.canvas_dict_wadatijack[eventID][key] = PylotCanvas(self.fig_dict_wadatijack[eventID][key])
def tune_autopicker(self):
'''
@@ -2092,14 +1967,6 @@ class MainWindow(QMainWindow):
self.tap.fill_tabs(picked=True)
for canvas in self.canvas_dict.values():
canvas.setZoomBorders2content()
if self.tap.pylot_picks:
station = self.tap.get_current_station()
p_pick = self.tap.pylot_picks[station]['P']
s_pick = self.tap.pylot_picks[station]['S']
self.tap.pickDlg.autopicks['P_tuning'] = p_pick
self.tap.pickDlg.autopicks['S_tuning'] = s_pick
self.tap.pickDlg.drawPicks(phase='P_tuning', picktype='auto', picks=p_pick)
self.tap.pickDlg.drawPicks(phase='S_tuning', picktype='auto', picks=s_pick)
def autoPick(self):
autosave = self.get_current_event_path()
@@ -2108,13 +1975,12 @@ class MainWindow(QMainWindow):
"No autoPyLoT output declared!")
return
if not self.apw:
# init event selection options for autopick
self.pickoptions =[('current event', self.get_current_event, None),
('tune events', self.get_ref_events, self._style['ref']['rgba']),
('test events', self.get_test_events, self._style['test']['rgba']),
('all (picked) events', self.get_manu_picked_events, None),
('all events', self.get_all_events, None)]
self.pickoptions =[('current event', self.get_current_event),
('tune events', self.get_ref_events),
('test events', self.get_test_events),
('all (picked) events', self.get_manu_picked_events),
('all events', self.get_all_events)]
self.listWidget = QListWidget()
self.setDirty(True)
@@ -2126,9 +1992,7 @@ class MainWindow(QMainWindow):
self.apw.show()
def start_autopick(self):
if not self.pickoptions:
return
for key, func, _ in self.pickoptions:
for key, func in self.pickoptions:
if self.apw.rb_dict[key].isChecked():
# if radio button is checked break for loop and use func
break
@@ -2188,6 +2052,7 @@ class MainWindow(QMainWindow):
def finalizeAutoPick(self, result):
self.apw.enable(True)
if result:
result = removePicksAbove(result, 3)
self.init_canvas_dict_wadatijack()
for eventID in result.keys():
event = self.get_event_from_id(eventID)
@@ -2314,7 +2179,7 @@ class MainWindow(QMainWindow):
if self.pg:
pw = self.getPlotWidget().plotWidget
else:
ax = self.getPlotWidget().axes[0]
ax = self.getPlotWidget().axes
ylims = np.array([-.5, +.5]) + plotID
stat_picks = self.getPicks(type=picktype)[station]
@@ -2355,7 +2220,6 @@ class MainWindow(QMainWindow):
pen = make_pen(picktype, phaseID, 'lpp', quality)
pw.plot([lpp, lpp], ylims,
alpha=.25, pen=pen, name='LPP')
pen = make_pen(picktype, phaseID, 'mpp', quality)
if spe:
# pen = make_pen(picktype, phaseID, 'spe', quality)
# spe_l = pg.PlotDataItem([mpp - spe, mpp - spe], ylims, pen=pen,
@@ -2372,6 +2236,7 @@ class MainWindow(QMainWindow):
# fb = pw.addItem(fill)
# except:
# print('Warning: drawPicks: Could not create fill for symmetric pick error.')
pen = make_pen(picktype, phaseID, 'mpp', quality)
pw.plot([mpp, mpp], ylims, pen=pen, name='{}-Pick'.format(phase))
else:
pw.plot([mpp, mpp], ylims, pen=pen, name='{}-Pick (NO PICKERROR)'.format(phase))
@@ -2544,8 +2409,7 @@ class MainWindow(QMainWindow):
Start modal thread to init the array_map object.
'''
# Note: basemap generation freezes GUI but cannot be threaded as it generates a Pixmap.
self.amt = Thread(self, self.array_map.init_map, arg=None, progressText='Generating map...',
pb_widget=self.mainProgressBarWidget)
self.amt = Thread(self, self.array_map.init_map, arg=None, progressText='Generating map...')
self.amt.finished.connect(self.finish_array_map)
self.amt.start()
@@ -2572,7 +2436,7 @@ class MainWindow(QMainWindow):
lon = event.origins[0].longitude
self.array_map.eventLoc = (lat, lon)
if self.get_current_event():
self.array_map.refresh_drawings(self.get_current_event().getAutopicks())
self.array_map.refresh_drawings(self.get_current_event().getPicks())
self._eventChanged[1] = False
def init_event_table(self, tabindex=2):
@@ -2636,7 +2500,7 @@ class MainWindow(QMainWindow):
self.events_layout.removeWidget(self.event_table)
# init new qtable
self.event_table = QtGui.QTableWidget(self)
self.event_table = QtGui.QTableWidget()
self.event_table.setColumnCount(12)
self.event_table.setRowCount(len(eventlist))
self.event_table.setHorizontalHeaderLabels(['',
@@ -2690,8 +2554,8 @@ class MainWindow(QMainWindow):
item_notes = QtGui.QTableWidgetItem()
# manipulate items
item_ref.setBackground(self._ref_test_colors['ref'])
item_test.setBackground(self._ref_test_colors['test'])
item_ref.setBackground(self._colors['ref'])
item_test.setBackground(self._colors['test'])
item_path.setText(event.path)
if hasattr(event, 'origins'):
if event.origins:
@@ -2747,8 +2611,7 @@ class MainWindow(QMainWindow):
self.tabs.setCurrentIndex(tabindex)
def read_metadata_thread(self, fninv):
self.rm_thread = Thread(self, read_metadata, arg=fninv, progressText='Reading metadata...',
pb_widget=self.mainProgressBarWidget)
self.rm_thread = Thread(self, read_metadata, arg=fninv, progressText='Reading metadata...')
self.rm_thread.finished.connect(self.set_metadata)
self.rm_thread.start()
@@ -2766,7 +2629,7 @@ class MainWindow(QMainWindow):
def get_new_metadata(self):
self.init_metadata(new=True)
def init_metadata(self, new=False, ask_default=True):
def init_metadata(self, new=False):
def set_inv(settings):
fninv, _ = QFileDialog.getOpenFileName(self, self.tr(
"Select inventory..."), self.tr("Select file"))
@@ -2795,7 +2658,7 @@ class MainWindow(QMainWindow):
settings.setValue("inventoryFile", self.project.inv_path)
fninv = settings.value("inventoryFile", None)
if fninv and ask_default:
if fninv:
ans = QMessageBox.question(self, self.tr("Use default metadata..."),
self.tr(
"Do you want to use the default value for metadata?\n({})".format(fninv)),
@@ -2806,8 +2669,6 @@ class MainWindow(QMainWindow):
return None
elif ans == QMessageBox.Yes:
self.read_metadata_thread(fninv)
if fninv and not ask_default:
self.read_metadata_thread(fninv)
def calc_magnitude(self, type='ML'):
self.init_metadata()
@@ -2820,7 +2681,7 @@ class MainWindow(QMainWindow):
# raise ProcessingError('Restitution of waveform data failed!')
if type == 'ML':
local_mag = LocalMagnitude(corr_wf, self.get_data().get_evt_data(), self.inputs.get('sstop'),
verbosity=True) ## MP MP missing parameter wascaling in function call!
verbosity=True)
return local_mag.updated_event()
elif type == 'Mw':
moment_mag = MomentMagnitude(corr_wf, self.get_data().get_evt_data(), self.inputs.get('vp'),
@@ -2916,7 +2777,7 @@ class MainWindow(QMainWindow):
if not self.okToContinue():
return
if not fnm:
dlg = QFileDialog(parent=self)
dlg = QFileDialog()
fnm = dlg.getOpenFileName(self, 'Open project file...', filter='Pylot project (*.plp)')
if not fnm:
return
@@ -2931,12 +2792,10 @@ class MainWindow(QMainWindow):
self.setDirty(False)
if hasattr(self.project, 'metadata'):
if self.project.metadata:
self.init_metadata(ask_default=False)
#self.init_array_map(index=0)
self.init_array_map(index=0)
return
if hasattr(self.project, 'inv_path'):
self.init_metadata(ask_default=False)
#self.init_array_map(index=0)
self.init_array_map(index=0)
return
self.init_array_tab()
@@ -2945,7 +2804,7 @@ class MainWindow(QMainWindow):
'''
Save back project to new pickle file.
'''
dlg = QFileDialog(self)
dlg = QFileDialog()
fnm = dlg.getSaveFileName(self, 'Create a new project file...', filter='Pylot project (*.plp)')
filename = fnm[0]
if not len(fnm[0]):
@@ -3007,7 +2866,7 @@ class MainWindow(QMainWindow):
def setParameter(self, show=True):
if not self.paraBox:
self.paraBox = PylotParaBox(self._inputs, parent=self, windowflag=1)
self.paraBox = PylotParaBox(self._inputs)
self.paraBox.accepted.connect(self._setDirty)
self.paraBox.accepted.connect(self.filterOptionsFromParameter)
if show:
@@ -3025,16 +2884,16 @@ class MainWindow(QMainWindow):
def helpHelp(self):
if checkurl():
form = HelpForm(self,
form = HelpForm(
'https://ariadne.geophysik.ruhr-uni-bochum.de/trac/PyLoT/wiki')
else:
form = HelpForm(self, ':/help.html')
form = HelpForm(':/help.html')
form.show()
class Project(object):
'''
Pickable class containing information of a PyLoT project, like event lists and file locations.
Pickable class containing information of a QtPyLoT project, like event lists and file locations.
'''
def __init__(self):
@@ -3099,7 +2958,7 @@ class Project(object):
print(e, datetime, filename)
continue
for event in self.eventlist:
if eventID in str(event.resource_id) or event.origins:
if eventID in str(event.resource_id) or eventID in event.origins:
if event.origins:
origin = event.origins[0] # should have only one origin
if origin.time == datetime:
@@ -3219,10 +3078,9 @@ def create_window():
if app is None:
app = QApplication(sys.argv)
app_created = True
# set aplication/organization name, domain (important to do this BEFORE setupUI is called for correct QSettings)
app.setOrganizationName("Ruhr-University Bochum / BESTEC")
app.setOrganizationDomain("rub.de")
app.setApplicationName("PyLoT")
app.setOrganizationName("QtPyLoT");
app.setOrganizationDomain("rub.de");
app.setApplicationName("RUB");
app.references = set()
# app.references.add(window)
# window.show()
@@ -3231,7 +3089,6 @@ def create_window():
def main(args=None):
project_filename = None
#args.project_filename = 'C:/Shared/AlpArray/alparray_data/project_alparray_test.plp'
pylot_infile = None
if args:
if args.project_filename:
@@ -3251,15 +3108,20 @@ def main(args=None):
# create the main window
pylot_form = MainWindow(infile=pylot_infile)
pylot_form.setWindowIcon(app_icon)
icon = QIcon()
pylot_form.setWindowIcon(icon)
pylot_form.setIconSize(QSize(60, 60))
# set other App information
pylot_app.setApplicationVersion(pylot_form.__version__)
pylot_app.setWindowIcon(app_icon)
splash.showMessage('Loading. Please wait ...')
pylot_app.processEvents()
splash.showMessage('Loading. Please wait ...')
# set Application Information
pylot_app.setOrganizationName("Ruhr-University Bochum / BESTEC")
pylot_app.setOrganizationDomain("rub.de")
pylot_app.processEvents()
pylot_app.setApplicationName("PyLoT")
pylot_app.setApplicationVersion(pylot_form.__version__)
pylot_app.setWindowIcon(app_icon)
pylot_app.processEvents()
# Show main window and run the app
+21 -41
View File
@@ -1,6 +1,6 @@
# PyLoT
version: 0.2
version: 0.1a
The Python picking and Localisation Tool
@@ -14,7 +14,7 @@ to redevelop the software package in Python. The great work of the ObsPy
group allows easy handling of a bunch of seismic data and PyLoT will
benefit a lot compared to the former MatLab version.
The development of PyLoT is part of the joint research project MAGS2 and AlpArray.
The development of PyLoT is part of the joint research project MAGS2.
## Installation
@@ -25,7 +25,7 @@ Best way to install is to clone the repository and add the path to your Python p
In order to run PyLoT you need to install:
- python 2 or 3
- python
- scipy
- numpy
- matplotlib
@@ -34,24 +34,21 @@ In order to run PyLoT you need to install:
#### Some handwork:
PyLoT needs a properties folder on your system to work. It should be situated in your home directory
(on Windows usually C:/Users/*username*):
PyLoT needs a properties folder on your system to work. It should be situated in your home directory:
mkdir ~/.pylot
In the next step you have to copy some files to this directory:
*for local distance seismicity*
cp path-to-pylot/inputs/pylot.in ~/.pylot/
cp path-to-pylot/inputs/pylot_local.in ~/.pylot/pylot.in
for local distance seismicity
*for regional distance seismicity*
cp path-to-pylot/inputs/autoPyLoT_local.in ~/.pylot/autoPyLoT.in
cp path-to-pylot/inputs/pylot_regional.in ~/.pylot/pylot.in
for regional distance seismicity
*for global distance seismicity*
cp path-to-pylot/inputs/pylot_global.in ~/.pylot/pylot.in
cp path-to-pylot/inputs/autoPyLoT_regional.in ~/.pylot/autoPyLoT.in
and some extra information on error estimates (just needed for reading old PILOT data) and the Richter magnitude scaling relation
@@ -59,52 +56,35 @@ and some extra information on error estimates (just needed for reading old PILOT
You may need to do some modifications to these files. Especially folder names should be reviewed.
PyLoT has been tested on Mac OSX (10.11), Debian Linux 8 and on Windows 10.
PyLoT has been tested on Mac OSX (10.11) and Debian Linux 8.
## Release notes
#### Features:
- centralize all functionalities of PyLoT and control them from within the main GUI
- handling multiple events inside GUI with project files (save and load work progress)
- GUI based adjustments of pick parameters and I/O
- interactive tuning of parameters from within the GUI
- call automatic picking algorithm from within the GUI
- comparison of automatic with manual picks for multiple events using clear differentiation of manual picks into 'tune' and 'test-set' (beta)
- manual picking of different (user defined) phase types
- phase onset estimation with ObsPy TauPy
- interactive zoom/scale functionalities in all plots (mousewheel, pan, pan-zoom)
- array map to visualize stations and control onsets (beta feature, switch to manual picks not implemented)
- consistent manual phase picking through predefined SNR dependant zoom level
- uniform uncertainty estimation from waveform's properties for automatic and manual picks
- pdf representation and comparison of picks taking the uncertainty intrinsically into account
- Richter and moment magnitude estimation
- location determination with external installation of [NonLinLoc](http://alomax.free.fr/nlloc/index.html)
##### Platform support:
- Python 3 support
- Windows support
#### Known issues:
##### Performance:
- multiprocessing for automatic picking and restitution of multiple stations
- use pyqtgraph library for better performance on main waveform plot
- Magnitude estimation from manual PyLoT takes some time (instrument correction)
##### Visualization:
- pick uncertainty (quality classes) visualization with gradients
- pick color unification for all plots
- new icons and stylesheets
#### Known Issues:
- some Qt related errors might occur at runtime
- filter toggle not working in pickDlg
- PyLoT data structure requires at least three parent directories for waveform data directory
We hope to solve these with the next release.
## Staff
Original author(s): L. Kueperkoch, S. Wehling-Benatelli, M. Bischoff (PILOT)
Developer(s): S. Wehling-Benatelli, L. Kueperkoch, M. Paffrath, K. Olbert,
M. Bischoff, C. Wollin, M. Rische
Developer(s): S. Wehling-Benatelli, L. Kueperkoch, K. Olbert, M. Bischoff,
C. Wollin, M. Rische, M. Paffrath
Others: A. Bruestle, T. Meier, W. Friederich
[ObsPy]: http://github.com/obspy/obspy/wiki
September 2017
October 2016
+4 -4
View File
@@ -311,7 +311,7 @@ def autoPyLoT(input_dict=None, parameter=None, inputfile=None, fnames=None, even
# calculate seismic moment Mo and moment magnitude Mw
moment_mag = MomentMagnitude(corr_dat, evt, parameter.get('vp'),
parameter.get('Qp'),
parameter.get('rho'), True,
parameter.get('rho'), True, \
iplot)
# update pick with moment property values (w0, fc, Mo)
for stats, props in moment_mag.moment_props.items():
@@ -374,7 +374,7 @@ def autoPyLoT(input_dict=None, parameter=None, inputfile=None, fnames=None, even
for key in picks:
if picks[key]['P']['weight'] >= 4 or picks[key]['S']['weight'] >= 4:
badpicks.append([key, picks[key]['P']['mpp']])
print("autoPyLoT: After iteration No. %d: %d bad onsets found ..." % (nlloccounter,
print("autoPyLoT: After iteration No. %d: %d bad onsets found ..." % (nlloccounter, \
len(badpicks)))
if len(badpicks) == 0:
print("autoPyLoT: No more bad onsets found, stop iterative picking!")
@@ -384,7 +384,7 @@ def autoPyLoT(input_dict=None, parameter=None, inputfile=None, fnames=None, even
# calculate seismic moment Mo and moment magnitude Mw
moment_mag = MomentMagnitude(corr_dat, evt, parameter.get('vp'),
parameter.get('Qp'),
parameter.get('rho'), True,
parameter.get('rho'), True, \
iplot)
# update pick with moment property values (w0, fc, Mo)
for stats, props in moment_mag.moment_props.items():
@@ -502,4 +502,4 @@ if __name__ == "__main__":
picks = autoPyLoT(inputfile=str(cla.inputfile), fnames=str(cla.fnames),
eventid=str(cla.eventid), savepath=str(cla.spath),
ncores=cla.ncores, iplot=int(cla.iplot))
ncores=cla.ncores, iplot=str(cla.iplot))
+8
View File
@@ -0,0 +1,8 @@
git pull
Entferne qrc_resources.py
KONFLIKT (ändern/löschen): pylot/core/pick/getSNR.py gelöscht in HEAD und geändert in 67dd66535a213ba5c7cfe2be52aa6d5a7e8b7324. Stand 67dd66535a213ba5c7cfe2be52aa6d5a7e8b7324 von pylot/core/pick/getSNR.py wurde im Arbeitsbereich gelassen.
KONFLIKT (ändern/löschen): pylot/core/pick/fmpicker.py gelöscht in HEAD und geändert in 67dd66535a213ba5c7cfe2be52aa6d5a7e8b7324. Stand 67dd66535a213ba5c7cfe2be52aa6d5a7e8b7324 von pylot/core/pick/fmpicker.py wurde im Arbeitsbereich gelassen.
KONFLIKT (ändern/löschen): pylot/core/pick/earllatepicker.py gelöscht in HEAD und geändert in 67dd66535a213ba5c7cfe2be52aa6d5a7e8b7324. Stand 67dd66535a213ba5c7cfe2be52aa6d5a7e8b7324 von pylot/core/pick/earllatepicker.py wurde im Arbeitsbereich gelassen.
Automatisches Zusammenfügen von icons.qrc
Automatischer Merge fehlgeschlagen; beheben Sie die Konflikte und committen Sie dann das Ergebnis.
-2
View File
@@ -2,8 +2,6 @@
<qresource>
<file>icons/pylot.ico</file>
<file>icons/pylot.png</file>
<file>icons/back.png</file>
<file>icons/home.png</file>
<file>icons/newfile.png</file>
<file>icons/open.png</file>
<file>icons/openproject.png</file>
Binary file not shown.

Before

Width:  |  Height:  |  Size: 30 KiB

After

Width:  |  Height:  |  Size: 52 KiB

BIN
View File
Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

BIN
View File
Binary file not shown.

Before

Width:  |  Height:  |  Size: 23 KiB

BIN
View File
Binary file not shown.

Before

Width:  |  Height:  |  Size: 39 KiB

After

Width:  |  Height:  |  Size: 22 KiB

+4927 -7132
View File
File diff suppressed because it is too large Load Diff
+4927 -7132
View File
File diff suppressed because it is too large Load Diff
+100
View File
@@ -0,0 +1,100 @@
%This is a parameter input file for autoPyLoT.
%All main and special settings regarding data handling
%and picking are to be set here!
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
#main settings#
/DATA/Insheim #rootpath# %project path
EVENT_DATA/LOCAL #datapath# %data path
2013.02_Insheim #database# %name of data base
e0019.048.13 #eventID# %certain evnt ID for processing
True #apverbose#
PILOT #datastructure# %choose data structure
0 #iplot# %flag for plotting: 0 none, 1, partly, >1 everything
AUTOPHASES_AIC_HOS4_ARH #phasefile# %name of autoPILOT output phase file
AUTOLOC_AIC_HOS4_ARH #locfile# %name of autoPILOT output location file
AUTOFOCMEC_AIC_HOS4_ARH.in #focmecin# %name of focmec input file containing polarities
HYPOSAT #locrt# %location routine used ("HYPOINVERSE" or "HYPOSAT")
6 #pmin# %minimum required P picks for location
4 #p0min# %minimum required P picks for location if at least
%3 excellent P picks are found
2 #smin# %minimum required S picks for location
/home/ludger/bin/run_HYPOSAT4autoPILOT.csh #cshellp# %path and name of c-shell script to run location routine
7.6 8.5 #blon# %longitude bounding for location map
49 49.4 #blat# %lattitude bounding for location map
#parameters for moment magnitude estimation#
5000 #vp# %average P-wave velocity
2800 #vs# %average S-wave velocity
2200 #rho# %rock density [kg/m^3]
300 #Qp# %quality factor for P waves
100 #Qs# %quality factor for S waves
#common settings picker#
15 #pstart# %start time [s] for calculating CF for P-picking
40 #pstop# %end time [s] for calculating CF for P-picking
-1.0 #sstart# %start time [s] after or before(-) P-onset for calculating CF for S-picking
7 #sstop# %end time [s] after P-onset for calculating CF for S-picking
2 20 #bpz1# %lower/upper corner freq. of first band pass filter Z-comp. [Hz]
2 30 #bpz2# %lower/upper corner freq. of second band pass filter Z-comp. [Hz]
2 15 #bph1# %lower/upper corner freq. of first band pass filter H-comp. [Hz]
2 20 #bph2# %lower/upper corner freq. of second band pass filter z-comp. [Hz]
#special settings for calculating CF#
%!!Be careful when editing the following!!
#Z-component#
HOS #algoP# %choose algorithm for P-onset determination (HOS, ARZ, or AR3)
7 #tlta# %for HOS-/AR-AIC-picker, length of LTA window [s]
4 #hosorder# %for HOS-picker, order of Higher Order Statistics
2 #Parorder# %for AR-picker, order of AR process of Z-component
1.2 #tdet1z# %for AR-picker, length of AR determination window [s] for Z-component, 1st pick
0.4 #tpred1z# %for AR-picker, length of AR prediction window [s] for Z-component, 1st pick
0.6 #tdet2z# %for AR-picker, length of AR determination window [s] for Z-component, 2nd pick
0.2 #tpred2z# %for AR-picker, length of AR prediction window [s] for Z-component, 2nd pick
0.001 #addnoise# %add noise to seismogram for stable AR prediction
3 0.1 0.5 0.1 #tsnrz# %for HOS/AR, window lengths for SNR-and slope estimation [tnoise,tsafetey,tsignal,tslope] [s]
3 #pickwinP# %for initial AIC pick, length of P-pick window [s]
8 #Precalcwin# %for HOS/AR, window length [s] for recalculation of CF (relative to 1st pick)
0 #peps4aic# %for HOS/AR, artificial uplift of samples of AIC-function (P)
0.2 #aictsmooth# %for HOS/AR, take average of samples for smoothing of AIC-function [s]
0.1 #tsmoothP# %for HOS/AR, take average of samples for smoothing CF [s]
0.001 #ausP# %for HOS/AR, artificial uplift of samples (aus) of CF (P)
1.3 #nfacP# %for HOS/AR, noise factor for noise level determination (P)
#H-components#
ARH #algoS# %choose algorithm for S-onset determination (ARH or AR3)
0.8 #tdet1h# %for HOS/AR, length of AR-determination window [s], H-components, 1st pick
0.4 #tpred1h# %for HOS/AR, length of AR-prediction window [s], H-components, 1st pick
0.6 #tdet2h# %for HOS/AR, length of AR-determinaton window [s], H-components, 2nd pick
0.3 #tpred2h# %for HOS/AR, length of AR-prediction window [s], H-components, 2nd pick
4 #Sarorder# %for AR-picker, order of AR process of H-components
6 #Srecalcwin# %for AR-picker, window length [s] for recalculation of CF (2nd pick) (H)
3 #pickwinS# %for initial AIC pick, length of S-pick window [s]
2 0.2 1.5 0.5 #tsnrh# %for ARH/AR3, window lengths for SNR-and slope estimation [tnoise,tsafetey,tsignal,tslope] [s]
0.05 #aictsmoothS# %for AIC-picker, take average of samples for smoothing of AIC-function [s]
0.02 #tsmoothS# %for AR-picker, take average of samples for smoothing CF [s] (S)
0.2 #pepsS# %for AR-picker, artificial uplift of samples of CF (S)
0.4 #ausS# %for HOS/AR, artificial uplift of samples (aus) of CF (S)
1.5 #nfacS# %for AR-picker, noise factor for noise level determination (S)
%first-motion picker%
1 #minfmweight# %minimum required p weight for first-motion determination
2 #minFMSNR# %miniumum required SNR for first-motion determination
0.2 #fmpickwin# %pick window around P onset for calculating zero crossings
%quality assessment%
#inital AIC onset#
0.01 0.02 0.04 0.08 #timeerrorsP# %discrete time errors [s] corresponding to picking weights [0 1 2 3] for P
0.04 0.08 0.16 0.32 #timeerrorsS# %discrete time errors [s] corresponding to picking weights [0 1 2 3] for S
80 #minAICPslope# %below this slope [counts/s] the initial P pick is rejected
1.2 #minAICPSNR# %below this SNR the initial P pick is rejected
50 #minAICSslope# %below this slope [counts/s] the initial S pick is rejected
1.5 #minAICSSNR# %below this SNR the initial S pick is rejected
#check duration of signal using envelope function#
1.5 #prepickwin# %pre-signal window length [s] for noise level estimation
0.7 #minsiglength# %minimum required length of signal [s]
0.2 #sgap# %safety gap between noise and signal window [s]
2 #noisefactor# %noiselevel*noisefactor=threshold
60 #minpercent# %per cent of samples required higher than threshold
#check for spuriously picked S-onsets#
3.0 #zfac# %P-amplitude must exceed zfac times RMS-S amplitude
#jackknife-processing for P-picks#
3 #thresholdweight#%minimum required weight of picks
3 #dttolerance# %maximum allowed deviation of P picks from median [s]
4 #minstats# %minimum number of stations with reliable P picks
3 #Sdttolerance# %maximum allowed deviation from Wadati-diagram
+99
View File
@@ -0,0 +1,99 @@
%This is a parameter input file for autoPyLoT.
%All main and special settings regarding data handling
%and picking are to be set here!
%Parameters are optimized for local data sets!
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
#main settings#
/DATA/Insheim #rootpath# %project path
EVENT_DATA/LOCAL #datapath# %data path
2016.08_Insheim #database# %name of data base
e0007.224.16 #eventID# %event ID for single event processing
/DATA/Insheim/STAT_INFO #invdir# %full path to inventory or dataless-seed file
PILOT #datastructure#%choose data structure
0 #iplot# %flag for plotting: 0 none, 1 partly, >1 everything
True #apverbose# %choose 'True' or 'False' for terminal output
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
#NLLoc settings#
/home/ludger/NLLOC #nllocbin# %path to NLLoc executable
/home/ludger/NLLOC/Insheim #nllocroot# %root of NLLoc-processing directory
AUTOPHASES.obs #phasefile# %name of autoPyLoT-output phase file for NLLoc
%(in nllocroot/obs)
Insheim_min1d032016_auto.in #ctrfile# %name of autoPyLoT-output control file for NLLoc
%(in nllocroot/run)
ttime #ttpatter# %pattern of NLLoc ttimes from grid
%(in nllocroot/times)
AUTOLOC_nlloc #outpatter# %pattern of NLLoc-output file
%(returns 'eventID_outpatter')
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
#parameters for seismic moment estimation#
3530 #vp# %average P-wave velocity
2500 #rho# %average rock density [kg/m^3]
300 0.8 #Qp# %quality factor for P waves ([Qp, ap], Qp*f^a)
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
AUTOFOCMEC_AIC_HOS4_ARH.in #focmecin# %name of focmec input file containing derived polarities
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
#common settings picker#
15.0 #pstart# %start time [s] for calculating CF for P-picking
60.0 #pstop# %end time [s] for calculating CF for P-picking
-1.0 #sstart# %start time [s] relative to P-onset for calculating CF for S-picking
10.0 #sstop# %end time [s] after P-onset for calculating CF for S-picking
2 20 #bpz1# %lower/upper corner freq. of first band pass filter Z-comp. [Hz]
2 30 #bpz2# %lower/upper corner freq. of second band pass filter Z-comp. [Hz]
2 15 #bph1# %lower/upper corner freq. of first band pass filter H-comp. [Hz]
2 20 #bph2# %lower/upper corner freq. of second band pass filter z-comp. [Hz]
#special settings for calculating CF#
%!!Edit the following only if you know what you are doing!!%
#Z-component#
HOS #algoP# %choose algorithm for P-onset determination (HOS, ARZ, or AR3)
7.0 #tlta# %for HOS-/AR-AIC-picker, length of LTA window [s]
4 #hosorder# %for HOS-picker, order of Higher Order Statistics
2 #Parorder# %for AR-picker, order of AR process of Z-component
1.2 #tdet1z# %for AR-picker, length of AR determination window [s] for Z-component, 1st pick
0.4 #tpred1z# %for AR-picker, length of AR prediction window [s] for Z-component, 1st pick
0.6 #tdet2z# %for AR-picker, length of AR determination window [s] for Z-component, 2nd pick
0.2 #tpred2z# %for AR-picker, length of AR prediction window [s] for Z-component, 2nd pick
0.001 #addnoise# %add noise to seismogram for stable AR prediction
3 0.1 0.5 0.5 #tsnrz# %for HOS/AR, window lengths for SNR-and slope estimation [tnoise,tsafetey,tsignal,tslope] [s]
3.0 #pickwinP# %for initial AIC pick, length of P-pick window [s]
6.0 #Precalcwin# %for HOS/AR, window length [s] for recalculation of CF (relative to 1st pick)
0.2 #aictsmooth# %for HOS/AR, take average of samples for smoothing of AIC-function [s]
0.1 #tsmoothP# %for HOS/AR, take average of samples for smoothing CF [s]
0.001 #ausP# %for HOS/AR, artificial uplift of samples (aus) of CF (P)
1.3 #nfacP# %for HOS/AR, noise factor for noise level determination (P)
#H-components#
ARH #algoS# %choose algorithm for S-onset determination (ARH or AR3)
0.8 #tdet1h# %for HOS/AR, length of AR-determination window [s], H-components, 1st pick
0.4 #tpred1h# %for HOS/AR, length of AR-prediction window [s], H-components, 1st pick
0.6 #tdet2h# %for HOS/AR, length of AR-determinaton window [s], H-components, 2nd pick
0.3 #tpred2h# %for HOS/AR, length of AR-prediction window [s], H-components, 2nd pick
4 #Sarorder# %for AR-picker, order of AR process of H-components
5.0 #Srecalcwin# %for AR-picker, window length [s] for recalculation of CF (2nd pick) (H)
3.0 #pickwinS# %for initial AIC pick, length of S-pick window [s]
2 0.2 1.5 0.5 #tsnrh# %for ARH/AR3, window lengths for SNR-and slope estimation [tnoise,tsafetey,tsignal,tslope] [s]
0.5 #aictsmoothS# %for AIC-picker, take average of samples for smoothing of AIC-function [s]
0.7 #tsmoothS# %for AR-picker, take average of samples for smoothing CF [s] (S)
0.9 #ausS# %for HOS/AR, artificial uplift of samples (aus) of CF (S)
1.5 #nfacS# %for AR-picker, noise factor for noise level determination (S)
%first-motion picker%
1 #minfmweight# %minimum required P weight for first-motion determination
2 #minFMSNR# %miniumum required SNR for first-motion determination
0.2 #fmpickwin# %pick window around P onset for calculating zero crossings
%quality assessment%
#inital AIC onset#
0.05 0.10 0.20 0.40 #timeerrorsP# %discrete time errors [s] corresponding to picking weights [0 1 2 3] for P
0.10 0.20 0.40 0.80 #timeerrorsS# %discrete time errors [s] corresponding to picking weights [0 1 2 3] for S
4 #minAICPslope# %below this slope [counts/s] the initial P pick is rejected
1.2 #minAICPSNR# %below this SNR the initial P pick is rejected
2 #minAICSslope# %below this slope [counts/s] the initial S pick is rejected
1.5 #minAICSSNR# %below this SNR the initial S pick is rejected
#check duration of signal using envelope function#
3 #minsiglength# %minimum required length of signal [s]
1.0 #noisefactor# %noiselevel*noisefactor=threshold
40 #minpercent# %required percentage of samples higher than threshold
#check for spuriously picked S-onsets#
2.0 #zfac# %P-amplitude must exceed at least zfac times RMS-S amplitude
#check statistics of P onsets#
2.5 #mdttolerance# %maximum allowed deviation of P picks from median [s]
#wadati check#
1.0 #wdttolerance# %maximum allowed deviation from Wadati-diagram
+100
View File
@@ -0,0 +1,100 @@
%This is a parameter input file for autoPyLoT.
%All main and special settings regarding data handling
%and picking are to be set here!
%Parameters are optimized for regional data sets!
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
#main settings#
/DATA/Egelados #rootpath# %project path
EVENT_DATA/LOCAL #datapath# %data path
2006.01_Nisyros #database# %name of data base
e1412.008.06 #eventID# %event ID for single event processing
/DATA/Egelados/STAT_INFO #invdir# %full path to inventory or dataless-seed file
PILOT #datastructure# %choose data structure
0 #iplot# %flag for plotting: 0 none, 1, partly, >1 everything
True #apverbose# %choose 'True' or 'False' for terminal output
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
#NLLoc settings#
/home/ludger/NLLOC #nllocbin# %path to NLLoc executable
/home/ludger/NLLOC/Insheim #nllocroot# %root of NLLoc-processing directory
AUTOPHASES.obs #phasefile# %name of autoPyLoT-output phase file for NLLoc
%(in nllocroot/obs)
Insheim_min1d2015_auto.in #ctrfile# %name of autoPyLoT-output control file for NLLoc
%(in nllocroot/run)
ttime #ttpatter# %pattern of NLLoc ttimes from grid
%(in nllocroot/times)
AUTOLOC_nlloc #outpatter# %pattern of NLLoc-output file
%(returns 'eventID_outpatter')
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
#parameters for seismic moment estimation#
3530 #vp# %average P-wave velocity
2700 #rho# %average rock density [kg/m^3]
1000f**0.8 #Qp# %quality factor for P waves (Qp*f^a)
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
AUTOFOCMEC_AIC_HOS4_ARH.in #focmecin# %name of focmec input file containing derived polarities
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
#common settings picker#
20 #pstart# %start time [s] for calculating CF for P-picking
100 #pstop# %end time [s] for calculating CF for P-picking
1.0 #sstart# %start time [s] after or before(-) P-onset for calculating CF for S-picking
100 #sstop# %end time [s] after P-onset for calculating CF for S-picking
3 10 #bpz1# %lower/upper corner freq. of first band pass filter Z-comp. [Hz]
3 12 #bpz2# %lower/upper corner freq. of second band pass filter Z-comp. [Hz]
3 8 #bph1# %lower/upper corner freq. of first band pass filter H-comp. [Hz]
3 6 #bph2# %lower/upper corner freq. of second band pass filter H-comp. [Hz]
#special settings for calculating CF#
%!!Be careful when editing the following!!
#Z-component#
HOS #algoP# %choose algorithm for P-onset determination (HOS, ARZ, or AR3)
7 #tlta# %for HOS-/AR-AIC-picker, length of LTA window [s]
4 #hosorder# %for HOS-picker, order of Higher Order Statistics
2 #Parorder# %for AR-picker, order of AR process of Z-component
1.2 #tdet1z# %for AR-picker, length of AR determination window [s] for Z-component, 1st pick
0.4 #tpred1z# %for AR-picker, length of AR prediction window [s] for Z-component, 1st pick
0.6 #tdet2z# %for AR-picker, length of AR determination window [s] for Z-component, 2nd pick
0.2 #tpred2z# %for AR-picker, length of AR prediction window [s] for Z-component, 2nd pick
0.001 #addnoise# %add noise to seismogram for stable AR prediction
5 0.2 3.0 1.5 #tsnrz# %for HOS/AR, window lengths for SNR-and slope estimation [tnoise,tsafetey,tsignal,tslope] [s]
3 #pickwinP# %for initial AIC and refined pick, length of P-pick window [s]
8 #Precalcwin# %for HOS/AR, window length [s] for recalculation of CF (relative to 1st pick)
1.0 #aictsmooth# %for HOS/AR, take average of samples for smoothing of AIC-function [s]
0.3 #tsmoothP# %for HOS/AR, take average of samples for smoothing CF [s]
0.3 #ausP# %for HOS/AR, artificial uplift of samples (aus) of CF (P)
1.3 #nfacP# %for HOS/AR, noise factor for noise level determination (P)
#H-components#
ARH #algoS# %choose algorithm for S-onset determination (ARH or AR3)
0.8 #tdet1h# %for HOS/AR, length of AR-determination window [s], H-components, 1st pick
0.4 #tpred1h# %for HOS/AR, length of AR-prediction window [s], H-components, 1st pick
0.6 #tdet2h# %for HOS/AR, length of AR-determinaton window [s], H-components, 2nd pick
0.3 #tpred2h# %for HOS/AR, length of AR-prediction window [s], H-components, 2nd pick
4 #Sarorder# %for AR-picker, order of AR process of H-components
10 #Srecalcwin# %for AR-picker, window length [s] for recalculation of CF (2nd pick) (H)
25 #pickwinS# %for initial AIC and refined pick, length of S-pick window [s]
5 0.2 3.0 3.0 #tsnrh# %for ARH/AR3, window lengths for SNR-and slope estimation [tnoise,tsafetey,tsignal,tslope] [s]
3.5 #aictsmoothS# %for AIC-picker, take average of samples for smoothing of AIC-function [s]
1.0 #tsmoothS# %for AR-picker, take average of samples for smoothing CF [s] (S)
0.2 #ausS# %for HOS/AR, artificial uplift of samples (aus) of CF (S)
1.5 #nfacS# %for AR-picker, noise factor for noise level determination (S)
%first-motion picker%
1 #minfmweight# %minimum required p weight for first-motion determination
2 #minFMSNR# %miniumum required SNR for first-motion determination
6.0 #fmpickwin# %pick window around P onset for calculating zero crossings
%quality assessment%
#inital AIC onset#
0.04 0.08 0.16 0.32 #timeerrorsP# %discrete time errors [s] corresponding to picking weights [0 1 2 3] for P
0.04 0.08 0.16 0.32 #timeerrorsS# %discrete time errors [s] corresponding to picking weights [0 1 2 3] for S
3 #minAICPslope# %below this slope [counts/s] the initial P pick is rejected
1.2 #minAICPSNR# %below this SNR the initial P pick is rejected
5 #minAICSslope# %below this slope [counts/s] the initial S pick is rejected
2.5 #minAICSSNR# %below this SNR the initial S pick is rejected
#check duration of signal using envelope function#
30 #minsiglength# %minimum required length of signal [s]
2.5 #noisefactor# %noiselevel*noisefactor=threshold
60 #minpercent# %required percentage of samples higher than threshold
#check for spuriously picked S-onsets#
0.5 #zfac# %P-amplitude must exceed at least zfac times RMS-S amplitude
#check statistics of P onsets#
45 #mdttolerance# %maximum allowed deviation of P picks from median [s]
#wadati check#
3.0 #wdttolerance# %maximum allowed deviation from Wadati-diagram
+2
View File
@@ -0,0 +1,2 @@
P bandpass 4 2.0 20.0
S bandpass 4 2.0 15.0
+38 -40
View File
@@ -4,19 +4,19 @@
%Parameters are optimized for %extent data sets!
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
#main settings#
#rootpath# %project path
#datapath# %data path
#database# %name of data base
#eventID# %event ID for single event processing (* for all events found in database)
#invdir# %full path to inventory or dataless-seed file
/home/marcel/marcel_scratch #rootpath# %project path
alparray #datapath# %data path
waveforms #database# %name of data base
e0006.036.13 #eventID# %event ID for single event processing (* for all events found in database)
None #invdir# %full path to inventory or dataless-seed file
PILOT #datastructure# %choose data structure
True #apverbose# %choose 'True' or 'False' for terminal output
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
#NLLoc settings#
None #nllocbin# %path to NLLoc executable
None #nllocroot# %root of NLLoc-processing directory
None #phasefile# %name of autoPyLoT-output phase file for NLLoc
None #ctrfile# %name of autoPyLoT-output control file for NLLoc
/progs/bin #nllocbin# %path to NLLoc executable
/home/ludger/NLLOC/Insheim #nllocroot# %root of NLLoc-processing directory
AUTOPHASES.obs #phasefile# %name of autoPyLoT-output phase file for NLLoc
Insheim_min1d032016_auto.in #ctrfile# %name of autoPyLoT-output control file for NLLoc
ttime #ttpatter# %pattern of NLLoc ttimes from grid
AUTOLOC_nlloc #outpatter# %pattern of NLLoc-output file
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -37,64 +37,62 @@ bandpass bandpass #filter_type# %filter type
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
#common settings picker#
global #extent# %extent of array ("local", "regional" or "global")
-150.0 #pstart# %start time [s] for calculating CF for P-picking (if TauPy: seconds relative to estimated onset)
600.0 #pstop# %end time [s] for calculating CF for P-picking (if TauPy: seconds relative to estimated onset)
50.0 #pstart# %start time [s] for calculating CF for P-picking
600.0 #pstop# %end time [s] for calculating CF for P-picking
200.0 #sstart# %start time [s] relative to P-onset for calculating CF for S-picking
1150.0 #sstop# %end time [s] after P-onset for calculating CF for S-picking
True #use_taup# %use estimated traveltimes from TauPy for calculating windows for CF
iasp91 #taup_model# %define TauPy model for traveltime estimation. Possible values: 1066a, 1066b, ak135, ak135f, herrin, iasp91, jb, prem, pwdk, sp6
True #use_taup# %use estimated traveltimes from taupy for calculating windows for CF
0.05 0.5 #bpz1# %lower/upper corner freq. of first band pass filter Z-comp. [Hz]
0.001 0.5 #bpz2# %lower/upper corner freq. of second band pass filter Z-comp. [Hz]
0.01 0.5 #bpz2# %lower/upper corner freq. of second band pass filter Z-comp. [Hz]
0.05 0.5 #bph1# %lower/upper corner freq. of first band pass filter H-comp. [Hz]
0.001 0.5 #bph2# %lower/upper corner freq. of second band pass filter z-comp. [Hz]
0.01 0.5 #bph2# %lower/upper corner freq. of second band pass filter z-comp. [Hz]
#special settings for calculating CF#
%!!Edit the following only if you know what you are doing!!%
#Z-component#
HOS #algoP# %choose algorithm for P-onset determination (HOS, ARZ, or AR3)
150.0 #tlta# %for HOS-/AR-AIC-picker, length of LTA window [s]
15.0 #tlta# %for HOS-/AR-AIC-picker, length of LTA window [s]
4 #hosorder# %for HOS-picker, order of Higher Order Statistics
2 #Parorder# %for AR-picker, order of AR process of Z-component
16.0 #tdet1z# %for AR-picker, length of AR determination window [s] for Z-component, 1st pick
10.0 #tpred1z# %for AR-picker, length of AR prediction window [s] for Z-component, 1st pick
12.0 #tdet2z# %for AR-picker, length of AR determination window [s] for Z-component, 2nd pick
6.0 #tpred2z# %for AR-picker, length of AR prediction window [s] for Z-component, 2nd pick
6.0 #tdet1z# %for AR-picker, length of AR determination window [s] for Z-component, 1st pick
2.0 #tpred1z# %for AR-picker, length of AR prediction window [s] for Z-component, 1st pick
3.0 #tdet2z# %for AR-picker, length of AR determination window [s] for Z-component, 2nd pick
1.0 #tpred2z# %for AR-picker, length of AR prediction window [s] for Z-component, 2nd pick
0.001 #addnoise# %add noise to seismogram for stable AR prediction
60.0 10.0 40.0 10.0 #tsnrz# %for HOS/AR, window lengths for SNR-and slope estimation [tnoise, tsafetey, tsignal, tslope] [s]
150.0 #pickwinP# %for initial AIC pick, length of P-pick window [s]
35.0 #Precalcwin# %for HOS/AR, window length [s] for recalculation of CF (relative to 1st pick)
60.0 10.0 150.0 3.0 #tsnrz# %for HOS/AR, window lengths for SNR-and slope estimation [tnoise, tsafetey, tsignal, tslope] [s]
10.0 #pickwinP# %for initial AIC pick, length of P-pick window [s]
20.0 #Precalcwin# %for HOS/AR, window length [s] for recalculation of CF (relative to 1st pick)
6.0 #aictsmooth# %for HOS/AR, take average of samples for smoothing of AIC-function [s]
4.0 #tsmoothP# %for HOS/AR, take average of samples for smoothing CF [s]
0.001 #ausP# %for HOS/AR, artificial uplift of samples (aus) of CF (P)
1.1 #nfacP# %for HOS/AR, noise factor for noise level determination (P)
#H-components#
ARH #algoS# %choose algorithm for S-onset determination (ARH or AR3)
12.0 #tdet1h# %for HOS/AR, length of AR-determination window [s], H-components, 1st pick
6.0 #tpred1h# %for HOS/AR, length of AR-prediction window [s], H-components, 1st pick
8.0 #tdet2h# %for HOS/AR, length of AR-determinaton window [s], H-components, 2nd pick
4.0 #tpred2h# %for HOS/AR, length of AR-prediction window [s], H-components, 2nd pick
6.0 #tdet1h# %for HOS/AR, length of AR-determination window [s], H-components, 1st pick
4.0 #tpred1h# %for HOS/AR, length of AR-prediction window [s], H-components, 1st pick
6.0 #tdet2h# %for HOS/AR, length of AR-determinaton window [s], H-components, 2nd pick
3.0 #tpred2h# %for HOS/AR, length of AR-prediction window [s], H-components, 2nd pick
4 #Sarorder# %for AR-picker, order of AR process of H-components
30.0 #Srecalcwin# %for AR-picker, window length [s] for recalculation of CF (2nd pick) (H)
195.0 #pickwinS# %for initial AIC pick, length of S-pick window [s]
100.0 10.0 45.0 10.0 #tsnrh# %for ARH/AR3, window lengths for SNR-and slope estimation [tnoise, tsafetey, tsignal, tslope] [s]
22.0 #aictsmoothS# %for AIC-picker, take average of samples for smoothing of AIC-function [s]
10.0 #tsmoothS# %for AR-picker, take average of samples for smoothing CF [s] (S)
0.001 #ausS# %for HOS/AR, artificial uplift of samples (aus) of CF (S)
5.0 #Srecalcwin# %for AR-picker, window length [s] for recalculation of CF (2nd pick) (H)
15.0 #pickwinS# %for initial AIC pick, length of S-pick window [s]
100.0 10.0 40.0 6.0 #tsnrh# %for ARH/AR3, window lengths for SNR-and slope estimation [tnoise, tsafetey, tsignal, tslope] [s]
2.0 #aictsmoothS# %for AIC-picker, take average of samples for smoothing of AIC-function [s]
3.0 #tsmoothS# %for AR-picker, take average of samples for smoothing CF [s] (S)
0.9 #ausS# %for HOS/AR, artificial uplift of samples (aus) of CF (S)
1.2 #nfacS# %for AR-picker, noise factor for noise level determination (S)
#first-motion picker#
1 #minfmweight# %minimum required P weight for first-motion determination
3.0 #minFMSNR# %miniumum required SNR for first-motion determination
10.0 #fmpickwin# %pick window around P onset for calculating zero crossings
2.0 #minFMSNR# %miniumum required SNR for first-motion determination
0.2 #fmpickwin# %pick window around P onset for calculating zero crossings
#quality assessment#
1.0 2.0 4.0 8.0 #timeerrorsP# %discrete time errors [s] corresponding to picking weights [0 1 2 3] for P
4.0 8.0 16.0 32.0 #timeerrorsS# %discrete time errors [s] corresponding to picking weights [0 1 2 3] for S
0.5 #minAICPslope# %below this slope [counts/s] the initial P pick is rejected
1.1 #minAICPSNR# %below this SNR the initial P pick is rejected
1.0 #minAICSslope# %below this slope [counts/s] the initial S pick is rejected
1.3 #minAICSSNR# %below this SNR the initial S pick is rejected
1.5 #minAICSSNR# %below this SNR the initial S pick is rejected
5.0 #minsiglength# %length of signal part for which amplitudes must exceed noiselevel [s]
1.0 #noisefactor# %noiselevel*noisefactor=threshold
10.0 #minpercent# %required percentage of amplitudes exceeding threshold
1.2 #zfac# %P-amplitude must exceed at least zfac times RMS-S amplitude
25.0 #mdttolerance# %maximum allowed deviation of P picks from median [s]
50.0 #wdttolerance# %maximum allowed deviation from Wadati-diagram
5.0 #jackfactor# %pick is removed if the variance of the subgroup with the pick removed is larger than the mean variance of all subgroups times safety factor
1.5 #zfac# %P-amplitude must exceed at least zfac times RMS-S amplitude
6.0 #mdttolerance# %maximum allowed deviation of P picks from median [s]
1.0 #wdttolerance# %maximum allowed deviation from Wadati-diagram
-100
View File
@@ -1,100 +0,0 @@
%This is a parameter input file for PyLoT/autoPyLoT.
%All main and special settings regarding data handling
%and picking are to be set here!
%Parameters are optimized for %extent data sets!
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
#main settings#
#rootpath# %project path
#datapath# %data path
#database# %name of data base
#eventID# %event ID for single event processing (* for all events found in database)
#invdir# %full path to inventory or dataless-seed file
PILOT #datastructure# %choose data structure
True #apverbose# %choose 'True' or 'False' for terminal output
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
#NLLoc settings#
None #nllocbin# %path to NLLoc executable
None #nllocroot# %root of NLLoc-processing directory
None #phasefile# %name of autoPyLoT-output phase file for NLLoc
None #ctrfile# %name of autoPyLoT-output control file for NLLoc
ttime #ttpatter# %pattern of NLLoc ttimes from grid
AUTOLOC_nlloc #outpatter# %pattern of NLLoc-output file
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
#parameters for seismic moment estimation#
3530.0 #vp# %average P-wave velocity
2500.0 #rho# %average rock density [kg/m^3]
300.0 0.8 #Qp# %quality factor for P waves (Qp*f^a); list(Qp, a)
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
#settings local magnitude#
1.11 0.0009 -2.0 #WAscaling# %Scaling relation (log(Ao)+Alog(r)+Br+C) of Wood-Anderson amplitude Ao [nm] If zeros are set, original Richter magnitude is calculated!
1.0382 -0.447 #magscaling# %Scaling relation for derived local magnitude [a*Ml+b]. If zeros are set, no scaling of network magnitude is applied!
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
#filter settings#
1.0 1.0 #minfreq# %Lower filter frequency [P, S]
10.0 10.0 #maxfreq# %Upper filter frequency [P, S]
2 2 #filter_order# %filter order [P, S]
bandpass bandpass #filter_type# %filter type (bandpass, bandstop, lowpass, highpass) [P, S]
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
#common settings picker#
local #extent# %extent of array ("local", "regional" or "global")
15.0 #pstart# %start time [s] for calculating CF for P-picking
60.0 #pstop# %end time [s] for calculating CF for P-picking
-1.0 #sstart# %start time [s] relative to P-onset for calculating CF for S-picking
10.0 #sstop# %end time [s] after P-onset for calculating CF for S-picking
True #use_taup# %use estimated traveltimes from TauPy for calculating windows for CF
iasp91 #taup_model# %define TauPy model for traveltime estimation
2.0 10.0 #bpz1# %lower/upper corner freq. of first band pass filter Z-comp. [Hz]
2.0 12.0 #bpz2# %lower/upper corner freq. of second band pass filter Z-comp. [Hz]
2.0 8.0 #bph1# %lower/upper corner freq. of first band pass filter H-comp. [Hz]
2.0 10.0 #bph2# %lower/upper corner freq. of second band pass filter z-comp. [Hz]
#special settings for calculating CF#
%!!Edit the following only if you know what you are doing!!%
#Z-component#
HOS #algoP# %choose algorithm for P-onset determination (HOS, ARZ, or AR3)
7.0 #tlta# %for HOS-/AR-AIC-picker, length of LTA window [s]
4 #hosorder# %for HOS-picker, order of Higher Order Statistics
2 #Parorder# %for AR-picker, order of AR process of Z-component
1.2 #tdet1z# %for AR-picker, length of AR determination window [s] for Z-component, 1st pick
0.4 #tpred1z# %for AR-picker, length of AR prediction window [s] for Z-component, 1st pick
0.6 #tdet2z# %for AR-picker, length of AR determination window [s] for Z-component, 2nd pick
0.2 #tpred2z# %for AR-picker, length of AR prediction window [s] for Z-component, 2nd pick
0.001 #addnoise# %add noise to seismogram for stable AR prediction
3.0 0.1 0.5 1.0 #tsnrz# %for HOS/AR, window lengths for SNR-and slope estimation [tnoise, tsafetey, tsignal, tslope] [s]
3.0 #pickwinP# %for initial AIC pick, length of P-pick window [s]
6.0 #Precalcwin# %for HOS/AR, window length [s] for recalculation of CF (relative to 1st pick)
0.2 #aictsmooth# %for HOS/AR, take average of samples for smoothing of AIC-function [s]
0.1 #tsmoothP# %for HOS/AR, take average of samples for smoothing CF [s]
0.001 #ausP# %for HOS/AR, artificial uplift of samples (aus) of CF (P)
1.3 #nfacP# %for HOS/AR, noise factor for noise level determination (P)
#H-components#
ARH #algoS# %choose algorithm for S-onset determination (ARH or AR3)
0.8 #tdet1h# %for HOS/AR, length of AR-determination window [s], H-components, 1st pick
0.4 #tpred1h# %for HOS/AR, length of AR-prediction window [s], H-components, 1st pick
0.6 #tdet2h# %for HOS/AR, length of AR-determinaton window [s], H-components, 2nd pick
0.3 #tpred2h# %for HOS/AR, length of AR-prediction window [s], H-components, 2nd pick
4 #Sarorder# %for AR-picker, order of AR process of H-components
5.0 #Srecalcwin# %for AR-picker, window length [s] for recalculation of CF (2nd pick) (H)
4.0 #pickwinS# %for initial AIC pick, length of S-pick window [s]
2.0 0.3 1.5 1.0 #tsnrh# %for ARH/AR3, window lengths for SNR-and slope estimation [tnoise, tsafetey, tsignal, tslope] [s]
1.0 #aictsmoothS# %for AIC-picker, take average of samples for smoothing of AIC-function [s]
0.7 #tsmoothS# %for AR-picker, take average of samples for smoothing CF [s] (S)
0.9 #ausS# %for HOS/AR, artificial uplift of samples (aus) of CF (S)
1.5 #nfacS# %for AR-picker, noise factor for noise level determination (S)
#first-motion picker#
1 #minfmweight# %minimum required P weight for first-motion determination
2.0 #minFMSNR# %miniumum required SNR for first-motion determination
0.2 #fmpickwin# %pick window around P onset for calculating zero crossings
#quality assessment#
0.02 0.04 0.08 0.16 #timeerrorsP# %discrete time errors [s] corresponding to picking weights [0 1 2 3] for P
0.04 0.08 0.16 0.32 #timeerrorsS# %discrete time errors [s] corresponding to picking weights [0 1 2 3] for S
0.8 #minAICPslope# %below this slope [counts/s] the initial P pick is rejected
1.1 #minAICPSNR# %below this SNR the initial P pick is rejected
1.0 #minAICSslope# %below this slope [counts/s] the initial S pick is rejected
1.5 #minAICSSNR# %below this SNR the initial S pick is rejected
1.0 #minsiglength# %length of signal part for which amplitudes must exceed noiselevel [s]
1.0 #noisefactor# %noiselevel*noisefactor=threshold
10.0 #minpercent# %required percentage of amplitudes exceeding threshold
1.5 #zfac# %P-amplitude must exceed at least zfac times RMS-S amplitude
6.0 #mdttolerance# %maximum allowed deviation of P picks from median [s]
1.0 #wdttolerance# %maximum allowed deviation from Wadati-diagram
5.0 #jackfactor# %pick is removed if the variance of the subgroup with the pick removed is larger than the mean variance of all subgroups times safety factor
-100
View File
@@ -1,100 +0,0 @@
%This is a parameter input file for PyLoT/autoPyLoT.
%All main and special settings regarding data handling
%and picking are to be set here!
%Parameters are optimized for %extent data sets!
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
#main settings#
#rootpath# %project path
#datapath# %data path
#database# %name of data base
#eventID# %event ID for single event processing (* for all events found in database)
#invdir# %full path to inventory or dataless-seed file
PILOT #datastructure# %choose data structure
True #apverbose# %choose 'True' or 'False' for terminal output
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
#NLLoc settings#
None #nllocbin# %path to NLLoc executable
None #nllocroot# %root of NLLoc-processing directory
None #phasefile# %name of autoPyLoT-output phase file for NLLoc
None #ctrfile# %name of autoPyLoT-output control file for NLLoc
ttime #ttpatter# %pattern of NLLoc ttimes from grid
AUTOLOC_nlloc #outpatter# %pattern of NLLoc-output file
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
#parameters for seismic moment estimation#
3530.0 #vp# %average P-wave velocity
2500.0 #rho# %average rock density [kg/m^3]
300.0 0.8 #Qp# %quality factor for P waves (Qp*f^a); list(Qp, a)
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
#settings local magnitude#
1.11 0.0009 -2.0 #WAscaling# %Scaling relation (log(Ao)+Alog(r)+Br+C) of Wood-Anderson amplitude Ao [nm] If zeros are set, original Richter magnitude is calculated!
1.0382 -0.447 #magscaling# %Scaling relation for derived local magnitude [a*Ml+b]. If zeros are set, no scaling of network magnitude is applied!
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
#filter settings#
1.0 1.0 #minfreq# %Lower filter frequency [P, S]
10.0 10.0 #maxfreq# %Upper filter frequency [P, S]
2 2 #filter_order# %filter order [P, S]
bandpass bandpass #filter_type# %filter type (bandpass, bandstop, lowpass, highpass) [P, S]
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
#common settings picker#
local #extent# %extent of array ("local", "regional" or "global")
15.0 #pstart# %start time [s] for calculating CF for P-picking
60.0 #pstop# %end time [s] for calculating CF for P-picking
-1.0 #sstart# %start time [s] relative to P-onset for calculating CF for S-picking
10.0 #sstop# %end time [s] after P-onset for calculating CF for S-picking
True #use_taup# %use estimated traveltimes from TauPy for calculating windows for CF
iasp91 #taup_model# %define TauPy model for traveltime estimation
2.0 10.0 #bpz1# %lower/upper corner freq. of first band pass filter Z-comp. [Hz]
2.0 12.0 #bpz2# %lower/upper corner freq. of second band pass filter Z-comp. [Hz]
2.0 8.0 #bph1# %lower/upper corner freq. of first band pass filter H-comp. [Hz]
2.0 10.0 #bph2# %lower/upper corner freq. of second band pass filter z-comp. [Hz]
#special settings for calculating CF#
%!!Edit the following only if you know what you are doing!!%
#Z-component#
HOS #algoP# %choose algorithm for P-onset determination (HOS, ARZ, or AR3)
7.0 #tlta# %for HOS-/AR-AIC-picker, length of LTA window [s]
4 #hosorder# %for HOS-picker, order of Higher Order Statistics
2 #Parorder# %for AR-picker, order of AR process of Z-component
1.2 #tdet1z# %for AR-picker, length of AR determination window [s] for Z-component, 1st pick
0.4 #tpred1z# %for AR-picker, length of AR prediction window [s] for Z-component, 1st pick
0.6 #tdet2z# %for AR-picker, length of AR determination window [s] for Z-component, 2nd pick
0.2 #tpred2z# %for AR-picker, length of AR prediction window [s] for Z-component, 2nd pick
0.001 #addnoise# %add noise to seismogram for stable AR prediction
3.0 0.1 0.5 1.0 #tsnrz# %for HOS/AR, window lengths for SNR-and slope estimation [tnoise, tsafetey, tsignal, tslope] [s]
3.0 #pickwinP# %for initial AIC pick, length of P-pick window [s]
6.0 #Precalcwin# %for HOS/AR, window length [s] for recalculation of CF (relative to 1st pick)
0.2 #aictsmooth# %for HOS/AR, take average of samples for smoothing of AIC-function [s]
0.1 #tsmoothP# %for HOS/AR, take average of samples for smoothing CF [s]
0.001 #ausP# %for HOS/AR, artificial uplift of samples (aus) of CF (P)
1.3 #nfacP# %for HOS/AR, noise factor for noise level determination (P)
#H-components#
ARH #algoS# %choose algorithm for S-onset determination (ARH or AR3)
0.8 #tdet1h# %for HOS/AR, length of AR-determination window [s], H-components, 1st pick
0.4 #tpred1h# %for HOS/AR, length of AR-prediction window [s], H-components, 1st pick
0.6 #tdet2h# %for HOS/AR, length of AR-determinaton window [s], H-components, 2nd pick
0.3 #tpred2h# %for HOS/AR, length of AR-prediction window [s], H-components, 2nd pick
4 #Sarorder# %for AR-picker, order of AR process of H-components
5.0 #Srecalcwin# %for AR-picker, window length [s] for recalculation of CF (2nd pick) (H)
4.0 #pickwinS# %for initial AIC pick, length of S-pick window [s]
2.0 0.3 1.5 1.0 #tsnrh# %for ARH/AR3, window lengths for SNR-and slope estimation [tnoise, tsafetey, tsignal, tslope] [s]
1.0 #aictsmoothS# %for AIC-picker, take average of samples for smoothing of AIC-function [s]
0.7 #tsmoothS# %for AR-picker, take average of samples for smoothing CF [s] (S)
0.9 #ausS# %for HOS/AR, artificial uplift of samples (aus) of CF (S)
1.5 #nfacS# %for AR-picker, noise factor for noise level determination (S)
#first-motion picker#
1 #minfmweight# %minimum required P weight for first-motion determination
2.0 #minFMSNR# %miniumum required SNR for first-motion determination
0.2 #fmpickwin# %pick window around P onset for calculating zero crossings
#quality assessment#
0.02 0.04 0.08 0.16 #timeerrorsP# %discrete time errors [s] corresponding to picking weights [0 1 2 3] for P
0.04 0.08 0.16 0.32 #timeerrorsS# %discrete time errors [s] corresponding to picking weights [0 1 2 3] for S
0.8 #minAICPslope# %below this slope [counts/s] the initial P pick is rejected
1.1 #minAICPSNR# %below this SNR the initial P pick is rejected
1.0 #minAICSslope# %below this slope [counts/s] the initial S pick is rejected
1.5 #minAICSSNR# %below this SNR the initial S pick is rejected
1.0 #minsiglength# %length of signal part for which amplitudes must exceed noiselevel [s]
1.0 #noisefactor# %noiselevel*noisefactor=threshold
10.0 #minpercent# %required percentage of amplitudes exceeding threshold
1.5 #zfac# %P-amplitude must exceed at least zfac times RMS-S amplitude
6.0 #mdttolerance# %maximum allowed deviation of P picks from median [s]
1.0 #wdttolerance# %maximum allowed deviation from Wadati-diagram
5.0 #jackfactor# %pick is removed if the variance of the subgroup with the pick removed is larger than the mean variance of all subgroups times safety factor
+5 -11
View File
@@ -158,29 +158,23 @@ def buildPyLoT(verbosity=None):
def installPyLoT(verbosity=None):
files_to_copy = {'pylot_local.in': ['~', '.pylot'],
'pylot_regional.in': ['~', '.pylot'],
'pylot_global.in': ['~', '.pylot']}
files_to_copy = {'autoPyLoT_local.in': ['~', '.pylot'],
'autoPyLoT_regional.in': ['~', '.pylot']}
if verbosity > 0:
print('starting installation of PyLoT ...')
if verbosity > 1:
print('copying input files into destination folder ...')
ans = input('please specify scope of interest '
'([0]=local, 1=regional, 2=global) :') or 0
'([0]=local, 1=regional) :') or 0
if not isinstance(ans, int):
ans = int(ans)
if ans == 0:
ans = 'local'
elif ans == 1:
ans = 'regional'
elif ans == 2:
ans = 'global'
ans = 'local' if ans is 0 else 'regional'
link_dest = []
for file, destination in files_to_copy.items():
link_file = ans in file
if link_file:
link_dest = copy.deepcopy(destination)
link_dest.append('pylot.in')
link_dest.append('autoPyLoT.in')
link_dest = os.path.join(*link_dest)
destination.append(file)
destination = os.path.join(*destination)
BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

+3 -3
View File
@@ -617,9 +617,9 @@ def calcsourcespec(wfstream, onset, vp, delta, azimuth, incidence,
p3, = plt.loglog(F, YYcor, 'r')
p4, = plt.loglog(F, fit, 'g')
plt.loglog([fc, fc], [w0 / 100, w0], 'g')
plt.legend([p1, p2, p3, p4], ['Raw Spectrum',
'Used Raw Spectrum',
'Q-Corrected Spectrum',
plt.legend([p1, p2, p3, p4], ['Raw Spectrum', \
'Used Raw Spectrum', \
'Q-Corrected Spectrum', \
'Fit to Spectrum'])
plt.title('Source Spectrum from P Pulse, w0=%e m/Hz, fc=%6.2f Hz' \
% (w0, fc))
+240
View File
@@ -0,0 +1,240 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
Created August/September 2015.
:author: Ludger Küperkoch / MAGS2 EP3 working group
"""
import matplotlib.pyplot as plt
import numpy as np
from obspy.core import Stream
from pylot.core.pick.utils import getsignalwin
from scipy.optimize import curve_fit
class Magnitude(object):
'''
Superclass for calculating Wood-Anderson peak-to-peak
amplitudes, local magnitudes and moment magnitudes.
'''
def __init__(self, wfstream, To, pwin, iplot):
'''
:param: wfstream
:type: `~obspy.core.stream.Stream
:param: To, onset time, P- or S phase
:type: float
:param: pwin, pick window [To To+pwin] to get maximum
peak-to-peak amplitude (WApp) or to calculate
source spectrum (DCfc)
:type: float
:param: iplot, no. of figure window for plotting interims results
:type: integer
'''
assert isinstance(wfstream, Stream), "%s is not a stream object" % str(wfstream)
self.setwfstream(wfstream)
self.setTo(To)
self.setpwin(pwin)
self.setiplot(iplot)
self.calcwapp()
self.calcsourcespec()
def getwfstream(self):
return self.wfstream
def setwfstream(self, wfstream):
self.wfstream = wfstream
def getTo(self):
return self.To
def setTo(self, To):
self.To = To
def getpwin(self):
return self.pwin
def setpwin(self, pwin):
self.pwin = pwin
def getiplot(self):
return self.iplot
def setiplot(self, iplot):
self.iplot = iplot
def getwapp(self):
return self.wapp
def getw0(self):
return self.w0
def getfc(self):
return self.fc
def calcwapp(self):
self.wapp = None
def calcsourcespec(self):
self.sourcespek = None
class WApp(Magnitude):
'''
Method to derive peak-to-peak amplitude as seen on a Wood-Anderson-
seismograph. Has to be derived from instrument corrected traces!
'''
def calcwapp(self):
print("Getting Wood-Anderson peak-to-peak amplitude ...")
print("Simulating Wood-Anderson seismograph ...")
self.wapp = None
stream = self.getwfstream()
# poles, zeros and sensitivity of WA seismograph
# (see Uhrhammer & Collins, 1990, BSSA, pp. 702-716)
paz_wa = {
'poles': [5.6089 - 5.4978j, -5.6089 - 5.4978j],
'zeros': [0j, 0j],
'gain': 2080,
'sensitivity': 1}
stream.simulate(paz_remove=None, paz_simulate=paz_wa)
trH1 = stream[0].data
trH2 = stream[1].data
ilen = min([len(trH1), len(trH2)])
# get RMS of both horizontal components
sqH = np.sqrt(np.power(trH1[0:ilen], 2) + np.power(trH2[0:ilen], 2))
# get time array
th = np.arange(0, len(sqH) * stream[0].stats.delta, stream[0].stats.delta)
# get maximum peak within pick window
iwin = getsignalwin(th, self.getTo(), self.getpwin())
self.wapp = np.max(sqH[iwin])
print("Determined Wood-Anderson peak-to-peak amplitude: %f mm") % self.wapp
if self.getiplot() > 1:
stream.plot()
f = plt.figure(2)
plt.plot(th, sqH)
plt.plot(th[iwin], sqH[iwin], 'g')
plt.plot([self.getTo(), self.getTo()], [0, max(sqH)], 'r', linewidth=2)
plt.title('Station %s, RMS Horizontal Traces, WA-peak-to-peak=%4.1f mm' \
% (stream[0].stats.station, self.wapp))
plt.xlabel('Time [s]')
plt.ylabel('Displacement [mm]')
plt.show()
raw_input()
plt.close(f)
class DCfc(Magnitude):
'''
Method to calculate the source spectrum and to derive from that the plateau
(so-called DC-value) and the corner frequency assuming Aki's omega-square
source model. Has to be derived from instrument corrected displacement traces!
'''
def calcsourcespec(self):
print("Calculating source spectrum ....")
self.w0 = None # DC-value
self.fc = None # corner frequency
stream = self.getwfstream()
tr = stream[0]
# get time array
t = np.arange(0, len(tr) * tr.stats.delta, tr.stats.delta)
iwin = getsignalwin(t, self.getTo(), self.getpwin())
xdat = tr.data[iwin]
# fft
fny = tr.stats.sampling_rate / 2
l = len(xdat) / tr.stats.sampling_rate
n = tr.stats.sampling_rate * l # number of fft bins after Bath
# find next power of 2 of data length
m = pow(2, np.ceil(np.log(len(xdat)) / np.log(2)))
N = int(np.power(m, 2))
y = tr.stats.delta * np.fft.fft(xdat, N)
Y = abs(y[: N / 2])
L = (N - 1) / tr.stats.sampling_rate
f = np.arange(0, fny, 1 / L)
# remove zero-frequency and frequencies above
# corner frequency of seismometer (assumed
# to be 100 Hz)
fi = np.where((f >= 1) & (f < 100))
F = f[fi]
YY = Y[fi]
# get plateau (DC value) and corner frequency
# initial guess of plateau
DCin = np.mean(YY[0:100])
# initial guess of corner frequency
# where spectral level reached 50% of flat level
iin = np.where(YY >= 0.5 * DCin)
Fcin = F[iin[0][np.size(iin) - 1]]
fit = synthsourcespec(F, DCin, Fcin)
[optspecfit, pcov] = curve_fit(synthsourcespec, F, YY.real, [DCin, Fcin])
self.w0 = optspecfit[0]
self.fc = optspecfit[1]
print("DCfc: Determined DC-value: %e m/Hz, \n" \
"Determined corner frequency: %f Hz" % (self.w0, self.fc))
# if self.getiplot() > 1:
iplot = 2
if iplot > 1:
print("DCfc: Determined DC-value: %e m/Hz, \n"
"Determined corner frequency: %f Hz" % (self.w0, self.fc))
if self.getiplot() > 1:
f1 = plt.figure()
plt.subplot(2, 1, 1)
# show displacement in mm
plt.plot(t, np.multiply(tr, 1000), 'k')
plt.plot(t[iwin], np.multiply(xdat, 1000), 'g')
plt.title('Seismogram and P pulse, station %s' % tr.stats.station)
plt.xlabel('Time since %s' % tr.stats.starttime)
plt.ylabel('Displacement [mm]')
plt.subplot(2, 1, 2)
plt.loglog(f, Y.real, 'k')
plt.loglog(F, YY.real)
plt.loglog(F, fit, 'g')
plt.title('Source Spectrum from P Pulse, DC=%e m/Hz, fc=%4.1f Hz' \
% (self.w0, self.fc))
plt.xlabel('Frequency [Hz]')
plt.ylabel('Amplitude [m/Hz]')
plt.grid()
plt.show()
raw_input()
plt.close(f1)
def synthsourcespec(f, omega0, fcorner):
'''
Calculates synthetic source spectrum from given plateau and corner
frequency assuming Akis omega-square model.
:param: f, frequencies
:type: array
:param: omega0, DC-value (plateau) of source spectrum
:type: float
:param: fcorner, corner frequency of source spectrum
:type: float
'''
# ssp = omega0 / (pow(2, (1 + f / fcorner)))
ssp = omega0 / (1 + pow(2, (f / fcorner)))
return ssp
+2 -1
View File
@@ -240,7 +240,7 @@ class Data(object):
mstation = picks[i].waveform_id.station_code
mstation_ext = mstation + '_'
for k in range(len(picks_copy)):
if ((picks_copy[k].waveform_id.station_code == mstation) or
if ((picks_copy[k].waveform_id.station_code == mstation) or \
(picks_copy[k].waveform_id.station_code == mstation_ext)) and \
(picks_copy[k].method_id == 'auto'):
del picks_copy[k]
@@ -442,6 +442,7 @@ class Data(object):
else:
if self.get_evt_data().picks:
raise OverwriteError('Existing picks would be overwritten!')
break
else:
picks = picks_from_picksdict(picks)
break
+26 -2
View File
@@ -273,6 +273,26 @@ defaults = {'rootpath': {'type': str,
'value': 1.5,
'namestring': 'Noise factor S'},
'checkwindowP': {'type': float,
'tooltip': 'time window before HOS/AR-maximum to check for smaller maxima [s]',
'value': 10.0,
'namestring': 'Check Window P'},
'minfactorP': {'type': float,
'tooltip': 'Second maximum must be at least minfactor * first maximum [-]',
'value': 0.7,
'namestring': 'Minimum Factor P'},
'checkwindowS': {'type': float,
'tooltip': 'time window before AR-maximum to check for smaller maxima [s]',
'value': 10.0,
'namestring': 'Check Window S'},
'minfactorS': {'type': float,
'tooltip': 'Second maximum must be at least minfactor * first maximum [-]',
'value': 0.7,
'namestring': 'Minimum Factor S'},
'minfmweight': {'type': int,
'tooltip': 'minimum required P weight for first-motion determination',
'value': 1,
@@ -455,7 +475,9 @@ settings_special_pick = {
'aictsmooth',
'tsmoothP',
'ausP',
'nfacP'],
'nfacP',
'checkwindowP',
'minfactorP'],
'h': [
'algoS',
'tdet1h',
@@ -469,7 +491,9 @@ settings_special_pick = {
'aictsmoothS',
'tsmoothS',
'ausS',
'nfacS'],
'nfacS',
'checkwindowS',
'minfactorS'],
'fm': [
'minfmweight',
'minFMSNR',
+3 -3
View File
@@ -865,7 +865,7 @@ def merge_picks(event, picks):
if p.waveform_id.station_code == station\
and p.waveform_id.network_code == network\
and p.phase_hint == phase\
and (str(p.method_id) in str(method)
and (str(p.method_id) in str(method)\
or str(method) in str(p.method_id)):
p.time, p.time_errors, p.waveform_id.network_code, p.method_id = time, err, network, method
del time, err, phase, station, network, method
@@ -907,14 +907,14 @@ def getQualitiesfromxml(xmlnames, ErrorsP, ErrorsS, plotflag=1):
for mpick in arrivals_copy:
phase = identifyPhase(loopIdentifyPhase(Pick.phase_hint))
if phase == 'P':
if ((mpick.waveform_id.station_code == mstation) or
if ((mpick.waveform_id.station_code == mstation) or \
(mpick.waveform_id.station_code == mstation_ext)) and \
((mpick.method_id).split('/')[1] == 'auto') and \
(mpick.time_errors['uncertainty'] <= ErrorsP[3]):
del mpick
break
elif phase == 'S':
if ((mpick.waveform_id.station_code == mstation) or
if ((mpick.waveform_id.station_code == mstation) or \
(mpick.waveform_id.station_code == mstation_ext)) and \
((mpick.method_id).split('/')[1] == 'auto') and \
(mpick.time_errors['uncertainty'] <= ErrorsS[3]):
+29 -69
View File
@@ -38,7 +38,7 @@ def autopickevent(data, param, iplot=0, fig_dict=None, fig_dict_wadatijack=None,
# get some parameters for quality control from
# parameter input file (usually pylot.in).
# parameter input file (usually autoPyLoT.in).
wdttolerance = param.get('wdttolerance')
mdttolerance = param.get('mdttolerance')
jackfactor = param.get('jackfactor')
@@ -64,11 +64,8 @@ def autopickevent(data, param, iplot=0, fig_dict=None, fig_dict_wadatijack=None,
print('iPlot Flag active: NO MULTIPROCESSING possible.')
return all_onsets
# rename str for ncores in case ncores == 0 (use all cores)
ncores_str = ncores if ncores != 0 else 'all available'
print('Autopickstation: Distribute autopicking for {} '
'stations on {} cores.'.format(len(input_tuples), ncores_str))
'stations on {} cores.'.format(len(input_tuples), ncores))
pool = gen_Pool(ncores)
result = pool.map(call_autopickstation, input_tuples)
@@ -113,7 +110,7 @@ def autopickstation(wfstream, pickparam, verbose=False,
:type wfstream: obspy.core.stream.Stream
:param pickparam: container of picking parameters from input file,
usually pylot.in
usually autoPyLoT.in
:type pickparam: PylotParameter
:param verbose:
:type verbose: bool
@@ -121,7 +118,7 @@ def autopickstation(wfstream, pickparam, verbose=False,
"""
# declaring pickparam variables (only for convenience)
# read your pylot.in for details!
# read your autoPyLoT.in for details!
plt_flag = 0
# special parameters for P picking
@@ -180,6 +177,10 @@ def autopickstation(wfstream, pickparam, verbose=False,
# parameter to check for spuriously picked S onset
zfac = pickparam.get('zfac')
# path to inventory-, dataless- or resp-files
checkwindowP = pickparam.get('checkwindowP')
minfactorP = pickparam.get('minfactorP')
checkwindowS = pickparam.get('checkwindowS')
minfactorS = pickparam.get('minfactorS')
# initialize output
Pweight = 4 # weight for P onset
@@ -228,10 +229,8 @@ def autopickstation(wfstream, pickparam, verbose=False,
data=str(zdat))
if verbose: print(msg)
z_copy = zdat.copy()
tr_filt = zdat[0].copy()
#remove constant offset from data to avoid unwanted filter response
tr_filt.detrend(type='demean')
# filter and taper data
tr_filt = zdat[0].copy()
tr_filt.filter('bandpass', freqmin=bpz1[0], freqmax=bpz1[1],
zerophase=False)
tr_filt.taper(max_percentage=0.05, type='hann')
@@ -327,11 +326,10 @@ def autopickstation(wfstream, pickparam, verbose=False,
key = 'aicFig'
if fig_dict:
fig = fig_dict[key]
linecolor = fig_dict['plot_style']['linecolor']['rgba_mpl']
else:
fig = None
linecolor = 'k'
aicpick = AICPicker(aiccf, tsnrz, pickwinP, iplot, None, aictsmoothP, fig=fig, linecolor=linecolor)
aicpick = AICPicker(aiccf, tsnrz, pickwinP, checkwindow=checkwindowP, minfactor=minfactorP,
iplot=iplot, Tsmooth=tsmoothP, fig=fig)
# add pstart and pstop to aic plot
if fig:
for ax in fig.axes:
@@ -354,21 +352,16 @@ def autopickstation(wfstream, pickparam, verbose=False,
key = 'slength'
if fig_dict:
fig = fig_dict[key]
linecolor = fig_dict['plot_style']['linecolor']['rgba_mpl']
else:
fig = None
linecolor = 'k'
Pflag = checksignallength(zne, aicpick.getpick(), tsnrz,
minsiglength / 2,
nfacsl, minpercent, iplot,
fig, linecolor)
fig)
else:
# filter and taper horizontal traces
trH1_filt = edat.copy()
trH2_filt = ndat.copy()
# remove constant offset from data to avoid unwanted filter response
trH1_filt.detrend(type='demean')
trH2_filt.detrend(type='demean')
trH1_filt.filter('bandpass', freqmin=bph1[0],
freqmax=bph1[1],
zerophase=False)
@@ -381,14 +374,12 @@ def autopickstation(wfstream, pickparam, verbose=False,
zne += trH2_filt
if fig_dict:
fig = fig_dict['slength']
linecolor = fig_dict['plot_style']['linecolor']['rgba_mpl']
else:
fig = None
linecolor = 'k'
Pflag = checksignallength(zne, aicpick.getpick(), tsnrz,
minsiglength,
nfacsl, minpercent, iplot,
fig, linecolor)
fig)
if Pflag == 1:
# check for spuriously picked S onset
@@ -401,12 +392,10 @@ def autopickstation(wfstream, pickparam, verbose=False,
if iplot > 1:
if fig_dict:
fig = fig_dict['checkZ4s']
linecolor = fig_dict['plot_style']['linecolor']['rgba_mpl']
else:
fig = None
linecolor = 'k'
Pflag = checkZ4S(zne, aicpick.getpick(), zfac,
tsnrz[2], iplot, fig, linecolor)
tsnrz[2], iplot, fig)
if Pflag == 0:
Pmarker = 'SinsteadP'
Pweight = 9
@@ -429,7 +418,6 @@ def autopickstation(wfstream, pickparam, verbose=False,
# re-filter waveform with larger bandpass
z_copy = zdat.copy()
tr_filt = zdat[0].copy()
tr_filt.detrend(type='demean')
tr_filt.filter('bandpass', freqmin=bpz2[0], freqmax=bpz2[1],
zerophase=False)
tr_filt.taper(max_percentage=0.05, type='hann')
@@ -459,12 +447,10 @@ def autopickstation(wfstream, pickparam, verbose=False,
algoP=algoP)
if fig_dict:
fig = fig_dict['refPpick']
linecolor = fig_dict['plot_style']['linecolor']['rgba_mpl']
else:
fig = None
linecolor = 'k'
refPpick = PragPicker(cf2, tsnrz, pickwinP, iplot, ausP, tsmoothP,
aicpick.getpick(), fig, linecolor)
refPpick = PragPicker(cf2, tsnrz, pickwinP, iplot=iplot, aus=ausP, Tsmooth=tsmoothP,
Pick1 = aicpick.getpick(), fig=fig)
mpickP = refPpick.getpick()
#############################################################
if mpickP is not None:
@@ -473,13 +459,10 @@ def autopickstation(wfstream, pickparam, verbose=False,
if iplot:
if fig_dict:
fig = fig_dict['el_Ppick']
linecolor = fig_dict['plot_style']['linecolor']['rgba_mpl']
else:
fig = None
linecolor = 'k'
epickP, lpickP, Perror = earllatepicker(z_copy, nfacP, tsnrz,
mpickP, iplot, fig=fig,
linecolor=linecolor)
mpickP, iplot, fig=fig)
else:
epickP, lpickP, Perror = earllatepicker(z_copy, nfacP, tsnrz,
mpickP, iplot)
@@ -509,10 +492,9 @@ def autopickstation(wfstream, pickparam, verbose=False,
if iplot:
if fig_dict:
fig = fig_dict['fm_picker']
linecolor = fig_dict['plot_style']['linecolor']['rgba_mpl']
else:
fig = None
FM = fmpicker(zdat, z_copy, fmpickwin, mpickP, iplot, fig, linecolor)
FM = fmpicker(zdat, z_copy, fmpickwin, mpickP, iplot, fig)
else:
FM = fmpicker(zdat, z_copy, fmpickwin, mpickP, iplot)
else:
@@ -592,8 +574,6 @@ def autopickstation(wfstream, pickparam, verbose=False,
# filter and taper data
trH1_filt = hdat[0].copy()
trH2_filt = hdat[1].copy()
trH1_filt.detrend(type='demean')
trH2_filt.detrend(type='demean')
trH1_filt.filter('bandpass', freqmin=bph1[0], freqmax=bph1[1],
zerophase=False)
trH2_filt.filter('bandpass', freqmin=bph1[0], freqmax=bph1[1],
@@ -612,9 +592,6 @@ def autopickstation(wfstream, pickparam, verbose=False,
trH1_filt = hdat[0].copy()
trH2_filt = hdat[1].copy()
trH3_filt = hdat[2].copy()
trH1_filt.detrend(type='demean')
trH2_filt.detrend(type='demean')
trH3_filt.detrend(type='demean')
trH1_filt.filter('bandpass', freqmin=bph1[0], freqmax=bph1[1],
zerophase=False)
trH2_filt.filter('bandpass', freqmin=bph1[0], freqmax=bph1[1],
@@ -652,12 +629,11 @@ def autopickstation(wfstream, pickparam, verbose=False,
# of class AutoPicking
if fig_dict:
fig = fig_dict['aicARHfig']
linecolor = fig_dict['plot_style']['linecolor']['rgba_mpl']
else:
fig = None
linecolor = 'k'
aicarhpick = AICPicker(haiccf, tsnrh, pickwinS, iplot, None,
aictsmoothS, fig=fig, linecolor=linecolor)
aicarhpick = AICPicker(haiccf, tsnrh, pickwinS, checkwindow=checkwindowS,
minfactor=minfactorS, iplot=iplot, Tsmooth=aictsmoothS,
fig=fig)
###############################################################
# go on with processing if AIC onset passes quality control
slope = aicarhpick.getSlope()
@@ -682,8 +658,6 @@ def autopickstation(wfstream, pickparam, verbose=False,
if algoS == 'ARH':
trH1_filt = hdat[0].copy()
trH2_filt = hdat[1].copy()
trH1_filt.detrend(type='demean')
trH2_filt.detrend(type='demean')
trH1_filt.filter('bandpass', freqmin=bph2[0], freqmax=bph2[1],
zerophase=False)
trH2_filt.filter('bandpass', freqmin=bph2[0], freqmax=bph2[1],
@@ -699,9 +673,6 @@ def autopickstation(wfstream, pickparam, verbose=False,
trH1_filt = hdat[0].copy()
trH2_filt = hdat[1].copy()
trH3_filt = hdat[2].copy()
trH1_filt.detrend(type='demean')
trH2_filt.detrend(type='demean')
trH3_filt.detrend(type='demean')
trH1_filt.filter('bandpass', freqmin=bph2[0], freqmax=bph2[1],
zerophase=False)
trH2_filt.filter('bandpass', freqmin=bph2[0], freqmax=bph2[1],
@@ -721,12 +692,10 @@ def autopickstation(wfstream, pickparam, verbose=False,
# get refined onset time from CF2 using class Picker
if fig_dict:
fig = fig_dict['refSpick']
linecolor = fig_dict['plot_style']['linecolor']['rgba_mpl']
else:
fig = None
linecolor = 'k'
refSpick = PragPicker(arhcf2, tsnrh, pickwinS, iplot, ausS,
tsmoothS, aicarhpick.getpick(), fig, linecolor)
refSpick = PragPicker(arhcf2, tsnrh, pickwinS, iplot=iplot, aus=ausS,
Tsmooth=tsmoothS, Pick1=aicarhpick.getpick(), fig=fig)
mpickS = refSpick.getpick()
#############################################################
if mpickS is not None:
@@ -736,15 +705,12 @@ def autopickstation(wfstream, pickparam, verbose=False,
if iplot:
if fig_dict:
fig = fig_dict['el_S1pick']
linecolor = fig_dict['plot_style']['linecolor']['rgba_mpl']
else:
fig = None
linecolor = 'k'
epickS1, lpickS1, Serror1 = earllatepicker(h_copy, nfacS,
tsnrh,
mpickS, iplot,
fig=fig,
linecolor=linecolor)
fig=fig)
else:
epickS1, lpickS1, Serror1 = earllatepicker(h_copy, nfacS,
tsnrh,
@@ -754,15 +720,12 @@ def autopickstation(wfstream, pickparam, verbose=False,
if iplot:
if fig_dict:
fig = fig_dict['el_S2pick']
linecolor = fig_dict['plot_style']['linecolor']['rgba_mpl']
else:
fig = None
linecolor = ''
epickS2, lpickS2, Serror2 = earllatepicker(h_copy, nfacS,
tsnrh,
mpickS, iplot,
fig=fig,
linecolor=linecolor)
fig=fig)
else:
epickS2, lpickS2, Serror2 = earllatepicker(h_copy, nfacS,
tsnrh,
@@ -854,7 +817,7 @@ def autopickstation(wfstream, pickparam, verbose=False,
hdat += ndat
else:
print('autopickstation: No horizontal component data available or '
print('autopickstation: No horizontal component data available or ' \
'bad P onset, skipping S picking!')
##############################################################
@@ -871,11 +834,8 @@ def autopickstation(wfstream, pickparam, verbose=False,
if fig_dict == None or fig_dict == 'None':
fig = plt.figure()
plt_flag = 1
linecolor = 'k'
else:
fig = fig_dict['mainFig']
linecolor = fig_dict['plot_style']['linecolor']['rgba_mpl']
fig._tight = True
ax1 = fig.add_subplot(311)
tdata = np.arange(0, zdat[0].stats.npts / tr_filt.stats.sampling_rate,
tr_filt.stats.delta)
@@ -883,7 +843,7 @@ def autopickstation(wfstream, pickparam, verbose=False,
wfldiff = len(tr_filt.data) - len(tdata)
if wfldiff < 0:
tdata = tdata[0:len(tdata) - abs(wfldiff)]
ax1.plot(tdata, tr_filt.data / max(tr_filt.data), color=linecolor, linewidth=0.7, label='Data')
ax1.plot(tdata, tr_filt.data / max(tr_filt.data), 'k', label='Data')
if Pweight < 4:
ax1.plot(cf1.getTimeArray(), cf1.getCF() / max(cf1.getCF()),
'b', label='CF1')
@@ -942,7 +902,7 @@ def autopickstation(wfstream, pickparam, verbose=False,
wfldiff = len(trH1_filt.data) - len(th1data)
if wfldiff < 0:
th1data = th1data[0:len(th1data) - abs(wfldiff)]
ax2.plot(th1data, trH1_filt.data / max(trH1_filt.data), color=linecolor, linewidth=0.7, label='Data')
ax2.plot(th1data, trH1_filt.data / max(trH1_filt.data), 'k', label='Data')
if Pweight < 4:
ax2.plot(arhcf1.getTimeArray(),
arhcf1.getCF() / max(arhcf1.getCF()), 'b', label='CF1')
@@ -991,7 +951,7 @@ def autopickstation(wfstream, pickparam, verbose=False,
wfldiff = len(trH2_filt.data) - len(th2data)
if wfldiff < 0:
th2data = th2data[0:len(th2data) - abs(wfldiff)]
ax3.plot(th2data, trH2_filt.data / max(trH2_filt.data), color=linecolor, linewidth=0.7, label='Data')
ax3.plot(th2data, trH2_filt.data / max(trH2_filt.data), 'k', label='Data')
if Pweight < 4:
p22, = ax3.plot(arhcf1.getTimeArray(),
arhcf1.getCF() / max(arhcf1.getCF()), 'b', label='CF1')
+14 -7
View File
@@ -26,7 +26,7 @@ class CharacteristicFunction(object):
SuperClass for different types of characteristic functions.
'''
def __init__(self, data, cut, t2=None, order=None, t1=None, fnoise=None):
def __init__(self, data, cut, t2=None, order=None, t1=None, fnoise=None, stealthMode=False):
'''
Initialize data type object with information from the original
Seismogram.
@@ -63,6 +63,7 @@ class CharacteristicFunction(object):
self.calcCF(self.getDataArray())
self.arpara = np.array([])
self.xpred = np.array([])
self._stealthMode = stealthMode
def __str__(self):
return '''\n\t{name} object:\n
@@ -136,6 +137,9 @@ class CharacteristicFunction(object):
def getXCF(self):
return self.xcf
def _getStealthMode(self):
return self._stealthMode()
def getDataArray(self, cut=None):
'''
If cut times are given, time series is cut from cut[0] (start time)
@@ -220,11 +224,13 @@ class AICcf(CharacteristicFunction):
def calcCF(self, data):
# if self._getStealthMode() is False:
# print 'Calculating AIC ...'
x = self.getDataArray()
xnp = x[0].data
ind = np.where(~np.isnan(xnp))[0]
if ind.size:
xnp[:ind[0]] = xnp[ind[0]]
nn = np.isnan(xnp)
if len(nn) > 1:
xnp[nn] = 0
datlen = len(xnp)
k = np.arange(1, datlen)
cf = np.zeros(datlen)
@@ -258,9 +264,13 @@ class HOScf(CharacteristicFunction):
if len(nn) > 1:
xnp[nn] = 0
if self.getOrder() == 3: # this is skewness
# if self._getStealthMode() is False:
# print 'Calculating skewness ...'
y = np.power(xnp, 3)
y1 = np.power(xnp, 2)
elif self.getOrder() == 4: # this is kurtosis
# if self._getStealthMode() is False:
# print 'Calculating kurtosis ...'
y = np.power(xnp, 4)
y1 = np.power(xnp, 2)
@@ -335,7 +345,6 @@ class ARZcf(CharacteristicFunction):
cf = tap * cf
io = np.where(cf == 0)
ino = np.where(cf > 0)
if np.size(ino):
cf[io] = cf[ino[0][0]]
self.cf = cf
@@ -468,7 +477,6 @@ class ARHcf(CharacteristicFunction):
cf = tap * cf
io = np.where(cf == 0)
ino = np.where(cf > 0)
if np.size(ino):
cf[io] = cf[ino[0][0]]
self.cf = cf
@@ -611,7 +619,6 @@ class AR3Ccf(CharacteristicFunction):
cf = tap * cf
io = np.where(cf == 0)
ino = np.where(cf > 0)
if np.size(ino):
cf[io] = cf[ino[0][0]]
self.cf = cf
+2 -2
View File
@@ -118,8 +118,8 @@ class Comparison(object):
"""
compare_pdfs = dict()
pdf_a = self.get('auto').generate_pdf_data(type)
pdf_b = self.get('manu').generate_pdf_data(type)
pdf_a = self.get(self.names[0]).generate_pdf_data(type)
pdf_b = self.get(self.names[1]).generate_pdf_data(type)
for station, phases in pdf_a.items():
if station in pdf_b.keys():
+18 -19
View File
@@ -23,9 +23,8 @@ import warnings
import matplotlib.pyplot as plt
import numpy as np
from scipy.signal import argrelmax
from pylot.core.pick.charfuns import CharacteristicFunction
from pylot.core.pick.utils import getnoisewin, getsignalwin
from pylot.core.pick.utils import getnoisewin, getsignalwin, get_maximum_index
class AutoPicker(object):
@@ -36,7 +35,7 @@ class AutoPicker(object):
warnings.simplefilter('ignore')
def __init__(self, cf, TSNR, PickWindow, iplot=0, aus=None, Tsmooth=None, Pick1=None, fig=None, linecolor='k'):
def __init__(self, cf, TSNR, PickWindow, checkwindow=None, minfactor=None, iplot=0, aus=None, Tsmooth=None, Pick1=None, fig=None):
'''
:param: cf, characteristic function, on which the picking algorithm is applied
:type: `~pylot.core.pick.CharFuns.CharacteristicFunction` object
@@ -63,8 +62,7 @@ class AutoPicker(object):
'''
assert isinstance(cf, CharacteristicFunction), "%s is not a CharacteristicFunction object" % str(cf)
self._linecolor = linecolor
self._pickcolor_p = 'b'
self.cf = cf.getCF()
self.Tcf = cf.getTimeArray()
self.Data = cf.getXCF()
@@ -76,6 +74,8 @@ class AutoPicker(object):
self.setTsmooth(Tsmooth)
self.setpick1(Pick1)
self.fig = fig
self.setCheckWindow(checkwindow)
self.minfactor = minfactor
self.calcPick()
def __str__(self):
@@ -91,6 +91,10 @@ class AutoPicker(object):
aus=self.getaus(),
Tsmooth=self.getTsmooth(),
Pick1=self.getpick1())
def setCheckWindow(self, checkwindow):
'''convert checkwindow to samples'''
if checkwindow:
self.checkwindow = int(checkwindow / self.Data[0].stats.delta)
def getTSNR(self):
return self.TSNR
@@ -190,7 +194,8 @@ class AICPicker(AutoPicker):
aicsmooth = aicsmooth - offset
# get maximum of HOS/AR-CF as startimg point for searching
# minimum in AIC function
icfmax = np.argmax(self.Data[0].data)
icfmax = get_maximum_index(self.Data[0].data, self.checkwindow, self.minfactor,
int(self.TSNR[1]/self.Data[0].stats.delta))
# find minimum in AIC-CF front of maximum of HOS/AR-CF
lpickwindow = int(round(self.PickWindow / self.dt))
@@ -254,12 +259,8 @@ class AICPicker(AutoPicker):
if len(dataslope) < 1:
print('No data in slope window found!')
return
imaxs, = argrelmax(dataslope)
if imaxs.size:
imax = imaxs[0]
else:
imax = np.argmax(dataslope)
iislope = islope[0][0:imax + 1]
iislope = islope[0][0:imax+1]
if len(iislope) < 2:
# calculate slope from initial onset to maximum of AIC function
print("AICPicker: Not enough data samples left for slope calculation!")
@@ -270,13 +271,13 @@ class AICPicker(AutoPicker):
print("Choose longer slope determination window!")
if self.iplot > 1:
if self.fig == None or self.fig == 'None':
fig = plt.figure()
fig = plt.figure() # self.iplot) ### WHY? MP MP
plt_flag = 1
else:
fig = self.fig
ax = fig.add_subplot(111)
x = self.Data[0].data
ax.plot(self.Tcf, x / max(x), color=self._linecolor, linewidth=0.7, label='(HOS-/AR-) Data')
ax.plot(self.Tcf, x / max(x), 'k', label='(HOS-/AR-) Data')
ax.plot(self.Tcf, aicsmooth / max(aicsmooth), 'r', label='Smoothed AIC-CF')
ax.legend(loc=1)
ax.set_xlabel('Time [s] since %s' % self.Data[0].stats.starttime)
@@ -309,12 +310,11 @@ class AICPicker(AutoPicker):
plt_flag = 1
else:
fig = self.fig
fig._tight = True
ax1 = fig.add_subplot(211)
x = self.Data[0].data
if len(self.Tcf) > len(self.Data[0].data): # why? LK
self.Tcf = self.Tcf[0:len(self.Tcf)-1]
ax1.plot(self.Tcf, x / max(x), color=self._linecolor, linewidth=0.7, label='(HOS-/AR-) Data')
ax1.plot(self.Tcf, x / max(x), 'k', label='(HOS-/AR-) Data')
ax1.plot(self.Tcf, aicsmooth / max(aicsmooth), 'r', label='Smoothed AIC-CF')
if self.Pick is not None:
ax1.plot([self.Pick, self.Pick], [-0.1, 0.5], 'b', linewidth=2, label='AIC-Pick')
@@ -324,7 +324,7 @@ class AICPicker(AutoPicker):
if self.Pick is not None:
ax2 = fig.add_subplot(2, 1, 2, sharex=ax1)
ax2.plot(self.Tcf, x, color=self._linecolor, linewidth=0.7, label='Data')
ax2.plot(self.Tcf, x, 'k', label='Data')
ax1.axvspan(self.Tcf[inoise[0]], self.Tcf[inoise[-1]], color='y', alpha=0.2, lw=0, label='Noise Window')
ax1.axvspan(self.Tcf[isignal[0]], self.Tcf[isignal[-1]], color='b', alpha=0.2, lw=0,
label='Signal Window')
@@ -479,12 +479,11 @@ class PragPicker(AutoPicker):
plt_flag = 1
else:
fig = self.fig
fig._tight = True
ax = fig.add_subplot(111)
ax.plot(Tcfpick, cfipick, color=self._linecolor, linewidth=0.7, label='CF')
ax.plot(Tcfpick, cfipick, 'k', label='CF')
ax.plot(Tcfpick, cfsmoothipick, 'r', label='Smoothed CF')
if pickflag > 0:
ax.plot([self.Pick, self.Pick], [min(cfipick), max(cfipick)], self._pickcolor_p, linewidth=2, label='Pick')
ax.plot([self.Pick, self.Pick], [min(cfipick), max(cfipick)], 'b', linewidth=2, label='Pick')
ax.set_xlabel('Time [s] since %s' % self.Data[0].stats.starttime)
ax.set_yticks([])
ax.set_title(self.Data[0].stats.station)
+97 -74
View File
@@ -13,9 +13,10 @@ import warnings
import matplotlib.pyplot as plt
import numpy as np
from obspy.core import Stream, UTCDateTime
from scipy.signal import argrelextrema
def earllatepicker(X, nfac, TSNR, Pick1, iplot=0, verbosity=1, fig=None, linecolor='k'):
def earllatepicker(X, nfac, TSNR, Pick1, iplot=0, verbosity=1, fig=None):
'''
Function to derive earliest and latest possible pick after Diehl & Kissling (2009)
as reasonable uncertainties. Latest possible pick is based on noise level,
@@ -94,7 +95,7 @@ def earllatepicker(X, nfac, TSNR, Pick1, iplot=0, verbosity=1, fig=None, linecol
# get earliest possible pick
EPick = np.nan
EPick = np.nan;
count = 0
pis = isignal
@@ -130,18 +131,17 @@ def earllatepicker(X, nfac, TSNR, Pick1, iplot=0, verbosity=1, fig=None, linecol
if fig == None or fig == 'None':
fig = plt.figure() # iplot)
plt_flag = 1
fig._tight = True
ax = fig.add_subplot(111)
ax.plot(t, x, color=linecolor, linewidth=0.7, label='Data')
ax.plot(t, x, 'k', label='Data')
ax.axvspan(t[inoise[0]], t[inoise[-1]], color='y', alpha=0.2, lw=0, label='Noise Window')
ax.axvspan(t[isignal[0]], t[isignal[-1]], color='b', alpha=0.2, lw=0, label='Signal Window')
ax.plot([t[0], t[int(len(t)) - 1]], [nlevel, nlevel], color=linecolor, linewidth=0.7, linestyle='dashed', label='Noise Level')
ax.plot([t[0], t[int(len(t)) - 1]], [nlevel, nlevel], '--k', label='Noise Level')
ax.plot(t[pis[zc]], np.zeros(len(zc)), '*g',
markersize=14, label='Zero Crossings')
ax.plot([t[0], t[int(len(t)) - 1]], [-nlevel, -nlevel], color=linecolor, linewidth=0.7, linestyle='dashed')
ax.plot([t[0], t[int(len(t)) - 1]], [-nlevel, -nlevel], '--k')
ax.plot([Pick1, Pick1], [max(x), -max(x)], 'b', linewidth=2, label='mpp')
ax.plot([LPick, LPick], [max(x) / 2, -max(x) / 2], color=linecolor, linewidth=0.7, linestyle='dashed', label='lpp')
ax.plot([EPick, EPick], [max(x) / 2, -max(x) / 2], color=linecolor, linewidth=0.7, linestyle='dashed', label='epp')
ax.plot([LPick, LPick], [max(x) / 2, -max(x) / 2], '--k', label='lpp')
ax.plot([EPick, EPick], [max(x) / 2, -max(x) / 2], '--k', label='epp')
ax.plot([Pick1 + PickError, Pick1 + PickError],
[max(x) / 2, -max(x) / 2], 'r--', label='spe')
ax.plot([Pick1 - PickError, Pick1 - PickError],
@@ -161,7 +161,7 @@ def earllatepicker(X, nfac, TSNR, Pick1, iplot=0, verbosity=1, fig=None, linecol
return EPick, LPick, PickError
def fmpicker(Xraw, Xfilt, pickwin, Pick, iplot=0, fig=None, linecolor='k'):
def fmpicker(Xraw, Xfilt, pickwin, Pick, iplot=0, fig=None):
'''
Function to derive first motion (polarity) of given phase onset Pick.
Calculation is based on zero crossings determined within time window pickwin
@@ -324,9 +324,8 @@ def fmpicker(Xraw, Xfilt, pickwin, Pick, iplot=0, fig=None, linecolor='k'):
if fig == None or fig == 'None':
fig = plt.figure() # iplot)
plt_flag = 1
fig._tight = True
ax1 = fig.add_subplot(211)
ax1.plot(t, xraw, color=linecolor, linewidth=0.7)
ax1.plot(t, xraw, 'k')
ax1.plot([Pick, Pick], [max(xraw), -max(xraw)], 'b', linewidth=2, label='Pick')
if P1 is not None:
ax1.plot(t[islope1], xraw[islope1], label='Slope Window')
@@ -340,7 +339,7 @@ def fmpicker(Xraw, Xfilt, pickwin, Pick, iplot=0, fig=None, linecolor='k'):
ax2 = fig.add_subplot(2, 1, 2, sharex=ax1)
ax2.set_title('First-Motion Determination, Filtered Data')
ax2.plot(t, xfilt, color=linecolor, linewidth=0.7)
ax2.plot(t, xfilt, 'k')
ax2.plot([Pick, Pick], [max(xfilt), -max(xfilt)], 'b',
linewidth=2)
if P2 is not None:
@@ -591,10 +590,7 @@ def wadaticheck(pickdic, dttolerance, iplot=0, fig_dict=None):
Ppicks = []
Spicks = []
SPtimes = []
stations = []
ibad = 0
for key in list(pickdic.keys()):
for key in pickdic:
if pickdic[key]['P']['weight'] < 4 and pickdic[key]['S']['weight'] < 4:
# calculate S-P time
spt = pickdic[key]['S']['mpp'] - pickdic[key]['P']['mpp']
@@ -624,19 +620,17 @@ def wadaticheck(pickdic, dttolerance, iplot=0, fig_dict=None):
badstations = []
# calculate deviations from Wadati regression
ii = 0
for key in list(pickdic.keys()):
ibad = 0
for key in pickdic:
if 'SPt' in pickdic[key]:
stations.append(key)
wddiff = abs(pickdic[key]['SPt'] - wdfit[ii])
ii += 1
# check, if deviation is larger than adjusted
if wddiff > dttolerance:
# remove pick from dictionary
pickdic.pop(key)
# # mark onset and downgrade S-weight to 9
# # (not used anymore)
# marker = 'badWadatiCheck'
# pickdic[key]['S']['weight'] = 9
# mark onset and downgrade S-weight to 9
# (not used anymore)
marker = 'badWadatiCheck'
pickdic[key]['S']['weight'] = 9
badstations.append(key)
ibad += 1
else:
@@ -649,7 +643,6 @@ def wadaticheck(pickdic, dttolerance, iplot=0, fig_dict=None):
checkedSPtimes.append(checkedSPtime)
pickdic[key]['S']['marked'] = marker
#pickdic[key]['S']['marked'] = marker
print("wadaticheck: the following stations failed the check:")
print(badstations)
@@ -680,28 +673,19 @@ def wadaticheck(pickdic, dttolerance, iplot=0, fig_dict=None):
if iplot > 0:
if fig_dict:
fig = fig_dict['wadati']
linecolor = fig_dict['plot_style']['linecolor']['rgba_mpl']
plt_flag = 0
else:
fig = plt.figure()
linecolor = 'k'
plt_flag = 1
ax = fig.add_subplot(111)
if ibad > 0:
ax.plot(Ppicks, SPtimes, 'ro', label='Skipped S-Picks')
if wfitflag == 0:
ax.plot(Ppicks, wdfit, color=linecolor, linewidth=0.7, label='Wadati 1')
ax.plot(Ppicks, wdfit+dttolerance, color='0.9', linewidth=0.5, label='Wadati 1 Tolerance')
ax.plot(Ppicks, wdfit-dttolerance, color='0.9', linewidth=0.5)
ax.plot(Ppicks, wdfit, 'k', label='Wadati 1')
ax.plot(checkedPpicks, checkedSPtimes, 'ko', label='Reliable S-Picks')
ax.plot(checkedPpicks, wdfit2, 'g', label='Wadati 2')
ax.plot(checkedPpicks, checkedSPtimes, color=linecolor,
linewidth=0, marker='o', label='Reliable S-Picks')
for Ppick, SPtime, station in zip(Ppicks, SPtimes, stations):
ax.text(Ppick, SPtime + 0.01, '{0}'.format(station), color='0.25')
ax.set_title('Wadati-Diagram, %d S-P Times, Vp/Vs(raw)=%5.2f,' \
'Vp/Vs(checked)=%5.2f' % (len(SPtimes), vpvsr, cvpvsr))
ax.legend(loc=1, numpoints=1)
ax.legend(loc=1)
else:
ax.set_title('Wadati-Diagram, %d S-P Times' % len(SPtimes))
@@ -720,7 +704,7 @@ def RMS(X):
return np.sqrt(np.sum(np.power(X, 2)) / len(X))
def checksignallength(X, pick, TSNR, minsiglength, nfac, minpercent, iplot=0, fig=None, linecolor='k'):
def checksignallength(X, pick, TSNR, minsiglength, nfac, minpercent, iplot=0, fig=None):
'''
Function to detect spuriously picked noise peaks.
Uses RMS trace of all 3 components (if available) to determine,
@@ -805,9 +789,8 @@ def checksignallength(X, pick, TSNR, minsiglength, nfac, minpercent, iplot=0, fi
if fig == None or fig == 'None':
fig = plt.figure() # iplot)
plt_flag = 1
fig._tight = True
ax = fig.add_subplot(111)
ax.plot(t, rms, color=linecolor, linewidth=0.7, label='RMS Data')
ax.plot(t, rms, 'k', label='RMS Data')
ax.axvspan(t[inoise[0]], t[inoise[-1]], color='y', alpha=0.2, lw=0, label='Noise Window')
ax.axvspan(t[isignal[0]], t[isignal[-1]], color='b', alpha=0.2, lw=0, label='Signal Window')
ax.plot([t[isignal[0]], t[isignal[len(isignal) - 1]]],
@@ -882,9 +865,9 @@ def checkPonsets(pickdic, dttolerance, jackfactor=5, iplot=0, fig_dict=None):
badstations = np.array(stations)[ibad]
print("checkPonsets: %d pick(s) deviate too much from median!" % len(ibad))
print(badstations)
print("checkPonsets: Skipped %d P pick(s) out of %d" % (len(badstations) \
+ len(badjkstations), len(stations)))
print(badstations)
goodmarker = 'goodPonsetcheck'
badmarker = 'badPonsetcheck'
@@ -893,21 +876,15 @@ def checkPonsets(pickdic, dttolerance, jackfactor=5, iplot=0, fig_dict=None):
# mark P onset as checked and keep P weight
pickdic[goodstations[i]]['P']['marked'] = goodmarker
for i in range(0, len(badstations)):
# remove pick from dictionary
pickdic.pop(badstations[i])
# mark P onset and downgrade P weight to 9
# (not used anymore)
pickdic[badstations[i]]['P']['marked'] = badmarker
pickdic[badstations[i]]['P']['weight'] = 9
for i in range(0, len(badjkstations)):
# remove pick from dictionary
pickdic.pop(badjkstations[i])
# for i in range(0, len(badstations)):
# # mark P onset and downgrade P weight to 9
# # (not used anymore)
# pickdic[badstations[i]]['P']['marked'] = badmarker
# pickdic[badstations[i]]['P']['weight'] = 9
# for i in range(0, len(badjkstations)):
# # mark P onset and downgrade P weight to 9
# # (not used anymore)
# pickdic[badjkstations[i]]['P']['marked'] = badjkmarker
# pickdic[badjkstations[i]]['P']['weight'] = 9
# mark P onset and downgrade P weight to 9
# (not used anymore)
pickdic[badjkstations[i]]['P']['marked'] = badjkmarker
pickdic[badjkstations[i]]['P']['weight'] = 9
checkedonsets = pickdic
@@ -920,22 +897,19 @@ def checkPonsets(pickdic, dttolerance, jackfactor=5, iplot=0, fig_dict=None):
plt_flag = 1
ax = fig.add_subplot(111)
if len(badstations) > 0:
ax.plot(ibad, np.array(Ppicks)[ibad], marker ='o', markerfacecolor='orange', markersize=14,
linestyle='None', label='Median Skipped P Picks')
if len(badjkstations) > 0:
ax.plot(badjk[0], np.array(Ppicks)[badjk], 'ro', markersize=14, label='Jackknife Skipped P Picks')
ax.plot(np.arange(0, len(Ppicks)), Ppicks, 'ro', markersize=14)
if len(badstations) < 1 and len(badjkstations) < 1:
ax.plot(np.arange(0, len(Ppicks)), Ppicks, 'go', markersize=14, label='Skipped P Picks')
else:
ax.plot(igood, np.array(Ppicks)[igood], 'go', markersize=14, label='Good P Picks')
ax.plot([0, len(Ppicks) - 1], [pmedian, pmedian], 'g', linewidth=2, label='Median')
ax.plot([0, len(Ppicks) - 1], [pmedian + dttolerance, pmedian + dttolerance], 'g--', linewidth=1.2,
dashes=[25, 25], label='Median Tolerance')
ax.plot([0, len(Ppicks) - 1], [pmedian - dttolerance, pmedian - dttolerance], 'g--', linewidth=1.2,
dashes=[25, 25])
for index, pick in enumerate(Ppicks):
ax.text(index, pick + 0.01, '{0}'.format(stations[index]), color='0.25')
ax.plot([0, len(Ppicks) - 1], [pmedian, pmedian], 'g',
linewidth=2, label='Median')
for i in range(0, len(Ppicks)):
ax.text(i, Ppicks[i] + 0.01, '{0}'.format(stations[i]))
ax.set_xlabel('Number of P Picks')
ax.set_ylabel('Onset Time [s] from 1.1.1970') # MP MP Improve this?
ax.legend(loc=1, numpoints=1)
ax.set_ylabel('Onset Time [s] from 1.1.1970')
ax.legend(loc=1)
ax.set_title('Jackknifing and Median Tests on P Onsets')
if plt_flag:
fig.show()
@@ -967,8 +941,9 @@ def jackknife(X, phi, h):
PHI_sub = None
# determine number of subgroups
g = int(len(X) / h)
if len(X) % h:
if (len(X) / h) % 1 != 0:
print("jackknife: Cannot divide quantity X in equal sized subgroups!")
print("Choose another size for subgroups!")
return PHI_jack, PHI_pseudo, PHI_sub
@@ -985,7 +960,7 @@ def jackknife(X, phi, h):
# estimators of subgroups
PHI_pseudo = []
PHI_sub = []
for i in range(0, g - 1):
for i in range(0, g):
# subgroup i, remove i-th sample
xx = X[:]
del xx[i]
@@ -1007,7 +982,7 @@ def jackknife(X, phi, h):
return PHI_jack, PHI_pseudo, PHI_sub
def checkZ4S(X, pick, zfac, checkwin, iplot, fig=None, linecolor='k'):
def checkZ4S(X, pick, zfac, checkwin, iplot, fig=None):
'''
Function to compare energy content of vertical trace with
energy content of horizontal traces to detect spuriously
@@ -1134,9 +1109,8 @@ def checkZ4S(X, pick, zfac, checkwin, iplot, fig=None, linecolor='k'):
fig = plt.figure() # self.iplot) ### WHY? MP MP
plt_flag = 1
ax = fig.add_subplot(3, 1, i + 1, sharex=ax1)
fig._tight = True
ax.plot(t, abs(trace.data), color='b', label='abs')
ax.plot(t, trace.data, color=linecolor, linewidth=0.7)
ax.plot(t, trace.data, color='k')
name = str(trace.stats.channel) + ': {}'.format(rms)
ax.plot([pick, pick + checkwin], [rms, rms], 'r', label='RMS {}'.format(name))
ax.plot([pick, pick], ax.get_ylim(), 'm', label='Pick')
@@ -1180,6 +1154,55 @@ def getQualityFromUncertainty(uncertainty, Errors):
return quality
def removePicksAbove(pickDic, minWeight):
'''remove picks from pick dicitonary with a weight > minweight'''
newdic = {}
for event in pickDic.keys():
newdic[event] = {}
for eventKey, eventDic in pickDic.items():
for station, phases in eventDic.items():
if phases['P']['weight'] < minWeight or phases['S']['weight'] < minWeight:
# dont append stations that will be empty to output dict
newdic[eventKey][station] = {}
if len(phases) > 2:
# copy over other values beside P/S information
additional_info = phases.copy()
if 'P' in phases.keys():
additional_info.pop('P')
if 'S' in phases.keys():
additional_info.pop('S')
newdic[eventKey][station].update(additional_info)
for phasename, phaseinfo in phases.items():
if phasename in ('P', 'S') and phaseinfo['weight'] < minWeight:
newdic[eventKey][station].update({phasename: phaseinfo})
return newdic
def get_maximum_index(data, checkwindow, minfactor, safetygap):
'''get maximum of CF as starting point, then check for highest local maximum
in front of it.
return second maximum if its larger than first maximum * minfactor, else
return first maximum.
checkwindow and safetygap are given in samples'''
icfmax1 = np.argmax(data)
imax_local = argrelextrema(data[icfmax1 - checkwindow:icfmax1 - safetygap], np.greater)[0] # indices of local maxima
if imax_local.size > 0:
imax_local = imax_local + icfmax1 - checkwindow
local_maxima = (imax_local, data[imax_local])
largest_local_max = np.where(local_maxima[1] == max(local_maxima[1]))
icfmax2 = local_maxima[0][largest_local_max]
if data[icfmax2] > data[icfmax1] * minfactor:
print("Found valid local maximum in front of first maximum")
return icfmax2[0]
else:
print("First maximum is the largest: {}>{}".format(data[icfmax1],
data[icfmax2]))
return icfmax1
else:
print("No local maxima found in check window")
return icfmax1
if __name__ == '__main__':
import doctest
+998
View File
@@ -0,0 +1,998 @@
#!/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
"""
import warnings
import matplotlib.pyplot as plt
import numpy as np
from obspy.core import Stream, UTCDateTime
def earllatepicker(X, nfac, TSNR, Pick1, iplot=0, stealthMode=False):
'''
Function to derive earliest and latest possible pick after Diehl & Kissling (2009)
as reasonable uncertainties. Latest possible pick is based on noise level,
earliest possible pick is half a signal wavelength in front of most likely
pick given by PragPicker or manually set by analyst. Most likely pick
(initial pick Pick1) must be given.
:param: X, time series (seismogram)
:type: `~obspy.core.stream.Stream`
:param: nfac (noise factor), nfac times noise level to calculate latest possible pick
:type: int
:param: TSNR, length of time windows around pick used to determine SNR [s]
:type: tuple (T_noise, T_gap, T_signal)
:param: Pick1, initial (most likely) onset time, starting point for earllatepicker
:type: float
:param: iplot, if given, results are plotted in figure(iplot)
:type: int
'''
assert isinstance(X, Stream), "%s is not a stream object" % str(X)
LPick = None
EPick = None
PickError = None
if stealthMode is False:
print
'earllatepicker: Get earliest and latest possible pick relative to most likely pick ...'
x = X[0].data
t = np.arange(0, X[0].stats.npts / X[0].stats.sampling_rate,
X[0].stats.delta)
inoise = getnoisewin(t, Pick1, TSNR[0], TSNR[1])
# get signal window
isignal = getsignalwin(t, Pick1, TSNR[2])
# remove mean
x = x - np.mean(x[inoise])
# calculate noise level
nlevel = np.sqrt(np.mean(np.square(x[inoise]))) * nfac
# get time where signal exceeds nlevel
ilup, = np.where(x[isignal] > nlevel)
ildown, = np.where(x[isignal] < -nlevel)
if not ilup.size and not ildown.size:
print("earllatepicker: Signal lower than noise level!")
print("Skip this trace!")
return LPick, EPick, PickError
il = min(np.min(ilup) if ilup.size else float('inf'),
np.min(ildown) if ildown.size else float('inf'))
LPick = t[isignal][il]
# get earliest possible pick
EPick = np.nan;
count = 0
pis = isignal
# if EPick stays NaN the signal window size will be doubled
while np.isnan(EPick):
if count > 0:
print("earllatepicker: Doubled signal window size %s time(s) "
"because of NaN for earliest pick." % count)
if stealthMode is False:
print("\nearllatepicker: Doubled signal window size %s time(s) "
"because of NaN for earliest pick." % count)
isigDoubleWinStart = pis[-1] + 1
isignalDoubleWin = np.arange(isigDoubleWinStart,
isigDoubleWinStart + len(pis))
if (isigDoubleWinStart + len(pis)) < X[0].data.size:
pis = np.concatenate((pis, isignalDoubleWin))
else:
print("Could not double signal window. Index out of bounds.")
break
count += 1
# determine all zero crossings in signal window (demeaned)
zc = crossings_nonzero_all(x[pis] - x[pis].mean())
# calculate mean half period T0 of signal as the average of the
T0 = np.mean(np.diff(zc)) * X[0].stats.delta # this is half wave length
# T0/4 is assumed as time difference between most likely and earliest possible pick!
EPick = Pick1 - T0 / 2
# get symmetric pick error as mean from earliest and latest possible pick
# by weighting latest possible pick two times earliest possible pick
diffti_tl = LPick - Pick1
diffti_te = Pick1 - EPick
PickError = (diffti_te + 2 * diffti_tl) / 3
if iplot > 1:
p = plt.figure(iplot)
p1, = plt.plot(t, x, 'k')
p2, = plt.plot(t[inoise], x[inoise])
p3, = plt.plot(t[isignal], x[isignal], 'r')
p4, = plt.plot([t[0], t[int(len(t)) - 1]], [nlevel, nlevel], '--k')
p5, = plt.plot(t[isignal[zc]], np.zeros(len(zc)), '*g',
markersize=14)
plt.legend([p1, p2, p3, p4, p5],
['Data', 'Noise Window', 'Signal Window', 'Noise Level',
'Zero Crossings'],
loc='best')
plt.plot([t[0], t[int(len(t)) - 1]], [-nlevel, -nlevel], '--k')
plt.plot([Pick1, Pick1], [max(x), -max(x)], 'b', linewidth=2)
plt.plot([LPick, LPick], [max(x) / 2, -max(x) / 2], '--k')
plt.plot([EPick, EPick], [max(x) / 2, -max(x) / 2], '--k')
plt.plot([Pick1 + PickError, Pick1 + PickError],
[max(x) / 2, -max(x) / 2], 'r--')
plt.plot([Pick1 - PickError, Pick1 - PickError],
[max(x) / 2, -max(x) / 2], 'r--')
plt.xlabel('Time [s] since %s' % X[0].stats.starttime)
plt.yticks([])
plt.title(
'Earliest-/Latest Possible/Most Likely Pick & Symmetric Pick Error, %s' %
X[0].stats.station)
plt.show()
raw_input()
plt.close(p)
return EPick, LPick, PickError
def fmpicker(Xraw, Xfilt, pickwin, Pick, iplot=0):
'''
Function to derive first motion (polarity) of given phase onset Pick.
Calculation is based on zero crossings determined within time window pickwin
after given onset time.
:param: Xraw, unfiltered time series (seismogram)
:type: `~obspy.core.stream.Stream`
:param: Xfilt, filtered time series (seismogram)
:type: `~obspy.core.stream.Stream`
:param: pickwin, time window after onset Pick within zero crossings are calculated
:type: float
:param: Pick, initial (most likely) onset time, starting point for fmpicker
:type: float
:param: iplot, if given, results are plotted in figure(iplot)
:type: int
'''
warnings.simplefilter('ignore', np.RankWarning)
assert isinstance(Xraw, Stream), "%s is not a stream object" % str(Xraw)
assert isinstance(Xfilt, Stream), "%s is not a stream object" % str(Xfilt)
FM = None
if Pick is not None:
print("fmpicker: Get first motion (polarity) of onset using unfiltered seismogram...")
xraw = Xraw[0].data
xfilt = Xfilt[0].data
t = np.arange(0, Xraw[0].stats.npts / Xraw[0].stats.sampling_rate,
Xraw[0].stats.delta)
# get pick window
ipick = np.where(
(t <= min([Pick + pickwin, len(Xraw[0])])) & (t >= Pick))
# remove mean
xraw[ipick] = xraw[ipick] - np.mean(xraw[ipick])
xfilt[ipick] = xfilt[ipick] - np.mean(xfilt[ipick])
# get zero crossings after most likely pick
# initial onset is assumed to be the first zero crossing
# first from unfiltered trace
zc1 = []
zc1.append(Pick)
index1 = []
i = 0
for j in range(ipick[0][1], ipick[0][len(t[ipick]) - 1]):
i = i + 1
if xraw[j - 1] <= 0 <= xraw[j]:
zc1.append(t[ipick][i])
index1.append(i)
elif xraw[j - 1] > 0 >= xraw[j]:
zc1.append(t[ipick][i])
index1.append(i)
if len(zc1) == 3:
break
# if time difference betweeen 1st and 2cnd zero crossing
# is too short, get time difference between 1st and 3rd
# to derive maximum
if zc1[1] - zc1[0] <= Xraw[0].stats.delta:
li1 = index1[1]
else:
li1 = index1[0]
if np.size(xraw[ipick[0][1]:ipick[0][li1]]) == 0:
print("fmpicker: Onset on unfiltered trace too emergent for first motion determination!")
P1 = None
else:
imax1 = np.argmax(abs(xraw[ipick[0][1]:ipick[0][li1]]))
if imax1 == 0:
imax1 = np.argmax(abs(xraw[ipick[0][1]:ipick[0][index1[1]]]))
if imax1 == 0:
print("fmpicker: Zero crossings too close!")
print("Skip first motion determination!")
return FM
islope1 = np.where((t >= Pick) & (t <= Pick + t[imax1]))
# calculate slope as polynomal fit of order 1
xslope1 = np.arange(0, len(xraw[islope1]), 1)
P1 = np.polyfit(xslope1, xraw[islope1], 1)
datafit1 = np.polyval(P1, xslope1)
# now using filterd trace
# next zero crossings after most likely pick
zc2 = []
zc2.append(Pick)
index2 = []
i = 0
for j in range(ipick[0][1], ipick[0][len(t[ipick]) - 1]):
i = i + 1
if xfilt[j - 1] <= 0 <= xfilt[j]:
zc2.append(t[ipick][i])
index2.append(i)
elif xfilt[j - 1] > 0 >= xfilt[j]:
zc2.append(t[ipick][i])
index2.append(i)
if len(zc2) == 3:
break
# if time difference betweeen 1st and 2cnd zero crossing
# is too short, get time difference between 1st and 3rd
# to derive maximum
if zc2[1] - zc2[0] <= Xfilt[0].stats.delta:
li2 = index2[1]
else:
li2 = index2[0]
if np.size(xfilt[ipick[0][1]:ipick[0][li2]]) == 0:
print("fmpicker: Onset on filtered trace too emergent for first motion determination!")
P2 = None
else:
imax2 = np.argmax(abs(xfilt[ipick[0][1]:ipick[0][li2]]))
if imax2 == 0:
imax2 = np.argmax(abs(xfilt[ipick[0][1]:ipick[0][index2[1]]]))
if imax2 == 0:
print("fmpicker: Zero crossings too close!")
print("Skip first motion determination!")
return FM
islope2 = np.where((t >= Pick) & (t <= Pick + t[imax2]))
# calculate slope as polynomal fit of order 1
xslope2 = np.arange(0, len(xfilt[islope2]), 1)
P2 = np.polyfit(xslope2, xfilt[islope2], 1)
datafit2 = np.polyval(P2, xslope2)
# compare results
if P1 is not None and P2 is not None:
if P1[0] < 0 and P2[0] < 0:
FM = 'D'
elif P1[0] >= 0 > P2[0]:
FM = '-'
elif P1[0] < 0 <= P2[0]:
FM = '-'
elif P1[0] > 0 and P2[0] > 0:
FM = 'U'
elif P1[0] <= 0 < P2[0]:
FM = '+'
elif P1[0] > 0 >= P2[0]:
FM = '+'
print("fmpicker: Found polarity %s" % FM)
if iplot > 1:
plt.figure(iplot)
plt.subplot(2, 1, 1)
plt.plot(t, xraw, 'k')
p1, = plt.plot([Pick, Pick], [max(xraw), -max(xraw)], 'b', linewidth=2)
if P1 is not None:
p2, = plt.plot(t[islope1], xraw[islope1])
p3, = plt.plot(zc1, np.zeros(len(zc1)), '*g', markersize=14)
p4, = plt.plot(t[islope1], datafit1, '--g', linewidth=2)
plt.legend([p1, p2, p3, p4],
['Pick', 'Slope Window', 'Zero Crossings', 'Slope'],
loc='best')
plt.text(Pick + 0.02, max(xraw) / 2, '%s' % FM, fontsize=14)
ax = plt.gca()
plt.yticks([])
plt.title('First-Motion Determination, %s, Unfiltered Data' % Xraw[
0].stats.station)
plt.subplot(2, 1, 2)
plt.title('First-Motion Determination, Filtered Data')
plt.plot(t, xfilt, 'k')
p1, = plt.plot([Pick, Pick], [max(xfilt), -max(xfilt)], 'b',
linewidth=2)
if P2 is not None:
p2, = plt.plot(t[islope2], xfilt[islope2])
p3, = plt.plot(zc2, np.zeros(len(zc2)), '*g', markersize=14)
p4, = plt.plot(t[islope2], datafit2, '--g', linewidth=2)
plt.text(Pick + 0.02, max(xraw) / 2, '%s' % FM, fontsize=14)
ax = plt.gca()
plt.xlabel('Time [s] since %s' % Xraw[0].stats.starttime)
plt.yticks([])
plt.show()
raw_input()
plt.close(iplot)
return FM
def crossings_nonzero_all(data):
pos = data > 0
npos = ~pos
return ((pos[:-1] & npos[1:]) | (npos[:-1] & pos[1:])).nonzero()[0]
def getSNR(X, TSNR, t1):
'''
Function to calculate SNR of certain part of seismogram relative to
given time (onset) out of given noise and signal windows. A safety gap
between noise and signal part can be set. Returns SNR and SNR [dB] and
noiselevel.
:param: X, time series (seismogram)
:type: `~obspy.core.stream.Stream`
:param: TSNR, length of time windows [s] around t1 (onset) used to determine SNR
:type: tuple (T_noise, T_gap, T_signal)
:param: t1, initial time (onset) from which noise and signal windows are calculated
:type: float
'''
assert isinstance(X, Stream), "%s is not a stream object" % str(X)
x = X[0].data
t = np.arange(0, X[0].stats.npts / X[0].stats.sampling_rate,
X[0].stats.delta)
# get noise window
inoise = getnoisewin(t, t1, TSNR[0], TSNR[1])
# get signal window
isignal = getsignalwin(t, t1, TSNR[2])
if np.size(inoise) < 1:
print("getSNR: Empty array inoise, check noise window!")
return
elif np.size(isignal) < 1:
print("getSNR: Empty array isignal, check signal window!")
return
# demean over entire waveform
x = x - np.mean(x[inoise])
# calculate ratios
noiselevel = np.sqrt(np.mean(np.square(x[inoise])))
signallevel = np.sqrt(np.mean(np.square(x[isignal])))
SNR = signallevel / noiselevel
SNRdB = 10 * np.log10(SNR)
return SNR, SNRdB, noiselevel
def getnoisewin(t, t1, tnoise, tgap):
'''
Function to extract indeces of data out of time series for noise calculation.
Returns an array of indeces.
:param: t, array of time stamps
:type: numpy array
:param: t1, time from which relativ to it noise window is extracted
:type: float
:param: tnoise, length of time window [s] for noise part extraction
:type: float
:param: tgap, safety gap between t1 (onset) and noise window to
ensure, that noise window contains no signal
:type: float
'''
# get noise window
inoise, = np.where((t <= max([t1 - tgap, 0])) \
& (t >= max([t1 - tnoise - tgap, 0])))
if np.size(inoise) < 1:
print("getnoisewin: Empty array inoise, check noise window!")
return inoise
def getsignalwin(t, t1, tsignal):
'''
Function to extract data out of time series for signal level calculation.
Returns an array of indeces.
:param: t, array of time stamps
:type: numpy array
:param: t1, time from which relativ to it signal window is extracted
:type: float
:param: tsignal, length of time window [s] for signal level calculation
:type: float
'''
# get signal window
isignal, = np.where((t <= min([t1 + tsignal, len(t)])) \
& (t >= t1))
if np.size(isignal) < 1:
print("getsignalwin: Empty array isignal, check signal window!")
return isignal
def getResolutionWindow(snr):
"""
Number -> Float
produce the half of the time resolution window width from given SNR
value
SNR >= 3 -> 2 sec HRW
3 > SNR >= 2 -> 5 sec MRW
2 > SNR >= 1.5 -> 10 sec LRW
1.5 > SNR -> 15 sec VLRW
see also Diehl et al. 2009
>>> getResolutionWindow(0.5)
7.5
>>> getResolutionWindow(1.8)
5.0
>>> getResolutionWindow(2.3)
2.5
>>> getResolutionWindow(4)
1.0
>>> getResolutionWindow(2)
2.5
"""
res_wins = {'HRW': 2., 'MRW': 5., 'LRW': 10., 'VLRW': 15.}
if snr < 1.5:
time_resolution = res_wins['VLRW']
elif snr < 2.:
time_resolution = res_wins['LRW']
elif snr < 3.:
time_resolution = res_wins['MRW']
else:
time_resolution = res_wins['HRW']
return time_resolution / 2
def wadaticheck(pickdic, dttolerance, iplot):
'''
Function to calculate Wadati-diagram from given P and S onsets in order
to detect S pick outliers. If a certain S-P time deviates by dttolerance
from regression of S-P time the S pick is marked and down graded.
: param: pickdic, dictionary containing picks and quality parameters
: type: dictionary
: param: dttolerance, maximum adjusted deviation of S-P time from
S-P time regression
: type: float
: param: iplot, if iplot > 1, Wadati diagram is shown
: type: int
'''
checkedonsets = pickdic
# search for good quality picks and calculate S-P time
Ppicks = []
Spicks = []
SPtimes = []
for key in pickdic:
if pickdic[key]['P']['weight'] < 4 and pickdic[key]['S']['weight'] < 4:
# calculate S-P time
spt = pickdic[key]['S']['mpp'] - pickdic[key]['P']['mpp']
# add S-P time to dictionary
pickdic[key]['SPt'] = spt
# add P onsets and corresponding S-P times to list
UTCPpick = UTCDateTime(pickdic[key]['P']['mpp'])
UTCSpick = UTCDateTime(pickdic[key]['S']['mpp'])
Ppicks.append(UTCPpick.timestamp)
Spicks.append(UTCSpick.timestamp)
SPtimes.append(spt)
if len(SPtimes) >= 3:
# calculate slope
p1 = np.polyfit(Ppicks, SPtimes, 1)
wdfit = np.polyval(p1, Ppicks)
wfitflag = 0
# calculate vp/vs ratio before check
vpvsr = p1[0] + 1
print("###############################################")
print("wadaticheck: Average Vp/Vs ratio before check: %f" % vpvsr)
checkedPpicks = []
checkedSpicks = []
checkedSPtimes = []
# calculate deviations from Wadati regression
ii = 0
ibad = 0
for key in pickdic:
if pickdic[key].has_key('SPt'):
wddiff = abs(pickdic[key]['SPt'] - wdfit[ii])
ii += 1
# check, if deviation is larger than adjusted
if wddiff > dttolerance:
# mark onset and downgrade S-weight to 9
# (not used anymore)
marker = 'badWadatiCheck'
pickdic[key]['S']['weight'] = 9
ibad += 1
else:
marker = 'goodWadatiCheck'
checkedPpick = UTCDateTime(pickdic[key]['P']['mpp'])
checkedPpicks.append(checkedPpick.timestamp)
checkedSpick = UTCDateTime(pickdic[key]['S']['mpp'])
checkedSpicks.append(checkedSpick.timestamp)
checkedSPtime = pickdic[key]['S']['mpp'] - pickdic[key]['P']['mpp']
checkedSPtimes.append(checkedSPtime)
pickdic[key]['S']['marked'] = marker
if len(checkedPpicks) >= 3:
# calculate new slope
p2 = np.polyfit(checkedPpicks, checkedSPtimes, 1)
wdfit2 = np.polyval(p2, checkedPpicks)
# calculate vp/vs ratio after check
cvpvsr = p2[0] + 1
print("wadaticheck: Average Vp/Vs ratio after check: %f" % cvpvsr)
print("wadatacheck: Skipped %d S pick(s)" % ibad)
else:
print("###############################################")
print("wadatacheck: Not enough checked S-P times available!")
print("Skip Wadati check!")
checkedonsets = pickdic
else:
print("wadaticheck: Not enough S-P times available for reliable regression!")
print("Skip wadati check!")
wfitflag = 1
# plot results
if iplot > 1:
plt.figure(iplot)
f1, = plt.plot(Ppicks, SPtimes, 'ro')
if wfitflag == 0:
f2, = plt.plot(Ppicks, wdfit, 'k')
f3, = plt.plot(checkedPpicks, checkedSPtimes, 'ko')
f4, = plt.plot(checkedPpicks, wdfit2, 'g')
plt.title('Wadati-Diagram, %d S-P Times, Vp/Vs(raw)=%5.2f,' \
'Vp/Vs(checked)=%5.2f' % (len(SPtimes), vpvsr, cvpvsr))
plt.legend([f1, f2, f3, f4], ['Skipped S-Picks', 'Wadati 1',
'Reliable S-Picks', 'Wadati 2'], loc='best')
else:
plt.title('Wadati-Diagram, %d S-P Times' % len(SPtimes))
plt.ylabel('S-P Times [s]')
plt.xlabel('P Times [s]')
plt.show()
raw_input()
plt.close(iplot)
return checkedonsets
def checksignallength(X, pick, TSNR, minsiglength, nfac, minpercent, iplot):
'''
Function to detect spuriously picked noise peaks.
Uses RMS trace of all 3 components (if available) to determine,
how many samples [per cent] after P onset are below certain
threshold, calculated from noise level times noise factor.
: param: X, time series (seismogram)
: type: `~obspy.core.stream.Stream`
: param: pick, initial (AIC) P onset time
: type: float
: param: TSNR, length of time windows around initial pick [s]
: type: tuple (T_noise, T_gap, T_signal)
: param: minsiglength, minium required signal length [s] to
declare pick as P onset
: type: float
: param: nfac, noise factor (nfac * noise level = threshold)
: type: float
: param: minpercent, minimum required percentage of samples
above calculated threshold
: type: float
: param: iplot, if iplot > 1, results are shown in figure
: type: int
'''
assert isinstance(X, Stream), "%s is not a stream object" % str(X)
print("Checking signal length ...")
if len(X) > 1:
# all three components available
# make sure, all components have equal lengths
ilen = min([len(X[0].data), len(X[1].data), len(X[2].data)])
x1 = X[0][0:ilen]
x2 = X[1][0:ilen]
x3 = X[2][0:ilen]
# get RMS trace
rms = np.sqrt((np.power(x1, 2) + np.power(x2, 2) + np.power(x3, 2)) / 3)
else:
x1 = X[0].data
rms = np.sqrt(np.power(2, x1))
t = np.arange(0, ilen / X[0].stats.sampling_rate,
X[0].stats.delta)
# get noise window in front of pick plus saftey gap
inoise = getnoisewin(t, pick - 0.5, TSNR[0], TSNR[1])
# get signal window
isignal = getsignalwin(t, pick, minsiglength)
# calculate minimum adjusted signal level
minsiglevel = max(rms[inoise]) * nfac
# minimum adjusted number of samples over minimum signal level
minnum = len(isignal) * minpercent / 100
# get number of samples above minimum adjusted signal level
numoverthr = len(np.where(rms[isignal] >= minsiglevel)[0])
if numoverthr >= minnum:
print("checksignallength: Signal reached required length.")
returnflag = 1
else:
print("checksignallength: Signal shorter than required minimum signal length!")
print("Presumably picked noise peak, pick is rejected!")
print("(min. signal length required: %s s)" % minsiglength)
returnflag = 0
if iplot == 2:
plt.figure(iplot)
p1, = plt.plot(t, rms, 'k')
p2, = plt.plot(t[inoise], rms[inoise], 'c')
p3, = plt.plot(t[isignal], rms[isignal], 'r')
p4, = plt.plot([t[isignal[0]], t[isignal[len(isignal) - 1]]],
[minsiglevel, minsiglevel], 'g', linewidth=2)
p5, = plt.plot([pick, pick], [min(rms), max(rms)], 'b', linewidth=2)
plt.legend([p1, p2, p3, p4, p5], ['RMS Data', 'RMS Noise Window',
'RMS Signal Window', 'Minimum Signal Level',
'Onset'], loc='best')
plt.xlabel('Time [s] since %s' % X[0].stats.starttime)
plt.ylabel('Counts')
plt.title('Check for Signal Length, Station %s' % X[0].stats.station)
plt.yticks([])
plt.show()
raw_input()
plt.close(iplot)
return returnflag
def checkPonsets(pickdic, dttolerance, iplot):
'''
Function to check statistics of P-onset times: Control deviation from
median (maximum adjusted deviation = dttolerance) and apply pseudo-
bootstrapping jackknife.
: param: pickdic, dictionary containing picks and quality parameters
: type: dictionary
: param: dttolerance, maximum adjusted deviation of P-onset time from
median of all P onsets
: type: float
: param: iplot, if iplot > 1, Wadati diagram is shown
: type: int
'''
checkedonsets = pickdic
# search for good quality P picks
Ppicks = []
stations = []
for key in pickdic:
if pickdic[key]['P']['weight'] < 4:
# add P onsets to list
UTCPpick = UTCDateTime(pickdic[key]['P']['mpp'])
Ppicks.append(UTCPpick.timestamp)
stations.append(key)
# apply jackknife bootstrapping on variance of P onsets
print("###############################################")
print("checkPonsets: Apply jackknife bootstrapping on P-onset times ...")
[xjack, PHI_pseudo, PHI_sub] = jackknife(Ppicks, 'VAR', 1)
# get pseudo variances smaller than average variances
# (times safety factor), these picks passed jackknife test
ij = np.where(PHI_pseudo <= 2 * xjack)
# these picks did not pass jackknife test
badjk = np.where(PHI_pseudo > 2 * xjack)
badjkstations = np.array(stations)[badjk]
print("checkPonsets: %d pick(s) did not pass jackknife test!" % len(badjkstations))
# calculate median from these picks
pmedian = np.median(np.array(Ppicks)[ij])
# find picks that deviate less than dttolerance from median
ii = np.where(abs(np.array(Ppicks)[ij] - pmedian) <= dttolerance)
jj = np.where(abs(np.array(Ppicks)[ij] - pmedian) > dttolerance)
igood = ij[0][ii]
ibad = ij[0][jj]
goodstations = np.array(stations)[igood]
badstations = np.array(stations)[ibad]
print("checkPonsets: %d pick(s) deviate too much from median!" % len(ibad))
print("checkPonsets: Skipped %d P pick(s) out of %d" % (len(badstations) \
+ len(badjkstations), len(stations)))
goodmarker = 'goodPonsetcheck'
badmarker = 'badPonsetcheck'
badjkmarker = 'badjkcheck'
for i in range(0, len(goodstations)):
# mark P onset as checked and keep P weight
pickdic[goodstations[i]]['P']['marked'] = goodmarker
for i in range(0, len(badstations)):
# mark P onset and downgrade P weight to 9
# (not used anymore)
pickdic[badstations[i]]['P']['marked'] = badmarker
pickdic[badstations[i]]['P']['weight'] = 9
for i in range(0, len(badjkstations)):
# mark P onset and downgrade P weight to 9
# (not used anymore)
pickdic[badjkstations[i]]['P']['marked'] = badjkmarker
pickdic[badjkstations[i]]['P']['weight'] = 9
checkedonsets = pickdic
if iplot > 1:
p1, = plt.plot(np.arange(0, len(Ppicks)), Ppicks, 'r+', markersize=14)
p2, = plt.plot(igood, np.array(Ppicks)[igood], 'g*', markersize=14)
p3, = plt.plot([0, len(Ppicks) - 1], [pmedian, pmedian], 'g',
linewidth=2)
for i in range(0, len(Ppicks)):
plt.text(i, Ppicks[i] + 0.2, stations[i])
plt.xlabel('Number of P Picks')
plt.ylabel('Onset Time [s] from 1.1.1970')
plt.legend([p1, p2, p3], ['Skipped P Picks', 'Good P Picks', 'Median'],
loc='best')
plt.title('Check P Onsets')
plt.show()
raw_input()
return checkedonsets
def jackknife(X, phi, h):
'''
Function to calculate the Jackknife Estimator for a given quantity,
special type of boot strapping. Returns the jackknife estimator PHI_jack
the pseudo values PHI_pseudo and the subgroup parameters PHI_sub.
: param: X, given quantity
: type: list
: param: phi, chosen estimator, choose between:
"MED" for median
"MEA" for arithmetic mean
"VAR" for variance
: type: string
: param: h, size of subgroups, optinal, default = 1
: type: integer
'''
PHI_jack = None
PHI_pseudo = None
PHI_sub = None
# determine number of subgroups
g = len(X) / h
if type(g) is not int:
print("jackknife: Cannot divide quantity X in equal sized subgroups!")
print("Choose another size for subgroups!")
return PHI_jack, PHI_pseudo, PHI_sub
else:
# estimator of undisturbed spot check
if phi == 'MEA':
phi_sc = np.mean(X)
elif phi == 'VAR':
phi_sc = np.var(X)
elif phi == 'MED':
phi_sc = np.median(X)
# estimators of subgroups
PHI_pseudo = []
PHI_sub = []
for i in range(0, g - 1):
# subgroup i, remove i-th sample
xx = X[:]
del xx[i]
# calculate estimators of disturbed spot check
if phi == 'MEA':
phi_sub = np.mean(xx)
elif phi == 'VAR':
phi_sub = np.var(xx)
elif phi == 'MED':
phi_sub = np.median(xx)
PHI_sub.append(phi_sub)
# pseudo values
phi_pseudo = g * phi_sc - ((g - 1) * phi_sub)
PHI_pseudo.append(phi_pseudo)
# jackknife estimator
PHI_jack = np.mean(PHI_pseudo)
return PHI_jack, PHI_pseudo, PHI_sub
def checkZ4S(X, pick, zfac, checkwin, iplot):
'''
Function to compare energy content of vertical trace with
energy content of horizontal traces to detect spuriously
picked S onsets instead of P onsets. Usually, P coda shows
larger longitudal energy on vertical trace than on horizontal
traces, where the transversal energy is larger within S coda.
Be careful: there are special circumstances, where this is not
the case!
: param: X, fitered(!) time series, three traces
: type: `~obspy.core.stream.Stream`
: param: pick, initial (AIC) P onset time
: type: float
: param: zfac, factor for threshold determination,
vertical energy must exceed coda level times zfac
to declare a pick as P onset
: type: float
: param: checkwin, window length [s] for calculating P-coda
energy content
: type: float
: param: iplot, if iplot > 1, energy content and threshold
are shown
: type: int
'''
assert isinstance(X, Stream), "%s is not a stream object" % str(X)
print("Check for spuriously picked S onset instead of P onset ...")
returnflag = 0
# split components
zdat = X.select(component="Z")
edat = X.select(component="E")
if len(edat) == 0: # check for other components
edat = X.select(component="2")
ndat = X.select(component="N")
if len(ndat) == 0: # check for other components
ndat = X.select(component="1")
z = zdat[0].data
tz = np.arange(0, zdat[0].stats.npts / zdat[0].stats.sampling_rate,
zdat[0].stats.delta)
# calculate RMS trace from vertical component
absz = np.sqrt(np.power(z, 2))
# calculate RMS trace from both horizontal traces
# make sure, both traces have equal lengths
lene = len(edat[0].data)
lenn = len(ndat[0].data)
minlen = min([lene, lenn])
absen = np.sqrt(np.power(edat[0].data[0:minlen - 1], 2) \
+ np.power(ndat[0].data[0:minlen - 1], 2))
# get signal window
isignal = getsignalwin(tz, pick, checkwin)
# calculate energy levels
zcodalevel = max(absz[isignal])
encodalevel = max(absen[isignal])
# calculate threshold
minsiglevel = encodalevel * zfac
# vertical P-coda level must exceed horizontal P-coda level
# zfac times encodalevel
if zcodalevel < minsiglevel:
print("checkZ4S: Maybe S onset? Skip this P pick!")
else:
print("checkZ4S: P onset passes checkZ4S test!")
returnflag = 1
if iplot > 1:
te = np.arange(0, edat[0].stats.npts / edat[0].stats.sampling_rate,
edat[0].stats.delta)
tn = np.arange(0, ndat[0].stats.npts / ndat[0].stats.sampling_rate,
ndat[0].stats.delta)
plt.plot(tz, z / max(z), 'k')
plt.plot(tz[isignal], z[isignal] / max(z), 'r')
plt.plot(te, edat[0].data / max(edat[0].data) + 1, 'k')
plt.plot(te[isignal], edat[0].data[isignal] / max(edat[0].data) + 1, 'r')
plt.plot(tn, ndat[0].data / max(ndat[0].data) + 2, 'k')
plt.plot(tn[isignal], ndat[0].data[isignal] / max(ndat[0].data) + 2, 'r')
plt.plot([tz[isignal[0]], tz[isignal[len(isignal) - 1]]],
[minsiglevel / max(z), minsiglevel / max(z)], 'g',
linewidth=2)
plt.xlabel('Time [s] since %s' % zdat[0].stats.starttime)
plt.ylabel('Normalized Counts')
plt.yticks([0, 1, 2], [zdat[0].stats.channel, edat[0].stats.channel,
ndat[0].stats.channel])
plt.title('CheckZ4S, Station %s' % zdat[0].stats.station)
plt.show()
raw_input()
return returnflag
def writephases(arrivals, fformat, filename):
'''
Function of methods to write phases to the following standard file
formats used for locating earthquakes:
HYPO71, NLLoc, VELEST, HYPOSAT, HYPOINVERSE and hypoDD
:param: arrivals
:type: dictionary containing all phase information including
station ID, phase, first motion, weight (uncertainty),
....
:param: fformat
:type: string, chosen file format (location routine),
choose between NLLoc, HYPO71, HYPOSAT, VELEST,
HYPOINVERSE, and hypoDD
:param: filename, full path and name of phase file
:type: string
'''
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')
for key in arrivals:
if arrivals[key]['P']['weight'] < 4:
# write phase information to NLLoc-phase file
# see the NLLoc tutorial at www.alomax.free.fr/nlloc/
fm = arrivals[key]['P']['fm']
onset = arrivals[key]['P']['mpp']
year = onset.year
month = onset.month
day = onset.day
hh = onset.hour
mm = onset.minute
ss = onset.second
ms = onset.microsecond
ss_ms = ss + (ms / 1E06)
fid.write('%s ? ? ? P %s %d%02d%02d %02d%02d %7.4f GAU 0 0 0 0 1 \n' \
% (key, fm, year, month, day, hh, mm, ss_ms))
if arrivals[key]['S']['weight'] < 4:
fm = '?'
onset = arrivals[key]['S']['mpp']
year = onset.year
month = onset.month
day = onset.day
hh = onset.hour
mm = onset.minute
ss = onset.second
ms = onset.microsecond
ss_ms = ss + (ms / 1E06)
fid.write('%s ? ? ? S %s %d%02d%02d %02d%02d %7.4f GAU 0 0 0 0 1 \n' \
% (key, fm, year, month, day, hh, mm, ss_ms))
fid.close()
if __name__ == '__main__':
import doctest
doctest.testmod()
+1 -1
View File
@@ -7,7 +7,7 @@ except:
from urllib.request import urlopen
def checkurl(url='https://ariadne.geophysik.ruhr-uni-bochum.de/trac/PyLoT/'):
def checkurl(url='https://ariadne.geophysik.rub.de/trac/PyLoT'):
try:
urlopen(url, timeout=1)
return True
+36 -1
View File
@@ -5,6 +5,41 @@ from PySide.QtCore import QThread, Signal, Qt, Slot, QRunnable, QObject
from PySide.QtGui import QDialog, QProgressBar, QLabel, QHBoxLayout, QPushButton
class AutoPickThread(QThread):
message = Signal(str)
finished = Signal()
def __init__(self, parent, func, infile, fnames, eventid, savepath):
super(AutoPickThread, self).__init__()
self.setParent(parent)
self.func = func
self.infile = infile
self.fnames = fnames
self.eventid = eventid
self.savepath = savepath
def run(self):
sys.stdout = self
picks = self.func(None, None, self.infile, self.fnames, self.eventid, self.savepath)
print("Autopicking finished!\n")
try:
for station in picks:
self.parent().addPicks(station, picks[station], type='auto')
except AttributeError:
print(picks)
sys.stdout = sys.__stdout__
self.finished.emit()
def write(self, text):
self.message.emit(text)
def flush(self):
pass
class Thread(QThread):
message = Signal(str)
@@ -96,6 +131,7 @@ class Worker(QRunnable):
try:
result = self.fun(self.args)
except:
#traceback.print_exc()
exctype, value = sys.exc_info ()[:2]
print(exctype, value, traceback.format_exc())
self.signals.error.emit ((exctype, value, traceback.format_exc ()))
@@ -103,7 +139,6 @@ class Worker(QRunnable):
self.signals.result.emit(result)
finally:
self.signals.finished.emit('Done')
sys.stdout = sys.__stdout__
def write(self, text):
self.signals.message.emit(text)
+31 -22
View File
@@ -14,7 +14,6 @@ from obspy.signal.rotate import rotate2zne
from obspy.io.xseed.utils import SEEDParserException
from pylot.core.io.inputs import PylotParameter
from pylot.styles import style_settings
from scipy.interpolate import splrep, splev
from PySide import QtCore, QtGui
@@ -22,7 +21,7 @@ from PySide import QtCore, QtGui
try:
import pyqtgraph as pg
except Exception as e:
print('PyLoT: Could not import pyqtgraph. {}'.format(e))
print('QtPyLoT: Could not import pyqtgraph. {}'.format(e))
pg = None
def _pickle_method(m):
@@ -72,8 +71,6 @@ def gen_Pool(ncores=0):
if ncores == 0:
ncores = multiprocessing.cpu_count()
print('gen_Pool: Generated multiprocessing Pool with {} cores\n'.format(ncores))
pool = multiprocessing.Pool(ncores)
return pool
@@ -580,22 +577,36 @@ def modify_rgba(rgba, modifier, intensity):
def base_phase_colors(picktype, phase):
phasecolors = style_settings.phasecolors
return phasecolors[picktype][phase]
phases = {
'manual':
{
'P':
{
'rgba': (0, 0, 255, 255),
'modifier': 'g'
},
'S':
{
'rgba': (255, 0, 0, 255),
'modifier': 'b'
}
},
'auto':
{
'P':
{
'rgba': (140, 0, 255, 255),
'modifier': 'g'
},
'S':
{
'rgba': (255, 140, 0, 255),
'modifier': 'b'
}
}
}
return phases[picktype][phase]
def transform_colors_mpl_str(colors, no_alpha=False):
colors = list(colors)
colors_mpl = tuple([color / 255. for color in colors])
if no_alpha:
colors_mpl = '({}, {}, {})'.format(*colors_mpl)
else:
colors_mpl = '({}, {}, {}, {})'.format(*colors_mpl)
return colors_mpl
def transform_colors_mpl(colors):
colors = list(colors)
colors_mpl = tuple([color / 255. for color in colors])
return colors_mpl
def remove_underscores(data):
"""
@@ -691,7 +702,7 @@ def get_stations(data):
return stations
def check4rotated(data, metadata=None, verbosity=1):
def check4rotated(data, metadata=None):
def rotate_components(wfstream, metadata=None):
"""rotates components if orientation code is numeric.
@@ -700,13 +711,11 @@ def check4rotated(data, metadata=None, verbosity=1):
# indexing fails if metadata is None
metadata[0]
except:
if verbosity:
msg = 'Warning: could not rotate traces since no metadata was given\nset Inventory file!'
print(msg)
return wfstream
if metadata[0] is None:
# sometimes metadata is (None, (None,))
if verbosity:
msg = 'Warning: could not rotate traces since no metadata was given\nCheck inventory directory!'
print(msg)
return wfstream
+154 -249
View File
@@ -16,6 +16,11 @@ import time
import numpy as np
try:
import pyqtgraph as pg
except:
pg = None
from matplotlib.figure import Figure
from pylot.core.util.utils import find_horizontals, identifyPhase, loopIdentifyPhase, trim_station_components, \
identifyPhaseID, check4rotated
@@ -48,18 +53,23 @@ from pylot.core.pick.compare import Comparison
from pylot.core.util.defaults import OUTPUTFORMATS, FILTERDEFAULTS, \
SetChannelComponents
from pylot.core.util.utils import prepTimeAxis, full_range, scaleWFData, \
demeanTrace, isSorted, findComboBoxIndex, clims, pick_linestyle_plt, pick_color_plt, \
check4rotated, check4doubled, check4gaps, remove_underscores
demeanTrace, isSorted, findComboBoxIndex, clims, pick_linestyle_plt, pick_color_plt
from autoPyLoT import autoPyLoT
from pylot.core.util.thread import Thread
if sys.version_info.major == 3:
import icons_rc_3 as icons_rc
pass
elif sys.version_info.major == 2:
import icons_rc_2 as icons_rc
pass
else:
raise ImportError('Could not determine python version.')
if pg:
pg.setConfigOption('background', 'w')
pg.setConfigOption('foreground', 'k')
pg.setConfigOptions(antialias=True)
# pg.setConfigOption('leftButtonPan', False)
def getDataType(parent):
type = QInputDialog().getItem(parent, "Select phases type", "Type:",
@@ -89,7 +99,6 @@ def plot_pdf(_axes, x, y, annotation, bbox_props, xlabel=None, ylabel=None,
_axes.set_ylabel(ylabel)
_anno = _axes.annotate(annotation, xy=(.05, .5), xycoords='axes fraction')
_anno.set_bbox(bbox_props)
_anno.draggable()
return _axes
@@ -263,11 +272,9 @@ class ComparisonWidget(QWidget):
_gs = gridspec.GridSpec(3, 2)
self.clf()
self.canvas.figure._tight = True
_axes = self.canvas.figure.add_subplot(_gs[0:2, :])
_ax1 = self.canvas.figure.add_subplot(_gs[2, 0])
_ax2 = self.canvas.figure.add_subplot(_gs[2, 1])
self.canvas.figure.tight_layout()
# _axes.cla()
station = self.plotprops['station']
@@ -340,7 +347,6 @@ class ComparisonWidget(QWidget):
if wname != name:
self.widgets[wname].setEnabled(False)
self.canvas.figure.clf()
self.canvas.figure._tight = True
_axPstd, _axPexp = self.canvas.figure.add_subplot(221), self.canvas.figure.add_subplot(223)
_axSstd, _axSexp = self.canvas.figure.add_subplot(222), self.canvas.figure.add_subplot(224)
axes_dict = dict(P=dict(std=_axPstd, exp=_axPexp),
@@ -362,26 +368,16 @@ class ComparisonWidget(QWidget):
"number of samples: {nsamples}".format(phase=phase, nsamples=len(std))
_anno_std = axes_dict[phase]['std'].annotate(std_annotation, xy=(.05, .8), xycoords='axes fraction')
_anno_std.set_bbox(bbox_props)
_anno_std.draggable()
exp_annotation = "Distribution curve for {phase} differences'\n" \
"expectations (all stations)\n" \
"number of samples: {nsamples}".format(phase=phase, nsamples=len(exp))
_anno_exp = axes_dict[phase]['exp'].annotate(exp_annotation, xy=(.05, .8), xycoords='axes fraction')
_anno_exp.set_bbox(bbox_props)
_anno_exp.draggable()
axes_dict[phase]['exp'].set_xlabel('Time [s]')
# add colors (early, late) for expectation
ax = axes_dict[phase]['exp']
xlims = ax.get_xlim()
ylims = ax.get_ylim()
ax.fill_between([xlims[0], 0], ylims[0], ylims[1], color=(0.9, 1.0, 0.9, 0.5), label='earlier than manual')
ax.fill_between([0, xlims[1]], ylims[0], ylims[1], color=(1.0, 0.9, 0.9, 0.5), label='later than manual')
legend = ax.legend()
legend.draggable()
axes_dict[phase]['exp'].set_xlabel('expectation [s]')
axes_dict[phase]['std'].set_xlabel('standard deviation [s]')
for ax in axes_dict['P'].values():
ax.set_ylabel('Frequency [-]')
ax.set_ylabel('number of picks [-]')
self.canvas.draw()
else:
@@ -439,32 +435,29 @@ class PlotWidget(FigureCanvas):
class WaveformWidgetPG(QtGui.QWidget):
def __init__(self, parent, title='Title'):
QtGui.QWidget.__init__(self, parent=parent)
self.pg = self.parent().pg
# added because adding widget to scrollArea will set scrollArea to parent
self.orig_parent = parent
def __init__(self, parent=None, xlabel='x', ylabel='y', title='Title'):
QtGui.QWidget.__init__(self, parent) # , 1)
self.setParent(parent)
self._parent = parent
# attribute plotdict is a dictionary connecting position and a name
self.plotdict = dict()
# create plot
self.main_layout = QtGui.QVBoxLayout()
self.label = QtGui.QLabel()
self.setLayout(self.main_layout)
self.plotWidget = self.pg.PlotWidget(self.parent(), title=title, autoDownsample=True)
self.plotWidget = pg.PlotWidget(title=title, autoDownsample=True)
self.main_layout.addWidget(self.plotWidget)
self.main_layout.addWidget(self.label)
self.plotWidget.showGrid(x=False, y=True, alpha=0.3)
self.plotWidget.showGrid(x=False, y=True, alpha=0.2)
self.plotWidget.hideAxis('bottom')
self.plotWidget.hideAxis('left')
self.wfstart, self.wfend = 0, 0
self.pen_multicursor = self.pg.mkPen(self.parent()._style['multicursor']['rgba'])
self.pen_linecolor = self.pg.mkPen(self.parent()._style['linecolor']['rgba'])
self.reinitMoveProxy()
self._proxy = self.pg.SignalProxy(self.plotWidget.scene().sigMouseMoved, rateLimit=60, slot=self.mouseMoved)
self._proxy = pg.SignalProxy(self.plotWidget.scene().sigMouseMoved, rateLimit=60, slot=self.mouseMoved)
def reinitMoveProxy(self):
self.vLine = self.pg.InfiniteLine(angle=90, movable=False, pen=self.pen_multicursor)
self.hLine = self.pg.InfiniteLine(angle=0, movable=False, pen=self.pen_multicursor)
self.vLine = pg.InfiniteLine(angle=90, movable=False)
self.hLine = pg.InfiniteLine(angle=0, movable=False)
self.plotWidget.addItem(self.vLine, ignoreBounds=True)
self.plotWidget.addItem(self.hLine, ignoreBounds=True)
@@ -474,10 +467,10 @@ class WaveformWidgetPG(QtGui.QWidget):
mousePoint = self.plotWidget.getPlotItem().vb.mapSceneToView(pos)
x, y, = (mousePoint.x(), mousePoint.y())
# if x > 0:# and index < len(data1):
wfID = self.orig_parent.getWFID(y)
station = self.orig_parent.getStationName(wfID)
wfID = self._parent.getWFID(y)
station = self._parent.getStationName(wfID)
abstime = self.wfstart + x
if self.orig_parent.get_current_event():
if self._parent.get_current_event():
self.label.setText("station = {}, T = {}, t = {} [s]".format(station, abstime, x))
self.vLine.setPos(mousePoint.x())
self.hLine.setPos(mousePoint.y())
@@ -491,6 +484,12 @@ class WaveformWidgetPG(QtGui.QWidget):
def clearPlotDict(self):
self.plotdict = dict()
def getParent(self):
return self._parent
def setParent(self, parent):
self._parent = parent
def plotWFData(self, wfdata, title=None, zoomx=None, zoomy=None,
noiselevel=None, scaleddata=False, mapping=True,
component='*', nth_sample=1, iniPick=None, verbosity=0):
@@ -611,6 +610,7 @@ class WaveformWidgetPG(QtGui.QWidget):
class PylotCanvas(FigureCanvas):
def __init__(self, figure=None, parent=None, connect_events=True, multicursor=False,
panZoomX=True, panZoomY=True):
self._parent = parent
if not figure:
figure = Figure()
# create axes
@@ -618,19 +618,17 @@ class PylotCanvas(FigureCanvas):
self.axes = figure.axes
self.figure = figure
self.figure.set_facecolor(parent._style['background']['rgba_mpl'])
self.figure.set_facecolor((1., 1., 1.))
# attribute plotdict is a dictionary connecting position and a name
self.plotdict = dict()
# initialize super class
super(PylotCanvas, self).__init__(self.figure)
self.setParent(parent)
self.orig_parent = parent
if multicursor:
# add a cursor for station selection
self.multiCursor = MultiCursor(self.figure.canvas, self.axes,
horizOn=True, useblit=True,
color=parent._style['multicursor']['rgba_mpl'], lw=1)
color='m', lw=1)
# initialize panning attributes
self.press = None
@@ -745,7 +743,7 @@ class PylotCanvas(FigureCanvas):
def saveFigure(self):
if self.figure:
fd = QtGui.QFileDialog()
fname, filter = fd.getSaveFileName(self.parent(), filter='Images (*.png)')
fname, filter = fd.getSaveFileName(self._parent, filter='Images (*.png)')
if not fname:
return
if not fname.endswith('.png'):
@@ -886,6 +884,12 @@ class PylotCanvas(FigureCanvas):
def clearPlotDict(self):
self.plotdict = dict()
def getParent(self):
return self._parent
def setParent(self, parent):
self._parent = parent
def plotWFData(self, wfdata, title=None, zoomx=None, zoomy=None,
noiselevel=None, scaleddata=False, mapping=True,
component='*', nth_sample=1, iniPick=None, verbosity=0):
@@ -918,9 +922,6 @@ class PylotCanvas(FigureCanvas):
nsc.sort()
nsc.reverse()
style = self.orig_parent._style
linecolor = style['linecolor']['rgba_mpl']
for n, (network, station, channel) in enumerate(nsc):
st = st_select.select(network=network, station=station, channel=channel)
trace = st[0]
@@ -941,13 +942,11 @@ class PylotCanvas(FigureCanvas):
trace.normalize(np.max(np.abs(trace.data)) * 2)
times = [time for index, time in enumerate(time_ax) if not index % nth_sample]
data = [datum + n for index, datum in enumerate(trace.data) if not index % nth_sample]
ax.plot(times, data, color=linecolor, linewidth=0.7)
ax.plot(times, data, 'k', linewidth=0.7)
if noiselevel is not None:
for level in noiselevel:
ax.plot([time_ax[0], time_ax[-1]],
[level, level],
color = linecolor,
linestyle = 'dashed')
[level, level], '--k')
self.setPlotDict(n, (station, channel, network))
if iniPick:
ax.vlines(iniPick, ax.get_ylim()[0], ax.get_ylim()[1],
@@ -1110,8 +1109,7 @@ class PickDlg(QDialog):
def __init__(self, parent=None, data=None, station=None, network=None, picks=None,
autopicks=None, rotate=False, parameter=None, embedded=False, metadata=None,
event=None, filteroptions=None, model='iasp91'):
super(PickDlg, self).__init__(parent, 1)
self.orig_parent = parent
super(PickDlg, self).__init__(parent)
# initialize attributes
self.parameter = parameter
@@ -1131,7 +1129,6 @@ class PickDlg(QDialog):
pylot_user = getpass.getuser()
self._user = settings.value('user/Login', pylot_user)
self._dirty = False
self._style = parent._style
if picks:
self.picks = copy.deepcopy(picks)
self._init_picks = picks
@@ -1270,8 +1267,8 @@ class PickDlg(QDialog):
self.plot_arrivals_button.setCheckable(True)
# create accept/reject button
self.accept_button = QPushButton('&Accept')
self.reject_button = QPushButton('&Reject')
self.accept_button = QPushButton('&Accept Picks')
self.reject_button = QPushButton('&Reject Picks')
self.disable_ar_buttons()
# add hotkeys
@@ -1295,20 +1292,10 @@ class PickDlg(QDialog):
_dialtoolbar.addSeparator()
_dialtoolbar.addAction(self.resetPicksAction)
if self._embedded:
manu_label = QLabel('Manual Onsets:')
manu_label.setStyleSheet('QLabel {'
'padding:2px;'
'padding-left:5px}')
_dialtoolbar.addWidget(manu_label)
_dialtoolbar.addWidget(self.accept_button)
_dialtoolbar.addWidget(self.reject_button)
else:
_dialtoolbar.addWidget(self.nextStation)
est_label = QLabel('Estimated onsets:')
est_label.setStyleSheet('QLabel {'
'padding:2px;'
'padding-left:5px}')
_dialtoolbar.addWidget(est_label)
_dialtoolbar.addWidget(self.plot_arrivals_button)
# layout the innermost widget
@@ -1410,7 +1397,7 @@ class PickDlg(QDialog):
return
ax = self.multicompfig.axes[0]
if not textOnly:
ylims = self.getGlobalLimits(ax, 'y')
ylims = self.getGlobalLimits('y')
else:
ylims = self.multicompfig.getYLims(ax)
stime = self.getStartTime()
@@ -1538,46 +1525,36 @@ class PickDlg(QDialog):
self.leave_picking_mode()
def init_p_pick(self):
self.set_button_border_color(self.p_button, 'yellow')
self.set_button_color(self.p_button, 'yellow')
self.activatePicking()
self.currentPhase = str(self.p_button.text())
def init_s_pick(self):
self.set_button_border_color(self.s_button, 'yellow')
self.set_button_color(self.s_button, 'yellow')
self.activatePicking()
self.currentPhase = str(self.s_button.text())
def getPhaseID(self, phase):
return identifyPhaseID(phase)
def set_button_border_color(self, button, color=None):
'''
Set background color of a button.
button: type = QtGui.QAbstractButton
color: type = QtGui.QColor or type = str (RGBA)
'''
def set_button_color(self, button, color=None):
if type(color) == QtGui.QColor:
button.setStyleSheet({'QPushButton{background-color:transparent}'})
palette = button.palette()
role = button.backgroundRole()
palette.setColor(role, color)
button.setPalette(palette)
button.setAutoFillBackground(True)
elif type(color) == str:
button.setStyleSheet('QPushButton{border-color: %s}' % color)
elif type(color) == tuple:
button.setStyleSheet('QPushButton{border-color: rgba%s}' % str(color))
elif not color:
button.setStyleSheet(self.orig_parent._style['stylesheet'])
elif type(color) == str or not color:
button.setStyleSheet("background-color: {}".format(color))
def reset_p_button(self):
self.set_button_border_color(self.p_button)
self.set_button_color(self.p_button)
self.p_button.setEnabled(True)
self.p_button.setChecked(False)
self.p_button.setText('P')
def reset_s_button(self):
self.set_button_border_color(self.s_button)
self.set_button_color(self.s_button)
self.s_button.setEnabled(True)
self.s_button.setChecked(False)
self.s_button.setText('S')
@@ -1627,7 +1604,6 @@ class PickDlg(QDialog):
return self.station
def getChannelID(self, key):
if key < 0: key = 0
return self.multicompfig.getPlotDict()[int(key)][1]
def getTraceID(self, channels):
@@ -1662,8 +1638,8 @@ class PickDlg(QDialog):
def setYLims(self, limits):
self.cur_ylim = limits
def getGlobalLimits(self, ax, axis):
return self.multicompfig.getGlobalLimits(ax, axis)
def getGlobalLimits(self, axis):
return self.multicompfig.getGlobalLimits(axis)
def getWFData(self):
return self.data
@@ -1717,10 +1693,10 @@ class PickDlg(QDialog):
self.cidpress = self.multicompfig.connectPressEvent(self.setPick)
if self.getPhaseID(self.currentPhase) == 'P':
self.set_button_border_color(self.p_button, 'green')
self.set_button_color(self.p_button, 'green')
self.setIniPickP(gui_event, wfdata, trace_number)
elif self.getPhaseID(self.currentPhase) == 'S':
self.set_button_border_color(self.s_button, 'green')
self.set_button_color(self.s_button, 'green')
self.setIniPickS(gui_event, wfdata)
self.zoomAction.setEnabled(False)
@@ -1955,14 +1931,13 @@ class PickDlg(QDialog):
self.drawPicks(picktype='manual')
self.drawPicks(picktype='auto')
def drawPicks(self, phase=None, picktype='manual', textOnly=False, picks=None):
def drawPicks(self, phase=None, picktype='manual', textOnly=False):
# plotting picks
ax = self.multicompfig.axes[0]
if not textOnly:
ylims = self.multicompfig.getGlobalLimits(ax, 'y')
else:
ylims = ax.get_ylim()
if not picks:
if self.getPicks(picktype):
if phase is not None and not phase == 'SPt':
if (type(self.getPicks(picktype)[phase]) is dict
@@ -2260,20 +2235,9 @@ class MultiEventWidget(QWidget):
self.start_button = QtGui.QPushButton('Start')
for index, (key, func, color) in enumerate(self.options):
for index, (key, func) in enumerate(self.options):
rb = QtGui.QRadioButton(key)
rb.toggled.connect(self.check_rb_selection)
if color:
color = 'rgba{}'.format(color)
else:
color = 'transparent'
rb.setStyleSheet('QRadioButton{'
'background-color: %s;'
'border-style:outset;'
'border-width:1px;'
'border-radius:5px;'
'padding:5px;'
'}' % str(color))
if index == 0:
rb.setChecked(True)
self.rb_dict[key] = rb
@@ -2288,7 +2252,7 @@ class MultiEventWidget(QWidget):
self.main_layout.insertLayout(0, self.rb_layout)
def refresh_tooltips(self):
for key, func, color in self.options:
for key, func in self.options:
eventlist = func()
if not type(eventlist) == list:
eventlist = [eventlist]
@@ -2324,7 +2288,6 @@ class AutoPickWidget(MultiEventWidget):
def __init__(self, parent, options):
MultiEventWidget.__init__(self, options, parent, 1)
self.events2plot = {}
self.connect_buttons()
self.init_plot_layout()
self.init_log_layout()
@@ -2392,9 +2355,6 @@ class AutoPickWidget(MultiEventWidget):
self.main_layout.setStretch(1, 1)
def reinitEvents2plot(self):
for eventID, eventDict in self.events2plot.items():
for widget_key, widget in eventDict.items():
widget.setParent(None)
self.events2plot = {}
self.eventbox.clear()
self.refresh_plot_tabs()
@@ -2473,18 +2433,17 @@ class TuneAutopicker(QWidget):
QWidget used to modifiy and test picking parameters for autopicking algorithm.
:param: parent
:type: PyLoT Mainwindow
:type: QtPyLoT Mainwindow
'''
def __init__(self, parent):
QtGui.QWidget.__init__(self, parent, 1)
self._style = parent._style
self.parent = parent
self.setParent(parent)
self.setWindowTitle('PyLoT - Tune Autopicker')
self.parameter = self.parent()._inputs
self.fig_dict = self.parent().fig_dict
self.parameter = parent._inputs
self.set_fig_dict(parent.fig_dict)
self.data = Data()
self.pdlg_widget = None
self.pylot_picks = None
self.init_main_layouts()
self.init_eventlist()
self.init_figure_tabs()
@@ -2496,9 +2455,8 @@ class TuneAutopicker(QWidget):
self.add_log()
self.set_stretch()
self.resize(1280, 720)
self._manual_pick_plots = []
if hasattr(self.parent(), 'metadata'):
self.metadata = self.parent().metadata
if hasattr(parent, 'metadata'):
self.metadata = self.parent.metadata
else:
self.metadata = None
# self.setWindowModality(QtCore.Qt.WindowModality.ApplicationModal)
@@ -2506,7 +2464,6 @@ class TuneAutopicker(QWidget):
def set_fig_dict(self, fig_dict):
for key, value in fig_dict.items():
if key is not 'mainFig':
value._tight = True
self.fig_dict = fig_dict
@@ -2521,7 +2478,7 @@ class TuneAutopicker(QWidget):
self.setLayout(self.main_layout)
def init_eventlist(self):
self.eventBox = self.parent().createEventBox()
self.eventBox = self.parent.createEventBox()
self.eventBox.setMaxVisibleItems(20)
self.fill_eventbox()
self.trace_layout.addWidget(self.eventBox)
@@ -2540,18 +2497,13 @@ class TuneAutopicker(QWidget):
self.stationBox.activated.connect(self.fill_tabs)
def fill_stationbox(self):
fnames = self.parent().getWFFnames_from_eventbox(eventbox=self.eventBox)
fnames = self.parent.getWFFnames_from_eventbox(eventbox=self.eventBox)
self.data.setWFData(fnames)
wfdat = self.data.getWFData() # all available streams
# remove possible underscores in station names
wfdat = remove_underscores(wfdat)
# rotate misaligned stations to ZNE
# check for gaps and doubled channels
check4gaps(wfdat)
check4doubled(wfdat)
wfdat = check4rotated(wfdat, self.parent().metadata, verbosity=0)
# trim station components to same start value
trim_station_components(wfdat, trim_start=True, trim_end=False)
# rotate misaligned stations to ZNE
wfdat = check4rotated(wfdat, self.parent.metadata)
self.stationBox.clear()
stations = []
for trace in self.data.getWFData():
@@ -2565,7 +2517,7 @@ class TuneAutopicker(QWidget):
for network, station in stations:
item = QtGui.QStandardItem(network + '.' + station)
if station in self.get_current_event().pylot_picks:
item.setBackground(self.parent()._ref_test_colors['ref'])
item.setBackground(self.parent._colors['ref'])
model.appendRow(item)
def init_figure_tabs(self):
@@ -2580,7 +2532,7 @@ class TuneAutopicker(QWidget):
self.stb_names = ['aicARHfig', 'refSpick', 'el_S1pick', 'el_S2pick']
def add_parameters(self):
self.paraBox = PylotParaBox(self.parameter, parent=self, windowflag=0)
self.paraBox = PylotParaBox(self.parameter)
self.paraBox.set_tune_mode(True)
self.update_eventID()
self.parameter_layout.addWidget(self.paraBox)
@@ -2589,7 +2541,6 @@ class TuneAutopicker(QWidget):
def add_buttons(self):
self.pick_button = QtGui.QPushButton('Pick Trace')
self.pick_button.setStyleSheet('QPushButton{border-color: rgba(110, 200, 0, 255)}')
self.pick_button.clicked.connect(self.call_picker)
self.close_button = QtGui.QPushButton('Close')
self.close_button.clicked.connect(self.hide)
@@ -2607,7 +2558,7 @@ class TuneAutopicker(QWidget):
def get_current_event(self):
path = self.eventBox.currentText()
return self.parent().project.getEventFromPath(path)
return self.parent.project.getEventFromPath(path)
def get_current_event_name(self):
return self.eventBox.currentText().split('/')[-1]
@@ -2623,7 +2574,10 @@ class TuneAutopicker(QWidget):
def get_current_event_autopicks(self, station):
event = self.get_current_event()
if event.pylot_autopicks:
if station in event.pylot_autopicks:
return event.pylot_autopicks[station]
else:
return
def get_current_station(self):
return str(self.stationBox.currentText()).split('.')[-1]
@@ -2632,66 +2586,51 @@ class TuneAutopicker(QWidget):
widget = QtGui.QWidget()
v_layout = QtGui.QVBoxLayout()
v_layout.addWidget(canvas)
v_layout.addWidget(NavigationToolbar2QT(canvas, self))
widget.setLayout(v_layout)
return widget
def gen_pick_dlg(self):
if not self.get_current_event():
if self.pdlg_widget:
self.pdlg_widget.setParent(None)
self.pdlg_widget = None
self.pickDlg = None
return
station = self.get_current_station()
data = self.data.getWFData()
metadata = self.parent().metadata
metadata = self.parent.metadata
event = self.get_current_event()
filteroptions = self.parent().filteroptions
self.pickDlg = PickDlg(self, data=data.select(station=station),
filteroptions = self.parent.filteroptions
pickDlg = PickDlg(self, data=data.select(station=station),
station=station, parameter=self.parameter,
picks=self.get_current_event_picks(station),
autopicks=self.get_current_event_autopicks(station),
metadata=metadata, event=event, filteroptions=filteroptions,
embedded=True)
self.pickDlg.update_picks.connect(self.picks_from_pickdlg)
self.pickDlg.update_picks.connect(self.fill_eventbox)
self.pickDlg.update_picks.connect(self.fill_stationbox)
self.pickDlg.update_picks.connect(lambda: self.parent().setDirty(True))
self.pickDlg.update_picks.connect(self.parent().enableSaveEventAction)
self.pickDlg.update_picks.connect(self.plot_manual_picks_to_figs)
self.pdlg_widget = QtGui.QWidget(self)
pickDlg.update_picks.connect(self.picks_from_pickdlg)
pickDlg.update_picks.connect(self.fill_eventbox)
pickDlg.update_picks.connect(self.fill_stationbox)
pickDlg.update_picks.connect(lambda: self.parent.setDirty(True))
pickDlg.update_picks.connect(self.parent.enableSaveEventAction)
self.pickDlg = QtGui.QWidget()
hl = QtGui.QHBoxLayout()
self.pdlg_widget.setLayout(hl)
hl.addWidget(self.pickDlg)
self.pickDlg.setLayout(hl)
hl.addWidget(pickDlg)
def picks_from_pickdlg(self, picks=None):
station = self.get_current_station()
replot = self.parent().addPicks(station, picks)
replot = self.parent.addPicks(station, picks)
self.get_current_event().setPick(station, picks)
if self.get_current_event() == self.parent().get_current_event():
if self.get_current_event() == self.parent.get_current_event():
if replot:
self.parent().plotWaveformDataThread()
self.parent().drawPicks()
self.parent.plotWaveformDataThread()
self.parent.drawPicks()
else:
self.parent().drawPicks(station)
self.parent().draw()
def clear_plotitem(self, plotitem):
if type(plotitem) == list:
for item in plotitem:
self.clear_plotitem(item)
return
try:
plotitem.remove()
except Exception as e:
print('Warning could not remove item {}: {}'.format(plotitem, e))
self.parent.drawPicks(station)
self.parent.draw()
def plot_manual_picks_to_figs(self):
picks = self.get_current_event_picks(self.get_current_station())
if not picks:
return
for plotitem in self._manual_pick_plots:
self.clear_plotitem(plotitem)
self._manual_pick_plots = []
st = self.data.getWFData()
tr = st.select(station=self.get_current_station())[0]
starttime = tr.stats.starttime
@@ -2710,48 +2649,47 @@ class TuneAutopicker(QWidget):
('refSpick', 0),
('el_S1pick', 0),
('el_S2pick', 0)]
qualityPpick = getQualityFromUncertainty(picks['P']['spe'], self.parameter['timeerrorsP'])
qualitySpick = getQualityFromUncertainty(picks['S']['spe'], self.parameter['timeerrorsS'])
for p_ax in p_axes:
axes = self.parent().fig_dict[p_ax[0]].axes
axes = self.parent.fig_dict[p_ax[0]].axes
if not axes:
continue
ax = axes[p_ax[1]]
self.plot_manual_pick_to_ax(ax=ax, picks=picks, phase='P',
starttime=starttime, quality=qualityPpick)
self.plot_manual_Ppick_to_ax(ax, (picks['P']['mpp'] - starttime))
for s_ax in s_axes:
axes = self.parent().fig_dict[s_ax[0]].axes
axes = self.parent.fig_dict[s_ax[0]].axes
if not axes:
continue
ax = axes[s_ax[1]]
self.plot_manual_pick_to_ax(ax=ax, picks=picks, phase='S',
starttime=starttime, quality=qualitySpick)
for canvas in self.parent().canvas_dict.values():
canvas.draw()
def plot_manual_pick_to_ax(self, ax, picks, phase, starttime, quality):
mpp = picks[phase]['mpp'] - starttime
color = pick_color_plt('manual', phase, quality)
self.plot_manual_Spick_to_ax(ax, (picks['S']['mpp'] - starttime))
def plot_manual_Ppick_to_ax(self, ax, pick):
y_top = 0.9 * ax.get_ylim()[1]
y_bot = 0.9 * ax.get_ylim()[0]
self._manual_pick_plots.append(ax.vlines(mpp, y_bot, y_top,
color=color, linewidth=2,
label='manual {} Onset (quality: {})'.format(phase, quality)))
self._manual_pick_plots.append(ax.plot([mpp - 0.5, mpp + 0.5],
[y_bot, y_bot], linewidth=2,
color=color))
self._manual_pick_plots.append(ax.plot([mpp - 0.5, mpp + 0.5],
[y_top, y_top], linewidth=2,
color=color))
ax.vlines(pick, y_bot, y_top,
color='teal', linewidth=2, label='manual P Onset')
ax.plot([pick - 0.5, pick + 0.5],
[y_bot, y_bot], linewidth=2, color='teal')
ax.plot([pick - 0.5, pick + 0.5],
[y_top, y_top], linewidth=2, color='teal')
ax.legend(loc=1)
def plot_manual_Spick_to_ax(self, ax, pick):
y_top = 0.9 * ax.get_ylim()[1]
y_bot = 0.9 * ax.get_ylim()[0]
ax.vlines(pick, y_bot, y_top,
color='magenta', linewidth=2, label='manual S Onset')
ax.plot([pick - 0.5, pick + 0.5],
[y_bot, y_bot], linewidth=2, color='magenta')
ax.plot([pick - 0.5, pick + 0.5],
[y_top, y_top], linewidth=2, color='magenta')
ax.legend(loc=1)
def fill_tabs(self, event=None, picked=False):
self.clear_all()
canvas_dict = self.parent.canvas_dict
self.gen_pick_dlg()
canvas_dict = self.parent().canvas_dict
self.overview = self.gen_tab_widget('Overview', canvas_dict['mainFig'])
id0 = self.figure_tabs.insertTab(0, self.pdlg_widget, 'Traces Plot')
id0 = self.figure_tabs.insertTab(0, self.pickDlg, 'Traces Plot')
id1 = self.figure_tabs.insertTab(1, self.overview, 'Overview')
id2 = self.figure_tabs.insertTab(2, self.p_tabs, 'P')
id3 = self.figure_tabs.insertTab(3, self.s_tabs, 'S')
@@ -2794,12 +2732,12 @@ class TuneAutopicker(QWidget):
self.init_tab_names()
def fill_eventbox(self):
project = self.parent().project
project = self.parent.project
if not project:
return
# update own list
self.parent().fill_eventbox(eventBox=self.eventBox, select_events='ref')
index_start = self.parent().eventBox.currentIndex()
self.parent.fill_eventbox(eventBox=self.eventBox, select_events='ref')
index_start = self.parent.eventBox.currentIndex()
index = index_start
if index == -1:
index += 1
@@ -2818,7 +2756,7 @@ class TuneAutopicker(QWidget):
if not index == index_start:
self.eventBox.activated.emit(index)
# update parent
self.parent().fill_eventbox()
self.parent.fill_eventbox()
def update_eventID(self):
self.paraBox.boxes['eventID'].setText(
@@ -2840,7 +2778,6 @@ class TuneAutopicker(QWidget):
'locflag': 0,
'savexml': False}
for key in self.fig_dict.keys():
if not key == 'plot_style':
self.fig_dict[key].clear()
self.ap_thread = Thread(self, autoPyLoT, arg=args,
progressText='Picking trace...',
@@ -2882,8 +2819,8 @@ class TuneAutopicker(QWidget):
def params_from_gui(self):
parameters = self.paraBox.params_from_gui()
if self.parent():
self.parent()._inputs = parameters
if self.parent:
self.parent._inputs = parameters
return parameters
def set_stretch(self):
@@ -2891,11 +2828,10 @@ class TuneAutopicker(QWidget):
self.tune_layout.setStretch(1, 1)
def clear_all(self):
if hasattr(self, 'pdlg_widget'):
if self.pdlg_widget:
self.pdlg_widget.setParent(None)
# TODO: removing widget by parent deletion raises exception when activating stationbox:
# RuntimeError: Internal C++ object (PylotCanvas) already deleted.
if hasattr(self, 'pickDlg'):
if self.pickDlg:
self.pickDlg.setParent(None)
del (self.pickDlg)
if hasattr(self, 'overview'):
self.overview.setParent(None)
if hasattr(self, 'p_tabs'):
@@ -2924,7 +2860,7 @@ class PylotParaBox(QtGui.QWidget):
accepted = QtCore.Signal(str)
rejected = QtCore.Signal(str)
def __init__(self, parameter, parent=None, windowflag=1):
def __init__(self, parameter, parent=None):
'''
Generate Widget containing parameters for PyLoT.
@@ -2932,7 +2868,7 @@ class PylotParaBox(QtGui.QWidget):
:type: PylotParameter (object)
'''
QtGui.QWidget.__init__(self, parent, windowflag)
QtGui.QWidget.__init__(self, parent)
self.parameter = parameter
self.tabs = QtGui.QTabWidget()
self.layout = QtGui.QVBoxLayout()
@@ -3475,6 +3411,9 @@ class SubmitLocal(QWidget):
self.main_layout.addWidget(self.button)
def start(self):
print('subprocess Popen')
def start(self, pp_export, ncores):
self.execute_command(pp_export, ncores)
@@ -3494,7 +3433,6 @@ class SubmitLocal(QWidget):
class PropertiesDlg(QDialog):
def __init__(self, parent=None, infile=None, inputs=None):
super(PropertiesDlg, self).__init__(parent)
self._pylot_mainwindow = self.parent()
self.infile = infile
self.inputs = inputs
@@ -3795,29 +3733,14 @@ class PhasesTab(PropTab):
class GraphicsTab(PropTab):
def __init__(self, parent=None):
super(GraphicsTab, self).__init__(parent)
self.pylot_mainwindow = parent._pylot_mainwindow
self.init_layout()
self.add_pg_cb()
self.add_nth_sample()
self.add_style_settings()
self.setLayout(self.main_layout)
def init_layout(self):
self.main_layout = QGridLayout()
def add_style_settings(self):
styles = self.pylot_mainwindow._styles
active_stylename = self.pylot_mainwindow._stylename
label = QtGui.QLabel('Application style (might require Application restart):')
self.style_cb = QComboBox()
for stylename, style in styles.items():
self.style_cb.addItem(stylename, style)
index_current_style = self.style_cb.findText(active_stylename)
self.style_cb.setCurrentIndex(index_current_style)
self.main_layout.addWidget(label, 2, 0)
self.main_layout.addWidget(self.style_cb, 2, 1)
self.style_cb.activated.connect(self.set_current_style)
def add_nth_sample(self):
settings = QSettings()
nth_sample = settings.value("nth_sample")
@@ -3834,12 +3757,6 @@ class GraphicsTab(PropTab):
self.main_layout.addWidget(self.spinbox_nth_sample, 1, 1)
def add_pg_cb(self):
try:
import pyqtgraph as pg
pg = True
except:
pg = False
text = {True: 'Use pyqtgraphic library for plotting',
False: 'Cannot use library: pyqtgraphic not found on system'}
label = QLabel('PyQt graphic')
@@ -3851,10 +3768,6 @@ class GraphicsTab(PropTab):
self.main_layout.addWidget(label, 0, 0)
self.main_layout.addWidget(self.checkbox_pg, 0, 1)
def set_current_style(self):
selected_style = self.style_cb.currentText()
self.pylot_mainwindow.set_style(selected_style)
def getValues(self):
values = {'nth_sample': self.spinbox_nth_sample.value(),
'pyqtgraphic': self.checkbox_pg.isChecked()}
@@ -4302,23 +4215,15 @@ class LoadDataDlg(QDialog):
class HelpForm(QDialog):
def __init__(self, parent=None,
page=QUrl('https://ariadne.geophysik.ruhr-uni-bochum.de/trac/PyLoT/')):
super(HelpForm, self).__init__(parent, 1)
def __init__(self, page=QUrl('https://ariadne.geophysik.rub.de/trac/PyLoT'),
parent=None):
super(HelpForm, self).__init__(parent)
self.setAttribute(Qt.WA_DeleteOnClose)
self.setAttribute(Qt.WA_GroupLeader)
self.home_page = page
back_icon = QIcon()
back_icon.addPixmap(QPixmap(':/icons/back.png'))
home_icon = QIcon()
home_icon.addPixmap(QPixmap(':/icons/home.png'))
backAction = QAction(back_icon, "&Back", self)
backAction = QAction(QIcon(":/back.png"), "&Back", self)
backAction.setShortcut(QKeySequence.Back)
homeAction = QAction(home_icon, "&Home", self)
homeAction = QAction(QIcon(":/home.png"), "&Home", self)
homeAction.setShortcut("Home")
self.pageLabel = QLabel()
@@ -4331,21 +4236,21 @@ class HelpForm(QDialog):
layout = QVBoxLayout()
layout.addWidget(toolBar)
layout.addWidget(self.webBrowser)
layout.addWidget(self.webBrowser, 1)
self.setLayout(layout)
backAction.triggered.connect(self.webBrowser.back)
homeAction.triggered.connect(self.home)
self.webBrowser.urlChanged.connect(self.updatePageTitle)
self.connect(backAction, Signal("triggered()"),
self.webBrowser, Slot("backward()"))
self.connect(homeAction, Signal("triggered()"),
self.webBrowser, Slot("home()"))
self.connect(self.webBrowser, Signal("sourceChanged(QUrl)"),
self.updatePageTitle)
self.resize(1280, 720)
self.resize(400, 600)
self.setWindowTitle("{0} Help".format(QApplication.applicationName()))
def home(self):
self.webBrowser.load(self.home_page)
def updatePageTitle(self):
self.pageLabel.setText(self.webBrowser.title())
self.pageLabel.setText(self.webBrowser.documentTitle())
if __name__ == '__main__':
+319295
View File
File diff suppressed because it is too large Load Diff
+84755
View File
File diff suppressed because it is too large Load Diff
-1
View File
@@ -1 +0,0 @@
# -*- coding: utf-8 -*-
-259
View File
@@ -1,259 +0,0 @@
QMainWindow{
background-color: qlineargradient(spread:reflect, x1:0, y1:0, x2:0, y2:0.5, stop:0 rgba(230, 230, 230, 255), stop:1 rgba(255, 255, 255, 255));
color: rgba(0, 0, 0, 255);
}
QWidget{
background-color: qlineargradient(spread:pad, x1:0, y1:0, x2:0, y2:1, stop:0 rgba(235, 235, 235, 255), stop:1 rgba(230, 230, 230, 255));
color: rgba(0, 0, 0, 255);
}
QToolBar QWidget:checked{
background-color: transparent;
border-color: rgba(230, 230, 230, 255);
border-width: 2px;
border-style:inset;
}
QComboBox{
background-color: rgba(255, 255, 255, 255);
color: rgba(0, 0, 0, 255);
min-height: 1.5em;
selection-background-color: qlineargradient(spread:pad, x1:0, y1:0, x2:1, y2:0, stop:0 rgba(0, 55, 140, 150), stop:1 rgba(0, 70, 180, 150));
}
QComboBox *{
background-color: rgba(255, 255, 255, 255);
color: rgba(0, 0, 0, 255);
selection-background-color: qlineargradient(spread:pad, x1:0, y1:0, x2:1, y2:0, stop:0 rgba(0, 55, 140, 150), stop:1 rgba(0, 70, 180, 150));
selection-color: rgba(255, 255, 255, 255);
}
QMenuBar{
background-color: qlineargradient(spread:pad, x1:0, y1:0, x2:0, y2:2, stop:0 rgba(240, 240, 240, 255), stop:1 rgba(230, 230, 230, 255));
padding:1px;
}
QMenuBar::item{
background-color: qlineargradient(spread:pad, x1:0, y1:0, x2:0, y2:2, stop:0 rgba(240, 240, 240, 255), stop:1 rgba(230, 230, 230, 255));
color: rgba(0, 0, 0, 255);
padding:3px;
padding-left:5px;
padding-right:5px;
}
QMenu{
background-color: qlineargradient(spread:reflect, x1:0, y1:0, x2:0, y2:0.5, stop:0 rgba(230, 230, 230, 255), stop:1 rgba(230, 230, 230 255));
color: rgba(0, 0, 0, 255);
padding:0;
}
*::item:selected{
color: rgba(0, 0, 0, 255);
background-color: qlineargradient(spread:pad, x1:0, y1:0, x2:1, y2:0, stop:0 rgba(0, 55, 140, 150), stop:1 rgba(0, 70, 180, 150));
}
QToolBar{
background-color: qlineargradient(spread:reflect, x1:0, y1:0, x2:0, y2:0.5, stop:0 rgba(230, 230, 230, 255), stop:1 rgba(255, 255, 255, 255));
border-style:solid;
border-color:rgba(200, 200, 200, 150);
border-width:1px;
}
QToolBar *{
background-color: qlineargradient(spread:reflect, x1:0, y1:0, x2:0, y2:0.5, stop:0 rgba(230, 230, 230, 255), stop:1 rgba(255, 255, 255, 255));
}
QMessageBox{
background-color: rgba(255, 255, 255, 255);
color: rgba(0, 0, 0, 255);
}
QTableWidget{
background-color: rgba(255, 255, 255, 255);
color:rgba(0, 0, 0, 255);
border-color:rgba(0, 0, 0, 255);
selection-background-color: rgba(200, 210, 230, 255);
}
QTableCornerButton::section{
border: none;
background-color: qlineargradient(spread:pad, x1:0, y1:0, x2:1, y2:0, stop:0 rgba(255, 255, 255, 255), stop:1 rgba(230, 230, 230, 255));
}
QHeaderView::section{
background-color:qlineargradient(spread:pad, x1:0, y1:0, x2:1, y2:0, stop:0 rgba(255, 255, 255, 255), stop:1 rgba(230, 230, 230, 255));
border:none;
border-top-style:solid;
border-width:1px;
border-top-color:qlineargradient(spread:pad, x1:0, y1:0, x2:1, y2:0, stop:0 rgba(255, 255, 255, 255), stop:1 rgba(230, 230, 230, 255));
color:rgba(0, 0, 0, 255);
padding:5px;
}
QHeaderView::section:checked{
background-color:qlineargradient(spread:pad, x1:0, y1:0, x2:1, y2:0, stop:0 rgba(0, 55, 140, 150), stop:1 rgba(0, 70, 180, 150));
border-top-color:qlineargradient(spread:pad, x1:0, y1:0, x2:1, y2:0, stop:0 rgba(0, 55, 140, 150), stop:1 rgba(0, 70, 180, 150));
}
QHeaderView{
background-color:qlineargradient(spread:pad, x1:0, y1:0, x2:1, y2:0, stop:0 rgba(255, 255, 255, 255), stop:1 rgba(230, 230, 230, 255));
border:none;
border-top-style:solid;
border-width:1px;
border-top-color:rgba(230, 230, 230, 255);
color:rgba(0, 0, 0, 255);
}
QListWidget{
background-color:rgba(230, 230, 230, 255);
color:rgba(0, 0, 0, 255);
}
QStatusBar{
background-color:rgba(255, 255, 255, 255);
color:rgba(0, 0, 0, 255);
}
QPushButton{
background-color:qlineargradient(spread:reflect, x1:0, y1:0, x2:0, y2:0.5, stop:0 rgba(230, 230, 230, 255), stop:1 rgba(245, 245, 245, 255));
color:rgba(0, 0, 0, 255);
border-style: outset;
border-width: 1px;
border-color: rgba(100, 100, 120, 255);
min-width: 6em;
padding: 4px;
padding-left:5px;
padding-right:5px;
border-radius: 2px;
}
QPushButton:pressed{
background-color: rgba(230, 230, 230, 255);
border-style: inset;
}
QPushButton:checked{
background-color: rgba(230, 230, 230, 255);
border-style: inset;
}
*:disabled{
color:rgba(100, 100, 120, 255);
}
QTabBar{
background-color:transparent;
}
QTabBar::tab{
background-color:qlineargradient(spread:pad, x1:0, y1:0, x2:0, y2:1, stop:0 rgba(230, 230, 230, 255), stop:1 rgba(210, 210, 210, 255));
color: rgba(0, 0, 0, 255);
border-style:solid;
border-color:rgba(210, 210, 210 255);
border-bottom-color: transparent;
border-width:1px;
padding:5px;
}
QTabBar::tab:selected{
background-color:qlineargradient(spread:pad, x1:0, y1:0, x2:0, y2:1, stop:0 rgba(255, 255, 255, 255), stop:1 rgba(245, 245, 245, 255));
color: rgba(0, 0, 0, 255);
border-style:solid;
border-color:rgba(245, 245, 245, 255);
border-bottom-color: transparent;
border-width:1px;
padding:5px;
}
QTabBar::tab:disabled{
background-color:qlineargradient(spread:pad, x1:0, y1:0, x2:0, y2:1, stop:0 rgba(230, 230, 230, 255), stop:1 rgba(210, 210, 210, 255));
color: rgba(100, 100, 120, 255);
}
QTabWidget{
background-color:transparent;
}
QTabWidget::pane{
background-color:rgba(0, 0, 0, 255);
border-style:solid;
border-color:rgba(245, 245, 245, 255);
border-width:1px;
}
QTabWidget::tab{
background-color:rgba(255, 255, 255, 255);
}
QTabWidget > QWidget{
background-color: rgba(245, 245, 245, 255);
color: rgba(0, 0, 0, 255);
}
QScrollArea{
background: transparent;
}
QScrollArea>QWidget>QWidget{
background: transparent;
}
QLabel{
color: rgba(0, 0, 0, 255);
background-color: transparent;
}
QTextEdit{
color: rgba(0, 0, 0, 255);
background-color: rgba(255, 255, 255, 255);
}
QSpinBox{
color: rgba(0, 0, 0, 255);
background-color: rgba(255, 255, 255, 255);
}
QDoubleSpinBox{
color: rgba(0, 0, 0, 255);
background-color: rgba(255, 255, 255, 255);
}
QCheckBox{
background-color:transparent;
border:none;
}
QLineEdit{
background-color: rgba(255, 255, 255, 255);
border: 1px inset;
border-radius:0;
border-color: rgba(100, 100, 120, 255);
}
QLineEdit:disabled{
background-color: rgba(255, 255, 255, 255);
border: 1px inset;
border-radius:0;
border-color: rgba(200, 200, 200, 255);
}
QListWidget{
background-color:rgba(255, 255, 255, 255)
}
QProgressBar{
background-color:rgba(230, 230, 230, 255);
}
QProgressBar::chunk{
background-color:qlineargradient(spread:reflect, x1:0, y1:0, x2:0.5, y2:0, stop:0 transparent, stop:1 rgba(0, 70, 180, 150));
}
QStatusBar{
background-color: qlineargradient(spread:pad, x1:0, y1:0, x2:0, y2:1, stop:0 rgba(235, 235, 235, 255), stop:1 rgba(230, 230, 230, 255));
color: rgba(0, 0, 0, 255);
}
-258
View File
@@ -1,258 +0,0 @@
QMainWindow{
background-color: qlineargradient(spread:reflect, x1:0, y1:0, x2:0, y2:0.5, stop:0 rgba(70, 70, 80, 255), stop:1 rgba(60, 60, 70, 255));
color: rgba(255, 255, 255, 255);
}
QWidget{
background-color: qlineargradient(spread:reflect, x1:0, y1:0, x2:0, y2:0.5, stop:0 rgba(70, 70, 80, 255), stop:1 rgba(60, 60, 70, 255));
color: rgba(255, 255, 255, 255);
}
QToolBar QWidget:checked{
background-color: transparent;
border-color: rgba(100, 100, 120, 255);
border-width: 2px;
border-style:inset;
}
QComboBox{
background-color: rgba(90, 90, 100, 255);
color: rgba(255, 255, 255, 255);
min-height: 1.5em;
selection-background-color: qlineargradient(spread:pad, x1:0, y1:0, x2:1, y2:0, stop:0 rgba(0, 144, 180, 255), stop:1 rgba(0, 150, 190, 255));
}
QComboBox *{
background-color: rgba(90, 90, 100, 255);
color: rgba(255, 255, 255, 255);
selection-background-color: qlineargradient(spread:pad, x1:0, y1:0, x2:1, y2:0, stop:0 rgba(0, 144, 180, 255), stop:1 rgba(0, 150, 190, 255));
selection-color: rgba(255, 255, 255, 255);
}
QMenuBar{
background-color: qlineargradient(spread:pad, x1:0, y1:0, x2:0, y2:1, stop:0 rgba(70, 70, 80, 255), stop:1 rgba(60, 60, 70, 255));
padding:1px;
}
QMenuBar::item{
background-color: qlineargradient(spread:pad, x1:0, y1:0, x2:0, y2:1, stop:0 rgba(70, 70, 80, 255), stop:1 rgba(60, 60, 70, 255));
color: rgba(255, 255, 255, 255);
padding:3px;
padding-left:5px;
padding-right:5px;
}
QMenu{
background-color: qlineargradient(spread:pad, x1:0, y1:0, x2:0, y2:1, stop:0 rgba(70, 70, 80, 255), stop:1 rgba(60, 60, 70, 255));
color: rgba(255, 255, 255, 255);
padding:0;
}
*::item:selected{
color: rgba(255, 255, 255, 255);
background-color: qlineargradient(spread:pad, x1:0, y1:0, x2:1, y2:0, stop:0 rgba(0, 144, 180, 255), stop:1 rgba(0, 150, 190, 255));
}
QToolBar{
background-color: qlineargradient(spread:reflect, x1:0, y1:0, x2:0, y2:0.5, stop:0 rgba(70, 70, 80, 255), stop:1 rgba(60, 60, 70, 255));
border-style:solid;
border-color:rgba(80, 80, 90, 255);
border-width:1px;
}
QToolBar *{
background-color: qlineargradient(spread:reflect, x1:0, y1:0, x2:0, y2:0.5, stop:0 rgba(70, 70, 80, 255), stop:1 rgba(60, 60, 70, 255));
}
QMessageBox{
background-color: rgba(60, 60, 70, 255);
color: rgba(255, 255, 255, 255);
}
QTableWidget{
background-color: rgba(80, 80, 90, 255);
color:rgba(255, 255, 255, 255);
border-color:rgba(255, 255, 255, 255);
selection-background-color: rgba(200, 210, 230, 255);
}
QTableCornerButton::section{
border: none;
background-color: qlineargradient(spread:pad, x1:0, y1:0, x2:1, y2:0, stop:0 rgba(60, 60, 70, 255), stop:1 rgba(70, 70, 80, 255));
}
QHeaderView::section{
background-color:qlineargradient(spread:pad, x1:0, y1:0, x2:1, y2:0, stop:0 rgba(60, 60, 70, 255), stop:1 rgba(70, 70, 80, 255));
border:none;
border-top-style:solid;
border-width:1px;
border-top-color:qlineargradient(spread:pad, x1:0, y1:0, x2:1, y2:0, stop:0 rgba(60, 60, 70, 255), stop:1 rgba(70, 70, 80, 255));
color:rgba(255, 255, 255, 255);
padding:5px;
}
QHeaderView::section:checked{
background-color:qlineargradient(spread:pad, x1:0, y1:0, x2:1, y2:0, stop:0 rgba(0, 120, 150, 255), stop:1 rgba(0, 150, 190, 255));
border-top-color:qlineargradient(spread:pad, x1:0, y1:0, x2:1, y2:0, stop:0 rgba(0, 120, 150, 255), stop:1 rgba(0, 150, 190, 255));
}
QHeaderView{
background-color:qlineargradient(spread:pad, x1:0, y1:0, x2:1, y2:0, stop:0 rgba(60, 60, 70, 255), stop:1 rgba(70, 70, 80, 255));
border:none;
border-top-style:solid;
border-width:1px;
border-top-color:rgba(70, 70, 80, 255);
color:rgba(255, 255, 255, 255);
}
QListWidget{
background-color:rgba(200, 200, 200, 255);
color:rgba(255, 255, 255, 255);
}
QStatusBar{
background-color:rgba(60, 60, 70, 255);
color:rgba(255, 255, 255, 255);
}
QPushButton{
background-color:qlineargradient(spread:reflect, x1:0, y1:0, x2:0, y2:0.5, stop:0 rgba(70, 70, 80, 255), stop:1 rgba(60, 60, 70, 255));
color:rgba(255, 255, 255, 255);
border-style: outset;
border-width: 2px;
border-color: rgba(50, 50, 60, 255);
min-width: 6em;
padding: 4px;
padding-left:5px;
padding-right:5px;
border-radius: 2px;
}
QPushButton:pressed{
background-color: qlineargradient(spread:reflect, x1:0, y1:0, x2:0, y2:0.5, stop:0 rgba(80, 80, 90, 255), stop:1 rgba(70, 70, 80, 255));
border-style: inset;
}
QPushButton:checked{
background-color: qlineargradient(spread:reflect, x1:0, y1:0, x2:0, y2:0.5, stop:0 rgba(80, 80, 90, 255), stop:1 rgba(70, 70, 80, 255));
border-style: inset;
}
*:disabled{
color: rgba(130, 130, 130, 255);
}
QTabBar{
background-color:transparent;
}
QTabBar::tab{
background-color:qlineargradient(spread:pad, x1:0, y1:0, x2:0, y2:1, stop:0 rgba(70, 70, 80, 255), stop:1 rgba(60, 60, 70, 255));
color: rgba(255, 255, 255, 255);
border-style:solid;
border-color:rgba(70, 70, 80, 255);
border-bottom-color: transparent;
border-width:1px;
padding:5px;
}
QTabBar::tab:selected{
background-color:qlineargradient(spread:pad, x1:0, y1:0, x2:0, y2:1, stop:0 rgba(80, 80, 90, 255), stop:1 rgba(70, 70, 80, 255));
color: rgba(255, 255, 255, 255);
border-style:solid;
border-color:rgba(70, 70, 80, 255);
border-bottom-color: transparent;
border-width:1px;
padding:5px;
}
QTabBar::tab:disabled{
background-color:qlineargradient(spread:pad, x1:0, y1:0, x2:0, y2:1, stop:0 rgba(70, 70, 80, 255), stop:1 rgba(60, 60, 70, 255));
color: rgba(100, 100, 120, 255);
}
QTabWidget{
background-color:transparent;
}
QTabWidget::pane{
background-color:rgba(70, 70, 80, 255);
border-style:solid;
border-color:rgba(70, 70, 80, 255);
border-width:1px;
}
QTabWidget::tab{
background-color:rgba(70, 70, 80, 255);
}
QTabWidget > QWidget{
background-color: rgba(70, 70, 80, 255);
color: rgba(255, 255, 255, 255);
}
QScrollArea{
background: transparent;
}
QScrollArea>QWidget>QWidget{
background: transparent;
}
QLabel{
color: rgba(255, 255, 255, 255);
background-color: transparent;
}
QTextEdit{
color: rgba(255, 255, 255, 255);
background-color: rgba(90, 90, 100, 255);
}
QSpinBox{
color: rgba(255, 255, 255, 255);
background-color: rgba(90, 90, 100, 255);
}
QDoubleSpinBox{
color: rgba(255, 255, 255, 255);
background-color: rgba(90, 90, 100, 255);
}
QCheckBox{
background-color:transparent;
border:none;
}
QLineEdit{
background-color: rgba(90, 90, 100, 255);
border: 1px inset;
border-radius:0;
border-color: rgba(100, 100, 120, 255);
}
QLineEdit:disabled{
background-color: rgba(90, 90, 100, 255);
border: 1px inset;
border-radius:0;
border-color: rgba(200, 200, 200, 255);
}
QListWidget{
background-color:rgba(60, 60, 70, 255)
}
QProgressBar{
background-color:rgba(60, 60, 70, 255);
}
QProgressBar::chunk{
background-color:qlineargradient(spread:reflect, x1:0, y1:0, x2:0.5, y2:0, stop:0 transparent, stop:1 rgba(0, 150, 190, 255));
}
QStatusBar{
background-color: qlineargradient(spread:reflect, x1:0, y1:0, x2:0, y2:0.5, stop:0 rgba(70, 70, 80, 255), stop:1 rgba(60, 60, 70, 255));
color: rgba(255, 255, 255, 255);
}
-70
View File
@@ -1,70 +0,0 @@
# -*- coding: utf-8 -*-
# Set base phase colors for manual and automatic picks
# together with a modifier (r, g, or b) used to alternate
# the base color
phasecolors = {
'manual': {
'P':{
'rgba': (0, 0, 255, 255),
'modifier': 'g'},
'S':{
'rgba': (255, 0, 0, 255),
'modifier': 'b'}
},
'auto':{
'P':{
'rgba': (140, 0, 255, 255),
'modifier': 'g'},
'S':{
'rgba': (255, 140, 0, 255),
'modifier': 'b'}
}
}
# Set plot colors and stylesheet for each style
stylecolors = {
'default':{
'linecolor':{
'rgba': (0, 0, 0, 255)},
'background': {
'rgba': (255, 255, 255, 255)},
'multicursor': {
'rgba': (255, 190, 0, 255)},
'ref': {
'rgba': (200, 210, 230, 255)},
'test': {
'rgba': (200, 230, 200, 255)},
'stylesheet': {
'filename': None}
},
'dark': {
'linecolor': {
'rgba': (230, 230, 230, 255)},
'background': {
'rgba': (50, 50, 60, 255)},
'multicursor': {
'rgba': (0, 150, 190, 255)},
'ref': {
'rgba': (80, 110, 170, 255)},
'test': {
'rgba': (130, 190, 100, 255)},
'stylesheet': {
'filename': 'dark.qss'}
},
'bright': {
'linecolor': {
'rgba': (0, 0, 0, 255)},
'background': {
'rgba': (255, 255, 255, 255)},
'multicursor': {
'rgba': (100, 100, 190, 255)},
'ref': {
'rgba': (200, 210, 230, 255)},
'test': {
'rgba': (200, 230, 200, 255)},
'stylesheet': {
'filename': 'bright.qss'}
}
}
View File
+13
View File
@@ -0,0 +1,13 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import sys
from PySide.QtGui import QApplication
from pylot.core.util.widgets import HelpForm
app = QApplication(sys.argv)
win = HelpForm()
win.show()
app.exec_()
+20
View File
@@ -0,0 +1,20 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import sys
import matplotlib
matplotlib.use('Qt4Agg')
matplotlib.rcParams['backend.qt4'] = 'PySide'
from PySide.QtGui import QApplication
from obspy.core import read
from pylot.core.util.widgets import PickDlg
app = QApplication(sys.argv)
data = read()
win = PickDlg(data=data)
win.show()
app.exec_()
+13
View File
@@ -0,0 +1,13 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import sys
from PySide.QtGui import QApplication
from pylot.core.util.widgets import PropertiesDlg
app = QApplication(sys.argv)
win = PropertiesDlg()
win.show()
app.exec_()
+19
View File
@@ -0,0 +1,19 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import sys
import time
from PySide.QtGui import QApplication
from pylot.core.util.widgets import FilterOptionsDialog, PropertiesDlg, HelpForm
dialogs = [FilterOptionsDialog, PropertiesDlg, HelpForm]
app = QApplication(sys.argv)
for dlg in dialogs:
win = dlg()
win.show()
time.sleep(1)
win.destroy()
+23
View File
@@ -0,0 +1,23 @@
# -*- coding: utf-8 -*-
'''
Created on 10.11.2014
@author: sebastianw
'''
import unittest
class Test(unittest.TestCase):
def setUp(self):
pass
def tearDown(self):
pass
def testName(self):
pass
if __name__ == "__main__":
# import sys;sys.argv = ['', 'Test.testName']
unittest.main()
+17
View File
@@ -0,0 +1,17 @@
# -*- coding: utf-8 -*-
'''
Created on 10.11.2014
@author: sebastianw
'''
import unittest
class Test(unittest.TestCase):
def testName(self):
pass
if __name__ == "__main__":
# import sys;sys.argv = ['', 'Test.testName']
unittest.main()
+311
View File
@@ -0,0 +1,311 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
Script to run autoPyLoT-script "makeCF.py".
Only for test purposes!
"""
import argparse
import glob
from obspy.core import read
from pylot.core.pick.charfuns import *
from pylot.core.pick.picker import *
def run_makeCF(project, database, event, iplot, station=None):
# parameters for CF calculation
t2 = 7 # length of moving window for HOS calculation [sec]
p = 4 # order of HOS
cuttimes = [10, 50] # start and end time for CF calculation
bpz = [2, 30] # corner frequencies of bandpass filter, vertical component
bph = [2, 15] # corner frequencies of bandpass filter, horizontal components
tdetz = 1.2 # length of AR-determination window [sec], vertical component
tdeth = 0.8 # length of AR-determination window [sec], horizontal components
tpredz = 0.4 # length of AR-prediction window [sec], vertical component
tpredh = 0.4 # length of AR-prediction window [sec], horizontal components
addnoise = 0.001 # add noise to seismogram for stable AR prediction
arzorder = 2 # chosen order of AR process, vertical component
arhorder = 4 # chosen order of AR process, horizontal components
TSNRhos = [5, 0.5, 1, 0.1] # window lengths [s] for calculating SNR for earliest/latest pick and quality assessment
# from HOS-CF [noise window, safety gap, signal window, slope determination window]
TSNRarz = [5, 0.5, 1, 0.5] # window lengths [s] for calculating SNR for earliest/lates pick and quality assessment
# from ARZ-CF
# get waveform data
if station:
dpz = '/data/%s/EVENT_DATA/LOCAL/%s/%s/%s*HZ.msd' % (project, database, event, station)
dpe = '/data/%s/EVENT_DATA/LOCAL/%s/%s/%s*HE.msd' % (project, database, event, station)
dpn = '/data/%s/EVENT_DATA/LOCAL/%s/%s/%s*HN.msd' % (project, database, event, station)
# dpz = '/DATA/%s/EVENT_DATA/LOCAL/%s/%s/%s*_z.gse' % (project, database, event, station)
# dpe = '/DATA/%s/EVENT_DATA/LOCAL/%s/%s/%s*_e.gse' % (project, database, event, station)
# dpn = '/DATA/%s/EVENT_DATA/LOCAL/%s/%s/%s*_n.gse' % (project, database, event, station)
else:
# dpz = '/DATA/%s/EVENT_DATA/LOCAL/%s/%s/*_z.gse' % (project, database, event)
# dpe = '/DATA/%s/EVENT_DATA/LOCAL/%s/%s/*_e.gse' % (project, database, event)
# dpn = '/DATA/%s/EVENT_DATA/LOCAL/%s/%s/*_n.gse' % (project, database, event)
dpz = '/data/%s/EVENT_DATA/LOCAL/%s/%s/*HZ.msd' % (project, database, event)
dpe = '/data/%s/EVENT_DATA/LOCAL/%s/%s/*HE.msd' % (project, database, event)
dpn = '/data/%s/EVENT_DATA/LOCAL/%s/%s/*HN.msd' % (project, database, event)
wfzfiles = glob.glob(dpz)
wfefiles = glob.glob(dpe)
wfnfiles = glob.glob(dpn)
if wfzfiles:
for i in range(len(wfzfiles)):
print
'Vertical component data found ...'
print
wfzfiles[i]
st = read('%s' % wfzfiles[i])
st_copy = st.copy()
# filter and taper data
tr_filt = st[0].copy()
tr_filt.filter('bandpass', freqmin=bpz[0], freqmax=bpz[1], zerophase=False)
tr_filt.taper(max_percentage=0.05, type='hann')
st_copy[0].data = tr_filt.data
##############################################################
# calculate HOS-CF using subclass HOScf of class CharacteristicFunction
hoscf = HOScf(st_copy, cuttimes, t2, p) # instance of HOScf
##############################################################
# calculate AIC-HOS-CF using subclass AICcf of class CharacteristicFunction
# class needs stream object => build it
tr_aic = tr_filt.copy()
tr_aic.data = hoscf.getCF()
st_copy[0].data = tr_aic.data
aiccf = AICcf(st_copy, cuttimes) # instance of AICcf
##############################################################
# get prelimenary onset time from AIC-HOS-CF using subclass AICPicker of class AutoPicking
aicpick = AICPicker(aiccf, None, TSNRhos, 3, 10, None, 0.1)
##############################################################
# get refined onset time from HOS-CF using class Picker
hospick = PragPicker(hoscf, None, TSNRhos, 2, 10, 0.001, 0.2, aicpick.getpick())
# get earliest and latest possible picks
hosELpick = EarlLatePicker(hoscf, 1.5, TSNRhos, None, 10, None, None, hospick.getpick())
##############################################################
# calculate ARZ-CF using subclass ARZcf of class CharcteristicFunction
# get stream object of filtered data
st_copy[0].data = tr_filt.data
arzcf = ARZcf(st_copy, cuttimes, tpredz, arzorder, tdetz, addnoise) # instance of ARZcf
##############################################################
# calculate AIC-ARZ-CF using subclass AICcf of class CharacteristicFunction
# class needs stream object => build it
tr_arzaic = tr_filt.copy()
tr_arzaic.data = arzcf.getCF()
st_copy[0].data = tr_arzaic.data
araiccf = AICcf(st_copy, cuttimes, tpredz, 0, tdetz) # instance of AICcf
##############################################################
# get onset time from AIC-ARZ-CF using subclass AICPicker of class AutoPicking
aicarzpick = AICPicker(araiccf, 1.5, TSNRarz, 2, 10, None, 0.1)
##############################################################
# get refined onset time from ARZ-CF using class Picker
arzpick = PragPicker(arzcf, 1.5, TSNRarz, 2.0, 10, 0.1, 0.05, aicarzpick.getpick())
# get earliest and latest possible picks
arzELpick = EarlLatePicker(arzcf, 1.5, TSNRarz, None, 10, None, None, arzpick.getpick())
elif not wfzfiles:
print
'No vertical component data found!'
if wfefiles and wfnfiles:
for i in range(len(wfefiles)):
print
'Horizontal component data found ...'
print
wfefiles[i]
print
wfnfiles[i]
# merge streams
H = read('%s' % wfefiles[i])
H += read('%s' % wfnfiles[i])
H_copy = H.copy()
# filter and taper data
trH1_filt = H[0].copy()
trH2_filt = H[1].copy()
trH1_filt.filter('bandpass', freqmin=bph[0], freqmax=bph[1], zerophase=False)
trH2_filt.filter('bandpass', freqmin=bph[0], freqmax=bph[1], zerophase=False)
trH1_filt.taper(max_percentage=0.05, type='hann')
trH2_filt.taper(max_percentage=0.05, type='hann')
H_copy[0].data = trH1_filt.data
H_copy[1].data = trH2_filt.data
##############################################################
# calculate ARH-CF using subclass ARHcf of class CharcteristicFunction
arhcf = ARHcf(H_copy, cuttimes, tpredh, arhorder, tdeth, addnoise) # instance of ARHcf
##############################################################
# calculate AIC-ARH-CF using subclass AICcf of class CharacteristicFunction
# class needs stream object => build it
tr_arhaic = trH1_filt.copy()
tr_arhaic.data = arhcf.getCF()
H_copy[0].data = tr_arhaic.data
# calculate ARH-AIC-CF
arhaiccf = AICcf(H_copy, cuttimes, tpredh, 0, tdeth) # instance of AICcf
##############################################################
# get onset time from AIC-ARH-CF using subclass AICPicker of class AutoPicking
aicarhpick = AICPicker(arhaiccf, 1.5, TSNRarz, 4, 10, None, 0.1)
###############################################################
# get refined onset time from ARH-CF using class Picker
arhpick = PragPicker(arhcf, 1.5, TSNRarz, 2.5, 10, 0.1, 0.05, aicarhpick.getpick())
# get earliest and latest possible picks
arhELpick = EarlLatePicker(arhcf, 1.5, TSNRarz, None, 10, None, None, arhpick.getpick())
# create stream with 3 traces
# merge streams
AllC = read('%s' % wfefiles[i])
AllC += read('%s' % wfnfiles[i])
AllC += read('%s' % wfzfiles[i])
# filter and taper data
All1_filt = AllC[0].copy()
All2_filt = AllC[1].copy()
All3_filt = AllC[2].copy()
All1_filt.filter('bandpass', freqmin=bph[0], freqmax=bph[1], zerophase=False)
All2_filt.filter('bandpass', freqmin=bph[0], freqmax=bph[1], zerophase=False)
All3_filt.filter('bandpass', freqmin=bpz[0], freqmax=bpz[1], zerophase=False)
All1_filt.taper(max_percentage=0.05, type='hann')
All2_filt.taper(max_percentage=0.05, type='hann')
All3_filt.taper(max_percentage=0.05, type='hann')
AllC[0].data = All1_filt.data
AllC[1].data = All2_filt.data
AllC[2].data = All3_filt.data
# calculate AR3C-CF using subclass AR3Ccf of class CharacteristicFunction
ar3ccf = AR3Ccf(AllC, cuttimes, tpredz, arhorder, tdetz, addnoise) # instance of AR3Ccf
# get earliest and latest possible pick from initial ARH-pick
ar3cELpick = EarlLatePicker(ar3ccf, 1.5, TSNRarz, None, 10, None, None, arhpick.getpick())
##############################################################
if iplot:
# plot vertical trace
plt.figure()
tr = st[0]
tdata = np.arange(0, tr.stats.npts / tr.stats.sampling_rate, tr.stats.delta)
p1, = plt.plot(tdata, tr_filt.data / max(tr_filt.data), 'k')
p2, = plt.plot(hoscf.getTimeArray(), hoscf.getCF() / max(hoscf.getCF()), 'r')
p3, = plt.plot(aiccf.getTimeArray(), aiccf.getCF() / max(aiccf.getCF()), 'b')
p4, = plt.plot(arzcf.getTimeArray(), arzcf.getCF() / max(arzcf.getCF()), 'g')
p5, = plt.plot(araiccf.getTimeArray(), araiccf.getCF() / max(araiccf.getCF()), 'y')
plt.plot([aicpick.getpick(), aicpick.getpick()], [-1, 1], 'b--')
plt.plot([aicpick.getpick() - 0.5, aicpick.getpick() + 0.5], [1, 1], 'b')
plt.plot([aicpick.getpick() - 0.5, aicpick.getpick() + 0.5], [-1, -1], 'b')
plt.plot([hospick.getpick(), hospick.getpick()], [-1.3, 1.3], 'r', linewidth=2)
plt.plot([hospick.getpick() - 0.5, hospick.getpick() + 0.5], [1.3, 1.3], 'r')
plt.plot([hospick.getpick() - 0.5, hospick.getpick() + 0.5], [-1.3, -1.3], 'r')
plt.plot([hosELpick.getLpick(), hosELpick.getLpick()], [-1.1, 1.1], 'r--')
plt.plot([hosELpick.getEpick(), hosELpick.getEpick()], [-1.1, 1.1], 'r--')
plt.plot([aicarzpick.getpick(), aicarzpick.getpick()], [-1.2, 1.2], 'y', linewidth=2)
plt.plot([aicarzpick.getpick() - 0.5, aicarzpick.getpick() + 0.5], [1.2, 1.2], 'y')
plt.plot([aicarzpick.getpick() - 0.5, aicarzpick.getpick() + 0.5], [-1.2, -1.2], 'y')
plt.plot([arzpick.getpick(), arzpick.getpick()], [-1.4, 1.4], 'g', linewidth=2)
plt.plot([arzpick.getpick() - 0.5, arzpick.getpick() + 0.5], [1.4, 1.4], 'g')
plt.plot([arzpick.getpick() - 0.5, arzpick.getpick() + 0.5], [-1.4, -1.4], 'g')
plt.plot([arzELpick.getLpick(), arzELpick.getLpick()], [-1.2, 1.2], 'g--')
plt.plot([arzELpick.getEpick(), arzELpick.getEpick()], [-1.2, 1.2], 'g--')
plt.yticks([])
plt.ylim([-1.5, 1.5])
plt.xlabel('Time [s]')
plt.ylabel('Normalized Counts')
plt.title('%s, %s, CF-SNR=%7.2f, CF-Slope=%12.2f' % (tr.stats.station, \
tr.stats.channel, aicpick.getSNR(),
aicpick.getSlope()))
plt.suptitle(tr.stats.starttime)
plt.legend([p1, p2, p3, p4, p5], ['Data', 'HOS-CF', 'HOSAIC-CF', 'ARZ-CF', 'ARZAIC-CF'])
# plot horizontal traces
plt.figure(2)
plt.subplot(2, 1, 1)
tsteph = tpredh / 4
th1data = np.arange(0, trH1_filt.stats.npts / trH1_filt.stats.sampling_rate, trH1_filt.stats.delta)
th2data = np.arange(0, trH2_filt.stats.npts / trH2_filt.stats.sampling_rate, trH2_filt.stats.delta)
tarhcf = np.arange(0, len(arhcf.getCF()) * tsteph, tsteph) + cuttimes[0] + tdeth + tpredh
p21, = plt.plot(th1data, trH1_filt.data / max(trH1_filt.data), 'k')
p22, = plt.plot(arhcf.getTimeArray(), arhcf.getCF() / max(arhcf.getCF()), 'r')
p23, = plt.plot(arhaiccf.getTimeArray(), arhaiccf.getCF() / max(arhaiccf.getCF()))
plt.plot([aicarhpick.getpick(), aicarhpick.getpick()], [-1, 1], 'b')
plt.plot([aicarhpick.getpick() - 0.5, aicarhpick.getpick() + 0.5], [1, 1], 'b')
plt.plot([aicarhpick.getpick() - 0.5, aicarhpick.getpick() + 0.5], [-1, -1], 'b')
plt.plot([arhpick.getpick(), arhpick.getpick()], [-1, 1], 'r')
plt.plot([arhpick.getpick() - 0.5, arhpick.getpick() + 0.5], [1, 1], 'r')
plt.plot([arhpick.getpick() - 0.5, arhpick.getpick() + 0.5], [-1, -1], 'r')
plt.plot([arhELpick.getLpick(), arhELpick.getLpick()], [-0.8, 0.8], 'r--')
plt.plot([arhELpick.getEpick(), arhELpick.getEpick()], [-0.8, 0.8], 'r--')
plt.plot([arhpick.getpick() + arhELpick.getPickError(), arhpick.getpick() + arhELpick.getPickError()], \
[-0.2, 0.2], 'r--')
plt.plot([arhpick.getpick() - arhELpick.getPickError(), arhpick.getpick() - arhELpick.getPickError()], \
[-0.2, 0.2], 'r--')
plt.yticks([])
plt.ylim([-1.5, 1.5])
plt.ylabel('Normalized Counts')
plt.title([trH1_filt.stats.station, trH1_filt.stats.channel])
plt.suptitle(trH1_filt.stats.starttime)
plt.legend([p21, p22, p23], ['Data', 'ARH-CF', 'ARHAIC-CF'])
plt.subplot(2, 1, 2)
plt.plot(th2data, trH2_filt.data / max(trH2_filt.data), 'k')
plt.plot(arhcf.getTimeArray(), arhcf.getCF() / max(arhcf.getCF()), 'r')
plt.plot(arhaiccf.getTimeArray(), arhaiccf.getCF() / max(arhaiccf.getCF()))
plt.plot([aicarhpick.getpick(), aicarhpick.getpick()], [-1, 1], 'b')
plt.plot([aicarhpick.getpick() - 0.5, aicarhpick.getpick() + 0.5], [1, 1], 'b')
plt.plot([aicarhpick.getpick() - 0.5, aicarhpick.getpick() + 0.5], [-1, -1], 'b')
plt.plot([arhpick.getpick(), arhpick.getpick()], [-1, 1], 'r')
plt.plot([arhpick.getpick() - 0.5, arhpick.getpick() + 0.5], [1, 1], 'r')
plt.plot([arhpick.getpick() - 0.5, arhpick.getpick() + 0.5], [-1, -1], 'r')
plt.plot([arhELpick.getLpick(), arhELpick.getLpick()], [-0.8, 0.8], 'r--')
plt.plot([arhELpick.getEpick(), arhELpick.getEpick()], [-0.8, 0.8], 'r--')
plt.plot([arhpick.getpick() + arhELpick.getPickError(), arhpick.getpick() + arhELpick.getPickError()], \
[-0.2, 0.2], 'r--')
plt.plot([arhpick.getpick() - arhELpick.getPickError(), arhpick.getpick() - arhELpick.getPickError()], \
[-0.2, 0.2], 'r--')
plt.title([trH2_filt.stats.station, trH2_filt.stats.channel])
plt.yticks([])
plt.ylim([-1.5, 1.5])
plt.xlabel('Time [s]')
plt.ylabel('Normalized Counts')
# plot 3-component window
plt.figure(3)
plt.subplot(3, 1, 1)
p31, = plt.plot(tdata, tr_filt.data / max(tr_filt.data), 'k')
p32, = plt.plot(ar3ccf.getTimeArray(), ar3ccf.getCF() / max(ar3ccf.getCF()), 'r')
plt.plot([arhpick.getpick(), arhpick.getpick()], [-1, 1], 'b')
plt.plot([arhpick.getpick() - 0.5, arhpick.getpick() + 0.5], [-1, -1], 'b')
plt.plot([arhpick.getpick() - 0.5, arhpick.getpick() + 0.5], [1, 1], 'b')
plt.plot([ar3cELpick.getLpick(), ar3cELpick.getLpick()], [-0.8, 0.8], 'b--')
plt.plot([ar3cELpick.getEpick(), ar3cELpick.getEpick()], [-0.8, 0.8], 'b--')
plt.yticks([])
plt.xticks([])
plt.ylabel('Normalized Counts')
plt.title([tr.stats.station, tr.stats.channel])
plt.suptitle(trH1_filt.stats.starttime)
plt.legend([p31, p32], ['Data', 'AR3C-CF'])
plt.subplot(3, 1, 2)
plt.plot(th1data, trH1_filt.data / max(trH1_filt.data), 'k')
plt.plot(ar3ccf.getTimeArray(), ar3ccf.getCF() / max(ar3ccf.getCF()), 'r')
plt.plot([arhpick.getpick(), arhpick.getpick()], [-1, 1], 'b')
plt.plot([arhpick.getpick() - 0.5, arhpick.getpick() + 0.5], [-1, -1], 'b')
plt.plot([arhpick.getpick() - 0.5, arhpick.getpick() + 0.5], [1, 1], 'b')
plt.plot([ar3cELpick.getLpick(), ar3cELpick.getLpick()], [-0.8, 0.8], 'b--')
plt.plot([ar3cELpick.getEpick(), ar3cELpick.getEpick()], [-0.8, 0.8], 'b--')
plt.yticks([])
plt.xticks([])
plt.ylabel('Normalized Counts')
plt.title([trH1_filt.stats.station, trH1_filt.stats.channel])
plt.subplot(3, 1, 3)
plt.plot(th2data, trH2_filt.data / max(trH2_filt.data), 'k')
plt.plot(ar3ccf.getTimeArray(), ar3ccf.getCF() / max(ar3ccf.getCF()), 'r')
plt.plot([arhpick.getpick(), arhpick.getpick()], [-1, 1], 'b')
plt.plot([arhpick.getpick() - 0.5, arhpick.getpick() + 0.5], [-1, -1], 'b')
plt.plot([arhpick.getpick() - 0.5, arhpick.getpick() + 0.5], [1, 1], 'b')
plt.plot([ar3cELpick.getLpick(), ar3cELpick.getLpick()], [-0.8, 0.8], 'b--')
plt.plot([ar3cELpick.getEpick(), ar3cELpick.getEpick()], [-0.8, 0.8], 'b--')
plt.yticks([])
plt.ylabel('Normalized Counts')
plt.title([trH2_filt.stats.station, trH2_filt.stats.channel])
plt.xlabel('Time [s]')
plt.show()
raw_input()
plt.close()
if __name__ == '__main__':
parser = argparse.ArgumentParser()
parser.add_argument('--project', type=str, help='project name (e.g. Insheim)')
parser.add_argument('--database', type=str, help='event data base (e.g. 2014.09_Insheim)')
parser.add_argument('--event', type=str, help='event ID (e.g. e0010.015.14)')
parser.add_argument('--iplot', help='anything, if set, figure occurs')
parser.add_argument('--station', type=str, help='Station ID (e.g. INS3) (optional)')
args = parser.parse_args()
run_makeCF(args.project, args.database, args.event, args.iplot, args.station)
+8
View File
@@ -0,0 +1,8 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
from pylot.core.util.pdf import ProbabilityDensityFunction
pdf = ProbabilityDensityFunction.from_pick(0.34, 0.5, 0.54, type='exp')
pdf2 = ProbabilityDensityFunction.from_pick(0.34, 0.5, 0.54, type='exp')
diff = pdf - pdf2
+16
View File
@@ -0,0 +1,16 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import argparse
import numpy
from pylot.core.pick.utils import getnoisewin
if __name__ == "__main__":
parser = argparse.ArgumentParser()
parser.add_argument('--t', type=numpy.array, help='numpy array of time stamps')
parser.add_argument('--t1', type=float, help='time from which relativ to it noise window is extracted')
parser.add_argument('--tnoise', type=float, help='length of time window [s] for noise part extraction')
parser.add_argument('--tgap', type=float, help='safety gap between signal (t1=onset) and noise')
args = parser.parse_args()
getnoisewin(args.t, args.t1, args.tnoise, args.tgap)
+29
View File
@@ -0,0 +1,29 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
"""
Created Mar 2015
Transcription of the rezipe of Diehl et al. (2009) for consistent phase
picking. For a given inital (the most likely) pick, the corresponding earliest
and latest possible pick is calculated based on noise measurements in front of
the most likely pick and signal wavelength derived from zero crossings.
:author: Ludger Kueperkoch / MAGS2 EP3 working group
"""
import argparse
import obspy
from pylot.core.pick.utils import earllatepicker
if __name__ == "__main__":
parser = argparse.ArgumentParser()
parser.add_argument('--X', type=~obspy.core.stream.Stream,
help='time series (seismogram) read with obspy module read')
parser.add_argument('--nfac', type=int,
help='(noise factor), nfac times noise level to calculate latest possible pick')
parser.add_argument('--TSNR', type=tuple, help='length of time windows around pick used to determine SNR \
[s] (Tnoise, Tgap, Tsignal)')
parser.add_argument('--Pick1', type=float, help='Onset time of most likely pick')
parser.add_argument('--iplot', type=int, help='if set, figure no. iplot occurs')
args = parser.parse_args()
earllatepicker(args.X, args.nfac, args.TSNR, args.Pick1, args.iplot)
+25
View File
@@ -0,0 +1,25 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
"""
Created Mar 2015
Function to derive first motion (polarity) for given phase onset based on zero crossings.
:author: MAGS2 EP3 working group / Ludger Kueperkoch
"""
import argparse
import obspy
from pylot.core.pick.utils import fmpicker
if __name__ == "__main__":
parser = argparse.ArgumentParser()
parser.add_argument('--Xraw', type=obspy.core.stream.Stream,
help='unfiltered time series (seismogram) read with obspy module read')
parser.add_argument('--Xfilt', type=obspy.core.stream.Stream,
help='filtered time series (seismogram) read with obspy module read')
parser.add_argument('--pickwin', type=float, help='length of pick window [s] for first motion determination')
parser.add_argument('--Pick', type=float, help='Onset time of most likely pick')
parser.add_argument('--iplot', type=int, help='if set, figure no. iplot occurs')
args = parser.parse_args()
fmpicker(args.Xraw, args.Xfilt, args.pickwin, args.Pick, args.iplot)
+41
View File
@@ -0,0 +1,41 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import argparse
from pylot.core.io.phases import reassess_pilot_db
from pylot.core.util.version import get_git_version as _getVersionString
__version__ = _getVersionString()
__author__ = 'S. Wehling-Benatelli'
if __name__ == '__main__':
parser = argparse.ArgumentParser(
description='reassess old PILOT event data base in terms of consistent '
'automatic uncertainty estimation',
epilog='Script written by {author} belonging to PyLoT version'
' {version}\n'.format(author=__author__,
version=__version__)
)
parser.add_argument(
'root', type=str, help='specifies the root directory'
)
parser.add_argument(
'db', type=str, help='specifies the database name'
)
parser.add_argument(
'--output', '-o', type=str, help='path to the output directory',
dest='output'
)
parser.add_argument(
'--parameterfile', '-p', type=str,
help='full path to the parameterfile', dest='parfile'
)
parser.add_argument(
'--verbosity', '-v', action='count', help='increase output verbosity',
default=0, dest='verbosity'
)
args = parser.parse_args()
reassess_pilot_db(args.root, args.db, args.output, args.parfile, args.verbosity)
+38
View File
@@ -0,0 +1,38 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import argparse
from pylot.core.io.phases import reassess_pilot_event
from pylot.core.util.version import get_git_version as _getVersionString
__version__ = _getVersionString()
__author__ = 'S. Wehling-Benatelli'
if __name__ == '__main__':
parser = argparse.ArgumentParser(
description='reassess old PILOT event data in terms of consistent '
'automatic uncertainty estimation',
epilog='Script written by {author} belonging to PyLoT version'
' {version}\n'.format(author=__author__,
version=__version__)
)
parser.add_argument(
'root', type=str, help='specifies the root directory'
)
parser.add_argument(
'db', type=str, help='specifies the database name'
)
parser.add_argument(
'id', type=str, help='PILOT event identifier'
)
parser.add_argument(
'--output', '-o', type=str, help='path to the output directory', dest='output'
)
parser.add_argument(
'--parameterfile', '-p', type=str, help='full path to the parameterfile', dest='parfile'
)
args = parser.parse_args()
reassess_pilot_event(args.root, args.db, args.id, args.output, args.parfile)
+15
View File
@@ -0,0 +1,15 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import argparse
import numpy
from pylot.core.pick.utils import getsignalwin
if __name__ == "__main__":
parser = argparse.ArgumentParser()
parser.add_argument('--t', type=numpy.array, help='numpy array of time stamps')
parser.add_argument('--t1', type=float, help='time from which relativ to it signal window is extracted')
parser.add_argument('--tsignal', type=float, help='length of time window [s] for signal part extraction')
args = parser.parse_args()
getsignalwin(args.t, args.t1, args.tsignal)
+32
View File
@@ -0,0 +1,32 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
"""
Created Mar/Apr 2015
Function to calculate SNR of certain part of seismogram relative
to given time. Returns SNR and SNR [dB].
:author: Ludger Kueperkoch /MAGS EP3 working group
"""
import argparse
import obspy
from pylot.core.pick.utils import getSNR
if __name__ == "__main__":
parser = argparse.ArgumentParser()
parser.add_argument('--data', '-d', type=obspy.core.stream.Stream,
help='time series (seismogram) read with obspy module '
'read',
dest='data')
parser.add_argument('--tsnr', '-s', type=tuple,
help='length of time windows around pick used to '
'determine SNR [s] (Tnoise, Tgap, Tsignal)',
dest='tsnr')
parser.add_argument('--time', '-t', type=float,
help='initial time from which noise and signal windows '
'are calculated',
dest='time')
args = parser.parse_args()
print
getSNR(args.data, args.tsnr, args.time)
+314
View File
@@ -0,0 +1,314 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
"""
Script to run autoPyLoT-script "run_makeCF.py".
Only for test purposes!
"""
import argparse
import glob
from obspy.core import read
from pylot.core.pick.utils import *
def run_makeCF(project, database, event, iplot, station=None):
# parameters for CF calculation
t2 = 7 # length of moving window for HOS calculation [sec]
p = 4 # order of HOS
cuttimes = [10, 50] # start and end time for CF calculation
bpz = [2, 30] # corner frequencies of bandpass filter, vertical component
bph = [2, 15] # corner frequencies of bandpass filter, horizontal components
tdetz = 1.2 # length of AR-determination window [sec], vertical component
tdeth = 0.8 # length of AR-determination window [sec], horizontal components
tpredz = 0.4 # length of AR-prediction window [sec], vertical component
tpredh = 0.4 # length of AR-prediction window [sec], horizontal components
addnoise = 0.001 # add noise to seismogram for stable AR prediction
arzorder = 2 # chosen order of AR process, vertical component
arhorder = 4 # chosen order of AR process, horizontal components
TSNRhos = [5, 0.5, 1, .6] # window lengths [s] for calculating SNR for earliest/latest pick and quality assessment
# from HOS-CF [noise window, safety gap, signal window, slope determination window]
TSNRarz = [5, 0.5, 1, 1.0] # window lengths [s] for calculating SNR for earliest/lates pick and quality assessment
# from ARZ-CF
# get waveform data
if station:
dpz = '/DATA/%s/EVENT_DATA/LOCAL/%s/%s/%s*HZ.msd' % (project, database, event, station)
dpe = '/DATA/%s/EVENT_DATA/LOCAL/%s/%s/%s*HE.msd' % (project, database, event, station)
dpn = '/DATA/%s/EVENT_DATA/LOCAL/%s/%s/%s*HN.msd' % (project, database, event, station)
# dpz = '/DATA/%s/EVENT_DATA/LOCAL/%s/%s/%s*_z.gse' % (project, database, event, station)
# dpe = '/DATA/%s/EVENT_DATA/LOCAL/%s/%s/%s*_e.gse' % (project, database, event, station)
# dpn = '/DATA/%s/EVENT_DATA/LOCAL/%s/%s/%s*_n.gse' % (project, database, event, station)
else:
dpz = '/DATA/%s/EVENT_DATA/LOCAL/%s/%s/*HZ.msd' % (project, database, event)
dpe = '/DATA/%s/EVENT_DATA/LOCAL/%s/%s/*HE.msd' % (project, database, event)
dpn = '/DATA/%s/EVENT_DATA/LOCAL/%s/%s/*HN.msd' % (project, database, event)
wfzfiles = glob.glob(dpz)
wfefiles = glob.glob(dpe)
wfnfiles = glob.glob(dpn)
if wfzfiles:
for i in range(len(wfzfiles)):
print
'Vertical component data found ...'
print
wfzfiles[i]
st = read('%s' % wfzfiles[i])
st_copy = st.copy()
# filter and taper data
tr_filt = st[0].copy()
tr_filt.filter('bandpass', freqmin=bpz[0], freqmax=bpz[1], zerophase=False)
tr_filt.taper(max_percentage=0.05, type='hann')
st_copy[0].data = tr_filt.data
##############################################################
# calculate HOS-CF using subclass HOScf of class CharacteristicFunction
hoscf = HOScf(st_copy, cuttimes, t2, p) # instance of HOScf
##############################################################
# calculate AIC-HOS-CF using subclass AICcf of class CharacteristicFunction
# class needs stream object => build it
tr_aic = tr_filt.copy()
tr_aic.data = hoscf.getCF()
st_copy[0].data = tr_aic.data
aiccf = AICcf(st_copy, cuttimes) # instance of AICcf
##############################################################
# get prelimenary onset time from AIC-HOS-CF using subclass AICPicker of class AutoPicking
aicpick = AICPicker(aiccf, TSNRhos, 3, 10, None, 0.1)
##############################################################
# get refined onset time from HOS-CF using class Picker
hospick = PragPicker(hoscf, TSNRhos, 2, 10, 0.001, 0.2, aicpick.getpick())
#############################################################
# get earliest and latest possible picks
st_copy[0].data = tr_filt.data
[lpickhos, epickhos, pickerrhos] = earllatepicker(st_copy, 1.5, TSNRhos, hospick.getpick(), 10)
#############################################################
# get SNR
[SNR, SNRdB] = getSNR(st_copy, TSNRhos, hospick.getpick())
print
'SNR:', SNR, 'SNR[dB]:', SNRdB
##########################################################
# get first motion of onset
hosfm = fmpicker(st, st_copy, 0.2, hospick.getpick(), 11)
##############################################################
# calculate ARZ-CF using subclass ARZcf of class CharcteristicFunction
arzcf = ARZcf(st, cuttimes, tpredz, arzorder, tdetz, addnoise) # instance of ARZcf
##############################################################
# calculate AIC-ARZ-CF using subclass AICcf of class CharacteristicFunction
# class needs stream object => build it
tr_arzaic = tr_filt.copy()
tr_arzaic.data = arzcf.getCF()
st_copy[0].data = tr_arzaic.data
araiccf = AICcf(st_copy, cuttimes, tpredz, 0, tdetz) # instance of AICcf
##############################################################
# get onset time from AIC-ARZ-CF using subclass AICPicker of class AutoPicking
aicarzpick = AICPicker(araiccf, TSNRarz, 2, 10, None, 0.1)
##############################################################
# get refined onset time from ARZ-CF using class Picker
arzpick = PragPicker(arzcf, TSNRarz, 2.0, 10, 0.1, 0.05, aicarzpick.getpick())
# get earliest and latest possible picks
st_copy[0].data = tr_filt.data
[lpickarz, epickarz, pickerrarz] = earllatepicker(st_copy, 1.5, TSNRarz, arzpick.getpick(), 10)
elif not wfzfiles:
print
'No vertical component data found!'
if wfefiles and wfnfiles:
for i in range(len(wfefiles)):
print
'Horizontal component data found ...'
print
wfefiles[i]
print
wfnfiles[i]
# merge streams
H = read('%s' % wfefiles[i])
H += read('%s' % wfnfiles[i])
H_copy = H.copy()
# filter and taper data
trH1_filt = H[0].copy()
trH2_filt = H[1].copy()
trH1_filt.filter('bandpass', freqmin=bph[0], freqmax=bph[1], zerophase=False)
trH2_filt.filter('bandpass', freqmin=bph[0], freqmax=bph[1], zerophase=False)
trH1_filt.taper(max_percentage=0.05, type='hann')
trH2_filt.taper(max_percentage=0.05, type='hann')
H_copy[0].data = trH1_filt.data
H_copy[1].data = trH2_filt.data
##############################################################
# calculate ARH-CF using subclass ARHcf of class CharcteristicFunction
arhcf = ARHcf(H_copy, cuttimes, tpredh, arhorder, tdeth, addnoise) # instance of ARHcf
##############################################################
# calculate AIC-ARH-CF using subclass AICcf of class CharacteristicFunction
# class needs stream object => build it
tr_arhaic = trH1_filt.copy()
tr_arhaic.data = arhcf.getCF()
H_copy[0].data = tr_arhaic.data
# calculate ARH-AIC-CF
arhaiccf = AICcf(H_copy, cuttimes, tpredh, 0, tdeth) # instance of AICcf
##############################################################
# get onset time from AIC-ARH-CF using subclass AICPicker of class AutoPicking
aicarhpick = AICPicker(arhaiccf, TSNRarz, 4, 10, None, 0.1)
###############################################################
# get refined onset time from ARH-CF using class Picker
arhpick = PragPicker(arhcf, TSNRarz, 2.5, 10, 0.1, 0.05, aicarhpick.getpick())
# get earliest and latest possible picks
H_copy[0].data = trH1_filt.data
[lpickarh1, epickarh1, pickerrarh1] = earllatepicker(H_copy, 1.5, TSNRarz, arhpick.getpick(), 10)
H_copy[0].data = trH2_filt.data
[lpickarh2, epickarh2, pickerrarh2] = earllatepicker(H_copy, 1.5, TSNRarz, arhpick.getpick(), 10)
# get earliest pick of both earliest possible picks
epick = [epickarh1, epickarh2]
lpick = [lpickarh1, lpickarh2]
pickerr = [pickerrarh1, pickerrarh2]
ipick = np.argmin([epickarh1, epickarh2])
epickarh = epick[ipick]
lpickarh = lpick[ipick]
pickerrarh = pickerr[ipick]
# create stream with 3 traces
# merge streams
AllC = read('%s' % wfefiles[i])
AllC += read('%s' % wfnfiles[i])
AllC += read('%s' % wfzfiles[i])
# filter and taper data
All1_filt = AllC[0].copy()
All2_filt = AllC[1].copy()
All3_filt = AllC[2].copy()
All1_filt.filter('bandpass', freqmin=bph[0], freqmax=bph[1], zerophase=False)
All2_filt.filter('bandpass', freqmin=bph[0], freqmax=bph[1], zerophase=False)
All3_filt.filter('bandpass', freqmin=bpz[0], freqmax=bpz[1], zerophase=False)
All1_filt.taper(max_percentage=0.05, type='hann')
All2_filt.taper(max_percentage=0.05, type='hann')
All3_filt.taper(max_percentage=0.05, type='hann')
AllC[0].data = All1_filt.data
AllC[1].data = All2_filt.data
AllC[2].data = All3_filt.data
# calculate AR3C-CF using subclass AR3Ccf of class CharacteristicFunction
ar3ccf = AR3Ccf(AllC, cuttimes, tpredz, arhorder, tdetz, addnoise) # instance of AR3Ccf
##############################################################
if iplot:
# plot vertical trace
plt.figure()
tr = st[0]
tdata = np.arange(0, tr.stats.npts / tr.stats.sampling_rate, tr.stats.delta)
p1, = plt.plot(tdata, tr_filt.data / max(tr_filt.data), 'k')
p2, = plt.plot(hoscf.getTimeArray(), hoscf.getCF() / max(hoscf.getCF()), 'r')
p3, = plt.plot(aiccf.getTimeArray(), aiccf.getCF() / max(aiccf.getCF()), 'b')
p4, = plt.plot(arzcf.getTimeArray(), arzcf.getCF() / max(arzcf.getCF()), 'g')
p5, = plt.plot(araiccf.getTimeArray(), araiccf.getCF() / max(araiccf.getCF()), 'y')
plt.plot([aicpick.getpick(), aicpick.getpick()], [-1, 1], 'b--')
plt.plot([aicpick.getpick() - 0.5, aicpick.getpick() + 0.5], [1, 1], 'b')
plt.plot([aicpick.getpick() - 0.5, aicpick.getpick() + 0.5], [-1, -1], 'b')
plt.plot([hospick.getpick(), hospick.getpick()], [-1.3, 1.3], 'r', linewidth=2)
plt.plot([hospick.getpick() - 0.5, hospick.getpick() + 0.5], [1.3, 1.3], 'r')
plt.plot([hospick.getpick() - 0.5, hospick.getpick() + 0.5], [-1.3, -1.3], 'r')
plt.plot([lpickhos, lpickhos], [-1.1, 1.1], 'r--')
plt.plot([epickhos, epickhos], [-1.1, 1.1], 'r--')
plt.plot([aicarzpick.getpick(), aicarzpick.getpick()], [-1.2, 1.2], 'y', linewidth=2)
plt.plot([aicarzpick.getpick() - 0.5, aicarzpick.getpick() + 0.5], [1.2, 1.2], 'y')
plt.plot([aicarzpick.getpick() - 0.5, aicarzpick.getpick() + 0.5], [-1.2, -1.2], 'y')
plt.plot([arzpick.getpick(), arzpick.getpick()], [-1.4, 1.4], 'g', linewidth=2)
plt.plot([arzpick.getpick() - 0.5, arzpick.getpick() + 0.5], [1.4, 1.4], 'g')
plt.plot([arzpick.getpick() - 0.5, arzpick.getpick() + 0.5], [-1.4, -1.4], 'g')
plt.plot([lpickarz, lpickarz], [-1.2, 1.2], 'g--')
plt.plot([epickarz, epickarz], [-1.2, 1.2], 'g--')
plt.yticks([])
plt.ylim([-1.5, 1.5])
plt.xlabel('Time [s]')
plt.ylabel('Normalized Counts')
plt.title('%s, %s, CF-SNR=%7.2f, CF-Slope=%12.2f' % (tr.stats.station,
tr.stats.channel, aicpick.getSNR(),
aicpick.getSlope()))
plt.suptitle(tr.stats.starttime)
plt.legend([p1, p2, p3, p4, p5], ['Data', 'HOS-CF', 'HOSAIC-CF', 'ARZ-CF', 'ARZAIC-CF'])
# plot horizontal traces
plt.figure(2)
plt.subplot(2, 1, 1)
tsteph = tpredh / 4
th1data = np.arange(0, trH1_filt.stats.npts / trH1_filt.stats.sampling_rate, trH1_filt.stats.delta)
th2data = np.arange(0, trH2_filt.stats.npts / trH2_filt.stats.sampling_rate, trH2_filt.stats.delta)
tarhcf = np.arange(0, len(arhcf.getCF()) * tsteph, tsteph) + cuttimes[0] + tdeth + tpredh
p21, = plt.plot(th1data, trH1_filt.data / max(trH1_filt.data), 'k')
p22, = plt.plot(arhcf.getTimeArray(), arhcf.getCF() / max(arhcf.getCF()), 'r')
p23, = plt.plot(arhaiccf.getTimeArray(), arhaiccf.getCF() / max(arhaiccf.getCF()))
plt.plot([aicarhpick.getpick(), aicarhpick.getpick()], [-1, 1], 'b')
plt.plot([aicarhpick.getpick() - 0.5, aicarhpick.getpick() + 0.5], [1, 1], 'b')
plt.plot([aicarhpick.getpick() - 0.5, aicarhpick.getpick() + 0.5], [-1, -1], 'b')
plt.plot([arhpick.getpick(), arhpick.getpick()], [-1, 1], 'r')
plt.plot([arhpick.getpick() - 0.5, arhpick.getpick() + 0.5], [1, 1], 'r')
plt.plot([arhpick.getpick() - 0.5, arhpick.getpick() + 0.5], [-1, -1], 'r')
plt.plot([lpickarh, lpickarh], [-0.8, 0.8], 'r--')
plt.plot([epickarh, epickarh], [-0.8, 0.8], 'r--')
plt.plot([arhpick.getpick() + pickerrarh, arhpick.getpick() + pickerrarh], [-0.2, 0.2], 'r--')
plt.plot([arhpick.getpick() - pickerrarh, arhpick.getpick() - pickerrarh], [-0.2, 0.2], 'r--')
plt.yticks([])
plt.ylim([-1.5, 1.5])
plt.ylabel('Normalized Counts')
plt.title([trH1_filt.stats.station, trH1_filt.stats.channel])
plt.suptitle(trH1_filt.stats.starttime)
plt.legend([p21, p22, p23], ['Data', 'ARH-CF', 'ARHAIC-CF'])
plt.subplot(2, 1, 2)
plt.plot(th2data, trH2_filt.data / max(trH2_filt.data), 'k')
plt.plot(arhcf.getTimeArray(), arhcf.getCF() / max(arhcf.getCF()), 'r')
plt.plot(arhaiccf.getTimeArray(), arhaiccf.getCF() / max(arhaiccf.getCF()))
plt.plot([aicarhpick.getpick(), aicarhpick.getpick()], [-1, 1], 'b')
plt.plot([aicarhpick.getpick() - 0.5, aicarhpick.getpick() + 0.5], [1, 1], 'b')
plt.plot([aicarhpick.getpick() - 0.5, aicarhpick.getpick() + 0.5], [-1, -1], 'b')
plt.plot([arhpick.getpick(), arhpick.getpick()], [-1, 1], 'r')
plt.plot([arhpick.getpick() - 0.5, arhpick.getpick() + 0.5], [1, 1], 'r')
plt.plot([arhpick.getpick() - 0.5, arhpick.getpick() + 0.5], [-1, -1], 'r')
plt.plot([lpickarh, lpickarh], [-0.8, 0.8], 'r--')
plt.plot([epickarh, epickarh], [-0.8, 0.8], 'r--')
plt.plot([arhpick.getpick() + pickerrarh, arhpick.getpick() + pickerrarh], [-0.2, 0.2], 'r--')
plt.plot([arhpick.getpick() - pickerrarh, arhpick.getpick() - pickerrarh], [-0.2, 0.2], 'r--')
plt.title([trH2_filt.stats.station, trH2_filt.stats.channel])
plt.yticks([])
plt.ylim([-1.5, 1.5])
plt.xlabel('Time [s]')
plt.ylabel('Normalized Counts')
# plot 3-component window
plt.figure(3)
plt.subplot(3, 1, 1)
p31, = plt.plot(tdata, tr_filt.data / max(tr_filt.data), 'k')
p32, = plt.plot(ar3ccf.getTimeArray(), ar3ccf.getCF() / max(ar3ccf.getCF()), 'r')
plt.plot([arhpick.getpick(), arhpick.getpick()], [-1, 1], 'b')
plt.plot([arhpick.getpick() - 0.5, arhpick.getpick() + 0.5], [-1, -1], 'b')
plt.plot([arhpick.getpick() - 0.5, arhpick.getpick() + 0.5], [1, 1], 'b')
plt.yticks([])
plt.xticks([])
plt.ylabel('Normalized Counts')
plt.title([tr.stats.station, tr.stats.channel])
plt.suptitle(trH1_filt.stats.starttime)
plt.legend([p31, p32], ['Data', 'AR3C-CF'])
plt.subplot(3, 1, 2)
plt.plot(th1data, trH1_filt.data / max(trH1_filt.data), 'k')
plt.plot(ar3ccf.getTimeArray(), ar3ccf.getCF() / max(ar3ccf.getCF()), 'r')
plt.plot([arhpick.getpick(), arhpick.getpick()], [-1, 1], 'b')
plt.plot([arhpick.getpick() - 0.5, arhpick.getpick() + 0.5], [-1, -1], 'b')
plt.plot([arhpick.getpick() - 0.5, arhpick.getpick() + 0.5], [1, 1], 'b')
plt.yticks([])
plt.xticks([])
plt.ylabel('Normalized Counts')
plt.title([trH1_filt.stats.station, trH1_filt.stats.channel])
plt.subplot(3, 1, 3)
plt.plot(th2data, trH2_filt.data / max(trH2_filt.data), 'k')
plt.plot(ar3ccf.getTimeArray(), ar3ccf.getCF() / max(ar3ccf.getCF()), 'r')
plt.plot([arhpick.getpick(), arhpick.getpick()], [-1, 1], 'b')
plt.plot([arhpick.getpick() - 0.5, arhpick.getpick() + 0.5], [-1, -1], 'b')
plt.plot([arhpick.getpick() - 0.5, arhpick.getpick() + 0.5], [1, 1], 'b')
plt.yticks([])
plt.ylabel('Normalized Counts')
plt.title([trH2_filt.stats.station, trH2_filt.stats.channel])
plt.xlabel('Time [s]')
plt.show()
raw_input()
plt.close()
parser = argparse.ArgumentParser()
parser.add_argument('--project', type=str, help='project name (e.g. Insheim)')
parser.add_argument('--database', type=str, help='event data base (e.g. 2014.09_Insheim)')
parser.add_argument('--event', type=str, help='event ID (e.g. e0010.015.14)')
parser.add_argument('--iplot', help='anything, if set, figure occurs')
parser.add_argument('--station', type=str, help='Station ID (e.g. INS3) (optional)')
args = parser.parse_args()
run_makeCF(args.project, args.database, args.event, args.iplot, args.station)
+2 -2
View File
@@ -4,11 +4,11 @@ from distutils.core import setup
setup(
name='PyLoT',
version='0.2',
version='0.1a1',
packages=['pylot', 'pylot.core', 'pylot.core.loc', 'pylot.core.pick',
'pylot.core.io', 'pylot.core.util', 'pylot.core.active',
'pylot.core.analysis', 'pylot.testing'],
requires=['obspy', 'PySide', 'matplotlib', 'numpy'],
requires=['obspy', 'PySide'],
url='dummy',
license='LGPLv3',
author='Sebastian Wehling-Benatelli',