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, \ from PySide.QtGui import QMainWindow, QInputDialog, QIcon, QFileDialog, \
QWidget, QHBoxLayout, QVBoxLayout, QStyle, QKeySequence, QLabel, QFrame, QAction, \ QWidget, QHBoxLayout, QVBoxLayout, QStyle, QKeySequence, QLabel, QFrame, QAction, \
QDialog, QErrorMessage, QApplication, QPixmap, QMessageBox, QSplashScreen, \ QDialog, QErrorMessage, QApplication, QPixmap, QMessageBox, QSplashScreen, \
QActionGroup, QListWidget, QLineEdit, QListView, QAbstractItemView, \ QActionGroup, QListWidget, QDockWidget, QLineEdit, QListView, QAbstractItemView, \
QTreeView, QComboBox, QTabWidget, QPushButton, QGridLayout QTreeView, QComboBox, QTabWidget, QPushButton, QGridLayout
import numpy as np import numpy as np
from obspy import UTCDateTime from obspy import UTCDateTime
@@ -49,7 +49,7 @@ from obspy.core.util import AttribDict
try: try:
import pyqtgraph as pg import pyqtgraph as pg
except Exception as e: except Exception as e:
print('PyLoT: Could not import pyqtgraph. {}'.format(e)) print('QtPyLoT: Could not import pyqtgraph. {}'.format(e))
pg = None pg = None
try: try:
@@ -64,18 +64,18 @@ from pylot.core.io.data import Data
from pylot.core.io.inputs import FilterOptions, PylotParameter from pylot.core.io.inputs import FilterOptions, PylotParameter
from autoPyLoT import autoPyLoT from autoPyLoT import autoPyLoT
from pylot.core.pick.compare import Comparison from pylot.core.pick.compare import Comparison
from pylot.core.pick.utils import symmetrize_error, getQualityFromUncertainty from pylot.core.pick.utils import symmetrize_error, getQualityFromUncertainty, removePicksAbove
from pylot.core.io.phases import picksdict_from_picks from pylot.core.io.phases import picksdict_from_picks
import pylot.core.loc.nll as nll import pylot.core.loc.nll as nll
from pylot.core.util.defaults import FILTERDEFAULTS, SetChannelComponents from pylot.core.util.defaults import FILTERDEFAULTS, SetChannelComponents
from pylot.core.util.errors import DatastructureError, \ from pylot.core.util.errors import FormatError, DatastructureError, \
OverwriteError OverwriteError
from pylot.core.util.connection import checkurl from pylot.core.util.connection import checkurl
from pylot.core.util.dataprocessing import read_metadata, restitute_data from pylot.core.util.dataprocessing import read_metadata, restitute_data
from pylot.core.util.utils import fnConstructor, getLogin, \ from pylot.core.util.utils import fnConstructor, getLogin, \
full_range, readFilterInformation, trim_station_components, check4gaps, make_pen, pick_color_plt, \ full_range, readFilterInformation, trim_station_components, check4gaps, make_pen, pick_color_plt, \
pick_linestyle_plt, remove_underscores, check4doubled, identifyPhaseID, excludeQualityClasses, has_spe, \ 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.util.event import Event
from pylot.core.io.location import create_creation_info, create_event from pylot.core.io.location import create_creation_info, create_event
from pylot.core.util.widgets import FilterOptionsDialog, NewEventDlg, \ 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.thread import Thread, Worker
from pylot.core.util.version import get_git_version as _getVersionString from pylot.core.util.version import get_git_version as _getVersionString
from pylot.styles import style_settings
if sys.version_info.major == 3: if sys.version_info.major == 3:
import icons_rc_3 as icons_rc import icons_rc_3 as icons_rc
elif sys.version_info.major == 2: elif sys.version_info.major == 2:
@@ -112,7 +110,6 @@ class MainWindow(QMainWindow):
print('Using default input file {}'.format(infile)) print('Using default input file {}'.format(infile))
if os.path.isfile(infile) == False: if os.path.isfile(infile) == False:
infile = QFileDialog().getOpenFileName(caption='Choose PyLoT-input file') infile = QFileDialog().getOpenFileName(caption='Choose PyLoT-input file')
if not os.path.exists(infile[0]): if not os.path.exists(infile[0]):
QMessageBox.warning(self, "PyLoT Warning", QMessageBox.warning(self, "PyLoT Warning",
"No PyLoT-input file declared!") "No PyLoT-input file declared!")
@@ -127,7 +124,6 @@ class MainWindow(QMainWindow):
self.project = Project() self.project = Project()
self.project.parameter = self._inputs self.project.parameter = self._inputs
self.tap = None self.tap = None
self.apw = None
self.paraBox = None self.paraBox = None
self.array_map = None self.array_map = None
self._metadata = None self._metadata = None
@@ -144,6 +140,12 @@ class MainWindow(QMainWindow):
# default factor for dataplot e.g. enabling/disabling scrollarea # default factor for dataplot e.g. enabling/disabling scrollarea
self.height_factor = 12 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 # UI has to be set up before(!) children widgets are about to show up
self.createAction = createAction self.createAction = createAction
# read settings # read settings
@@ -172,8 +174,6 @@ class MainWindow(QMainWindow):
self.fnames = None self.fnames = None
self._stime = None self._stime = None
structure_setting = settings.value("data/Structure", "PILOT") structure_setting = settings.value("data/Structure", "PILOT")
if not structure_setting:
structure_setting = 'PILOT'
self.dataStructure = DATASTRUCTURE[structure_setting]() self.dataStructure = DATASTRUCTURE[structure_setting]()
self.seismicPhase = str(settings.value("phase", "P")) self.seismicPhase = str(settings.value("phase", "P"))
if settings.value("data/dataRoot", None) is None: if settings.value("data/dataRoot", None) is None:
@@ -210,8 +210,6 @@ class MainWindow(QMainWindow):
except: except:
self.startTime = UTCDateTime() self.startTime = UTCDateTime()
self.init_styles()
pylot_icon = QIcon() pylot_icon = QIcon()
pylot_icon.addPixmap(QPixmap(':/icons/pylot.png')) pylot_icon.addPixmap(QPixmap(':/icons/pylot.png'))
@@ -553,13 +551,6 @@ class MainWindow(QMainWindow):
self.addActions(toolbars["autoPyLoT"], pickActions) self.addActions(toolbars["autoPyLoT"], pickActions)
self.addActions(toolbars["LocationTools"], locationToolActions) 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 # add event combo box and ref/test buttons
self.eventBox = self.createEventBox() self.eventBox = self.createEventBox()
@@ -576,24 +567,21 @@ class MainWindow(QMainWindow):
self.eventBox.activated.connect(self.refreshEvents) self.eventBox.activated.connect(self.refreshEvents)
# add main tab widget # add main tab widget
self.tabs = QTabWidget(self) self.tabs = QTabWidget()
self._main_layout.addWidget(self.tabs) self._main_layout.addWidget(self.tabs)
self.tabs.currentChanged.connect(self.refreshTabs) 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 # 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 # create central matplotlib figure canvas widget
self.pg = pg
self.init_wfWidget() self.init_wfWidget()
# init main widgets for main tabs # init main widgets for main tabs
wf_tab = QtGui.QWidget(self) wf_tab = QtGui.QWidget()
array_tab = QtGui.QWidget(self) array_tab = QtGui.QWidget()
events_tab = QtGui.QWidget(self) events_tab = QtGui.QWidget()
# init main widgets layouts # init main widgets layouts
self.wf_layout = QtGui.QVBoxLayout() self.wf_layout = QtGui.QVBoxLayout()
@@ -636,8 +624,8 @@ class MainWindow(QMainWindow):
self.dataPlot = PylotCanvas(parent=self, connect_events=False, multicursor=True) self.dataPlot = PylotCanvas(parent=self, connect_events=False, multicursor=True)
self.dataPlot.updateWidget(xlab, None, plottitle) self.dataPlot.updateWidget(xlab, None, plottitle)
else: else:
self.pg = pg self.pg = True
self.dataPlot = WaveformWidgetPG(parent=self, self.dataPlot = WaveformWidgetPG(parent=self, xlabel=xlab, ylabel=None,
title=plottitle) title=plottitle)
self.dataPlot.setCursor(Qt.CrossCursor) self.dataPlot.setCursor(Qt.CrossCursor)
self.wf_scroll_area.setWidget(self.dataPlot) 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. 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.test_event_button = QtGui.QPushButton('Test')
self.ref_event_button.setToolTip('Set manual picks of current ' + self.ref_event_button.setToolTip('Set manual picks of current ' +
'event as reference picks for autopicker tuning.') 'event as reference picks for autopicker tuning.')
@@ -656,8 +644,8 @@ class MainWindow(QMainWindow):
'event as test picks for autopicker testing.') 'event as test picks for autopicker testing.')
self.ref_event_button.setCheckable(True) self.ref_event_button.setCheckable(True)
self.test_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_color(self.ref_event_button, self._colors['ref'])
self.set_button_border_color(self.test_event_button, self._style['test']['rgba']) self.set_button_color(self.test_event_button, self._colors['test'])
self.ref_event_button.clicked.connect(self.toggleRef) self.ref_event_button.clicked.connect(self.toggleRef)
self.test_event_button.clicked.connect(self.toggleTest) self.test_event_button.clicked.connect(self.toggleTest)
self.ref_event_button.setEnabled(False) self.ref_event_button.setEnabled(False)
@@ -675,86 +663,6 @@ class MainWindow(QMainWindow):
if event.key() == QtCore.Qt.Key.Key_Shift: if event.key() == QtCore.Qt.Key.Key_Shift:
self._shift = False 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 @property
def metadata(self): def metadata(self):
return self._metadata return self._metadata
@@ -806,8 +714,12 @@ class MainWindow(QMainWindow):
settings = QSettings() settings = QSettings()
return settings.value("data/dataRoot") return settings.value("data/dataRoot")
def load_autopicks(self, fname=None):
self.load_data(fname, type='auto')
def load_loc(self, fname=None): 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): def load_pilotevent(self):
filt = "PILOT location files (*LOC*.mat)" filt = "PILOT location files (*LOC*.mat)"
@@ -822,8 +734,10 @@ class MainWindow(QMainWindow):
filter=filt, dir=loc_dir) filter=filt, dir=loc_dir)
fn_phases = fn_phases[0] fn_phases = fn_phases[0]
type = getDataType(self)
fname_dict = dict(phasfn=fn_phases, locfn=fn_loc) 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): def load_multiple_data(self):
if not self.okToContinue(): if not self.okToContinue():
@@ -888,27 +802,20 @@ class MainWindow(QMainWindow):
def add_recentfile(self, event): def add_recentfile(self, event):
self.recentfiles.insert(0, 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. Set background color of a button.
button: type = QtGui.QAbstractButton button: type = QtGui.QAbstractButton
color: type = QtGui.QColor or type = str (RGBA) color: type = QtGui.QColor or type = str (RGBA)
''' '''
if type(color) == QtGui.QColor: if type(color) == QtGui.QColor:
button.setStyleSheet({'QPushButton{background-color:transparent}'})
palette = button.palette() palette = button.palette()
role = button.backgroundRole() role = button.backgroundRole()
palette.setColor(role, color) palette.setColor(role, color)
button.setPalette(palette) button.setPalette(palette)
button.setAutoFillBackground(True) button.setAutoFillBackground(True)
elif type(color) == str: elif type(color) == str or not color:
button.setStyleSheet('QPushButton{border-color: %s}' button.setStyleSheet("background-color: {}".format(color))
'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'])
def getWFFnames(self): def getWFFnames(self):
try: try:
@@ -964,7 +871,7 @@ class MainWindow(QMainWindow):
def get_current_event(self, eventbox=None): 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: if not eventbox:
eventbox = self.eventBox eventbox = self.eventBox
@@ -973,7 +880,7 @@ class MainWindow(QMainWindow):
def get_current_event_path(self, eventbox=None): 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) event = self.get_current_event(eventbox)
if event: if event:
@@ -981,7 +888,7 @@ class MainWindow(QMainWindow):
def get_current_event_name(self, eventbox=None): 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) path = self.get_current_event_path(eventbox)
if path: if path:
@@ -1122,7 +1029,7 @@ class MainWindow(QMainWindow):
''' '''
# if pick widget is open, refresh tooltips as well # if pick widget is open, refresh tooltips as well
if self.apw: if hasattr(self, 'apw'):
self.apw.refresh_tooltips() self.apw.refresh_tooltips()
if hasattr(self, 'cmpw'): if hasattr(self, 'cmpw'):
self.cmpw.refresh_tooltips() self.cmpw.refresh_tooltips()
@@ -1184,9 +1091,9 @@ class MainWindow(QMainWindow):
item_ref = QtGui.QStandardItem() # str(event_ref)) item_ref = QtGui.QStandardItem() # str(event_ref))
item_test = QtGui.QStandardItem() # str(event_test)) item_test = QtGui.QStandardItem() # str(event_test))
if event_ref: if event_ref:
item_ref.setBackground(self._ref_test_colors['ref']) item_ref.setBackground(self._colors['ref'])
if event_test: if event_test:
item_test.setBackground(self._ref_test_colors['test']) item_test.setBackground(self._colors['test'])
item_notes = QtGui.QStandardItem(event.notes) item_notes = QtGui.QStandardItem(event.notes)
openIcon = self.style().standardIcon(QStyle.SP_DirOpenIcon) openIcon = self.style().standardIcon(QStyle.SP_DirOpenIcon)
@@ -1342,11 +1249,10 @@ class MainWindow(QMainWindow):
if len(eventdict) < 1: if len(eventdict) < 1:
return return
# init event selection options for autopick # init event selection options for autopick
self.compareoptions =[('tune events', self.get_ref_events, self._style['ref']['rgba']), self.compareoptions =[('tune events', self.get_ref_events),
('test events', self.get_test_events, self._style['test']['rgba']), ('test events', self.get_test_events),
('all (picked) events', self.get_manu_picked_events, None)] ('all (picked) events', self.get_manu_picked_events)]
self.cmpw = CompareEventsWidget(self, self.compareoptions, eventdict, comparisons) self.cmpw = CompareEventsWidget(self, self.compareoptions, eventdict, comparisons)
self.cmpw.start.connect(self.compareMulti) self.cmpw.start.connect(self.compareMulti)
@@ -1354,9 +1260,7 @@ class MainWindow(QMainWindow):
self.cmpw.show() self.cmpw.show()
def compareMulti(self): def compareMulti(self):
if not self.compareoptions: for key, func in self.compareoptions:
return
for key, func, color in self.compareoptions:
if self.cmpw.rb_dict[key].isChecked(): if self.cmpw.rb_dict[key].isChecked():
# if radio button is checked break for loop and use func # if radio button is checked break for loop and use func
break break
@@ -1370,10 +1274,7 @@ class MainWindow(QMainWindow):
def buildMultiCompareWidget(self, eventlist): def buildMultiCompareWidget(self, eventlist):
global_comparison = Comparison(eventlist=eventlist) global_comparison = Comparison(eventlist=eventlist)
compare_widget = ComparisonWidget(global_comparison, self) compare_widget = ComparisonWidget(global_comparison, self)
for events_name, rb in self.cmpw.rb_dict.items(): compare_widget.setWindowTitle('Histograms for all selected events')
if rb.isChecked():
break
compare_widget.setWindowTitle('Histograms for {}'.format(events_name))
compare_widget.hideToolbar() compare_widget.hideToolbar()
compare_widget.setHistboxChecked(True) compare_widget.setHistboxChecked(True)
return compare_widget return compare_widget
@@ -1531,8 +1432,7 @@ class MainWindow(QMainWindow):
''' '''
if load: if load:
self.wfd_thread = Thread(self, self.loadWaveformData, self.wfd_thread = Thread(self, self.loadWaveformData,
progressText='Reading data input...', progressText='Reading data input...')
pb_widget=self.mainProgressBarWidget)
if load and plot: if load and plot:
self.wfd_thread.finished.connect(self.plotWaveformDataThread) self.wfd_thread.finished.connect(self.plotWaveformDataThread)
@@ -1562,7 +1462,7 @@ class MainWindow(QMainWindow):
check4gaps(wfdat) check4gaps(wfdat)
check4doubled(wfdat) check4doubled(wfdat)
# check for stations with rotated components # 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 to same start value
trim_station_components(wfdat, trim_start=True, trim_end=False) trim_station_components(wfdat, trim_start=True, trim_end=False)
self._stime = full_range(self.get_data().getWFData())[0] self._stime = full_range(self.get_data().getWFData())[0]
@@ -1622,8 +1522,7 @@ class MainWindow(QMainWindow):
self.getPlotWidget().updateWidget() self.getPlotWidget().updateWidget()
plots = self.wfp_thread.data plots = self.wfp_thread.data
for times, data in plots: for times, data in plots:
self.dataPlot.plotWidget.getPlotItem().plot(times, data, self.dataPlot.plotWidget.getPlotItem().plot(times, data, pen='k')
pen=self.dataPlot.pen_linecolor)
self.dataPlot.reinitMoveProxy() self.dataPlot.reinitMoveProxy()
self.dataPlot.plotWidget.showAxis('left') self.dataPlot.plotWidget.showAxis('left')
self.dataPlot.plotWidget.showAxis('bottom') self.dataPlot.plotWidget.showAxis('bottom')
@@ -1633,7 +1532,7 @@ class MainWindow(QMainWindow):
if self.pg: if self.pg:
self.finish_pg_plot() self.finish_pg_plot()
else: else:
self._max_xlims = self.dataPlot.getXLims(self.dataPlot.axes[0]) self._max_xlims = self.dataPlot.getXLims()
plotWidget = self.getPlotWidget() plotWidget = self.getPlotWidget()
plotDict = plotWidget.getPlotDict() plotDict = plotWidget.getPlotDict()
pos = plotDict.keys() pos = plotDict.keys()
@@ -1671,22 +1570,10 @@ class MainWindow(QMainWindow):
if event.pylot_picks and event.pylot_autopicks: if event.pylot_picks and event.pylot_autopicks:
for station in event.pylot_picks: for station in event.pylot_picks:
if station in event.pylot_autopicks: if station in event.pylot_autopicks:
try:
autopick_p = event.pylot_autopicks[station]['P']['spe'] autopick_p = event.pylot_autopicks[station]['P']['spe']
except KeyError:
autopick_p = None
try:
manupick_p = event.pylot_picks[station]['P']['spe'] manupick_p = event.pylot_picks[station]['P']['spe']
except KeyError:
manupick_p = None
try:
autopick_s = event.pylot_autopicks[station]['S']['spe'] autopick_s = event.pylot_autopicks[station]['S']['spe']
except KeyError:
autopick_s = None
try:
manupick_s = event.pylot_picks[station]['S']['spe'] manupick_s = event.pylot_picks[station]['S']['spe']
except KeyError:
manupick_s = None
if autopick_p and manupick_p: if autopick_p and manupick_p:
return True return True
elif autopick_s and manupick_s: elif autopick_s and manupick_s:
@@ -1707,7 +1594,7 @@ class MainWindow(QMainWindow):
self.dataPlot.plotWidget.hideAxis('bottom') self.dataPlot.plotWidget.hideAxis('bottom')
self.dataPlot.plotWidget.hideAxis('left') self.dataPlot.plotWidget.hideAxis('left')
else: else:
self.dataPlot.axes[0].cla() self.dataPlot.getAxes().cla()
self.loadlocationaction.setEnabled(False) self.loadlocationaction.setEnabled(False)
self.auto_tune.setEnabled(False) self.auto_tune.setEnabled(False)
self.auto_pick.setEnabled(False) self.auto_pick.setEnabled(False)
@@ -1729,8 +1616,7 @@ class MainWindow(QMainWindow):
''' '''
self.clearWaveformDataPlot() self.clearWaveformDataPlot()
self.wfp_thread = Thread(self, self.plotWaveformData, self.wfp_thread = Thread(self, self.plotWaveformData,
progressText='Plotting waveform data...', progressText='Plotting waveform data...')
pb_widget=self.mainProgressBarWidget)
self.wfp_thread.finished.connect(self.finishWaveformDataPlot) self.wfp_thread.finished.connect(self.finishWaveformDataPlot)
self.wfp_thread.start() self.wfp_thread.start()
@@ -1866,27 +1752,27 @@ class MainWindow(QMainWindow):
self.checkFilterOptions() self.checkFilterOptions()
# def updateFilterOptions(self): def updateFilterOptions(self):
# try: try:
# settings = QSettings() settings = QSettings()
# if settings.value("filterdefaults", if settings.value("filterdefaults",
# None) is None and not self.getFilters(): None) is None and not self.getFilters():
# for key, value in FILTERDEFAULTS.items(): for key, value in FILTERDEFAULTS.items():
# self.setFilterOptions(FilterOptions(**value), key) self.setFilterOptions(FilterOptions(**value), key)
# elif settings.value("filterdefaults", None) is not None: elif settings.value("filterdefaults", None) is not None:
# for key, value in settings.value("filterdefaults"): for key, value in settings.value("filterdefaults"):
# self.setFilterOptions(FilterOptions(**value), key) self.setFilterOptions(FilterOptions(**value), key)
# except Exception as e: except Exception as e:
# self.update_status('Error ...') self.update_status('Error ...')
# emsg = QErrorMessage(self) emsg = QErrorMessage(self)
# emsg.showMessage('Error: {0}'.format(e)) emsg.showMessage('Error: {0}'.format(e))
# else: else:
# self.update_status('Filter loaded ... ' self.update_status('Filter loaded ... '
# '[{0}: {1} Hz]'.format( '[{0}: {1} Hz]'.format(
# self.getFilterOptions().getFilterType(), self.getFilterOptions().getFilterType(),
# self.getFilterOptions().getFreq())) self.getFilterOptions().getFreq()))
# if self.filterAction.isChecked(): if self.filterAction.isChecked():
# self.filterWaveformData() self.filterWaveformData()
def getSeismicPhase(self): def getSeismicPhase(self):
return self.seismicPhase return self.seismicPhase
@@ -2020,35 +1906,26 @@ class MainWindow(QMainWindow):
'el_S1pick', 'el_S1pick',
'el_S2pick', 'el_S2pick',
'refSpick', 'refSpick',
'aicARHfig', 'aicARHfig'
'plot_style'
] ]
for key in self.fig_keys: for key in self.fig_keys:
if key == 'plot_style':
fig = self._style
else:
fig = Figure() fig = Figure()
self.fig_dict[key] = fig self.fig_dict[key] = fig
def init_canvas_dict(self): def init_canvas_dict(self):
self.canvas_dict = {} self.canvas_dict = {}
for key in self.fig_keys: for key in self.fig_keys:
if not key == 'plot_style': self.canvas_dict[key] = PylotCanvas(self.fig_dict[key])
self.canvas_dict[key] = PylotCanvas(self.fig_dict[key], parent=self)
def init_fig_dict_wadatijack(self, eventIDs): def init_fig_dict_wadatijack(self, eventIDs):
self.fig_dict_wadatijack = {} self.fig_dict_wadatijack = {}
self.fig_keys_wadatijack = [ self.fig_keys_wadatijack = [
'jackknife', 'jackknife',
'wadati', 'wadati'
'plot_style'
] ]
for eventID in eventIDs: for eventID in eventIDs:
self.fig_dict_wadatijack[eventID] = {} self.fig_dict_wadatijack[eventID] = {}
for key in self.fig_keys_wadatijack: for key in self.fig_keys_wadatijack:
if key == 'plot_style':
fig = self._style
else:
fig = Figure() fig = Figure()
self.fig_dict_wadatijack[eventID][key] = fig self.fig_dict_wadatijack[eventID][key] = fig
@@ -2057,9 +1934,7 @@ class MainWindow(QMainWindow):
for eventID in self.fig_dict_wadatijack.keys(): for eventID in self.fig_dict_wadatijack.keys():
self.canvas_dict_wadatijack[eventID] = {} self.canvas_dict_wadatijack[eventID] = {}
for key in self.fig_keys_wadatijack: 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])
self.canvas_dict_wadatijack[eventID][key] = PylotCanvas(self.fig_dict_wadatijack[eventID][key],
parent=self)
def tune_autopicker(self): def tune_autopicker(self):
''' '''
@@ -2092,14 +1967,6 @@ class MainWindow(QMainWindow):
self.tap.fill_tabs(picked=True) self.tap.fill_tabs(picked=True)
for canvas in self.canvas_dict.values(): for canvas in self.canvas_dict.values():
canvas.setZoomBorders2content() 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): def autoPick(self):
autosave = self.get_current_event_path() autosave = self.get_current_event_path()
@@ -2108,13 +1975,12 @@ class MainWindow(QMainWindow):
"No autoPyLoT output declared!") "No autoPyLoT output declared!")
return return
if not self.apw:
# init event selection options for autopick # init event selection options for autopick
self.pickoptions =[('current event', self.get_current_event, None), self.pickoptions =[('current event', self.get_current_event),
('tune events', self.get_ref_events, self._style['ref']['rgba']), ('tune events', self.get_ref_events),
('test events', self.get_test_events, self._style['test']['rgba']), ('test events', self.get_test_events),
('all (picked) events', self.get_manu_picked_events, None), ('all (picked) events', self.get_manu_picked_events),
('all events', self.get_all_events, None)] ('all events', self.get_all_events)]
self.listWidget = QListWidget() self.listWidget = QListWidget()
self.setDirty(True) self.setDirty(True)
@@ -2126,9 +1992,7 @@ class MainWindow(QMainWindow):
self.apw.show() self.apw.show()
def start_autopick(self): def start_autopick(self):
if not self.pickoptions: for key, func in self.pickoptions:
return
for key, func, _ in self.pickoptions:
if self.apw.rb_dict[key].isChecked(): if self.apw.rb_dict[key].isChecked():
# if radio button is checked break for loop and use func # if radio button is checked break for loop and use func
break break
@@ -2188,6 +2052,7 @@ class MainWindow(QMainWindow):
def finalizeAutoPick(self, result): def finalizeAutoPick(self, result):
self.apw.enable(True) self.apw.enable(True)
if result: if result:
result = removePicksAbove(result, 3)
self.init_canvas_dict_wadatijack() self.init_canvas_dict_wadatijack()
for eventID in result.keys(): for eventID in result.keys():
event = self.get_event_from_id(eventID) event = self.get_event_from_id(eventID)
@@ -2314,7 +2179,7 @@ class MainWindow(QMainWindow):
if self.pg: if self.pg:
pw = self.getPlotWidget().plotWidget pw = self.getPlotWidget().plotWidget
else: else:
ax = self.getPlotWidget().axes[0] ax = self.getPlotWidget().axes
ylims = np.array([-.5, +.5]) + plotID ylims = np.array([-.5, +.5]) + plotID
stat_picks = self.getPicks(type=picktype)[station] stat_picks = self.getPicks(type=picktype)[station]
@@ -2355,7 +2220,6 @@ class MainWindow(QMainWindow):
pen = make_pen(picktype, phaseID, 'lpp', quality) pen = make_pen(picktype, phaseID, 'lpp', quality)
pw.plot([lpp, lpp], ylims, pw.plot([lpp, lpp], ylims,
alpha=.25, pen=pen, name='LPP') alpha=.25, pen=pen, name='LPP')
pen = make_pen(picktype, phaseID, 'mpp', quality)
if spe: if spe:
# pen = make_pen(picktype, phaseID, 'spe', quality) # pen = make_pen(picktype, phaseID, 'spe', quality)
# spe_l = pg.PlotDataItem([mpp - spe, mpp - spe], ylims, pen=pen, # spe_l = pg.PlotDataItem([mpp - spe, mpp - spe], ylims, pen=pen,
@@ -2372,6 +2236,7 @@ class MainWindow(QMainWindow):
# fb = pw.addItem(fill) # fb = pw.addItem(fill)
# except: # except:
# print('Warning: drawPicks: Could not create fill for symmetric pick error.') # 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)) pw.plot([mpp, mpp], ylims, pen=pen, name='{}-Pick'.format(phase))
else: else:
pw.plot([mpp, mpp], ylims, pen=pen, name='{}-Pick (NO PICKERROR)'.format(phase)) 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. Start modal thread to init the array_map object.
''' '''
# Note: basemap generation freezes GUI but cannot be threaded as it generates a Pixmap. # 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...', self.amt = Thread(self, self.array_map.init_map, arg=None, progressText='Generating map...')
pb_widget=self.mainProgressBarWidget)
self.amt.finished.connect(self.finish_array_map) self.amt.finished.connect(self.finish_array_map)
self.amt.start() self.amt.start()
@@ -2572,7 +2436,7 @@ class MainWindow(QMainWindow):
lon = event.origins[0].longitude lon = event.origins[0].longitude
self.array_map.eventLoc = (lat, lon) self.array_map.eventLoc = (lat, lon)
if self.get_current_event(): 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 self._eventChanged[1] = False
def init_event_table(self, tabindex=2): def init_event_table(self, tabindex=2):
@@ -2636,7 +2500,7 @@ class MainWindow(QMainWindow):
self.events_layout.removeWidget(self.event_table) self.events_layout.removeWidget(self.event_table)
# init new qtable # init new qtable
self.event_table = QtGui.QTableWidget(self) self.event_table = QtGui.QTableWidget()
self.event_table.setColumnCount(12) self.event_table.setColumnCount(12)
self.event_table.setRowCount(len(eventlist)) self.event_table.setRowCount(len(eventlist))
self.event_table.setHorizontalHeaderLabels(['', self.event_table.setHorizontalHeaderLabels(['',
@@ -2690,8 +2554,8 @@ class MainWindow(QMainWindow):
item_notes = QtGui.QTableWidgetItem() item_notes = QtGui.QTableWidgetItem()
# manipulate items # manipulate items
item_ref.setBackground(self._ref_test_colors['ref']) item_ref.setBackground(self._colors['ref'])
item_test.setBackground(self._ref_test_colors['test']) item_test.setBackground(self._colors['test'])
item_path.setText(event.path) item_path.setText(event.path)
if hasattr(event, 'origins'): if hasattr(event, 'origins'):
if event.origins: if event.origins:
@@ -2747,8 +2611,7 @@ class MainWindow(QMainWindow):
self.tabs.setCurrentIndex(tabindex) self.tabs.setCurrentIndex(tabindex)
def read_metadata_thread(self, fninv): def read_metadata_thread(self, fninv):
self.rm_thread = Thread(self, read_metadata, arg=fninv, progressText='Reading metadata...', self.rm_thread = Thread(self, read_metadata, arg=fninv, progressText='Reading metadata...')
pb_widget=self.mainProgressBarWidget)
self.rm_thread.finished.connect(self.set_metadata) self.rm_thread.finished.connect(self.set_metadata)
self.rm_thread.start() self.rm_thread.start()
@@ -2766,7 +2629,7 @@ class MainWindow(QMainWindow):
def get_new_metadata(self): def get_new_metadata(self):
self.init_metadata(new=True) self.init_metadata(new=True)
def init_metadata(self, new=False, ask_default=True): def init_metadata(self, new=False):
def set_inv(settings): def set_inv(settings):
fninv, _ = QFileDialog.getOpenFileName(self, self.tr( fninv, _ = QFileDialog.getOpenFileName(self, self.tr(
"Select inventory..."), self.tr("Select file")) "Select inventory..."), self.tr("Select file"))
@@ -2795,7 +2658,7 @@ class MainWindow(QMainWindow):
settings.setValue("inventoryFile", self.project.inv_path) settings.setValue("inventoryFile", self.project.inv_path)
fninv = settings.value("inventoryFile", None) fninv = settings.value("inventoryFile", None)
if fninv and ask_default: if fninv:
ans = QMessageBox.question(self, self.tr("Use default metadata..."), ans = QMessageBox.question(self, self.tr("Use default metadata..."),
self.tr( self.tr(
"Do you want to use the default value for metadata?\n({})".format(fninv)), "Do you want to use the default value for metadata?\n({})".format(fninv)),
@@ -2806,8 +2669,6 @@ class MainWindow(QMainWindow):
return None return None
elif ans == QMessageBox.Yes: elif ans == QMessageBox.Yes:
self.read_metadata_thread(fninv) self.read_metadata_thread(fninv)
if fninv and not ask_default:
self.read_metadata_thread(fninv)
def calc_magnitude(self, type='ML'): def calc_magnitude(self, type='ML'):
self.init_metadata() self.init_metadata()
@@ -2820,7 +2681,7 @@ class MainWindow(QMainWindow):
# raise ProcessingError('Restitution of waveform data failed!') # raise ProcessingError('Restitution of waveform data failed!')
if type == 'ML': if type == 'ML':
local_mag = LocalMagnitude(corr_wf, self.get_data().get_evt_data(), self.inputs.get('sstop'), 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() return local_mag.updated_event()
elif type == 'Mw': elif type == 'Mw':
moment_mag = MomentMagnitude(corr_wf, self.get_data().get_evt_data(), self.inputs.get('vp'), 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(): if not self.okToContinue():
return return
if not fnm: if not fnm:
dlg = QFileDialog(parent=self) dlg = QFileDialog()
fnm = dlg.getOpenFileName(self, 'Open project file...', filter='Pylot project (*.plp)') fnm = dlg.getOpenFileName(self, 'Open project file...', filter='Pylot project (*.plp)')
if not fnm: if not fnm:
return return
@@ -2931,12 +2792,10 @@ class MainWindow(QMainWindow):
self.setDirty(False) self.setDirty(False)
if hasattr(self.project, 'metadata'): if hasattr(self.project, 'metadata'):
if 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 return
if hasattr(self.project, 'inv_path'): 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 return
self.init_array_tab() self.init_array_tab()
@@ -2945,7 +2804,7 @@ class MainWindow(QMainWindow):
''' '''
Save back project to new pickle file. 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)') fnm = dlg.getSaveFileName(self, 'Create a new project file...', filter='Pylot project (*.plp)')
filename = fnm[0] filename = fnm[0]
if not len(fnm[0]): if not len(fnm[0]):
@@ -3007,7 +2866,7 @@ class MainWindow(QMainWindow):
def setParameter(self, show=True): def setParameter(self, show=True):
if not self.paraBox: 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._setDirty)
self.paraBox.accepted.connect(self.filterOptionsFromParameter) self.paraBox.accepted.connect(self.filterOptionsFromParameter)
if show: if show:
@@ -3025,16 +2884,16 @@ class MainWindow(QMainWindow):
def helpHelp(self): def helpHelp(self):
if checkurl(): if checkurl():
form = HelpForm(self, form = HelpForm(
'https://ariadne.geophysik.ruhr-uni-bochum.de/trac/PyLoT/wiki') 'https://ariadne.geophysik.ruhr-uni-bochum.de/trac/PyLoT/wiki')
else: else:
form = HelpForm(self, ':/help.html') form = HelpForm(':/help.html')
form.show() form.show()
class Project(object): 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): def __init__(self):
@@ -3099,7 +2958,7 @@ class Project(object):
print(e, datetime, filename) print(e, datetime, filename)
continue continue
for event in self.eventlist: 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: if event.origins:
origin = event.origins[0] # should have only one origin origin = event.origins[0] # should have only one origin
if origin.time == datetime: if origin.time == datetime:
@@ -3219,10 +3078,9 @@ def create_window():
if app is None: if app is None:
app = QApplication(sys.argv) app = QApplication(sys.argv)
app_created = True app_created = True
# set aplication/organization name, domain (important to do this BEFORE setupUI is called for correct QSettings) app.setOrganizationName("QtPyLoT");
app.setOrganizationName("Ruhr-University Bochum / BESTEC") app.setOrganizationDomain("rub.de");
app.setOrganizationDomain("rub.de") app.setApplicationName("RUB");
app.setApplicationName("PyLoT")
app.references = set() app.references = set()
# app.references.add(window) # app.references.add(window)
# window.show() # window.show()
@@ -3231,7 +3089,6 @@ def create_window():
def main(args=None): def main(args=None):
project_filename = None project_filename = None
#args.project_filename = 'C:/Shared/AlpArray/alparray_data/project_alparray_test.plp'
pylot_infile = None pylot_infile = None
if args: if args:
if args.project_filename: if args.project_filename:
@@ -3251,15 +3108,20 @@ def main(args=None):
# create the main window # create the main window
pylot_form = MainWindow(infile=pylot_infile) pylot_form = MainWindow(infile=pylot_infile)
pylot_form.setWindowIcon(app_icon) icon = QIcon()
pylot_form.setWindowIcon(icon)
pylot_form.setIconSize(QSize(60, 60)) pylot_form.setIconSize(QSize(60, 60))
# set other App information splash.showMessage('Loading. Please wait ...')
pylot_app.setApplicationVersion(pylot_form.__version__)
pylot_app.setWindowIcon(app_icon)
pylot_app.processEvents() 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() pylot_app.processEvents()
# Show main window and run the app # Show main window and run the app
+21 -41
View File
@@ -1,6 +1,6 @@
# PyLoT # PyLoT
version: 0.2 version: 0.1a
The Python picking and Localisation Tool 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 group allows easy handling of a bunch of seismic data and PyLoT will
benefit a lot compared to the former MatLab version. benefit a lot compared to the former MatLab version.
The development of PyLoT is part of the joint research project MAGS2 and AlpArray. The development of PyLoT is part of the joint research project MAGS2.
## Installation ## 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: In order to run PyLoT you need to install:
- python 2 or 3 - python
- scipy - scipy
- numpy - numpy
- matplotlib - matplotlib
@@ -34,24 +34,21 @@ In order to run PyLoT you need to install:
#### Some handwork: #### Some handwork:
PyLoT needs a properties folder on your system to work. It should be situated in your home directory PyLoT needs a properties folder on your system to work. It should be situated in your home directory:
(on Windows usually C:/Users/*username*):
mkdir ~/.pylot mkdir ~/.pylot
In the next step you have to copy some files to this directory: In the next step you have to copy some files to this directory:
*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/autoPyLoT_regional.in ~/.pylot/autoPyLoT.in
cp path-to-pylot/inputs/pylot_global.in ~/.pylot/pylot.in
and some extra information on error estimates (just needed for reading old PILOT data) and the Richter magnitude scaling relation 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. 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 ## Release notes
#### Features: #### Features:
- centralize all functionalities of PyLoT and control them from within the main GUI - consistent manual phase picking through predefined SNR dependant zoom level
- handling multiple events inside GUI with project files (save and load work progress) - uniform uncertainty estimation from waveform's properties for automatic and manual picks
- GUI based adjustments of pick parameters and I/O - pdf representation and comparison of picks taking the uncertainty intrinsically into account
- interactive tuning of parameters from within the GUI - Richter and moment magnitude estimation
- call automatic picking algorithm from within the GUI - location determination with external installation of [NonLinLoc](http://alomax.free.fr/nlloc/index.html)
- 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)
##### Platform support: #### Known issues:
- Python 3 support
- Windows support
##### Performance: - Magnitude estimation from manual PyLoT takes some time (instrument correction)
- multiprocessing for automatic picking and restitution of multiple stations
- use pyqtgraph library for better performance on main waveform plot
##### Visualization: We hope to solve these with the next release.
- 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
## Staff ## Staff
Original author(s): L. Kueperkoch, S. Wehling-Benatelli, M. Bischoff (PILOT) Original author(s): L. Kueperkoch, S. Wehling-Benatelli, M. Bischoff (PILOT)
Developer(s): S. Wehling-Benatelli, L. Kueperkoch, M. Paffrath, K. Olbert, Developer(s): S. Wehling-Benatelli, L. Kueperkoch, K. Olbert, M. Bischoff,
M. Bischoff, C. Wollin, M. Rische C. Wollin, M. Rische, M. Paffrath
Others: A. Bruestle, T. Meier, W. Friederich Others: A. Bruestle, T. Meier, W. Friederich
[ObsPy]: http://github.com/obspy/obspy/wiki [ObsPy]: http://github.com/obspy/obspy/wiki
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 # calculate seismic moment Mo and moment magnitude Mw
moment_mag = MomentMagnitude(corr_dat, evt, parameter.get('vp'), moment_mag = MomentMagnitude(corr_dat, evt, parameter.get('vp'),
parameter.get('Qp'), parameter.get('Qp'),
parameter.get('rho'), True, parameter.get('rho'), True, \
iplot) iplot)
# update pick with moment property values (w0, fc, Mo) # update pick with moment property values (w0, fc, Mo)
for stats, props in moment_mag.moment_props.items(): 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: for key in picks:
if picks[key]['P']['weight'] >= 4 or picks[key]['S']['weight'] >= 4: if picks[key]['P']['weight'] >= 4 or picks[key]['S']['weight'] >= 4:
badpicks.append([key, picks[key]['P']['mpp']]) badpicks.append([key, picks[key]['P']['mpp']])
print("autoPyLoT: After iteration No. %d: %d bad onsets found ..." % (nlloccounter, print("autoPyLoT: After iteration No. %d: %d bad onsets found ..." % (nlloccounter, \
len(badpicks))) len(badpicks)))
if len(badpicks) == 0: if len(badpicks) == 0:
print("autoPyLoT: No more bad onsets found, stop iterative picking!") print("autoPyLoT: No more bad onsets found, stop iterative picking!")
@@ -384,7 +384,7 @@ def autoPyLoT(input_dict=None, parameter=None, inputfile=None, fnames=None, even
# calculate seismic moment Mo and moment magnitude Mw # calculate seismic moment Mo and moment magnitude Mw
moment_mag = MomentMagnitude(corr_dat, evt, parameter.get('vp'), moment_mag = MomentMagnitude(corr_dat, evt, parameter.get('vp'),
parameter.get('Qp'), parameter.get('Qp'),
parameter.get('rho'), True, parameter.get('rho'), True, \
iplot) iplot)
# update pick with moment property values (w0, fc, Mo) # update pick with moment property values (w0, fc, Mo)
for stats, props in moment_mag.moment_props.items(): 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), picks = autoPyLoT(inputfile=str(cla.inputfile), fnames=str(cla.fnames),
eventid=str(cla.eventid), savepath=str(cla.spath), eventid=str(cla.eventid), savepath=str(cla.spath),
ncores=cla.ncores, iplot=int(cla.iplot)) 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> <qresource>
<file>icons/pylot.ico</file> <file>icons/pylot.ico</file>
<file>icons/pylot.png</file> <file>icons/pylot.png</file>
<file>icons/back.png</file>
<file>icons/home.png</file>
<file>icons/newfile.png</file> <file>icons/newfile.png</file>
<file>icons/open.png</file> <file>icons/open.png</file>
<file>icons/openproject.png</file> <file>icons/openproject.png</file>
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! %Parameters are optimized for %extent data sets!
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
#main settings# #main settings#
#rootpath# %project path /home/marcel/marcel_scratch #rootpath# %project path
#datapath# %data path alparray #datapath# %data path
#database# %name of data base waveforms #database# %name of data base
#eventID# %event ID for single event processing (* for all events found in database) e0006.036.13 #eventID# %event ID for single event processing (* for all events found in database)
#invdir# %full path to inventory or dataless-seed file None #invdir# %full path to inventory or dataless-seed file
PILOT #datastructure# %choose data structure PILOT #datastructure# %choose data structure
True #apverbose# %choose 'True' or 'False' for terminal output True #apverbose# %choose 'True' or 'False' for terminal output
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
#NLLoc settings# #NLLoc settings#
None #nllocbin# %path to NLLoc executable /progs/bin #nllocbin# %path to NLLoc executable
None #nllocroot# %root of NLLoc-processing directory /home/ludger/NLLOC/Insheim #nllocroot# %root of NLLoc-processing directory
None #phasefile# %name of autoPyLoT-output phase file for NLLoc AUTOPHASES.obs #phasefile# %name of autoPyLoT-output phase file for NLLoc
None #ctrfile# %name of autoPyLoT-output control file for NLLoc Insheim_min1d032016_auto.in #ctrfile# %name of autoPyLoT-output control file for NLLoc
ttime #ttpatter# %pattern of NLLoc ttimes from grid ttime #ttpatter# %pattern of NLLoc ttimes from grid
AUTOLOC_nlloc #outpatter# %pattern of NLLoc-output file AUTOLOC_nlloc #outpatter# %pattern of NLLoc-output file
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -37,64 +37,62 @@ bandpass bandpass #filter_type# %filter type
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
#common settings picker# #common settings picker#
global #extent# %extent of array ("local", "regional" or "global") 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) 50.0 #pstart# %start time [s] for calculating CF for P-picking
600.0 #pstop# %end 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
200.0 #sstart# %start time [s] relative to P-onset for calculating CF for S-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 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 True #use_taup# %use estimated traveltimes from taupy for calculating windows for CF
iasp91 #taup_model# %define TauPy model for traveltime estimation. Possible values: 1066a, 1066b, ak135, ak135f, herrin, iasp91, jb, prem, pwdk, sp6
0.05 0.5 #bpz1# %lower/upper corner freq. of first band pass filter Z-comp. [Hz] 0.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.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# #special settings for calculating CF#
%!!Edit the following only if you know what you are doing!!% %!!Edit the following only if you know what you are doing!!%
#Z-component# #Z-component#
HOS #algoP# %choose algorithm for P-onset determination (HOS, ARZ, or AR3) 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 4 #hosorder# %for HOS-picker, order of Higher Order Statistics
2 #Parorder# %for AR-picker, order of AR process of Z-component 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 6.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 2.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 3.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 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 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] 60.0 10.0 150.0 3.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] 10.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) 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] 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] 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) 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) 1.1 #nfacP# %for HOS/AR, noise factor for noise level determination (P)
#H-components# #H-components#
ARH #algoS# %choose algorithm for S-onset determination (ARH or AR3) 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 #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 4.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 6.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 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 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) 5.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] 15.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] 100.0 10.0 40.0 6.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] 2.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) 3.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) 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) 1.2 #nfacS# %for AR-picker, noise factor for noise level determination (S)
#first-motion picker# #first-motion picker#
1 #minfmweight# %minimum required P weight for first-motion determination 1 #minfmweight# %minimum required P weight for first-motion determination
3.0 #minFMSNR# %miniumum required SNR for first-motion determination 2.0 #minFMSNR# %miniumum required SNR for first-motion determination
10.0 #fmpickwin# %pick window around P onset for calculating zero crossings 0.2 #fmpickwin# %pick window around P onset for calculating zero crossings
#quality assessment# #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 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 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 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.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.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] 5.0 #minsiglength# %length of signal part for which amplitudes must exceed noiselevel [s]
1.0 #noisefactor# %noiselevel*noisefactor=threshold 1.0 #noisefactor# %noiselevel*noisefactor=threshold
10.0 #minpercent# %required percentage of amplitudes exceeding threshold 10.0 #minpercent# %required percentage of amplitudes exceeding threshold
1.2 #zfac# %P-amplitude must exceed at least zfac times RMS-S amplitude 1.5 #zfac# %P-amplitude must exceed at least zfac times RMS-S amplitude
25.0 #mdttolerance# %maximum allowed deviation of P picks from median [s] 6.0 #mdttolerance# %maximum allowed deviation of P picks from median [s]
50.0 #wdttolerance# %maximum allowed deviation from Wadati-diagram 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
-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): def installPyLoT(verbosity=None):
files_to_copy = {'pylot_local.in': ['~', '.pylot'], files_to_copy = {'autoPyLoT_local.in': ['~', '.pylot'],
'pylot_regional.in': ['~', '.pylot'], 'autoPyLoT_regional.in': ['~', '.pylot']}
'pylot_global.in': ['~', '.pylot']}
if verbosity > 0: if verbosity > 0:
print('starting installation of PyLoT ...') print('starting installation of PyLoT ...')
if verbosity > 1: if verbosity > 1:
print('copying input files into destination folder ...') print('copying input files into destination folder ...')
ans = input('please specify scope of interest ' ans = input('please specify scope of interest '
'([0]=local, 1=regional, 2=global) :') or 0 '([0]=local, 1=regional) :') or 0
if not isinstance(ans, int): if not isinstance(ans, int):
ans = int(ans) ans = int(ans)
if ans == 0: ans = 'local' if ans is 0 else 'regional'
ans = 'local'
elif ans == 1:
ans = 'regional'
elif ans == 2:
ans = 'global'
link_dest = [] link_dest = []
for file, destination in files_to_copy.items(): for file, destination in files_to_copy.items():
link_file = ans in file link_file = ans in file
if link_file: if link_file:
link_dest = copy.deepcopy(destination) link_dest = copy.deepcopy(destination)
link_dest.append('pylot.in') link_dest.append('autoPyLoT.in')
link_dest = os.path.join(*link_dest) link_dest = os.path.join(*link_dest)
destination.append(file) destination.append(file)
destination = os.path.join(*destination) destination = os.path.join(*destination)
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') p3, = plt.loglog(F, YYcor, 'r')
p4, = plt.loglog(F, fit, 'g') p4, = plt.loglog(F, fit, 'g')
plt.loglog([fc, fc], [w0 / 100, w0], 'g') plt.loglog([fc, fc], [w0 / 100, w0], 'g')
plt.legend([p1, p2, p3, p4], ['Raw Spectrum', plt.legend([p1, p2, p3, p4], ['Raw Spectrum', \
'Used Raw Spectrum', 'Used Raw Spectrum', \
'Q-Corrected Spectrum', 'Q-Corrected Spectrum', \
'Fit to Spectrum']) 'Fit to Spectrum'])
plt.title('Source Spectrum from P Pulse, w0=%e m/Hz, fc=%6.2f Hz' \ plt.title('Source Spectrum from P Pulse, w0=%e m/Hz, fc=%6.2f Hz' \
% (w0, fc)) % (w0, fc))
+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 = picks[i].waveform_id.station_code
mstation_ext = mstation + '_' mstation_ext = mstation + '_'
for k in range(len(picks_copy)): 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].waveform_id.station_code == mstation_ext)) and \
(picks_copy[k].method_id == 'auto'): (picks_copy[k].method_id == 'auto'):
del picks_copy[k] del picks_copy[k]
@@ -442,6 +442,7 @@ class Data(object):
else: else:
if self.get_evt_data().picks: if self.get_evt_data().picks:
raise OverwriteError('Existing picks would be overwritten!') raise OverwriteError('Existing picks would be overwritten!')
break
else: else:
picks = picks_from_picksdict(picks) picks = picks_from_picksdict(picks)
break break
+26 -2
View File
@@ -273,6 +273,26 @@ defaults = {'rootpath': {'type': str,
'value': 1.5, 'value': 1.5,
'namestring': 'Noise factor S'}, '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, 'minfmweight': {'type': int,
'tooltip': 'minimum required P weight for first-motion determination', 'tooltip': 'minimum required P weight for first-motion determination',
'value': 1, 'value': 1,
@@ -455,7 +475,9 @@ settings_special_pick = {
'aictsmooth', 'aictsmooth',
'tsmoothP', 'tsmoothP',
'ausP', 'ausP',
'nfacP'], 'nfacP',
'checkwindowP',
'minfactorP'],
'h': [ 'h': [
'algoS', 'algoS',
'tdet1h', 'tdet1h',
@@ -469,7 +491,9 @@ settings_special_pick = {
'aictsmoothS', 'aictsmoothS',
'tsmoothS', 'tsmoothS',
'ausS', 'ausS',
'nfacS'], 'nfacS',
'checkwindowS',
'minfactorS'],
'fm': [ 'fm': [
'minfmweight', 'minfmweight',
'minFMSNR', 'minFMSNR',
+3 -3
View File
@@ -865,7 +865,7 @@ def merge_picks(event, picks):
if p.waveform_id.station_code == station\ if p.waveform_id.station_code == station\
and p.waveform_id.network_code == network\ and p.waveform_id.network_code == network\
and p.phase_hint == phase\ 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)): or str(method) in str(p.method_id)):
p.time, p.time_errors, p.waveform_id.network_code, p.method_id = time, err, network, method p.time, p.time_errors, p.waveform_id.network_code, p.method_id = time, err, network, method
del time, err, phase, station, network, method del time, err, phase, station, network, method
@@ -907,14 +907,14 @@ def getQualitiesfromxml(xmlnames, ErrorsP, ErrorsS, plotflag=1):
for mpick in arrivals_copy: for mpick in arrivals_copy:
phase = identifyPhase(loopIdentifyPhase(Pick.phase_hint)) phase = identifyPhase(loopIdentifyPhase(Pick.phase_hint))
if phase == 'P': 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.waveform_id.station_code == mstation_ext)) and \
((mpick.method_id).split('/')[1] == 'auto') and \ ((mpick.method_id).split('/')[1] == 'auto') and \
(mpick.time_errors['uncertainty'] <= ErrorsP[3]): (mpick.time_errors['uncertainty'] <= ErrorsP[3]):
del mpick del mpick
break break
elif phase == 'S': 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.waveform_id.station_code == mstation_ext)) and \
((mpick.method_id).split('/')[1] == 'auto') and \ ((mpick.method_id).split('/')[1] == 'auto') and \
(mpick.time_errors['uncertainty'] <= ErrorsS[3]): (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 # get some parameters for quality control from
# parameter input file (usually pylot.in). # parameter input file (usually autoPyLoT.in).
wdttolerance = param.get('wdttolerance') wdttolerance = param.get('wdttolerance')
mdttolerance = param.get('mdttolerance') mdttolerance = param.get('mdttolerance')
jackfactor = param.get('jackfactor') 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.') print('iPlot Flag active: NO MULTIPROCESSING possible.')
return all_onsets 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 {} ' 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) pool = gen_Pool(ncores)
result = pool.map(call_autopickstation, input_tuples) result = pool.map(call_autopickstation, input_tuples)
@@ -113,7 +110,7 @@ def autopickstation(wfstream, pickparam, verbose=False,
:type wfstream: obspy.core.stream.Stream :type wfstream: obspy.core.stream.Stream
:param pickparam: container of picking parameters from input file, :param pickparam: container of picking parameters from input file,
usually pylot.in usually autoPyLoT.in
:type pickparam: PylotParameter :type pickparam: PylotParameter
:param verbose: :param verbose:
:type verbose: bool :type verbose: bool
@@ -121,7 +118,7 @@ def autopickstation(wfstream, pickparam, verbose=False,
""" """
# declaring pickparam variables (only for convenience) # declaring pickparam variables (only for convenience)
# read your pylot.in for details! # read your autoPyLoT.in for details!
plt_flag = 0 plt_flag = 0
# special parameters for P picking # special parameters for P picking
@@ -180,6 +177,10 @@ def autopickstation(wfstream, pickparam, verbose=False,
# parameter to check for spuriously picked S onset # parameter to check for spuriously picked S onset
zfac = pickparam.get('zfac') zfac = pickparam.get('zfac')
# path to inventory-, dataless- or resp-files # 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 # initialize output
Pweight = 4 # weight for P onset Pweight = 4 # weight for P onset
@@ -228,10 +229,8 @@ def autopickstation(wfstream, pickparam, verbose=False,
data=str(zdat)) data=str(zdat))
if verbose: print(msg) if verbose: print(msg)
z_copy = zdat.copy() 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 # filter and taper data
tr_filt = zdat[0].copy()
tr_filt.filter('bandpass', freqmin=bpz1[0], freqmax=bpz1[1], tr_filt.filter('bandpass', freqmin=bpz1[0], freqmax=bpz1[1],
zerophase=False) zerophase=False)
tr_filt.taper(max_percentage=0.05, type='hann') tr_filt.taper(max_percentage=0.05, type='hann')
@@ -327,11 +326,10 @@ def autopickstation(wfstream, pickparam, verbose=False,
key = 'aicFig' key = 'aicFig'
if fig_dict: if fig_dict:
fig = fig_dict[key] fig = fig_dict[key]
linecolor = fig_dict['plot_style']['linecolor']['rgba_mpl']
else: else:
fig = None fig = None
linecolor = 'k' aicpick = AICPicker(aiccf, tsnrz, pickwinP, checkwindow=checkwindowP, minfactor=minfactorP,
aicpick = AICPicker(aiccf, tsnrz, pickwinP, iplot, None, aictsmoothP, fig=fig, linecolor=linecolor) iplot=iplot, Tsmooth=tsmoothP, fig=fig)
# add pstart and pstop to aic plot # add pstart and pstop to aic plot
if fig: if fig:
for ax in fig.axes: for ax in fig.axes:
@@ -354,21 +352,16 @@ def autopickstation(wfstream, pickparam, verbose=False,
key = 'slength' key = 'slength'
if fig_dict: if fig_dict:
fig = fig_dict[key] fig = fig_dict[key]
linecolor = fig_dict['plot_style']['linecolor']['rgba_mpl']
else: else:
fig = None fig = None
linecolor = 'k'
Pflag = checksignallength(zne, aicpick.getpick(), tsnrz, Pflag = checksignallength(zne, aicpick.getpick(), tsnrz,
minsiglength / 2, minsiglength / 2,
nfacsl, minpercent, iplot, nfacsl, minpercent, iplot,
fig, linecolor) fig)
else: else:
# filter and taper horizontal traces # filter and taper horizontal traces
trH1_filt = edat.copy() trH1_filt = edat.copy()
trH2_filt = ndat.copy() trH2_filt = ndat.copy()
# remove constant offset from data to avoid unwanted filter response
trH1_filt.detrend(type='demean')
trH2_filt.detrend(type='demean')
trH1_filt.filter('bandpass', freqmin=bph1[0], trH1_filt.filter('bandpass', freqmin=bph1[0],
freqmax=bph1[1], freqmax=bph1[1],
zerophase=False) zerophase=False)
@@ -381,14 +374,12 @@ def autopickstation(wfstream, pickparam, verbose=False,
zne += trH2_filt zne += trH2_filt
if fig_dict: if fig_dict:
fig = fig_dict['slength'] fig = fig_dict['slength']
linecolor = fig_dict['plot_style']['linecolor']['rgba_mpl']
else: else:
fig = None fig = None
linecolor = 'k'
Pflag = checksignallength(zne, aicpick.getpick(), tsnrz, Pflag = checksignallength(zne, aicpick.getpick(), tsnrz,
minsiglength, minsiglength,
nfacsl, minpercent, iplot, nfacsl, minpercent, iplot,
fig, linecolor) fig)
if Pflag == 1: if Pflag == 1:
# check for spuriously picked S onset # check for spuriously picked S onset
@@ -401,12 +392,10 @@ def autopickstation(wfstream, pickparam, verbose=False,
if iplot > 1: if iplot > 1:
if fig_dict: if fig_dict:
fig = fig_dict['checkZ4s'] fig = fig_dict['checkZ4s']
linecolor = fig_dict['plot_style']['linecolor']['rgba_mpl']
else: else:
fig = None fig = None
linecolor = 'k'
Pflag = checkZ4S(zne, aicpick.getpick(), zfac, Pflag = checkZ4S(zne, aicpick.getpick(), zfac,
tsnrz[2], iplot, fig, linecolor) tsnrz[2], iplot, fig)
if Pflag == 0: if Pflag == 0:
Pmarker = 'SinsteadP' Pmarker = 'SinsteadP'
Pweight = 9 Pweight = 9
@@ -429,7 +418,6 @@ def autopickstation(wfstream, pickparam, verbose=False,
# re-filter waveform with larger bandpass # re-filter waveform with larger bandpass
z_copy = zdat.copy() z_copy = zdat.copy()
tr_filt = zdat[0].copy() tr_filt = zdat[0].copy()
tr_filt.detrend(type='demean')
tr_filt.filter('bandpass', freqmin=bpz2[0], freqmax=bpz2[1], tr_filt.filter('bandpass', freqmin=bpz2[0], freqmax=bpz2[1],
zerophase=False) zerophase=False)
tr_filt.taper(max_percentage=0.05, type='hann') tr_filt.taper(max_percentage=0.05, type='hann')
@@ -459,12 +447,10 @@ def autopickstation(wfstream, pickparam, verbose=False,
algoP=algoP) algoP=algoP)
if fig_dict: if fig_dict:
fig = fig_dict['refPpick'] fig = fig_dict['refPpick']
linecolor = fig_dict['plot_style']['linecolor']['rgba_mpl']
else: else:
fig = None fig = None
linecolor = 'k' refPpick = PragPicker(cf2, tsnrz, pickwinP, iplot=iplot, aus=ausP, Tsmooth=tsmoothP,
refPpick = PragPicker(cf2, tsnrz, pickwinP, iplot, ausP, tsmoothP, Pick1 = aicpick.getpick(), fig=fig)
aicpick.getpick(), fig, linecolor)
mpickP = refPpick.getpick() mpickP = refPpick.getpick()
############################################################# #############################################################
if mpickP is not None: if mpickP is not None:
@@ -473,13 +459,10 @@ def autopickstation(wfstream, pickparam, verbose=False,
if iplot: if iplot:
if fig_dict: if fig_dict:
fig = fig_dict['el_Ppick'] fig = fig_dict['el_Ppick']
linecolor = fig_dict['plot_style']['linecolor']['rgba_mpl']
else: else:
fig = None fig = None
linecolor = 'k'
epickP, lpickP, Perror = earllatepicker(z_copy, nfacP, tsnrz, epickP, lpickP, Perror = earllatepicker(z_copy, nfacP, tsnrz,
mpickP, iplot, fig=fig, mpickP, iplot, fig=fig)
linecolor=linecolor)
else: else:
epickP, lpickP, Perror = earllatepicker(z_copy, nfacP, tsnrz, epickP, lpickP, Perror = earllatepicker(z_copy, nfacP, tsnrz,
mpickP, iplot) mpickP, iplot)
@@ -509,10 +492,9 @@ def autopickstation(wfstream, pickparam, verbose=False,
if iplot: if iplot:
if fig_dict: if fig_dict:
fig = fig_dict['fm_picker'] fig = fig_dict['fm_picker']
linecolor = fig_dict['plot_style']['linecolor']['rgba_mpl']
else: else:
fig = None fig = None
FM = fmpicker(zdat, z_copy, fmpickwin, mpickP, iplot, fig, linecolor) FM = fmpicker(zdat, z_copy, fmpickwin, mpickP, iplot, fig)
else: else:
FM = fmpicker(zdat, z_copy, fmpickwin, mpickP, iplot) FM = fmpicker(zdat, z_copy, fmpickwin, mpickP, iplot)
else: else:
@@ -592,8 +574,6 @@ def autopickstation(wfstream, pickparam, verbose=False,
# filter and taper data # filter and taper data
trH1_filt = hdat[0].copy() trH1_filt = hdat[0].copy()
trH2_filt = hdat[1].copy() trH2_filt = hdat[1].copy()
trH1_filt.detrend(type='demean')
trH2_filt.detrend(type='demean')
trH1_filt.filter('bandpass', freqmin=bph1[0], freqmax=bph1[1], trH1_filt.filter('bandpass', freqmin=bph1[0], freqmax=bph1[1],
zerophase=False) zerophase=False)
trH2_filt.filter('bandpass', freqmin=bph1[0], freqmax=bph1[1], trH2_filt.filter('bandpass', freqmin=bph1[0], freqmax=bph1[1],
@@ -612,9 +592,6 @@ def autopickstation(wfstream, pickparam, verbose=False,
trH1_filt = hdat[0].copy() trH1_filt = hdat[0].copy()
trH2_filt = hdat[1].copy() trH2_filt = hdat[1].copy()
trH3_filt = hdat[2].copy() trH3_filt = hdat[2].copy()
trH1_filt.detrend(type='demean')
trH2_filt.detrend(type='demean')
trH3_filt.detrend(type='demean')
trH1_filt.filter('bandpass', freqmin=bph1[0], freqmax=bph1[1], trH1_filt.filter('bandpass', freqmin=bph1[0], freqmax=bph1[1],
zerophase=False) zerophase=False)
trH2_filt.filter('bandpass', freqmin=bph1[0], freqmax=bph1[1], trH2_filt.filter('bandpass', freqmin=bph1[0], freqmax=bph1[1],
@@ -652,12 +629,11 @@ def autopickstation(wfstream, pickparam, verbose=False,
# of class AutoPicking # of class AutoPicking
if fig_dict: if fig_dict:
fig = fig_dict['aicARHfig'] fig = fig_dict['aicARHfig']
linecolor = fig_dict['plot_style']['linecolor']['rgba_mpl']
else: else:
fig = None fig = None
linecolor = 'k' aicarhpick = AICPicker(haiccf, tsnrh, pickwinS, checkwindow=checkwindowS,
aicarhpick = AICPicker(haiccf, tsnrh, pickwinS, iplot, None, minfactor=minfactorS, iplot=iplot, Tsmooth=aictsmoothS,
aictsmoothS, fig=fig, linecolor=linecolor) fig=fig)
############################################################### ###############################################################
# go on with processing if AIC onset passes quality control # go on with processing if AIC onset passes quality control
slope = aicarhpick.getSlope() slope = aicarhpick.getSlope()
@@ -682,8 +658,6 @@ def autopickstation(wfstream, pickparam, verbose=False,
if algoS == 'ARH': if algoS == 'ARH':
trH1_filt = hdat[0].copy() trH1_filt = hdat[0].copy()
trH2_filt = hdat[1].copy() trH2_filt = hdat[1].copy()
trH1_filt.detrend(type='demean')
trH2_filt.detrend(type='demean')
trH1_filt.filter('bandpass', freqmin=bph2[0], freqmax=bph2[1], trH1_filt.filter('bandpass', freqmin=bph2[0], freqmax=bph2[1],
zerophase=False) zerophase=False)
trH2_filt.filter('bandpass', freqmin=bph2[0], freqmax=bph2[1], trH2_filt.filter('bandpass', freqmin=bph2[0], freqmax=bph2[1],
@@ -699,9 +673,6 @@ def autopickstation(wfstream, pickparam, verbose=False,
trH1_filt = hdat[0].copy() trH1_filt = hdat[0].copy()
trH2_filt = hdat[1].copy() trH2_filt = hdat[1].copy()
trH3_filt = hdat[2].copy() trH3_filt = hdat[2].copy()
trH1_filt.detrend(type='demean')
trH2_filt.detrend(type='demean')
trH3_filt.detrend(type='demean')
trH1_filt.filter('bandpass', freqmin=bph2[0], freqmax=bph2[1], trH1_filt.filter('bandpass', freqmin=bph2[0], freqmax=bph2[1],
zerophase=False) zerophase=False)
trH2_filt.filter('bandpass', freqmin=bph2[0], freqmax=bph2[1], trH2_filt.filter('bandpass', freqmin=bph2[0], freqmax=bph2[1],
@@ -721,12 +692,10 @@ def autopickstation(wfstream, pickparam, verbose=False,
# get refined onset time from CF2 using class Picker # get refined onset time from CF2 using class Picker
if fig_dict: if fig_dict:
fig = fig_dict['refSpick'] fig = fig_dict['refSpick']
linecolor = fig_dict['plot_style']['linecolor']['rgba_mpl']
else: else:
fig = None fig = None
linecolor = 'k' refSpick = PragPicker(arhcf2, tsnrh, pickwinS, iplot=iplot, aus=ausS,
refSpick = PragPicker(arhcf2, tsnrh, pickwinS, iplot, ausS, Tsmooth=tsmoothS, Pick1=aicarhpick.getpick(), fig=fig)
tsmoothS, aicarhpick.getpick(), fig, linecolor)
mpickS = refSpick.getpick() mpickS = refSpick.getpick()
############################################################# #############################################################
if mpickS is not None: if mpickS is not None:
@@ -736,15 +705,12 @@ def autopickstation(wfstream, pickparam, verbose=False,
if iplot: if iplot:
if fig_dict: if fig_dict:
fig = fig_dict['el_S1pick'] fig = fig_dict['el_S1pick']
linecolor = fig_dict['plot_style']['linecolor']['rgba_mpl']
else: else:
fig = None fig = None
linecolor = 'k'
epickS1, lpickS1, Serror1 = earllatepicker(h_copy, nfacS, epickS1, lpickS1, Serror1 = earllatepicker(h_copy, nfacS,
tsnrh, tsnrh,
mpickS, iplot, mpickS, iplot,
fig=fig, fig=fig)
linecolor=linecolor)
else: else:
epickS1, lpickS1, Serror1 = earllatepicker(h_copy, nfacS, epickS1, lpickS1, Serror1 = earllatepicker(h_copy, nfacS,
tsnrh, tsnrh,
@@ -754,15 +720,12 @@ def autopickstation(wfstream, pickparam, verbose=False,
if iplot: if iplot:
if fig_dict: if fig_dict:
fig = fig_dict['el_S2pick'] fig = fig_dict['el_S2pick']
linecolor = fig_dict['plot_style']['linecolor']['rgba_mpl']
else: else:
fig = None fig = None
linecolor = ''
epickS2, lpickS2, Serror2 = earllatepicker(h_copy, nfacS, epickS2, lpickS2, Serror2 = earllatepicker(h_copy, nfacS,
tsnrh, tsnrh,
mpickS, iplot, mpickS, iplot,
fig=fig, fig=fig)
linecolor=linecolor)
else: else:
epickS2, lpickS2, Serror2 = earllatepicker(h_copy, nfacS, epickS2, lpickS2, Serror2 = earllatepicker(h_copy, nfacS,
tsnrh, tsnrh,
@@ -854,7 +817,7 @@ def autopickstation(wfstream, pickparam, verbose=False,
hdat += ndat hdat += ndat
else: else:
print('autopickstation: No horizontal component data available or ' print('autopickstation: No horizontal component data available or ' \
'bad P onset, skipping S picking!') 'bad P onset, skipping S picking!')
############################################################## ##############################################################
@@ -871,11 +834,8 @@ def autopickstation(wfstream, pickparam, verbose=False,
if fig_dict == None or fig_dict == 'None': if fig_dict == None or fig_dict == 'None':
fig = plt.figure() fig = plt.figure()
plt_flag = 1 plt_flag = 1
linecolor = 'k'
else: else:
fig = fig_dict['mainFig'] fig = fig_dict['mainFig']
linecolor = fig_dict['plot_style']['linecolor']['rgba_mpl']
fig._tight = True
ax1 = fig.add_subplot(311) ax1 = fig.add_subplot(311)
tdata = np.arange(0, zdat[0].stats.npts / tr_filt.stats.sampling_rate, tdata = np.arange(0, zdat[0].stats.npts / tr_filt.stats.sampling_rate,
tr_filt.stats.delta) tr_filt.stats.delta)
@@ -883,7 +843,7 @@ def autopickstation(wfstream, pickparam, verbose=False,
wfldiff = len(tr_filt.data) - len(tdata) wfldiff = len(tr_filt.data) - len(tdata)
if wfldiff < 0: if wfldiff < 0:
tdata = tdata[0:len(tdata) - abs(wfldiff)] tdata = tdata[0:len(tdata) - abs(wfldiff)]
ax1.plot(tdata, tr_filt.data / max(tr_filt.data), color=linecolor, linewidth=0.7, label='Data') ax1.plot(tdata, tr_filt.data / max(tr_filt.data), 'k', label='Data')
if Pweight < 4: if Pweight < 4:
ax1.plot(cf1.getTimeArray(), cf1.getCF() / max(cf1.getCF()), ax1.plot(cf1.getTimeArray(), cf1.getCF() / max(cf1.getCF()),
'b', label='CF1') 'b', label='CF1')
@@ -942,7 +902,7 @@ def autopickstation(wfstream, pickparam, verbose=False,
wfldiff = len(trH1_filt.data) - len(th1data) wfldiff = len(trH1_filt.data) - len(th1data)
if wfldiff < 0: if wfldiff < 0:
th1data = th1data[0:len(th1data) - abs(wfldiff)] th1data = th1data[0:len(th1data) - abs(wfldiff)]
ax2.plot(th1data, trH1_filt.data / max(trH1_filt.data), color=linecolor, linewidth=0.7, label='Data') ax2.plot(th1data, trH1_filt.data / max(trH1_filt.data), 'k', label='Data')
if Pweight < 4: if Pweight < 4:
ax2.plot(arhcf1.getTimeArray(), ax2.plot(arhcf1.getTimeArray(),
arhcf1.getCF() / max(arhcf1.getCF()), 'b', label='CF1') arhcf1.getCF() / max(arhcf1.getCF()), 'b', label='CF1')
@@ -991,7 +951,7 @@ def autopickstation(wfstream, pickparam, verbose=False,
wfldiff = len(trH2_filt.data) - len(th2data) wfldiff = len(trH2_filt.data) - len(th2data)
if wfldiff < 0: if wfldiff < 0:
th2data = th2data[0:len(th2data) - abs(wfldiff)] th2data = th2data[0:len(th2data) - abs(wfldiff)]
ax3.plot(th2data, trH2_filt.data / max(trH2_filt.data), color=linecolor, linewidth=0.7, label='Data') ax3.plot(th2data, trH2_filt.data / max(trH2_filt.data), 'k', label='Data')
if Pweight < 4: if Pweight < 4:
p22, = ax3.plot(arhcf1.getTimeArray(), p22, = ax3.plot(arhcf1.getTimeArray(),
arhcf1.getCF() / max(arhcf1.getCF()), 'b', label='CF1') arhcf1.getCF() / max(arhcf1.getCF()), 'b', label='CF1')
+14 -7
View File
@@ -26,7 +26,7 @@ class CharacteristicFunction(object):
SuperClass for different types of characteristic functions. SuperClass for different types of characteristic functions.
''' '''
def __init__(self, data, cut, t2=None, order=None, t1=None, fnoise=None): def __init__(self, data, cut, t2=None, order=None, t1=None, fnoise=None, stealthMode=False):
''' '''
Initialize data type object with information from the original Initialize data type object with information from the original
Seismogram. Seismogram.
@@ -63,6 +63,7 @@ class CharacteristicFunction(object):
self.calcCF(self.getDataArray()) self.calcCF(self.getDataArray())
self.arpara = np.array([]) self.arpara = np.array([])
self.xpred = np.array([]) self.xpred = np.array([])
self._stealthMode = stealthMode
def __str__(self): def __str__(self):
return '''\n\t{name} object:\n return '''\n\t{name} object:\n
@@ -136,6 +137,9 @@ class CharacteristicFunction(object):
def getXCF(self): def getXCF(self):
return self.xcf return self.xcf
def _getStealthMode(self):
return self._stealthMode()
def getDataArray(self, cut=None): def getDataArray(self, cut=None):
''' '''
If cut times are given, time series is cut from cut[0] (start time) If cut times are given, time series is cut from cut[0] (start time)
@@ -220,11 +224,13 @@ class AICcf(CharacteristicFunction):
def calcCF(self, data): def calcCF(self, data):
# if self._getStealthMode() is False:
# print 'Calculating AIC ...'
x = self.getDataArray() x = self.getDataArray()
xnp = x[0].data xnp = x[0].data
ind = np.where(~np.isnan(xnp))[0] nn = np.isnan(xnp)
if ind.size: if len(nn) > 1:
xnp[:ind[0]] = xnp[ind[0]] xnp[nn] = 0
datlen = len(xnp) datlen = len(xnp)
k = np.arange(1, datlen) k = np.arange(1, datlen)
cf = np.zeros(datlen) cf = np.zeros(datlen)
@@ -258,9 +264,13 @@ class HOScf(CharacteristicFunction):
if len(nn) > 1: if len(nn) > 1:
xnp[nn] = 0 xnp[nn] = 0
if self.getOrder() == 3: # this is skewness if self.getOrder() == 3: # this is skewness
# if self._getStealthMode() is False:
# print 'Calculating skewness ...'
y = np.power(xnp, 3) y = np.power(xnp, 3)
y1 = np.power(xnp, 2) y1 = np.power(xnp, 2)
elif self.getOrder() == 4: # this is kurtosis elif self.getOrder() == 4: # this is kurtosis
# if self._getStealthMode() is False:
# print 'Calculating kurtosis ...'
y = np.power(xnp, 4) y = np.power(xnp, 4)
y1 = np.power(xnp, 2) y1 = np.power(xnp, 2)
@@ -335,7 +345,6 @@ class ARZcf(CharacteristicFunction):
cf = tap * cf cf = tap * cf
io = np.where(cf == 0) io = np.where(cf == 0)
ino = np.where(cf > 0) ino = np.where(cf > 0)
if np.size(ino):
cf[io] = cf[ino[0][0]] cf[io] = cf[ino[0][0]]
self.cf = cf self.cf = cf
@@ -468,7 +477,6 @@ class ARHcf(CharacteristicFunction):
cf = tap * cf cf = tap * cf
io = np.where(cf == 0) io = np.where(cf == 0)
ino = np.where(cf > 0) ino = np.where(cf > 0)
if np.size(ino):
cf[io] = cf[ino[0][0]] cf[io] = cf[ino[0][0]]
self.cf = cf self.cf = cf
@@ -611,7 +619,6 @@ class AR3Ccf(CharacteristicFunction):
cf = tap * cf cf = tap * cf
io = np.where(cf == 0) io = np.where(cf == 0)
ino = np.where(cf > 0) ino = np.where(cf > 0)
if np.size(ino):
cf[io] = cf[ino[0][0]] cf[io] = cf[ino[0][0]]
self.cf = cf self.cf = cf
+2 -2
View File
@@ -118,8 +118,8 @@ class Comparison(object):
""" """
compare_pdfs = dict() compare_pdfs = dict()
pdf_a = self.get('auto').generate_pdf_data(type) pdf_a = self.get(self.names[0]).generate_pdf_data(type)
pdf_b = self.get('manu').generate_pdf_data(type) pdf_b = self.get(self.names[1]).generate_pdf_data(type)
for station, phases in pdf_a.items(): for station, phases in pdf_a.items():
if station in pdf_b.keys(): if station in pdf_b.keys():
+18 -19
View File
@@ -23,9 +23,8 @@ import warnings
import matplotlib.pyplot as plt import matplotlib.pyplot as plt
import numpy as np import numpy as np
from scipy.signal import argrelmax
from pylot.core.pick.charfuns import CharacteristicFunction 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): class AutoPicker(object):
@@ -36,7 +35,7 @@ class AutoPicker(object):
warnings.simplefilter('ignore') 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 :param: cf, characteristic function, on which the picking algorithm is applied
:type: `~pylot.core.pick.CharFuns.CharacteristicFunction` object :type: `~pylot.core.pick.CharFuns.CharacteristicFunction` object
@@ -63,8 +62,7 @@ class AutoPicker(object):
''' '''
assert isinstance(cf, CharacteristicFunction), "%s is not a CharacteristicFunction object" % str(cf) assert isinstance(cf, CharacteristicFunction), "%s is not a CharacteristicFunction object" % str(cf)
self._linecolor = linecolor
self._pickcolor_p = 'b'
self.cf = cf.getCF() self.cf = cf.getCF()
self.Tcf = cf.getTimeArray() self.Tcf = cf.getTimeArray()
self.Data = cf.getXCF() self.Data = cf.getXCF()
@@ -76,6 +74,8 @@ class AutoPicker(object):
self.setTsmooth(Tsmooth) self.setTsmooth(Tsmooth)
self.setpick1(Pick1) self.setpick1(Pick1)
self.fig = fig self.fig = fig
self.setCheckWindow(checkwindow)
self.minfactor = minfactor
self.calcPick() self.calcPick()
def __str__(self): def __str__(self):
@@ -91,6 +91,10 @@ class AutoPicker(object):
aus=self.getaus(), aus=self.getaus(),
Tsmooth=self.getTsmooth(), Tsmooth=self.getTsmooth(),
Pick1=self.getpick1()) 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): def getTSNR(self):
return self.TSNR return self.TSNR
@@ -190,7 +194,8 @@ class AICPicker(AutoPicker):
aicsmooth = aicsmooth - offset aicsmooth = aicsmooth - offset
# get maximum of HOS/AR-CF as startimg point for searching # get maximum of HOS/AR-CF as startimg point for searching
# minimum in AIC function # 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 # find minimum in AIC-CF front of maximum of HOS/AR-CF
lpickwindow = int(round(self.PickWindow / self.dt)) lpickwindow = int(round(self.PickWindow / self.dt))
@@ -254,12 +259,8 @@ class AICPicker(AutoPicker):
if len(dataslope) < 1: if len(dataslope) < 1:
print('No data in slope window found!') print('No data in slope window found!')
return return
imaxs, = argrelmax(dataslope)
if imaxs.size:
imax = imaxs[0]
else:
imax = np.argmax(dataslope) imax = np.argmax(dataslope)
iislope = islope[0][0:imax + 1] iislope = islope[0][0:imax+1]
if len(iislope) < 2: if len(iislope) < 2:
# calculate slope from initial onset to maximum of AIC function # calculate slope from initial onset to maximum of AIC function
print("AICPicker: Not enough data samples left for slope calculation!") print("AICPicker: Not enough data samples left for slope calculation!")
@@ -270,13 +271,13 @@ class AICPicker(AutoPicker):
print("Choose longer slope determination window!") print("Choose longer slope determination window!")
if self.iplot > 1: if self.iplot > 1:
if self.fig == None or self.fig == 'None': if self.fig == None or self.fig == 'None':
fig = plt.figure() fig = plt.figure() # self.iplot) ### WHY? MP MP
plt_flag = 1 plt_flag = 1
else: else:
fig = self.fig fig = self.fig
ax = fig.add_subplot(111) ax = fig.add_subplot(111)
x = self.Data[0].data x = self.Data[0].data
ax.plot(self.Tcf, x / max(x), 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.plot(self.Tcf, aicsmooth / max(aicsmooth), 'r', label='Smoothed AIC-CF')
ax.legend(loc=1) ax.legend(loc=1)
ax.set_xlabel('Time [s] since %s' % self.Data[0].stats.starttime) ax.set_xlabel('Time [s] since %s' % self.Data[0].stats.starttime)
@@ -309,12 +310,11 @@ class AICPicker(AutoPicker):
plt_flag = 1 plt_flag = 1
else: else:
fig = self.fig fig = self.fig
fig._tight = True
ax1 = fig.add_subplot(211) ax1 = fig.add_subplot(211)
x = self.Data[0].data x = self.Data[0].data
if len(self.Tcf) > len(self.Data[0].data): # why? LK if len(self.Tcf) > len(self.Data[0].data): # why? LK
self.Tcf = self.Tcf[0:len(self.Tcf)-1] 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') ax1.plot(self.Tcf, aicsmooth / max(aicsmooth), 'r', label='Smoothed AIC-CF')
if self.Pick is not None: if self.Pick is not None:
ax1.plot([self.Pick, self.Pick], [-0.1, 0.5], 'b', linewidth=2, label='AIC-Pick') ax1.plot([self.Pick, self.Pick], [-0.1, 0.5], 'b', linewidth=2, label='AIC-Pick')
@@ -324,7 +324,7 @@ class AICPicker(AutoPicker):
if self.Pick is not None: if self.Pick is not None:
ax2 = fig.add_subplot(2, 1, 2, sharex=ax1) ax2 = fig.add_subplot(2, 1, 2, sharex=ax1)
ax2.plot(self.Tcf, x, 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[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, ax1.axvspan(self.Tcf[isignal[0]], self.Tcf[isignal[-1]], color='b', alpha=0.2, lw=0,
label='Signal Window') label='Signal Window')
@@ -479,12 +479,11 @@ class PragPicker(AutoPicker):
plt_flag = 1 plt_flag = 1
else: else:
fig = self.fig fig = self.fig
fig._tight = True
ax = fig.add_subplot(111) ax = fig.add_subplot(111)
ax.plot(Tcfpick, cfipick, color=self._linecolor, linewidth=0.7, label='CF') ax.plot(Tcfpick, cfipick, 'k', label='CF')
ax.plot(Tcfpick, cfsmoothipick, 'r', label='Smoothed CF') ax.plot(Tcfpick, cfsmoothipick, 'r', label='Smoothed CF')
if pickflag > 0: if pickflag > 0:
ax.plot([self.Pick, self.Pick], [min(cfipick), max(cfipick)], 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_xlabel('Time [s] since %s' % self.Data[0].stats.starttime)
ax.set_yticks([]) ax.set_yticks([])
ax.set_title(self.Data[0].stats.station) ax.set_title(self.Data[0].stats.station)
+97 -74
View File
@@ -13,9 +13,10 @@ import warnings
import matplotlib.pyplot as plt import matplotlib.pyplot as plt
import numpy as np import numpy as np
from obspy.core import Stream, UTCDateTime from obspy.core import Stream, UTCDateTime
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) Function to derive earliest and latest possible pick after Diehl & Kissling (2009)
as reasonable uncertainties. Latest possible pick is based on noise level, as reasonable uncertainties. Latest possible pick is based on noise level,
@@ -94,7 +95,7 @@ def earllatepicker(X, nfac, TSNR, Pick1, iplot=0, verbosity=1, fig=None, linecol
# get earliest possible pick # get earliest possible pick
EPick = np.nan EPick = np.nan;
count = 0 count = 0
pis = isignal 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': if fig == None or fig == 'None':
fig = plt.figure() # iplot) fig = plt.figure() # iplot)
plt_flag = 1 plt_flag = 1
fig._tight = True
ax = fig.add_subplot(111) 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[inoise[0]], t[inoise[-1]], color='y', alpha=0.2, lw=0, label='Noise Window')
ax.axvspan(t[isignal[0]], t[isignal[-1]], color='b', alpha=0.2, lw=0, label='Signal Window') ax.axvspan(t[isignal[0]], t[isignal[-1]], color='b', alpha=0.2, lw=0, label='Signal Window')
ax.plot([t[0], t[int(len(t)) - 1]], [nlevel, nlevel], 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', ax.plot(t[pis[zc]], np.zeros(len(zc)), '*g',
markersize=14, label='Zero Crossings') markersize=14, label='Zero Crossings')
ax.plot([t[0], t[int(len(t)) - 1]], [-nlevel, -nlevel], 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([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([LPick, LPick], [max(x) / 2, -max(x) / 2], '--k', label='lpp')
ax.plot([EPick, EPick], [max(x) / 2, -max(x) / 2], color=linecolor, linewidth=0.7, linestyle='dashed', label='epp') ax.plot([EPick, EPick], [max(x) / 2, -max(x) / 2], '--k', label='epp')
ax.plot([Pick1 + PickError, Pick1 + PickError], ax.plot([Pick1 + PickError, Pick1 + PickError],
[max(x) / 2, -max(x) / 2], 'r--', label='spe') [max(x) / 2, -max(x) / 2], 'r--', label='spe')
ax.plot([Pick1 - PickError, Pick1 - PickError], ax.plot([Pick1 - PickError, Pick1 - PickError],
@@ -161,7 +161,7 @@ def earllatepicker(X, nfac, TSNR, Pick1, iplot=0, verbosity=1, fig=None, linecol
return EPick, LPick, PickError 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. Function to derive first motion (polarity) of given phase onset Pick.
Calculation is based on zero crossings determined within time window pickwin Calculation is based on zero crossings determined within time window pickwin
@@ -324,9 +324,8 @@ def fmpicker(Xraw, Xfilt, pickwin, Pick, iplot=0, fig=None, linecolor='k'):
if fig == None or fig == 'None': if fig == None or fig == 'None':
fig = plt.figure() # iplot) fig = plt.figure() # iplot)
plt_flag = 1 plt_flag = 1
fig._tight = True
ax1 = fig.add_subplot(211) 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') ax1.plot([Pick, Pick], [max(xraw), -max(xraw)], 'b', linewidth=2, label='Pick')
if P1 is not None: if P1 is not None:
ax1.plot(t[islope1], xraw[islope1], label='Slope Window') ax1.plot(t[islope1], xraw[islope1], label='Slope Window')
@@ -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 = fig.add_subplot(2, 1, 2, sharex=ax1)
ax2.set_title('First-Motion Determination, Filtered Data') ax2.set_title('First-Motion Determination, Filtered Data')
ax2.plot(t, xfilt, color=linecolor, linewidth=0.7) ax2.plot(t, xfilt, 'k')
ax2.plot([Pick, Pick], [max(xfilt), -max(xfilt)], 'b', ax2.plot([Pick, Pick], [max(xfilt), -max(xfilt)], 'b',
linewidth=2) linewidth=2)
if P2 is not None: if P2 is not None:
@@ -591,10 +590,7 @@ def wadaticheck(pickdic, dttolerance, iplot=0, fig_dict=None):
Ppicks = [] Ppicks = []
Spicks = [] Spicks = []
SPtimes = [] SPtimes = []
stations = [] for key in pickdic:
ibad = 0
for key in list(pickdic.keys()):
if pickdic[key]['P']['weight'] < 4 and pickdic[key]['S']['weight'] < 4: if pickdic[key]['P']['weight'] < 4 and pickdic[key]['S']['weight'] < 4:
# calculate S-P time # calculate S-P time
spt = pickdic[key]['S']['mpp'] - pickdic[key]['P']['mpp'] spt = pickdic[key]['S']['mpp'] - pickdic[key]['P']['mpp']
@@ -624,19 +620,17 @@ def wadaticheck(pickdic, dttolerance, iplot=0, fig_dict=None):
badstations = [] badstations = []
# calculate deviations from Wadati regression # calculate deviations from Wadati regression
ii = 0 ii = 0
for key in list(pickdic.keys()): ibad = 0
for key in pickdic:
if 'SPt' in pickdic[key]: if 'SPt' in pickdic[key]:
stations.append(key)
wddiff = abs(pickdic[key]['SPt'] - wdfit[ii]) wddiff = abs(pickdic[key]['SPt'] - wdfit[ii])
ii += 1 ii += 1
# check, if deviation is larger than adjusted # check, if deviation is larger than adjusted
if wddiff > dttolerance: if wddiff > dttolerance:
# remove pick from dictionary # mark onset and downgrade S-weight to 9
pickdic.pop(key) # (not used anymore)
# # mark onset and downgrade S-weight to 9 marker = 'badWadatiCheck'
# # (not used anymore) pickdic[key]['S']['weight'] = 9
# marker = 'badWadatiCheck'
# pickdic[key]['S']['weight'] = 9
badstations.append(key) badstations.append(key)
ibad += 1 ibad += 1
else: else:
@@ -649,7 +643,6 @@ def wadaticheck(pickdic, dttolerance, iplot=0, fig_dict=None):
checkedSPtimes.append(checkedSPtime) checkedSPtimes.append(checkedSPtime)
pickdic[key]['S']['marked'] = marker pickdic[key]['S']['marked'] = marker
#pickdic[key]['S']['marked'] = marker
print("wadaticheck: the following stations failed the check:") print("wadaticheck: the following stations failed the check:")
print(badstations) print(badstations)
@@ -680,28 +673,19 @@ def wadaticheck(pickdic, dttolerance, iplot=0, fig_dict=None):
if iplot > 0: if iplot > 0:
if fig_dict: if fig_dict:
fig = fig_dict['wadati'] fig = fig_dict['wadati']
linecolor = fig_dict['plot_style']['linecolor']['rgba_mpl']
plt_flag = 0 plt_flag = 0
else: else:
fig = plt.figure() fig = plt.figure()
linecolor = 'k'
plt_flag = 1 plt_flag = 1
ax = fig.add_subplot(111) ax = fig.add_subplot(111)
if ibad > 0:
ax.plot(Ppicks, SPtimes, 'ro', label='Skipped S-Picks') ax.plot(Ppicks, SPtimes, 'ro', label='Skipped S-Picks')
if wfitflag == 0: if wfitflag == 0:
ax.plot(Ppicks, wdfit, color=linecolor, linewidth=0.7, label='Wadati 1') ax.plot(Ppicks, wdfit, 'k', label='Wadati 1')
ax.plot(Ppicks, wdfit+dttolerance, color='0.9', linewidth=0.5, label='Wadati 1 Tolerance') ax.plot(checkedPpicks, checkedSPtimes, 'ko', label='Reliable S-Picks')
ax.plot(Ppicks, wdfit-dttolerance, color='0.9', linewidth=0.5)
ax.plot(checkedPpicks, wdfit2, 'g', label='Wadati 2') 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,' \ ax.set_title('Wadati-Diagram, %d S-P Times, Vp/Vs(raw)=%5.2f,' \
'Vp/Vs(checked)=%5.2f' % (len(SPtimes), vpvsr, cvpvsr)) 'Vp/Vs(checked)=%5.2f' % (len(SPtimes), vpvsr, cvpvsr))
ax.legend(loc=1, numpoints=1) ax.legend(loc=1)
else: else:
ax.set_title('Wadati-Diagram, %d S-P Times' % len(SPtimes)) 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)) 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. Function to detect spuriously picked noise peaks.
Uses RMS trace of all 3 components (if available) to determine, Uses RMS trace of all 3 components (if available) to determine,
@@ -805,9 +789,8 @@ def checksignallength(X, pick, TSNR, minsiglength, nfac, minpercent, iplot=0, fi
if fig == None or fig == 'None': if fig == None or fig == 'None':
fig = plt.figure() # iplot) fig = plt.figure() # iplot)
plt_flag = 1 plt_flag = 1
fig._tight = True
ax = fig.add_subplot(111) 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[inoise[0]], t[inoise[-1]], color='y', alpha=0.2, lw=0, label='Noise Window')
ax.axvspan(t[isignal[0]], t[isignal[-1]], color='b', alpha=0.2, lw=0, label='Signal Window') ax.axvspan(t[isignal[0]], t[isignal[-1]], color='b', alpha=0.2, lw=0, label='Signal Window')
ax.plot([t[isignal[0]], t[isignal[len(isignal) - 1]]], ax.plot([t[isignal[0]], t[isignal[len(isignal) - 1]]],
@@ -882,9 +865,9 @@ def checkPonsets(pickdic, dttolerance, jackfactor=5, iplot=0, fig_dict=None):
badstations = np.array(stations)[ibad] badstations = np.array(stations)[ibad]
print("checkPonsets: %d pick(s) deviate too much from median!" % len(ibad)) print("checkPonsets: %d pick(s) deviate too much from median!" % len(ibad))
print(badstations)
print("checkPonsets: Skipped %d P pick(s) out of %d" % (len(badstations) \ print("checkPonsets: Skipped %d P pick(s) out of %d" % (len(badstations) \
+ len(badjkstations), len(stations))) + len(badjkstations), len(stations)))
print(badstations)
goodmarker = 'goodPonsetcheck' goodmarker = 'goodPonsetcheck'
badmarker = 'badPonsetcheck' 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 # mark P onset as checked and keep P weight
pickdic[goodstations[i]]['P']['marked'] = goodmarker pickdic[goodstations[i]]['P']['marked'] = goodmarker
for i in range(0, len(badstations)): for i in range(0, len(badstations)):
# remove pick from dictionary # mark P onset and downgrade P weight to 9
pickdic.pop(badstations[i]) # (not used anymore)
pickdic[badstations[i]]['P']['marked'] = badmarker
pickdic[badstations[i]]['P']['weight'] = 9
for i in range(0, len(badjkstations)): for i in range(0, len(badjkstations)):
# remove pick from dictionary # mark P onset and downgrade P weight to 9
pickdic.pop(badjkstations[i]) # (not used anymore)
# for i in range(0, len(badstations)): pickdic[badjkstations[i]]['P']['marked'] = badjkmarker
# # mark P onset and downgrade P weight to 9 pickdic[badjkstations[i]]['P']['weight'] = 9
# # (not used anymore)
# pickdic[badstations[i]]['P']['marked'] = badmarker
# pickdic[badstations[i]]['P']['weight'] = 9
# for i in range(0, len(badjkstations)):
# # mark P onset and downgrade P weight to 9
# # (not used anymore)
# pickdic[badjkstations[i]]['P']['marked'] = badjkmarker
# pickdic[badjkstations[i]]['P']['weight'] = 9
checkedonsets = pickdic checkedonsets = pickdic
@@ -920,22 +897,19 @@ def checkPonsets(pickdic, dttolerance, jackfactor=5, iplot=0, fig_dict=None):
plt_flag = 1 plt_flag = 1
ax = fig.add_subplot(111) ax = fig.add_subplot(111)
if len(badstations) > 0: ax.plot(np.arange(0, len(Ppicks)), Ppicks, 'ro', markersize=14)
ax.plot(ibad, np.array(Ppicks)[ibad], marker ='o', markerfacecolor='orange', markersize=14, if len(badstations) < 1 and len(badjkstations) < 1:
linestyle='None', label='Median Skipped P Picks') ax.plot(np.arange(0, len(Ppicks)), Ppicks, 'go', markersize=14, label='Skipped P Picks')
if len(badjkstations) > 0: else:
ax.plot(badjk[0], np.array(Ppicks)[badjk], 'ro', markersize=14, label='Jackknife Skipped P Picks')
ax.plot(igood, np.array(Ppicks)[igood], 'go', markersize=14, label='Good P Picks') ax.plot(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, pmedian], 'g',
ax.plot([0, len(Ppicks) - 1], [pmedian + dttolerance, pmedian + dttolerance], 'g--', linewidth=1.2, linewidth=2, label='Median')
dashes=[25, 25], label='Median Tolerance') for i in range(0, len(Ppicks)):
ax.plot([0, len(Ppicks) - 1], [pmedian - dttolerance, pmedian - dttolerance], 'g--', linewidth=1.2, ax.text(i, Ppicks[i] + 0.01, '{0}'.format(stations[i]))
dashes=[25, 25])
for index, pick in enumerate(Ppicks):
ax.text(index, pick + 0.01, '{0}'.format(stations[index]), color='0.25')
ax.set_xlabel('Number of P Picks') ax.set_xlabel('Number of P Picks')
ax.set_ylabel('Onset Time [s] from 1.1.1970') # MP MP Improve this? ax.set_ylabel('Onset Time [s] from 1.1.1970')
ax.legend(loc=1, numpoints=1) ax.legend(loc=1)
ax.set_title('Jackknifing and Median Tests on P Onsets') ax.set_title('Jackknifing and Median Tests on P Onsets')
if plt_flag: if plt_flag:
fig.show() fig.show()
@@ -967,8 +941,9 @@ def jackknife(X, phi, h):
PHI_sub = None PHI_sub = None
# determine number of subgroups # 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("jackknife: Cannot divide quantity X in equal sized subgroups!")
print("Choose another size for subgroups!") print("Choose another size for subgroups!")
return PHI_jack, PHI_pseudo, PHI_sub return PHI_jack, PHI_pseudo, PHI_sub
@@ -985,7 +960,7 @@ def jackknife(X, phi, h):
# estimators of subgroups # estimators of subgroups
PHI_pseudo = [] PHI_pseudo = []
PHI_sub = [] PHI_sub = []
for i in range(0, g - 1): for i in range(0, g):
# subgroup i, remove i-th sample # subgroup i, remove i-th sample
xx = X[:] xx = X[:]
del xx[i] del xx[i]
@@ -1007,7 +982,7 @@ def jackknife(X, phi, h):
return PHI_jack, PHI_pseudo, PHI_sub return PHI_jack, PHI_pseudo, PHI_sub
def checkZ4S(X, pick, zfac, checkwin, iplot, fig=None, linecolor='k'): def checkZ4S(X, pick, zfac, checkwin, iplot, fig=None):
''' '''
Function to compare energy content of vertical trace with Function to compare energy content of vertical trace with
energy content of horizontal traces to detect spuriously energy content of horizontal traces to detect spuriously
@@ -1134,9 +1109,8 @@ def checkZ4S(X, pick, zfac, checkwin, iplot, fig=None, linecolor='k'):
fig = plt.figure() # self.iplot) ### WHY? MP MP fig = plt.figure() # self.iplot) ### WHY? MP MP
plt_flag = 1 plt_flag = 1
ax = fig.add_subplot(3, 1, i + 1, sharex=ax1) 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, 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) name = str(trace.stats.channel) + ': {}'.format(rms)
ax.plot([pick, pick + checkwin], [rms, rms], 'r', label='RMS {}'.format(name)) ax.plot([pick, pick + checkwin], [rms, rms], 'r', label='RMS {}'.format(name))
ax.plot([pick, pick], ax.get_ylim(), 'm', label='Pick') ax.plot([pick, pick], ax.get_ylim(), 'm', label='Pick')
@@ -1180,6 +1154,55 @@ def getQualityFromUncertainty(uncertainty, Errors):
return quality 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__': if __name__ == '__main__':
import doctest 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 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: try:
urlopen(url, timeout=1) urlopen(url, timeout=1)
return True 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 from PySide.QtGui import QDialog, QProgressBar, QLabel, QHBoxLayout, QPushButton
class AutoPickThread(QThread):
message = Signal(str)
finished = Signal()
def __init__(self, parent, func, infile, fnames, eventid, savepath):
super(AutoPickThread, self).__init__()
self.setParent(parent)
self.func = func
self.infile = infile
self.fnames = fnames
self.eventid = eventid
self.savepath = savepath
def run(self):
sys.stdout = self
picks = self.func(None, None, self.infile, self.fnames, self.eventid, self.savepath)
print("Autopicking finished!\n")
try:
for station in picks:
self.parent().addPicks(station, picks[station], type='auto')
except AttributeError:
print(picks)
sys.stdout = sys.__stdout__
self.finished.emit()
def write(self, text):
self.message.emit(text)
def flush(self):
pass
class Thread(QThread): class Thread(QThread):
message = Signal(str) message = Signal(str)
@@ -96,6 +131,7 @@ class Worker(QRunnable):
try: try:
result = self.fun(self.args) result = self.fun(self.args)
except: except:
#traceback.print_exc()
exctype, value = sys.exc_info ()[:2] exctype, value = sys.exc_info ()[:2]
print(exctype, value, traceback.format_exc()) print(exctype, value, traceback.format_exc())
self.signals.error.emit ((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) self.signals.result.emit(result)
finally: finally:
self.signals.finished.emit('Done') self.signals.finished.emit('Done')
sys.stdout = sys.__stdout__
def write(self, text): def write(self, text):
self.signals.message.emit(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 obspy.io.xseed.utils import SEEDParserException
from pylot.core.io.inputs import PylotParameter from pylot.core.io.inputs import PylotParameter
from pylot.styles import style_settings
from scipy.interpolate import splrep, splev from scipy.interpolate import splrep, splev
from PySide import QtCore, QtGui from PySide import QtCore, QtGui
@@ -22,7 +21,7 @@ from PySide import QtCore, QtGui
try: try:
import pyqtgraph as pg import pyqtgraph as pg
except Exception as e: except Exception as e:
print('PyLoT: Could not import pyqtgraph. {}'.format(e)) print('QtPyLoT: Could not import pyqtgraph. {}'.format(e))
pg = None pg = None
def _pickle_method(m): def _pickle_method(m):
@@ -72,8 +71,6 @@ def gen_Pool(ncores=0):
if ncores == 0: if ncores == 0:
ncores = multiprocessing.cpu_count() ncores = multiprocessing.cpu_count()
print('gen_Pool: Generated multiprocessing Pool with {} cores\n'.format(ncores))
pool = multiprocessing.Pool(ncores) pool = multiprocessing.Pool(ncores)
return pool return pool
@@ -580,22 +577,36 @@ def modify_rgba(rgba, modifier, intensity):
def base_phase_colors(picktype, phase): def base_phase_colors(picktype, phase):
phasecolors = style_settings.phasecolors phases = {
return phasecolors[picktype][phase] '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): def remove_underscores(data):
""" """
@@ -691,7 +702,7 @@ def get_stations(data):
return stations return stations
def check4rotated(data, metadata=None, verbosity=1): def check4rotated(data, metadata=None):
def rotate_components(wfstream, metadata=None): def rotate_components(wfstream, metadata=None):
"""rotates components if orientation code is numeric. """rotates components if orientation code is numeric.
@@ -700,13 +711,11 @@ def check4rotated(data, metadata=None, verbosity=1):
# indexing fails if metadata is None # indexing fails if metadata is None
metadata[0] metadata[0]
except: except:
if verbosity:
msg = 'Warning: could not rotate traces since no metadata was given\nset Inventory file!' msg = 'Warning: could not rotate traces since no metadata was given\nset Inventory file!'
print(msg) print(msg)
return wfstream return wfstream
if metadata[0] is None: if metadata[0] is None:
# sometimes metadata is (None, (None,)) # sometimes metadata is (None, (None,))
if verbosity:
msg = 'Warning: could not rotate traces since no metadata was given\nCheck inventory directory!' msg = 'Warning: could not rotate traces since no metadata was given\nCheck inventory directory!'
print(msg) print(msg)
return wfstream return wfstream
+154 -249
View File
@@ -16,6 +16,11 @@ import time
import numpy as np import numpy as np
try:
import pyqtgraph as pg
except:
pg = None
from matplotlib.figure import Figure from matplotlib.figure import Figure
from pylot.core.util.utils import find_horizontals, identifyPhase, loopIdentifyPhase, trim_station_components, \ from pylot.core.util.utils import find_horizontals, identifyPhase, loopIdentifyPhase, trim_station_components, \
identifyPhaseID, check4rotated identifyPhaseID, check4rotated
@@ -48,18 +53,23 @@ from pylot.core.pick.compare import Comparison
from pylot.core.util.defaults import OUTPUTFORMATS, FILTERDEFAULTS, \ from pylot.core.util.defaults import OUTPUTFORMATS, FILTERDEFAULTS, \
SetChannelComponents SetChannelComponents
from pylot.core.util.utils import prepTimeAxis, full_range, scaleWFData, \ from pylot.core.util.utils import prepTimeAxis, full_range, scaleWFData, \
demeanTrace, isSorted, findComboBoxIndex, clims, pick_linestyle_plt, pick_color_plt, \ demeanTrace, isSorted, findComboBoxIndex, clims, pick_linestyle_plt, pick_color_plt
check4rotated, check4doubled, check4gaps, remove_underscores
from autoPyLoT import autoPyLoT from autoPyLoT import autoPyLoT
from pylot.core.util.thread import Thread from pylot.core.util.thread import Thread
if sys.version_info.major == 3: if sys.version_info.major == 3:
import icons_rc_3 as icons_rc pass
elif sys.version_info.major == 2: elif sys.version_info.major == 2:
import icons_rc_2 as icons_rc pass
else: else:
raise ImportError('Could not determine python version.') 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): def getDataType(parent):
type = QInputDialog().getItem(parent, "Select phases type", "Type:", 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) _axes.set_ylabel(ylabel)
_anno = _axes.annotate(annotation, xy=(.05, .5), xycoords='axes fraction') _anno = _axes.annotate(annotation, xy=(.05, .5), xycoords='axes fraction')
_anno.set_bbox(bbox_props) _anno.set_bbox(bbox_props)
_anno.draggable()
return _axes return _axes
@@ -263,11 +272,9 @@ class ComparisonWidget(QWidget):
_gs = gridspec.GridSpec(3, 2) _gs = gridspec.GridSpec(3, 2)
self.clf() self.clf()
self.canvas.figure._tight = True
_axes = self.canvas.figure.add_subplot(_gs[0:2, :]) _axes = self.canvas.figure.add_subplot(_gs[0:2, :])
_ax1 = self.canvas.figure.add_subplot(_gs[2, 0]) _ax1 = self.canvas.figure.add_subplot(_gs[2, 0])
_ax2 = self.canvas.figure.add_subplot(_gs[2, 1]) _ax2 = self.canvas.figure.add_subplot(_gs[2, 1])
self.canvas.figure.tight_layout()
# _axes.cla() # _axes.cla()
station = self.plotprops['station'] station = self.plotprops['station']
@@ -340,7 +347,6 @@ class ComparisonWidget(QWidget):
if wname != name: if wname != name:
self.widgets[wname].setEnabled(False) self.widgets[wname].setEnabled(False)
self.canvas.figure.clf() self.canvas.figure.clf()
self.canvas.figure._tight = True
_axPstd, _axPexp = self.canvas.figure.add_subplot(221), self.canvas.figure.add_subplot(223) _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) _axSstd, _axSexp = self.canvas.figure.add_subplot(222), self.canvas.figure.add_subplot(224)
axes_dict = dict(P=dict(std=_axPstd, exp=_axPexp), 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)) "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 = axes_dict[phase]['std'].annotate(std_annotation, xy=(.05, .8), xycoords='axes fraction')
_anno_std.set_bbox(bbox_props) _anno_std.set_bbox(bbox_props)
_anno_std.draggable()
exp_annotation = "Distribution curve for {phase} differences'\n" \ exp_annotation = "Distribution curve for {phase} differences'\n" \
"expectations (all stations)\n" \ "expectations (all stations)\n" \
"number of samples: {nsamples}".format(phase=phase, nsamples=len(exp)) "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 = axes_dict[phase]['exp'].annotate(exp_annotation, xy=(.05, .8), xycoords='axes fraction')
_anno_exp.set_bbox(bbox_props) _anno_exp.set_bbox(bbox_props)
_anno_exp.draggable() axes_dict[phase]['exp'].set_xlabel('expectation [s]')
axes_dict[phase]['exp'].set_xlabel('Time [s]') axes_dict[phase]['std'].set_xlabel('standard deviation [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()
for ax in axes_dict['P'].values(): for ax in axes_dict['P'].values():
ax.set_ylabel('Frequency [-]') ax.set_ylabel('number of picks [-]')
self.canvas.draw() self.canvas.draw()
else: else:
@@ -439,32 +435,29 @@ class PlotWidget(FigureCanvas):
class WaveformWidgetPG(QtGui.QWidget): class WaveformWidgetPG(QtGui.QWidget):
def __init__(self, parent, title='Title'): def __init__(self, parent=None, xlabel='x', ylabel='y', title='Title'):
QtGui.QWidget.__init__(self, parent=parent) QtGui.QWidget.__init__(self, parent) # , 1)
self.pg = self.parent().pg self.setParent(parent)
# added because adding widget to scrollArea will set scrollArea to parent self._parent = parent
self.orig_parent = parent
# attribute plotdict is a dictionary connecting position and a name # attribute plotdict is a dictionary connecting position and a name
self.plotdict = dict() self.plotdict = dict()
# create plot # create plot
self.main_layout = QtGui.QVBoxLayout() self.main_layout = QtGui.QVBoxLayout()
self.label = QtGui.QLabel() self.label = QtGui.QLabel()
self.setLayout(self.main_layout) 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.plotWidget)
self.main_layout.addWidget(self.label) 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('bottom')
self.plotWidget.hideAxis('left') self.plotWidget.hideAxis('left')
self.wfstart, self.wfend = 0, 0 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.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): def reinitMoveProxy(self):
self.vLine = self.pg.InfiniteLine(angle=90, movable=False, pen=self.pen_multicursor) self.vLine = pg.InfiniteLine(angle=90, movable=False)
self.hLine = self.pg.InfiniteLine(angle=0, movable=False, pen=self.pen_multicursor) self.hLine = pg.InfiniteLine(angle=0, movable=False)
self.plotWidget.addItem(self.vLine, ignoreBounds=True) self.plotWidget.addItem(self.vLine, ignoreBounds=True)
self.plotWidget.addItem(self.hLine, ignoreBounds=True) self.plotWidget.addItem(self.hLine, ignoreBounds=True)
@@ -474,10 +467,10 @@ class WaveformWidgetPG(QtGui.QWidget):
mousePoint = self.plotWidget.getPlotItem().vb.mapSceneToView(pos) mousePoint = self.plotWidget.getPlotItem().vb.mapSceneToView(pos)
x, y, = (mousePoint.x(), mousePoint.y()) x, y, = (mousePoint.x(), mousePoint.y())
# if x > 0:# and index < len(data1): # if x > 0:# and index < len(data1):
wfID = self.orig_parent.getWFID(y) wfID = self._parent.getWFID(y)
station = self.orig_parent.getStationName(wfID) station = self._parent.getStationName(wfID)
abstime = self.wfstart + x 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.label.setText("station = {}, T = {}, t = {} [s]".format(station, abstime, x))
self.vLine.setPos(mousePoint.x()) self.vLine.setPos(mousePoint.x())
self.hLine.setPos(mousePoint.y()) self.hLine.setPos(mousePoint.y())
@@ -491,6 +484,12 @@ class WaveformWidgetPG(QtGui.QWidget):
def clearPlotDict(self): def clearPlotDict(self):
self.plotdict = dict() 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, def plotWFData(self, wfdata, title=None, zoomx=None, zoomy=None,
noiselevel=None, scaleddata=False, mapping=True, noiselevel=None, scaleddata=False, mapping=True,
component='*', nth_sample=1, iniPick=None, verbosity=0): component='*', nth_sample=1, iniPick=None, verbosity=0):
@@ -611,6 +610,7 @@ class WaveformWidgetPG(QtGui.QWidget):
class PylotCanvas(FigureCanvas): class PylotCanvas(FigureCanvas):
def __init__(self, figure=None, parent=None, connect_events=True, multicursor=False, def __init__(self, figure=None, parent=None, connect_events=True, multicursor=False,
panZoomX=True, panZoomY=True): panZoomX=True, panZoomY=True):
self._parent = parent
if not figure: if not figure:
figure = Figure() figure = Figure()
# create axes # create axes
@@ -618,19 +618,17 @@ class PylotCanvas(FigureCanvas):
self.axes = figure.axes self.axes = figure.axes
self.figure = figure 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 # attribute plotdict is a dictionary connecting position and a name
self.plotdict = dict() self.plotdict = dict()
# initialize super class # initialize super class
super(PylotCanvas, self).__init__(self.figure) super(PylotCanvas, self).__init__(self.figure)
self.setParent(parent)
self.orig_parent = parent
if multicursor: if multicursor:
# add a cursor for station selection # add a cursor for station selection
self.multiCursor = MultiCursor(self.figure.canvas, self.axes, self.multiCursor = MultiCursor(self.figure.canvas, self.axes,
horizOn=True, useblit=True, horizOn=True, useblit=True,
color=parent._style['multicursor']['rgba_mpl'], lw=1) color='m', lw=1)
# initialize panning attributes # initialize panning attributes
self.press = None self.press = None
@@ -745,7 +743,7 @@ class PylotCanvas(FigureCanvas):
def saveFigure(self): def saveFigure(self):
if self.figure: if self.figure:
fd = QtGui.QFileDialog() fd = QtGui.QFileDialog()
fname, filter = fd.getSaveFileName(self.parent(), filter='Images (*.png)') fname, filter = fd.getSaveFileName(self._parent, filter='Images (*.png)')
if not fname: if not fname:
return return
if not fname.endswith('.png'): if not fname.endswith('.png'):
@@ -886,6 +884,12 @@ class PylotCanvas(FigureCanvas):
def clearPlotDict(self): def clearPlotDict(self):
self.plotdict = dict() 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, def plotWFData(self, wfdata, title=None, zoomx=None, zoomy=None,
noiselevel=None, scaleddata=False, mapping=True, noiselevel=None, scaleddata=False, mapping=True,
component='*', nth_sample=1, iniPick=None, verbosity=0): component='*', nth_sample=1, iniPick=None, verbosity=0):
@@ -918,9 +922,6 @@ class PylotCanvas(FigureCanvas):
nsc.sort() nsc.sort()
nsc.reverse() nsc.reverse()
style = self.orig_parent._style
linecolor = style['linecolor']['rgba_mpl']
for n, (network, station, channel) in enumerate(nsc): for n, (network, station, channel) in enumerate(nsc):
st = st_select.select(network=network, station=station, channel=channel) st = st_select.select(network=network, station=station, channel=channel)
trace = st[0] trace = st[0]
@@ -941,13 +942,11 @@ class PylotCanvas(FigureCanvas):
trace.normalize(np.max(np.abs(trace.data)) * 2) trace.normalize(np.max(np.abs(trace.data)) * 2)
times = [time for index, time in enumerate(time_ax) if not index % nth_sample] 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] 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: if noiselevel is not None:
for level in noiselevel: for level in noiselevel:
ax.plot([time_ax[0], time_ax[-1]], ax.plot([time_ax[0], time_ax[-1]],
[level, level], [level, level], '--k')
color = linecolor,
linestyle = 'dashed')
self.setPlotDict(n, (station, channel, network)) self.setPlotDict(n, (station, channel, network))
if iniPick: if iniPick:
ax.vlines(iniPick, ax.get_ylim()[0], ax.get_ylim()[1], 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, def __init__(self, parent=None, data=None, station=None, network=None, picks=None,
autopicks=None, rotate=False, parameter=None, embedded=False, metadata=None, autopicks=None, rotate=False, parameter=None, embedded=False, metadata=None,
event=None, filteroptions=None, model='iasp91'): event=None, filteroptions=None, model='iasp91'):
super(PickDlg, self).__init__(parent, 1) super(PickDlg, self).__init__(parent)
self.orig_parent = parent
# initialize attributes # initialize attributes
self.parameter = parameter self.parameter = parameter
@@ -1131,7 +1129,6 @@ class PickDlg(QDialog):
pylot_user = getpass.getuser() pylot_user = getpass.getuser()
self._user = settings.value('user/Login', pylot_user) self._user = settings.value('user/Login', pylot_user)
self._dirty = False self._dirty = False
self._style = parent._style
if picks: if picks:
self.picks = copy.deepcopy(picks) self.picks = copy.deepcopy(picks)
self._init_picks = picks self._init_picks = picks
@@ -1270,8 +1267,8 @@ class PickDlg(QDialog):
self.plot_arrivals_button.setCheckable(True) self.plot_arrivals_button.setCheckable(True)
# create accept/reject button # create accept/reject button
self.accept_button = QPushButton('&Accept') self.accept_button = QPushButton('&Accept Picks')
self.reject_button = QPushButton('&Reject') self.reject_button = QPushButton('&Reject Picks')
self.disable_ar_buttons() self.disable_ar_buttons()
# add hotkeys # add hotkeys
@@ -1295,20 +1292,10 @@ class PickDlg(QDialog):
_dialtoolbar.addSeparator() _dialtoolbar.addSeparator()
_dialtoolbar.addAction(self.resetPicksAction) _dialtoolbar.addAction(self.resetPicksAction)
if self._embedded: 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.accept_button)
_dialtoolbar.addWidget(self.reject_button) _dialtoolbar.addWidget(self.reject_button)
else: else:
_dialtoolbar.addWidget(self.nextStation) _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) _dialtoolbar.addWidget(self.plot_arrivals_button)
# layout the innermost widget # layout the innermost widget
@@ -1410,7 +1397,7 @@ class PickDlg(QDialog):
return return
ax = self.multicompfig.axes[0] ax = self.multicompfig.axes[0]
if not textOnly: if not textOnly:
ylims = self.getGlobalLimits(ax, 'y') ylims = self.getGlobalLimits('y')
else: else:
ylims = self.multicompfig.getYLims(ax) ylims = self.multicompfig.getYLims(ax)
stime = self.getStartTime() stime = self.getStartTime()
@@ -1538,46 +1525,36 @@ class PickDlg(QDialog):
self.leave_picking_mode() self.leave_picking_mode()
def init_p_pick(self): 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.activatePicking()
self.currentPhase = str(self.p_button.text()) self.currentPhase = str(self.p_button.text())
def init_s_pick(self): 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.activatePicking()
self.currentPhase = str(self.s_button.text()) self.currentPhase = str(self.s_button.text())
def getPhaseID(self, phase): def getPhaseID(self, phase):
return identifyPhaseID(phase) return identifyPhaseID(phase)
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: if type(color) == QtGui.QColor:
button.setStyleSheet({'QPushButton{background-color:transparent}'})
palette = button.palette() palette = button.palette()
role = button.backgroundRole() role = button.backgroundRole()
palette.setColor(role, color) palette.setColor(role, color)
button.setPalette(palette) button.setPalette(palette)
button.setAutoFillBackground(True) button.setAutoFillBackground(True)
elif type(color) == str: elif type(color) == str or not color:
button.setStyleSheet('QPushButton{border-color: %s}' % color) button.setStyleSheet("background-color: {}".format(color))
elif type(color) == tuple:
button.setStyleSheet('QPushButton{border-color: rgba%s}' % str(color))
elif not color:
button.setStyleSheet(self.orig_parent._style['stylesheet'])
def reset_p_button(self): 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.setEnabled(True)
self.p_button.setChecked(False) self.p_button.setChecked(False)
self.p_button.setText('P') self.p_button.setText('P')
def reset_s_button(self): 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.setEnabled(True)
self.s_button.setChecked(False) self.s_button.setChecked(False)
self.s_button.setText('S') self.s_button.setText('S')
@@ -1627,7 +1604,6 @@ class PickDlg(QDialog):
return self.station return self.station
def getChannelID(self, key): def getChannelID(self, key):
if key < 0: key = 0
return self.multicompfig.getPlotDict()[int(key)][1] return self.multicompfig.getPlotDict()[int(key)][1]
def getTraceID(self, channels): def getTraceID(self, channels):
@@ -1662,8 +1638,8 @@ class PickDlg(QDialog):
def setYLims(self, limits): def setYLims(self, limits):
self.cur_ylim = limits self.cur_ylim = limits
def getGlobalLimits(self, ax, axis): def getGlobalLimits(self, axis):
return self.multicompfig.getGlobalLimits(ax, axis) return self.multicompfig.getGlobalLimits(axis)
def getWFData(self): def getWFData(self):
return self.data return self.data
@@ -1717,10 +1693,10 @@ class PickDlg(QDialog):
self.cidpress = self.multicompfig.connectPressEvent(self.setPick) self.cidpress = self.multicompfig.connectPressEvent(self.setPick)
if self.getPhaseID(self.currentPhase) == 'P': 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) self.setIniPickP(gui_event, wfdata, trace_number)
elif self.getPhaseID(self.currentPhase) == 'S': 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.setIniPickS(gui_event, wfdata)
self.zoomAction.setEnabled(False) self.zoomAction.setEnabled(False)
@@ -1955,14 +1931,13 @@ class PickDlg(QDialog):
self.drawPicks(picktype='manual') self.drawPicks(picktype='manual')
self.drawPicks(picktype='auto') 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 # plotting picks
ax = self.multicompfig.axes[0] ax = self.multicompfig.axes[0]
if not textOnly: if not textOnly:
ylims = self.multicompfig.getGlobalLimits(ax, 'y') ylims = self.multicompfig.getGlobalLimits(ax, 'y')
else: else:
ylims = ax.get_ylim() ylims = ax.get_ylim()
if not picks:
if self.getPicks(picktype): if self.getPicks(picktype):
if phase is not None and not phase == 'SPt': if phase is not None and not phase == 'SPt':
if (type(self.getPicks(picktype)[phase]) is dict if (type(self.getPicks(picktype)[phase]) is dict
@@ -2260,20 +2235,9 @@ class MultiEventWidget(QWidget):
self.start_button = QtGui.QPushButton('Start') 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 = QtGui.QRadioButton(key)
rb.toggled.connect(self.check_rb_selection) 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: if index == 0:
rb.setChecked(True) rb.setChecked(True)
self.rb_dict[key] = rb self.rb_dict[key] = rb
@@ -2288,7 +2252,7 @@ class MultiEventWidget(QWidget):
self.main_layout.insertLayout(0, self.rb_layout) self.main_layout.insertLayout(0, self.rb_layout)
def refresh_tooltips(self): def refresh_tooltips(self):
for key, func, color in self.options: for key, func in self.options:
eventlist = func() eventlist = func()
if not type(eventlist) == list: if not type(eventlist) == list:
eventlist = [eventlist] eventlist = [eventlist]
@@ -2324,7 +2288,6 @@ class AutoPickWidget(MultiEventWidget):
def __init__(self, parent, options): def __init__(self, parent, options):
MultiEventWidget.__init__(self, options, parent, 1) MultiEventWidget.__init__(self, options, parent, 1)
self.events2plot = {}
self.connect_buttons() self.connect_buttons()
self.init_plot_layout() self.init_plot_layout()
self.init_log_layout() self.init_log_layout()
@@ -2392,9 +2355,6 @@ class AutoPickWidget(MultiEventWidget):
self.main_layout.setStretch(1, 1) self.main_layout.setStretch(1, 1)
def reinitEvents2plot(self): def reinitEvents2plot(self):
for eventID, eventDict in self.events2plot.items():
for widget_key, widget in eventDict.items():
widget.setParent(None)
self.events2plot = {} self.events2plot = {}
self.eventbox.clear() self.eventbox.clear()
self.refresh_plot_tabs() self.refresh_plot_tabs()
@@ -2473,18 +2433,17 @@ class TuneAutopicker(QWidget):
QWidget used to modifiy and test picking parameters for autopicking algorithm. QWidget used to modifiy and test picking parameters for autopicking algorithm.
:param: parent :param: parent
:type: PyLoT Mainwindow :type: QtPyLoT Mainwindow
''' '''
def __init__(self, parent): def __init__(self, parent):
QtGui.QWidget.__init__(self, parent, 1) QtGui.QWidget.__init__(self, parent, 1)
self._style = parent._style self.parent = parent
self.setParent(parent)
self.setWindowTitle('PyLoT - Tune Autopicker') self.setWindowTitle('PyLoT - Tune Autopicker')
self.parameter = self.parent()._inputs self.parameter = parent._inputs
self.fig_dict = self.parent().fig_dict self.set_fig_dict(parent.fig_dict)
self.data = Data() self.data = Data()
self.pdlg_widget = None
self.pylot_picks = None
self.init_main_layouts() self.init_main_layouts()
self.init_eventlist() self.init_eventlist()
self.init_figure_tabs() self.init_figure_tabs()
@@ -2496,9 +2455,8 @@ class TuneAutopicker(QWidget):
self.add_log() self.add_log()
self.set_stretch() self.set_stretch()
self.resize(1280, 720) self.resize(1280, 720)
self._manual_pick_plots = [] if hasattr(parent, 'metadata'):
if hasattr(self.parent(), 'metadata'): self.metadata = self.parent.metadata
self.metadata = self.parent().metadata
else: else:
self.metadata = None self.metadata = None
# self.setWindowModality(QtCore.Qt.WindowModality.ApplicationModal) # self.setWindowModality(QtCore.Qt.WindowModality.ApplicationModal)
@@ -2506,7 +2464,6 @@ class TuneAutopicker(QWidget):
def set_fig_dict(self, fig_dict): def set_fig_dict(self, fig_dict):
for key, value in fig_dict.items(): for key, value in fig_dict.items():
if key is not 'mainFig':
value._tight = True value._tight = True
self.fig_dict = fig_dict self.fig_dict = fig_dict
@@ -2521,7 +2478,7 @@ class TuneAutopicker(QWidget):
self.setLayout(self.main_layout) self.setLayout(self.main_layout)
def init_eventlist(self): def init_eventlist(self):
self.eventBox = self.parent().createEventBox() self.eventBox = self.parent.createEventBox()
self.eventBox.setMaxVisibleItems(20) self.eventBox.setMaxVisibleItems(20)
self.fill_eventbox() self.fill_eventbox()
self.trace_layout.addWidget(self.eventBox) self.trace_layout.addWidget(self.eventBox)
@@ -2540,18 +2497,13 @@ class TuneAutopicker(QWidget):
self.stationBox.activated.connect(self.fill_tabs) self.stationBox.activated.connect(self.fill_tabs)
def fill_stationbox(self): 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) self.data.setWFData(fnames)
wfdat = self.data.getWFData() # all available streams 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 to same start value
trim_station_components(wfdat, trim_start=True, trim_end=False) trim_station_components(wfdat, trim_start=True, trim_end=False)
# rotate misaligned stations to ZNE
wfdat = check4rotated(wfdat, self.parent.metadata)
self.stationBox.clear() self.stationBox.clear()
stations = [] stations = []
for trace in self.data.getWFData(): for trace in self.data.getWFData():
@@ -2565,7 +2517,7 @@ class TuneAutopicker(QWidget):
for network, station in stations: for network, station in stations:
item = QtGui.QStandardItem(network + '.' + station) item = QtGui.QStandardItem(network + '.' + station)
if station in self.get_current_event().pylot_picks: 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) model.appendRow(item)
def init_figure_tabs(self): def init_figure_tabs(self):
@@ -2580,7 +2532,7 @@ class TuneAutopicker(QWidget):
self.stb_names = ['aicARHfig', 'refSpick', 'el_S1pick', 'el_S2pick'] self.stb_names = ['aicARHfig', 'refSpick', 'el_S1pick', 'el_S2pick']
def add_parameters(self): 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.paraBox.set_tune_mode(True)
self.update_eventID() self.update_eventID()
self.parameter_layout.addWidget(self.paraBox) self.parameter_layout.addWidget(self.paraBox)
@@ -2589,7 +2541,6 @@ class TuneAutopicker(QWidget):
def add_buttons(self): def add_buttons(self):
self.pick_button = QtGui.QPushButton('Pick Trace') 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.pick_button.clicked.connect(self.call_picker)
self.close_button = QtGui.QPushButton('Close') self.close_button = QtGui.QPushButton('Close')
self.close_button.clicked.connect(self.hide) self.close_button.clicked.connect(self.hide)
@@ -2607,7 +2558,7 @@ class TuneAutopicker(QWidget):
def get_current_event(self): def get_current_event(self):
path = self.eventBox.currentText() path = self.eventBox.currentText()
return self.parent().project.getEventFromPath(path) return self.parent.project.getEventFromPath(path)
def get_current_event_name(self): def get_current_event_name(self):
return self.eventBox.currentText().split('/')[-1] return self.eventBox.currentText().split('/')[-1]
@@ -2623,7 +2574,10 @@ class TuneAutopicker(QWidget):
def get_current_event_autopicks(self, station): def get_current_event_autopicks(self, station):
event = self.get_current_event() event = self.get_current_event()
if event.pylot_autopicks: if event.pylot_autopicks:
if station in event.pylot_autopicks:
return event.pylot_autopicks[station] return event.pylot_autopicks[station]
else:
return
def get_current_station(self): def get_current_station(self):
return str(self.stationBox.currentText()).split('.')[-1] return str(self.stationBox.currentText()).split('.')[-1]
@@ -2632,66 +2586,51 @@ class TuneAutopicker(QWidget):
widget = QtGui.QWidget() widget = QtGui.QWidget()
v_layout = QtGui.QVBoxLayout() v_layout = QtGui.QVBoxLayout()
v_layout.addWidget(canvas) v_layout.addWidget(canvas)
v_layout.addWidget(NavigationToolbar2QT(canvas, self))
widget.setLayout(v_layout) widget.setLayout(v_layout)
return widget return widget
def gen_pick_dlg(self): def gen_pick_dlg(self):
if not self.get_current_event(): if not self.get_current_event():
if self.pdlg_widget: self.pickDlg = None
self.pdlg_widget.setParent(None)
self.pdlg_widget = None
return return
station = self.get_current_station() station = self.get_current_station()
data = self.data.getWFData() data = self.data.getWFData()
metadata = self.parent().metadata metadata = self.parent.metadata
event = self.get_current_event() event = self.get_current_event()
filteroptions = self.parent().filteroptions filteroptions = self.parent.filteroptions
self.pickDlg = PickDlg(self, data=data.select(station=station), pickDlg = PickDlg(self, data=data.select(station=station),
station=station, parameter=self.parameter, station=station, parameter=self.parameter,
picks=self.get_current_event_picks(station), picks=self.get_current_event_picks(station),
autopicks=self.get_current_event_autopicks(station), autopicks=self.get_current_event_autopicks(station),
metadata=metadata, event=event, filteroptions=filteroptions, metadata=metadata, event=event, filteroptions=filteroptions,
embedded=True) embedded=True)
self.pickDlg.update_picks.connect(self.picks_from_pickdlg) pickDlg.update_picks.connect(self.picks_from_pickdlg)
self.pickDlg.update_picks.connect(self.fill_eventbox) pickDlg.update_picks.connect(self.fill_eventbox)
self.pickDlg.update_picks.connect(self.fill_stationbox) pickDlg.update_picks.connect(self.fill_stationbox)
self.pickDlg.update_picks.connect(lambda: self.parent().setDirty(True)) pickDlg.update_picks.connect(lambda: self.parent.setDirty(True))
self.pickDlg.update_picks.connect(self.parent().enableSaveEventAction) pickDlg.update_picks.connect(self.parent.enableSaveEventAction)
self.pickDlg.update_picks.connect(self.plot_manual_picks_to_figs) self.pickDlg = QtGui.QWidget()
self.pdlg_widget = QtGui.QWidget(self)
hl = QtGui.QHBoxLayout() hl = QtGui.QHBoxLayout()
self.pdlg_widget.setLayout(hl) self.pickDlg.setLayout(hl)
hl.addWidget(self.pickDlg) hl.addWidget(pickDlg)
def picks_from_pickdlg(self, picks=None): def picks_from_pickdlg(self, picks=None):
station = self.get_current_station() station = self.get_current_station()
replot = self.parent().addPicks(station, picks) replot = self.parent.addPicks(station, picks)
self.get_current_event().setPick(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: if replot:
self.parent().plotWaveformDataThread() self.parent.plotWaveformDataThread()
self.parent().drawPicks() self.parent.drawPicks()
else: else:
self.parent().drawPicks(station) self.parent.drawPicks(station)
self.parent().draw() 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))
def plot_manual_picks_to_figs(self): def plot_manual_picks_to_figs(self):
picks = self.get_current_event_picks(self.get_current_station()) picks = self.get_current_event_picks(self.get_current_station())
if not picks: if not picks:
return return
for plotitem in self._manual_pick_plots:
self.clear_plotitem(plotitem)
self._manual_pick_plots = []
st = self.data.getWFData() st = self.data.getWFData()
tr = st.select(station=self.get_current_station())[0] tr = st.select(station=self.get_current_station())[0]
starttime = tr.stats.starttime starttime = tr.stats.starttime
@@ -2710,48 +2649,47 @@ class TuneAutopicker(QWidget):
('refSpick', 0), ('refSpick', 0),
('el_S1pick', 0), ('el_S1pick', 0),
('el_S2pick', 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: 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: if not axes:
continue continue
ax = axes[p_ax[1]] ax = axes[p_ax[1]]
self.plot_manual_pick_to_ax(ax=ax, picks=picks, phase='P', self.plot_manual_Ppick_to_ax(ax, (picks['P']['mpp'] - starttime))
starttime=starttime, quality=qualityPpick)
for s_ax in s_axes: 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: if not axes:
continue continue
ax = axes[s_ax[1]] ax = axes[s_ax[1]]
self.plot_manual_pick_to_ax(ax=ax, picks=picks, phase='S', self.plot_manual_Spick_to_ax(ax, (picks['S']['mpp'] - starttime))
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)
def plot_manual_Ppick_to_ax(self, ax, pick):
y_top = 0.9 * ax.get_ylim()[1] y_top = 0.9 * ax.get_ylim()[1]
y_bot = 0.9 * ax.get_ylim()[0] y_bot = 0.9 * ax.get_ylim()[0]
self._manual_pick_plots.append(ax.vlines(mpp, y_bot, y_top, ax.vlines(pick, y_bot, y_top,
color=color, linewidth=2, color='teal', linewidth=2, label='manual P Onset')
label='manual {} Onset (quality: {})'.format(phase, quality))) ax.plot([pick - 0.5, pick + 0.5],
self._manual_pick_plots.append(ax.plot([mpp - 0.5, mpp + 0.5], [y_bot, y_bot], linewidth=2, color='teal')
[y_bot, y_bot], linewidth=2, ax.plot([pick - 0.5, pick + 0.5],
color=color)) [y_top, y_top], linewidth=2, color='teal')
self._manual_pick_plots.append(ax.plot([mpp - 0.5, mpp + 0.5], ax.legend(loc=1)
[y_top, y_top], linewidth=2,
color=color)) 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) ax.legend(loc=1)
def fill_tabs(self, event=None, picked=False): def fill_tabs(self, event=None, picked=False):
self.clear_all() self.clear_all()
canvas_dict = self.parent.canvas_dict
self.gen_pick_dlg() self.gen_pick_dlg()
canvas_dict = self.parent().canvas_dict
self.overview = self.gen_tab_widget('Overview', canvas_dict['mainFig']) 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') id1 = self.figure_tabs.insertTab(1, self.overview, 'Overview')
id2 = self.figure_tabs.insertTab(2, self.p_tabs, 'P') id2 = self.figure_tabs.insertTab(2, self.p_tabs, 'P')
id3 = self.figure_tabs.insertTab(3, self.s_tabs, 'S') id3 = self.figure_tabs.insertTab(3, self.s_tabs, 'S')
@@ -2794,12 +2732,12 @@ class TuneAutopicker(QWidget):
self.init_tab_names() self.init_tab_names()
def fill_eventbox(self): def fill_eventbox(self):
project = self.parent().project project = self.parent.project
if not project: if not project:
return return
# update own list # update own list
self.parent().fill_eventbox(eventBox=self.eventBox, select_events='ref') self.parent.fill_eventbox(eventBox=self.eventBox, select_events='ref')
index_start = self.parent().eventBox.currentIndex() index_start = self.parent.eventBox.currentIndex()
index = index_start index = index_start
if index == -1: if index == -1:
index += 1 index += 1
@@ -2818,7 +2756,7 @@ class TuneAutopicker(QWidget):
if not index == index_start: if not index == index_start:
self.eventBox.activated.emit(index) self.eventBox.activated.emit(index)
# update parent # update parent
self.parent().fill_eventbox() self.parent.fill_eventbox()
def update_eventID(self): def update_eventID(self):
self.paraBox.boxes['eventID'].setText( self.paraBox.boxes['eventID'].setText(
@@ -2840,7 +2778,6 @@ class TuneAutopicker(QWidget):
'locflag': 0, 'locflag': 0,
'savexml': False} 'savexml': False}
for key in self.fig_dict.keys(): for key in self.fig_dict.keys():
if not key == 'plot_style':
self.fig_dict[key].clear() self.fig_dict[key].clear()
self.ap_thread = Thread(self, autoPyLoT, arg=args, self.ap_thread = Thread(self, autoPyLoT, arg=args,
progressText='Picking trace...', progressText='Picking trace...',
@@ -2882,8 +2819,8 @@ class TuneAutopicker(QWidget):
def params_from_gui(self): def params_from_gui(self):
parameters = self.paraBox.params_from_gui() parameters = self.paraBox.params_from_gui()
if self.parent(): if self.parent:
self.parent()._inputs = parameters self.parent._inputs = parameters
return parameters return parameters
def set_stretch(self): def set_stretch(self):
@@ -2891,11 +2828,10 @@ class TuneAutopicker(QWidget):
self.tune_layout.setStretch(1, 1) self.tune_layout.setStretch(1, 1)
def clear_all(self): def clear_all(self):
if hasattr(self, 'pdlg_widget'): if hasattr(self, 'pickDlg'):
if self.pdlg_widget: if self.pickDlg:
self.pdlg_widget.setParent(None) self.pickDlg.setParent(None)
# TODO: removing widget by parent deletion raises exception when activating stationbox: del (self.pickDlg)
# RuntimeError: Internal C++ object (PylotCanvas) already deleted.
if hasattr(self, 'overview'): if hasattr(self, 'overview'):
self.overview.setParent(None) self.overview.setParent(None)
if hasattr(self, 'p_tabs'): if hasattr(self, 'p_tabs'):
@@ -2924,7 +2860,7 @@ class PylotParaBox(QtGui.QWidget):
accepted = QtCore.Signal(str) accepted = QtCore.Signal(str)
rejected = 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. Generate Widget containing parameters for PyLoT.
@@ -2932,7 +2868,7 @@ class PylotParaBox(QtGui.QWidget):
:type: PylotParameter (object) :type: PylotParameter (object)
''' '''
QtGui.QWidget.__init__(self, parent, windowflag) QtGui.QWidget.__init__(self, parent)
self.parameter = parameter self.parameter = parameter
self.tabs = QtGui.QTabWidget() self.tabs = QtGui.QTabWidget()
self.layout = QtGui.QVBoxLayout() self.layout = QtGui.QVBoxLayout()
@@ -3475,6 +3411,9 @@ class SubmitLocal(QWidget):
self.main_layout.addWidget(self.button) self.main_layout.addWidget(self.button)
def start(self):
print('subprocess Popen')
def start(self, pp_export, ncores): def start(self, pp_export, ncores):
self.execute_command(pp_export, ncores) self.execute_command(pp_export, ncores)
@@ -3494,7 +3433,6 @@ class SubmitLocal(QWidget):
class PropertiesDlg(QDialog): class PropertiesDlg(QDialog):
def __init__(self, parent=None, infile=None, inputs=None): def __init__(self, parent=None, infile=None, inputs=None):
super(PropertiesDlg, self).__init__(parent) super(PropertiesDlg, self).__init__(parent)
self._pylot_mainwindow = self.parent()
self.infile = infile self.infile = infile
self.inputs = inputs self.inputs = inputs
@@ -3795,29 +3733,14 @@ class PhasesTab(PropTab):
class GraphicsTab(PropTab): class GraphicsTab(PropTab):
def __init__(self, parent=None): def __init__(self, parent=None):
super(GraphicsTab, self).__init__(parent) super(GraphicsTab, self).__init__(parent)
self.pylot_mainwindow = parent._pylot_mainwindow
self.init_layout() self.init_layout()
self.add_pg_cb() self.add_pg_cb()
self.add_nth_sample() self.add_nth_sample()
self.add_style_settings()
self.setLayout(self.main_layout) self.setLayout(self.main_layout)
def init_layout(self): def init_layout(self):
self.main_layout = QGridLayout() 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): def add_nth_sample(self):
settings = QSettings() settings = QSettings()
nth_sample = settings.value("nth_sample") nth_sample = settings.value("nth_sample")
@@ -3834,12 +3757,6 @@ class GraphicsTab(PropTab):
self.main_layout.addWidget(self.spinbox_nth_sample, 1, 1) self.main_layout.addWidget(self.spinbox_nth_sample, 1, 1)
def add_pg_cb(self): def add_pg_cb(self):
try:
import pyqtgraph as pg
pg = True
except:
pg = False
text = {True: 'Use pyqtgraphic library for plotting', text = {True: 'Use pyqtgraphic library for plotting',
False: 'Cannot use library: pyqtgraphic not found on system'} False: 'Cannot use library: pyqtgraphic not found on system'}
label = QLabel('PyQt graphic') label = QLabel('PyQt graphic')
@@ -3851,10 +3768,6 @@ class GraphicsTab(PropTab):
self.main_layout.addWidget(label, 0, 0) self.main_layout.addWidget(label, 0, 0)
self.main_layout.addWidget(self.checkbox_pg, 0, 1) 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): def getValues(self):
values = {'nth_sample': self.spinbox_nth_sample.value(), values = {'nth_sample': self.spinbox_nth_sample.value(),
'pyqtgraphic': self.checkbox_pg.isChecked()} 'pyqtgraphic': self.checkbox_pg.isChecked()}
@@ -4302,23 +4215,15 @@ class LoadDataDlg(QDialog):
class HelpForm(QDialog): class HelpForm(QDialog):
def __init__(self, parent=None, def __init__(self, page=QUrl('https://ariadne.geophysik.rub.de/trac/PyLoT'),
page=QUrl('https://ariadne.geophysik.ruhr-uni-bochum.de/trac/PyLoT/')): parent=None):
super(HelpForm, self).__init__(parent, 1) super(HelpForm, self).__init__(parent)
self.setAttribute(Qt.WA_DeleteOnClose) self.setAttribute(Qt.WA_DeleteOnClose)
self.setAttribute(Qt.WA_GroupLeader) self.setAttribute(Qt.WA_GroupLeader)
self.home_page = page backAction = QAction(QIcon(":/back.png"), "&Back", self)
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.setShortcut(QKeySequence.Back) backAction.setShortcut(QKeySequence.Back)
homeAction = QAction(home_icon, "&Home", self) homeAction = QAction(QIcon(":/home.png"), "&Home", self)
homeAction.setShortcut("Home") homeAction.setShortcut("Home")
self.pageLabel = QLabel() self.pageLabel = QLabel()
@@ -4331,21 +4236,21 @@ class HelpForm(QDialog):
layout = QVBoxLayout() layout = QVBoxLayout()
layout.addWidget(toolBar) layout.addWidget(toolBar)
layout.addWidget(self.webBrowser) layout.addWidget(self.webBrowser, 1)
self.setLayout(layout) self.setLayout(layout)
backAction.triggered.connect(self.webBrowser.back) self.connect(backAction, Signal("triggered()"),
homeAction.triggered.connect(self.home) self.webBrowser, Slot("backward()"))
self.webBrowser.urlChanged.connect(self.updatePageTitle) 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())) self.setWindowTitle("{0} Help".format(QApplication.applicationName()))
def home(self):
self.webBrowser.load(self.home_page)
def updatePageTitle(self): def updatePageTitle(self):
self.pageLabel.setText(self.webBrowser.title()) self.pageLabel.setText(self.webBrowser.documentTitle())
if __name__ == '__main__': 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( setup(
name='PyLoT', name='PyLoT',
version='0.2', version='0.1a1',
packages=['pylot', 'pylot.core', 'pylot.core.loc', 'pylot.core.pick', packages=['pylot', 'pylot.core', 'pylot.core.loc', 'pylot.core.pick',
'pylot.core.io', 'pylot.core.util', 'pylot.core.active', 'pylot.core.io', 'pylot.core.util', 'pylot.core.active',
'pylot.core.analysis', 'pylot.testing'], 'pylot.core.analysis', 'pylot.testing'],
requires=['obspy', 'PySide', 'matplotlib', 'numpy'], requires=['obspy', 'PySide'],
url='dummy', url='dummy',
license='LGPLv3', license='LGPLv3',
author='Sebastian Wehling-Benatelli', author='Sebastian Wehling-Benatelli',