Merge branch 'tap_thread' into develop

This commit is contained in:
Marcel Paffrath 2017-05-17 13:27:03 +02:00
commit b97f79c31d
10 changed files with 1122 additions and 532 deletions

View File

@ -41,6 +41,13 @@ from PySide.QtGui import QMainWindow, QInputDialog, QIcon, QFileDialog, \
import numpy as np import numpy as np
from obspy import UTCDateTime from obspy import UTCDateTime
try:
from matplotlib.backends.backend_qt4agg import FigureCanvas
except ImportError:
from matplotlib.backends.backend_qt4agg import FigureCanvasQTAgg as FigureCanvas
from matplotlib.backends.backend_qt4agg import NavigationToolbar2QT as NavigationToolbar
from matplotlib.figure import Figure
from pylot.core.analysis.magnitude import RichterMagnitude, MomentMagnitude from pylot.core.analysis.magnitude import RichterMagnitude, MomentMagnitude
from pylot.core.io.data import Data from pylot.core.io.data import Data
from pylot.core.io.inputs import FilterOptions, AutoPickParameter from pylot.core.io.inputs import FilterOptions, AutoPickParameter
@ -59,7 +66,7 @@ from pylot.core.util.utils import fnConstructor, getLogin, \
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, \
WaveformWidget, PropertiesDlg, HelpForm, createAction, PickDlg, \ WaveformWidget, PropertiesDlg, HelpForm, createAction, PickDlg, \
getDataType, ComparisonDialog getDataType, ComparisonDialog, TuneAutopicker
from pylot.core.util.map_projection import map_projection from pylot.core.util.map_projection import map_projection
from pylot.core.util.structure import DATASTRUCTURE from pylot.core.util.structure import DATASTRUCTURE
from pylot.core.util.thread import AutoPickThread, Thread from pylot.core.util.thread import AutoPickThread, Thread
@ -90,6 +97,7 @@ class MainWindow(QMainWindow):
self._inputs = AutoPickParameter(infile) self._inputs = AutoPickParameter(infile)
self.project = Project() self.project = Project()
self.tap = None
self.array_map = None self.array_map = None
self._metadata = None self._metadata = None
self._eventChanged = [False, False] self._eventChanged = [False, False]
@ -416,9 +424,9 @@ class MainWindow(QMainWindow):
self.addActions(componentToolBar, componentActions) self.addActions(componentToolBar, componentActions)
self.auto_pick = self.createAction(parent=self, text='autoPick', self.auto_pick = self.createAction(parent=self, text='autoPick',
slot=self.autoPick, shortcut='Alt+Ctrl+A', slot=self.tune_autopicker, shortcut='Alt+Ctrl+A',
icon=auto_icon, tip='Automatically pick' icon=auto_icon, tip='Tune autopicking algorithm.')
' the displayed waveforms.')
self.auto_pick.setEnabled(False) self.auto_pick.setEnabled(False)
autoPickToolBar = self.addToolBar("autoPyLoT") autoPickToolBar = self.addToolBar("autoPyLoT")
@ -548,17 +556,6 @@ class MainWindow(QMainWindow):
self.drawPicks(picktype=type) self.drawPicks(picktype=type)
self.draw() self.draw()
def getCurrentEvent(self):
for event in self.project.eventlist:
if event.path == self.getCurrentEventPath():
return event
def getCurrentEventPath(self):
return str(self.eventBox.currentText().split('|')[0]).strip()
def getLastEvent(self):
return self.recentfiles[0]
def add_recentfile(self, event): def add_recentfile(self, event):
self.recentfiles.insert(0, event) self.recentfiles.insert(0, event)
@ -596,16 +593,29 @@ class MainWindow(QMainWindow):
else: else:
return return
def getWFFnames_from_eventlist(self): def getWFFnames_from_eventbox(self, eventlist=None, eventbox=None):
if self.dataStructure: if self.dataStructure:
searchPath = self.dataStructure.expandDataPath() directory = self.getCurrentEventPath(eventbox)
directory = self.getCurrentEventPath() fnames = [os.path.join(directory, f) for f in os.listdir(directory)]
self.fnames = [os.path.join(directory, f) for f in os.listdir(directory)]
else: else:
raise DatastructureError('not specified') raise DatastructureError('not specified')
if not self.fnames: return fnames
return None
return self.fnames def getCurrentEvent(self, eventlist=None, eventbox=None):
if not eventlist:
eventlist = self.project.eventlist
if not eventbox:
eventbox = self.eventBox
index = eventbox.currentIndex()
return eventbox.itemData(index)
def getCurrentEventPath(self, eventbox=None):
if not eventbox:
eventbox = self.eventBox
return str(eventbox.currentText().split('|')[0]).strip()
def getLastEvent(self):
return self.recentfiles[0]
def add_events(self): def add_events(self):
if not self.project: if not self.project:
@ -628,14 +638,14 @@ class MainWindow(QMainWindow):
def createEventBox(self): def createEventBox(self):
qcb = QComboBox() qcb = QComboBox()
palette = qcb.palette() palette = qcb.palette()
palette.setBrush(QtGui.QPalette.Inactive, QtGui.QPalette.Highlight, # change highlight color:
QtGui.QBrush(QtGui.QColor(0,0,127,127))) # palette.setBrush(QtGui.QPalette.Inactive, QtGui.QPalette.Highlight,
palette.setBrush(QtGui.QPalette.Active, QtGui.QPalette.Highlight, # QtGui.QBrush(QtGui.QColor(0,0,127,127)))
QtGui.QBrush(QtGui.QColor(0,0,127,127))) # palette.setBrush(QtGui.QPalette.Active, QtGui.QPalette.Highlight,
# QtGui.QBrush(QtGui.QColor(0,0,127,127)))
qcb.setPalette(palette) qcb.setPalette(palette)
return qcb return qcb
def init_events(self, new=False): def init_events(self, new=False):
nitems = self.eventBox.count() nitems = self.eventBox.count()
if len(self.project.eventlist) == 0: if len(self.project.eventlist) == 0:
@ -643,7 +653,7 @@ class MainWindow(QMainWindow):
self.clearWaveformDataPlot() self.clearWaveformDataPlot()
return return
self.eventBox.setEnabled(True) self.eventBox.setEnabled(True)
self.fill_eventbox() self.fill_eventbox(self.eventBox)
if new: if new:
self.eventBox.setCurrentIndex(0) self.eventBox.setCurrentIndex(0)
else: else:
@ -651,8 +661,14 @@ class MainWindow(QMainWindow):
self.refreshEvents() self.refreshEvents()
tabindex = self.tabs.currentIndex() tabindex = self.tabs.currentIndex()
def fill_eventbox(self): def fill_eventbox(self, eventBox=None, select_events='all'):
index=self.eventBox.currentIndex() '''
:param: select_events, can be 'all', 'ref'
:type: str
'''
if not eventBox:
eventBox = self.eventBox
index=eventBox.currentIndex()
tv=QtGui.QTableView() tv=QtGui.QTableView()
header = tv.horizontalHeader() header = tv.horizontalHeader()
header.setResizeMode(QtGui.QHeaderView.ResizeToContents) header.setResizeMode(QtGui.QHeaderView.ResizeToContents)
@ -661,16 +677,17 @@ class MainWindow(QMainWindow):
tv.verticalHeader().hide() tv.verticalHeader().hide()
tv.setSelectionBehavior(QtGui.QAbstractItemView.SelectRows) tv.setSelectionBehavior(QtGui.QAbstractItemView.SelectRows)
self.eventBox.setView(tv) eventBox.setView(tv)
self.eventBox.clear() eventBox.clear()
model = self.eventBox.model() model = eventBox.model()
plmax=0 plmax=0
#set maximum length of path string
for event in self.project.eventlist: for event in self.project.eventlist:
pl = len(event.path) pl = len(event.path)
if pl > plmax: if pl > plmax:
plmax=pl plmax=pl
for event in self.project.eventlist: for id, event in enumerate(self.project.eventlist):
event_path = event.path event_path = event.path
event_npicks = 0 event_npicks = 0
event_nautopicks = 0 event_nautopicks = 0
@ -681,11 +698,11 @@ class MainWindow(QMainWindow):
event_ref = event.isRefEvent() event_ref = event.isRefEvent()
event_test = event.isTestEvent() event_test = event.isTestEvent()
text = '{path:{plen}} | manual: [{p:3d}] | auto: [{a:3d}]' # text = '{path:{plen}} | manual: [{p:3d}] | auto: [{a:3d}]'
text = text.format(path=event_path, # text = text.format(path=event_path,
plen=plmax, # plen=plmax,
p=event_npicks, # p=event_npicks,
a=event_nautopicks) # a=event_nautopicks)
item_path = QtGui.QStandardItem('{path:{plen}}'.format(path=event_path, plen=plmax)) item_path = QtGui.QStandardItem('{path:{plen}}'.format(path=event_path, plen=plmax))
item_nmp = QtGui.QStandardItem(str(event_npicks)) item_nmp = QtGui.QStandardItem(str(event_npicks))
@ -714,8 +731,17 @@ class MainWindow(QMainWindow):
# item2.setForeground(QtGui.QColor('black')) # item2.setForeground(QtGui.QColor('black'))
# item2.setFont(font) # item2.setFont(font)
itemlist = [item_path, item_nmp, item_nap, item_ref, item_test, item_notes] itemlist = [item_path, item_nmp, item_nap, item_ref, item_test, item_notes]
if event_test and select_events == 'ref':
for item in itemlist:
item.setEnabled(False)
model.appendRow(itemlist) model.appendRow(itemlist)
self.eventBox.setCurrentIndex(index) if not event.path == self.eventBox.itemText(id):
message = ('Path missmatch creating eventbox.\n'
'{} unequal {}.'
.format(event.path, self.eventBox.itemText(id)))
raise ValueError(message)
eventBox.setItemData(id, event)
eventBox.setCurrentIndex(index)
def filename_from_action(self, action): def filename_from_action(self, action):
if action.data() is None: if action.data() is None:
@ -886,6 +912,7 @@ class MainWindow(QMainWindow):
self.refreshTabs() self.refreshTabs()
def refreshTabs(self): def refreshTabs(self):
plotted=False
if self._eventChanged[0] or self._eventChanged[1]: if self._eventChanged[0] or self._eventChanged[1]:
event = self.getCurrentEvent() event = self.getCurrentEvent()
if not event.picks: if not event.picks:
@ -901,18 +928,24 @@ class MainWindow(QMainWindow):
if len(self.project.eventlist) > 0: if len(self.project.eventlist) > 0:
if self._eventChanged[0]: if self._eventChanged[0]:
self.newWFplot() self.newWFplot()
plotted=True
if self.tabs.currentIndex() == 1: if self.tabs.currentIndex() == 1:
if self._eventChanged[1]: if self._eventChanged[1]:
self.refresh_array_map() self.refresh_array_map()
if not plotted and self._eventChanged[0]:
self.newWFplot(False)
if self.tabs.currentIndex() == 2: if self.tabs.currentIndex() == 2:
self.init_event_table() self.init_event_table()
def newWFplot(self): def newWFplot(self, plot=True):
self.loadWaveformDataThread() self.loadWaveformDataThread(plot)
if plot:
self._eventChanged[0] = False self._eventChanged[0] = False
def loadWaveformDataThread(self): def loadWaveformDataThread(self, plot=True):
wfd_thread = Thread(self, self.loadWaveformData, progressText='Reading data input...') wfd_thread = Thread(self, self.loadWaveformData,
progressText='Reading data input...')
if plot:
wfd_thread.finished.connect(self.plotWaveformDataThread) wfd_thread.finished.connect(self.plotWaveformDataThread)
wfd_thread.start() wfd_thread.start()
@ -924,7 +957,8 @@ class MainWindow(QMainWindow):
# ans = self.data.setWFData(self.getWFFnames()) # ans = self.data.setWFData(self.getWFFnames())
# else: # else:
# ans = False # ans = False
self.data.setWFData(self.getWFFnames_from_eventlist()) self.fnames = self.getWFFnames_from_eventbox(self.project.eventlist)
self.data.setWFData(self.fnames)
self._stime = full_range(self.get_data().getWFData())[0] self._stime = full_range(self.get_data().getWFData())[0]
def connectWFplotEvents(self): def connectWFplotEvents(self):
@ -981,7 +1015,8 @@ class MainWindow(QMainWindow):
self.draw() self.draw()
def plotWaveformDataThread(self): def plotWaveformDataThread(self):
wfp_thread = Thread(self, self.plotWaveformData, progressText='Plotting waveform data...') wfp_thread = Thread(self, self.plotWaveformData,
progressText='Plotting waveform data...')
wfp_thread.finished.connect(self.finishWaveformDataPlot) wfp_thread.finished.connect(self.finishWaveformDataPlot)
wfp_thread.start() wfp_thread.start()
@ -1113,7 +1148,7 @@ class MainWindow(QMainWindow):
station = self.getStationName(wfID) station = self.getStationName(wfID)
self.update_status('picking on station {0}'.format(station)) self.update_status('picking on station {0}'.format(station))
data = self.get_data().getWFData() data = self.get_data().getWFData()
pickDlg = PickDlg(self, infile=self.getinfile(), pickDlg = PickDlg(self, parameter=self._inputs,
data=data.select(station=station), data=data.select(station=station),
station=station, station=station,
picks=self.getPicksOnStation(station, 'manual'), picks=self.getPicksOnStation(station, 'manual'),
@ -1122,6 +1157,7 @@ class MainWindow(QMainWindow):
self.setDirty(True) self.setDirty(True)
self.update_status('picks accepted ({0})'.format(station)) self.update_status('picks accepted ({0})'.format(station))
replot = self.addPicks(station, pickDlg.getPicks()) replot = self.addPicks(station, pickDlg.getPicks())
self.getCurrentEvent().setPick(station, pickDlg.getPicks())
if replot: if replot:
self.plotWaveformData() self.plotWaveformData()
self.drawPicks() self.drawPicks()
@ -1141,6 +1177,40 @@ class MainWindow(QMainWindow):
self.listWidget.addItem(text) self.listWidget.addItem(text)
self.listWidget.scrollToBottom() self.listWidget.scrollToBottom()
def tune_autopicker(self):
self.fig_dict = {}
self.canvas_dict = {}
self.fig_keys = [
'mainFig',
'aicFig',
'slength',
'checkZ4s',
'refPpick',
'el_Ppick',
'fm_picker',
'el_S1pick',
'el_S2pick',
'refSpick',
'aicARHfig',
]
for key in self.fig_keys:
fig = Figure()
self.fig_dict[key] = fig
if not self.tap:
self.tap = TuneAutopicker(self)
self.update_autopicker()
self.tap.update.connect(self.update_autopicker)
self.tap.figure_tabs.setCurrentIndex(0)
else:
self.tap.fill_eventbox()
self.tap.show()
def update_autopicker(self):
for key in self.fig_dict.keys():
self.canvas_dict[key] = FigureCanvas(self.fig_dict[key])
self.tap.fill_tabs(picked=True)
def autoPick(self): def autoPick(self):
self.autosave = QFileDialog().getExistingDirectory(caption='Select autoPyLoT output') self.autosave = QFileDialog().getExistingDirectory(caption='Select autoPyLoT output')
if not os.path.exists(self.autosave): if not os.path.exists(self.autosave):
@ -1354,19 +1424,34 @@ class MainWindow(QMainWindow):
self.get_metadata() self.get_metadata()
if not self.metadata: if not self.metadata:
return return
self.am_figure = Figure()
self.am_canvas = FigureCanvas(self.am_figure)
self.am_toolbar = NavigationToolbar(self.am_canvas, self)
self.array_map = map_projection(self) self.array_map = map_projection(self)
#self.array_map_thread()
self.array_layout.addWidget(self.array_map) self.array_layout.addWidget(self.array_map)
self.tabs.setCurrentIndex(index) self.tabs.setCurrentIndex(index)
self.refresh_array_map() self.refresh_array_map()
def array_map_thread(self):
self.amt = Thread(self, self.array_map.init_map, arg=None, progressText='Generating map...')
self.amt.finished.connect(self.finish_array_map)
self.amt.start()
def finish_array_map(self):
self.array_map = self.amt.data
self.array_layout.addWidget(self.array_map)
#self.tabs.setCurrentIndex(index)
#self.refresh_array_map()
def refresh_array_map(self): def refresh_array_map(self):
if not self.array_map: if not self.array_map:
return return
# refresh with new picks here!!! # refresh with new picks here!!!
self.array_map.refresh_drawings(self.picks) self.array_map.refresh_drawings(self.getCurrentEvent().getPicks())
self._eventChanged[1] = False self._eventChanged[1] = False
def init_event_table(self, index=2): def init_event_table(self, tabindex=2):
def set_enabled(item, enabled=True, checkable=False): def set_enabled(item, enabled=True, checkable=False):
if enabled and not checkable: if enabled and not checkable:
item.setFlags(QtCore.Qt.ItemIsEnabled | QtCore.Qt.ItemIsSelectable) item.setFlags(QtCore.Qt.ItemIsEnabled | QtCore.Qt.ItemIsSelectable)
@ -1397,12 +1482,12 @@ class MainWindow(QMainWindow):
event.setTestEvent(True) event.setTestEvent(True)
elif column == 4 and not item_test.checkState(): elif column == 4 and not item_test.checkState():
event.setTestEvent(False) event.setTestEvent(False)
self.fill_eventbox() self.fill_eventbox(self.eventBox)
elif column == 5: elif column == 5:
#update event notes #update event notes
notes = table[row][5].text() notes = table[row][5].text()
event.addNotes(notes) event.addNotes(notes)
self.fill_eventbox() self.fill_eventbox(self.eventBox)
if hasattr(self, 'qtl'): if hasattr(self, 'qtl'):
self.qtl.setParent(None) self.qtl.setParent(None)
@ -1467,7 +1552,7 @@ class MainWindow(QMainWindow):
self.qtl.cellChanged[int, int].connect(cell_changed) self.qtl.cellChanged[int, int].connect(cell_changed)
self.events_layout.addWidget(self.qtl) self.events_layout.addWidget(self.qtl)
self.tabs.setCurrentIndex(index) 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...')
@ -1656,7 +1741,7 @@ class MainWindow(QMainWindow):
self.createNewProject(exists=True) self.createNewProject(exists=True)
def draw(self): def draw(self):
self.fill_eventbox() self.fill_eventbox(self.eventBox)
self.getPlotWidget().draw() self.getPlotWidget().draw()
def setDirty(self, value): def setDirty(self, value):
@ -1696,10 +1781,18 @@ class Project(object):
return return
for item in eventlist: for item in eventlist:
event = Event(item) event = Event(item)
if not event in self.eventlist: if not event.path in self.getPaths():
self.eventlist.append(event) self.eventlist.append(event)
else:
print('Skipping event with path {}. Already part of project.'.format(event.path))
self.setDirty() self.setDirty()
def getPaths(self):
paths = []
for event in self.eventlist:
paths.append(event.path)
return paths
def setDirty(self): def setDirty(self):
self.dirty = True self.dirty = True
@ -1752,18 +1845,12 @@ class Event(object):
''' '''
def __init__(self, path): def __init__(self, path):
self.path = path self.path = path
self.autopicks = None self.autopicks = {}
self.picks = None self.picks = {}
self.notes = None self.notes = ''
self._testEvent = False self._testEvent = False
self._refEvent = False self._refEvent = False
def addPicks(self, picks):
self.picks = picks
def addAutopicks(self, autopicks):
self.autopicks = autopicks
def addNotes(self, notes): def addNotes(self, notes):
self.notes = notes self.notes = notes
@ -1784,6 +1871,42 @@ class Event(object):
self._testEvent = bool self._testEvent = bool
if bool: self._refEvent = False if bool: self._refEvent = False
def addPicks(self, picks):
for station in picks:
self.picks[station] = picks[station]
def addAutopicks(self, autopicks):
for station in autopicks:
self.autopicks[station] = autopicks[station]
def setPick(self, station, pick):
if pick:
self.picks[station] = pick
def setPicks(self, picks):
self.picks = picks
def getPick(self, station):
if station in self.picks.keys():
return self.picks[station]
def getPicks(self):
return self.picks
def setAutopick(self, station, autopick):
if autopick:
self.autopicks[station] = autopick
def setAutopicks(self, autopicks):
self.autopicks = autopicks
def getAutopick(self, station):
if station in self.autopicks.keys():
return self.autopicks[station]
def getAutopicks(self):
return self.autopicks
class getExistingDirectories(QFileDialog): class getExistingDirectories(QFileDialog):
def __init__(self, *args): def __init__(self, *args):

View File

@ -29,7 +29,7 @@ from pylot.core.util.version import get_git_version as _getVersionString
__version__ = _getVersionString() __version__ = _getVersionString()
def autoPyLoT(parameter=None, inputfile=None, fnames=None, savepath=None, iplot=0): def autoPyLoT(input_dict=None, parameter=None, inputfile=None, fnames=None, savepath=None, station='all', iplot=0):
""" """
Determine phase onsets automatically utilizing the automatic picking Determine phase onsets automatically utilizing the automatic picking
algorithms by Kueperkoch et al. 2010/2012. algorithms by Kueperkoch et al. 2010/2012.
@ -55,6 +55,21 @@ def autoPyLoT(parameter=None, inputfile=None, fnames=None, savepath=None, iplot=
***********************************'''.format(version=_getVersionString()) ***********************************'''.format(version=_getVersionString())
print(splash) print(splash)
locflag = 1
if input_dict:
if input_dict.has_key('parameter'):
parameter = input_dict['parameter']
if input_dict.has_key('fig_dict'):
fig_dict = input_dict['fig_dict']
if input_dict.has_key('station'):
station = input_dict['station']
if input_dict.has_key('fnames'):
fnames = input_dict['fnames']
if input_dict.has_key('iplot'):
iplot = input_dict['iplot']
if input_dict.has_key('locflag'):
locflag = input_dict['locflag']
if not parameter: if not parameter:
if inputfile: if inputfile:
parameter = AutoPickParameter(inputfile) parameter = AutoPickParameter(inputfile)
@ -93,8 +108,7 @@ def autoPyLoT(parameter=None, inputfile=None, fnames=None, savepath=None, iplot=
datastructure.setExpandFields(exf) datastructure.setExpandFields(exf)
# check if default location routine NLLoc is available # check if default location routine NLLoc is available
if parameter['nllocbin']: if parameter['nllocbin'] and locflag:
locflag = 1
# get NLLoc-root path # get NLLoc-root path
nllocroot = parameter.get('nllocroot') nllocroot = parameter.get('nllocroot')
# get path to NLLoc executable # get path to NLLoc executable
@ -158,15 +172,20 @@ def autoPyLoT(parameter=None, inputfile=None, fnames=None, savepath=None, iplot=
now.minute) now.minute)
parameter.setParam(eventID=evID) parameter.setParam(eventID=evID)
wfdat = data.getWFData() # all available streams wfdat = data.getWFData() # all available streams
if not station == 'all':
wfdat = wfdat.select(station=station)
if not wfdat:
print('Could not find station {}. STOP!'.format(station))
return
wfdat = remove_underscores(wfdat) wfdat = remove_underscores(wfdat)
metadata = read_metadata(parameter.get('invdir')) metadata = read_metadata(parameter.get('invdir'))
corr_dat = restitute_data(wfdat.copy(), *metadata) corr_dat = restitute_data(wfdat.copy(), *metadata)
print('Working on event %s' % event) print('Working on event %s. Stations: %s' % (event, station))
print(data) print(wfdat)
########################################################## ##########################################################
# !automated picking starts here! # !automated picking starts here!
picks, mainFig = autopickevent(wfdat, parameter, iplot=iplot) picks = autopickevent(wfdat, parameter, iplot=iplot, fig_dict=fig_dict)
########################################################## ##########################################################
# locating # locating
if locflag == 1: if locflag == 1:
@ -233,7 +252,7 @@ def autoPyLoT(parameter=None, inputfile=None, fnames=None, savepath=None, iplot=
print("autoPyLoT: Number of maximum iterations reached, stop iterative picking!") print("autoPyLoT: Number of maximum iterations reached, stop iterative picking!")
break break
print("autoPyLoT: Starting with iteration No. %d ..." % nlloccounter) print("autoPyLoT: Starting with iteration No. %d ..." % nlloccounter)
picks, _ = iteratepicker(wfdat, nllocfile, picks, badpicks, parameter) picks = iteratepicker(wfdat, nllocfile, picks, badpicks, parameter, fig_dict=fig_dict)
# write phases to NLLoc-phase file # write phases to NLLoc-phase file
nll.export(picks, phasefile, parameter) nll.export(picks, phasefile, parameter)
# remove actual NLLoc-location file to keep only the last # remove actual NLLoc-location file to keep only the last
@ -317,7 +336,7 @@ def autoPyLoT(parameter=None, inputfile=None, fnames=None, savepath=None, iplot=
The Python picking and Location Tool\n The Python picking and Location Tool\n
************************************'''.format(version=_getVersionString()) ************************************'''.format(version=_getVersionString())
print(endsp) print(endsp)
return picks, mainFig return picks
if __name__ == "__main__": if __name__ == "__main__":
@ -344,4 +363,5 @@ if __name__ == "__main__":
cla = parser.parse_args() cla = parser.parse_args()
picks, mainFig = autoPyLoT(str(cla.inputfile), str(cla.fnames), str(cla.spath)) picks, mainFig = autoPyLoT(inputfile=str(cla.inputfile),
fnames=str(cla.fnames), savepath=str(cla.spath))

View File

@ -1 +1 @@
dc65-dirty 55bc-dirty

View File

@ -47,47 +47,12 @@ class AutoPickParameter(object):
self.__init_default_paras() self.__init_default_paras()
self.__init_subsettings() self.__init_subsettings()
self.__filename = fnin self.__filename = fnin
parFileCont = {} self._verbosity = verbosity
self._parFileCont = {}
# io from parsed arguments alternatively # io from parsed arguments alternatively
for key, val in kwargs.items(): for key, val in kwargs.items():
parFileCont[key] = val self._parFileCont[key] = val
self.from_file()
if self.__filename is not None:
inputFile = open(self.__filename, 'r')
else:
return
try:
lines = inputFile.readlines()
for line in lines:
parspl = line.split('\t')[:2]
parFileCont[parspl[0].strip()] = parspl[1]
except IndexError as e:
if verbosity > 0:
self._printParameterError(e)
inputFile.seek(0)
lines = inputFile.readlines()
for line in lines:
if not line.startswith(('#', '%', '\n', ' ')):
parspl = line.split('#')[:2]
parFileCont[parspl[1].strip()] = parspl[0].strip()
for key, value in parFileCont.items():
try:
val = int(value)
except:
try:
val = float(value)
except:
if len(value.split(' ')) > 1:
vallist = value.strip().split(' ')
val = []
for val0 in vallist:
val0 = float(val0)
val.append(val0)
else:
val = str(value.strip())
parFileCont[key] = val
self.__parameter = parFileCont
if fnout: if fnout:
self.export2File(fnout) self.export2File(fnout)
@ -186,15 +151,64 @@ class AutoPickParameter(object):
if not is_type == expect_type and not is_type == tuple: if not is_type == expect_type and not is_type == tuple:
message = 'Type check failed for param: {}, is type: {}, expected type:{}' message = 'Type check failed for param: {}, is type: {}, expected type:{}'
message = message.format(param, is_type, expect_type) message = message.format(param, is_type, expect_type)
raise TypeError(message) print(Warning(message))
def setParam(self, param, value): def setParamKV(self, param, value):
self.__setitem__(param, value) self.__setitem__(param, value)
def setParam(self, **kwargs):
for key in kwargs:
self.__setitem__(key, kwargs[key])
@staticmethod @staticmethod
def _printParameterError(errmsg): def _printParameterError(errmsg):
print('ParameterError:\n non-existent parameter %s' % errmsg) print('ParameterError:\n non-existent parameter %s' % errmsg)
def reset_defaults(self):
defaults = self.get_defaults()
for param in defaults:
self.setParamKV(param, defaults[param]['value'])
def from_file(self, fnin=None):
if not fnin:
if self.__filename is not None:
fnin = self.__filename
else:
return
inputFile = open(fnin, 'r')
try:
lines = inputFile.readlines()
for line in lines:
parspl = line.split('\t')[:2]
self._parFileCont[parspl[0].strip()] = parspl[1]
except IndexError as e:
if self._verbosity > 0:
self._printParameterError(e)
inputFile.seek(0)
lines = inputFile.readlines()
for line in lines:
if not line.startswith(('#', '%', '\n', ' ')):
parspl = line.split('#')[:2]
self._parFileCont[parspl[1].strip()] = parspl[0].strip()
for key, value in self._parFileCont.items():
try:
val = int(value)
except:
try:
val = float(value)
except:
if len(value.split(' ')) > 1:
vallist = value.strip().split(' ')
val = []
for val0 in vallist:
val0 = float(val0)
val.append(val0)
else:
val = str(value.strip())
self._parFileCont[key] = val
self.__parameter = self._parFileCont
def export2File(self, fnout): def export2File(self, fnout):
fid_out = open(fnout, 'w') fid_out = open(fnout, 'w')
lines = [] lines = []

View File

@ -21,10 +21,9 @@ from pylot.core.util.utils import getPatternLine, gen_Pool
from pylot.core.io.data import Data from pylot.core.io.data import Data
def autopickevent(data, param, iplot=0): def autopickevent(data, param, iplot=0, fig_dict=None):
stations = [] stations = []
all_onsets = {} all_onsets = {}
fig_dict = {}
input_tuples = [] input_tuples = []
# get some parameters for quality control from # get some parameters for quality control from
@ -45,22 +44,22 @@ def autopickevent(data, param, iplot=0):
if not iplot: if not iplot:
input_tuples.append((topick, param, apverbose)) input_tuples.append((topick, param, apverbose))
if iplot>0: if iplot>0:
all_onsets[station], fig_dict[station] = autopickstation(topick, param, verbose=apverbose, iplot=iplot) all_onsets[station] = autopickstation(topick, param, verbose=apverbose, iplot=iplot, fig_dict=fig_dict)
if iplot>0: if iplot>0:
print('iPlot Flag active: NO MULTIPROCESSING possible.') print('iPlot Flag active: NO MULTIPROCESSING possible.')
return all_onsets, fig_dict # changing structure of autopicking and figure generation MP MP return all_onsets
pool = gen_Pool() pool = gen_Pool()
result = pool.map(call_autopickstation, input_tuples) result = pool.map(call_autopickstation, input_tuples)
pool.close() pool.close()
for pick, fig_dict in result: for pick in result:
station = pick['station'] station = pick['station']
pick.pop('station') pick.pop('station')
all_onsets[station] = pick all_onsets[station] = pick
return all_onsets, fig_dict # changing structure of autopicking and figure generation MP MP return all_onsets
# quality control # quality control
# median check and jackknife on P-onset times # median check and jackknife on P-onset times
@ -75,7 +74,7 @@ def call_autopickstation(input_tuple):
return autopickstation(wfstream, pickparam, verbose, iplot=0) return autopickstation(wfstream, pickparam, verbose, iplot=0)
def autopickstation(wfstream, pickparam, verbose=False, iplot=0): def autopickstation(wfstream, pickparam, verbose=False, iplot=0, fig_dict=None):
""" """
:param wfstream: `~obspy.core.stream.Stream` containing waveform :param wfstream: `~obspy.core.stream.Stream` containing waveform
:type wfstream: obspy.core.stream.Stream :type wfstream: obspy.core.stream.Stream
@ -172,8 +171,6 @@ def autopickstation(wfstream, pickparam, verbose=False, iplot=0):
Ao = None # Wood-Anderson peak-to-peak amplitude Ao = None # Wood-Anderson peak-to-peak amplitude
picker = 'auto' # type of picks picker = 'auto' # type of picks
fig_dict = {}
# split components # split components
zdat = wfstream.select(component="Z") zdat = wfstream.select(component="Z")
if len(zdat) == 0: # check for other components if len(zdat) == 0: # check for other components
@ -235,9 +232,12 @@ def autopickstation(wfstream, pickparam, verbose=False, iplot=0):
############################################################## ##############################################################
# get prelimenary onset time from AIC-HOS-CF using subclass AICPicker # get prelimenary onset time from AIC-HOS-CF using subclass AICPicker
# of class AutoPicking # of class AutoPicking
aicpick = AICPicker(aiccf, tsnrz, pickwinP, iplot, None, tsmoothP)
key = 'aicFig' key = 'aicFig'
fig_dict[key] = aicpick.fig if fig_dict:
fig = fig_dict[key]
else:
fig = None
aicpick = AICPicker(aiccf, tsnrz, pickwinP, iplot, None, tsmoothP, fig=fig_dict[key])
############################################################## ##############################################################
if aicpick.getpick() is not None: if aicpick.getpick() is not None:
# check signal length to detect spuriously picked noise peaks # check signal length to detect spuriously picked noise peaks
@ -252,9 +252,14 @@ def autopickstation(wfstream, pickparam, verbose=False, iplot=0):
'{1}'.format(minsiglength, minsiglength / 2) '{1}'.format(minsiglength, minsiglength / 2)
if verbose: print(msg) if verbose: print(msg)
key = 'slength' key = 'slength'
Pflag, fig_dict[key] = checksignallength(zne, aicpick.getpick(), tsnrz, if fig_dict:
fig = fig_dict[key]
else:
fig = None
Pflag = checksignallength(zne, aicpick.getpick(), tsnrz,
minsiglength / 2, minsiglength / 2,
nfacsl, minpercent, iplot) nfacsl, minpercent, iplot,
fig)
else: else:
# filter and taper horizontal traces # filter and taper horizontal traces
trH1_filt = edat.copy() trH1_filt = edat.copy()
@ -269,10 +274,14 @@ def autopickstation(wfstream, pickparam, verbose=False, iplot=0):
trH2_filt.taper(max_percentage=0.05, type='hann') trH2_filt.taper(max_percentage=0.05, type='hann')
zne += trH1_filt zne += trH1_filt
zne += trH2_filt zne += trH2_filt
key = 'slenght' if fig_dict:
Pflag, fig_dict[key] = checksignallength(zne, aicpick.getpick(), tsnrz, fig = fig_dict['slength']
else:
fig = None
Pflag = checksignallength(zne, aicpick.getpick(), tsnrz,
minsiglength, minsiglength,
nfacsl, minpercent, iplot) nfacsl, minpercent, iplot,
fig)
if Pflag == 1: if Pflag == 1:
# check for spuriously picked S onset # check for spuriously picked S onset
@ -283,9 +292,12 @@ def autopickstation(wfstream, pickparam, verbose=False, iplot=0):
if verbose: print(msg) if verbose: print(msg)
else: else:
if iplot>1: if iplot>1:
key = 'checkZ4S' if fig_dict:
Pflag, fig_dict[key] = checkZ4S(zne, aicpick.getpick(), zfac, fig = fig_dict['checkZ4s']
tsnrz[3], iplot) else:
fig = None
Pflag = checkZ4S(zne, aicpick.getpick(), zfac,
tsnrz[3], iplot, fig)
if Pflag == 0: if Pflag == 0:
Pmarker = 'SinsteadP' Pmarker = 'SinsteadP'
Pweight = 9 Pweight = 9
@ -332,19 +344,24 @@ def autopickstation(wfstream, pickparam, verbose=False, iplot=0):
'correctly: maybe the algorithm name ({algoP}) is ' \ 'correctly: maybe the algorithm name ({algoP}) is ' \
'corrupted'.format( 'corrupted'.format(
algoP=algoP) algoP=algoP)
if fig_dict:
fig = fig_dict['refPpick']
else:
fig = None
refPpick = PragPicker(cf2, tsnrz, pickwinP, iplot, ausP, tsmoothP, refPpick = PragPicker(cf2, tsnrz, pickwinP, iplot, ausP, tsmoothP,
aicpick.getpick()) aicpick.getpick(), fig)
key = 'refPpick'
fig_dict[key] = refPpick.fig
mpickP = refPpick.getpick() mpickP = refPpick.getpick()
############################################################# #############################################################
if mpickP is not None: if mpickP is not None:
# quality assessment # quality assessment
# get earliest/latest possible pick and symmetrized uncertainty # get earliest/latest possible pick and symmetrized uncertainty
if iplot: if iplot:
key = 'el_Ppick' if fig_dict:
epickP, lpickP, Perror, fig_dict[key] = earllatepicker(z_copy, nfacP, tsnrz, fig = fig_dict['el_Ppick']
mpickP, iplot) else:
fig = None
epickP, lpickP, Perror = earllatepicker(z_copy, nfacP, tsnrz,
mpickP, iplot, fig=fig)
else: else:
epickP, lpickP, Perror = earllatepicker(z_copy, nfacP, tsnrz, epickP, lpickP, Perror = earllatepicker(z_copy, nfacP, tsnrz,
mpickP, iplot) mpickP, iplot)
@ -369,8 +386,11 @@ def autopickstation(wfstream, pickparam, verbose=False, iplot=0):
# certain quality required # certain quality required
if Pweight <= minfmweight and SNRP >= minFMSNR: if Pweight <= minfmweight and SNRP >= minFMSNR:
if iplot: if iplot:
key = 'fm_picker' if fig_dict:
FM, fig_dict[key] = fmpicker(zdat, z_copy, fmpickwin, mpickP, iplot) fig = fig_dict['fm_picker']
else:
fig = None
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:
@ -471,10 +491,12 @@ def autopickstation(wfstream, pickparam, verbose=False, iplot=0):
############################################################## ##############################################################
# get prelimenary onset time from AIC-HOS-CF using subclass AICPicker # get prelimenary onset time from AIC-HOS-CF using subclass AICPicker
# of class AutoPicking # of class AutoPicking
if fig_dict:
fig = fig_dict['aicARHfig']
else:
fig = None
aicarhpick = AICPicker(haiccf, tsnrh, pickwinS, iplot, None, aicarhpick = AICPicker(haiccf, tsnrh, pickwinS, iplot, None,
aictsmoothS) aictsmoothS, fig=fig)
key = 'aicARHfig'
fig_dict[key] = aicarhpick.fig
############################################################### ###############################################################
# go on with processing if AIC onset passes quality control # go on with processing if AIC onset passes quality control
if (aicarhpick.getSlope() >= minAICSslope and if (aicarhpick.getSlope() >= minAICSslope and
@ -528,10 +550,12 @@ def autopickstation(wfstream, pickparam, verbose=False, iplot=0):
addnoise) # instance of ARHcf addnoise) # instance of ARHcf
# get refined onset time from CF2 using class Picker # get refined onset time from CF2 using class Picker
if fig_dict:
fig = fig_dict['refSpick']
else:
fig = None
refSpick = PragPicker(arhcf2, tsnrh, pickwinS, iplot, ausS, refSpick = PragPicker(arhcf2, tsnrh, pickwinS, iplot, ausS,
tsmoothS, aicarhpick.getpick()) tsmoothS, aicarhpick.getpick(), fig)
key = 'refSpick'
fig_dict[key] = refSpick.fig
mpickS = refSpick.getpick() mpickS = refSpick.getpick()
############################################################# #############################################################
if mpickS is not None: if mpickS is not None:
@ -539,10 +563,14 @@ def autopickstation(wfstream, pickparam, verbose=False, iplot=0):
# get earliest/latest possible pick and symmetrized uncertainty # get earliest/latest possible pick and symmetrized uncertainty
h_copy[0].data = trH1_filt.data h_copy[0].data = trH1_filt.data
if iplot: if iplot:
key = 'el_S1pick' if fig_dict:
epickS1, lpickS1, Serror1, fig_dict[key] = earllatepicker(h_copy, nfacS, fig = fig_dict['el_S1pick']
else:
fig = None
epickS1, lpickS1, Serror1 = earllatepicker(h_copy, nfacS,
tsnrh, tsnrh,
mpickS, iplot) mpickS, iplot,
fig=fig)
else: else:
epickS1, lpickS1, Serror1 = earllatepicker(h_copy, nfacS, epickS1, lpickS1, Serror1 = earllatepicker(h_copy, nfacS,
tsnrh, tsnrh,
@ -550,10 +578,14 @@ def autopickstation(wfstream, pickparam, verbose=False, iplot=0):
h_copy[0].data = trH2_filt.data h_copy[0].data = trH2_filt.data
if iplot: if iplot:
key = 'el_S2pick' if fig_dict:
epickS2, lpickS2, Serror2, fig_dict[key] = earllatepicker(h_copy, nfacS, fig = fig_dict['el_S2pick']
else:
fig = None
epickS2, lpickS2, Serror2 = earllatepicker(h_copy, nfacS,
tsnrh, tsnrh,
mpickS, iplot) mpickS, iplot,
fig=fig)
else: else:
epickS2, lpickS2, Serror2 = earllatepicker(h_copy, nfacS, epickS2, lpickS2, Serror2 = earllatepicker(h_copy, nfacS,
tsnrh, tsnrh,
@ -649,7 +681,10 @@ def autopickstation(wfstream, pickparam, verbose=False, iplot=0):
############################################################## ##############################################################
if iplot > 0: if iplot > 0:
# plot vertical trace # plot vertical trace
if not fig_dict:
fig = plt.figure() fig = plt.figure()
else:
fig = fig_dict['mainFig']
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)
@ -700,7 +735,7 @@ def autopickstation(wfstream, pickparam, verbose=False, iplot=0):
if len(edat[0]) > 1 and len(ndat[0]) > 1 and Sflag == 1: if len(edat[0]) > 1 and len(ndat[0]) > 1 and Sflag == 1:
# plot horizontal traces # plot horizontal traces
ax2 = fig.add_subplot(312) ax2 = fig.add_subplot(3,1,2,sharex=ax1)
th1data = np.arange(0, th1data = np.arange(0,
trH1_filt.stats.npts / trH1_filt.stats.npts /
trH1_filt.stats.sampling_rate, trH1_filt.stats.sampling_rate,
@ -749,7 +784,7 @@ def autopickstation(wfstream, pickparam, verbose=False, iplot=0):
ax2.set_ylabel('Normalized Counts') ax2.set_ylabel('Normalized Counts')
#fig.suptitle(trH1_filt.stats.starttime) #fig.suptitle(trH1_filt.stats.starttime)
ax3 = fig.add_subplot(313) ax3 = fig.add_subplot(3,1,3, sharex=ax1)
th2data = np.arange(0, th2data = np.arange(0,
trH2_filt.stats.npts / trH2_filt.stats.npts /
trH2_filt.stats.sampling_rate, trH2_filt.stats.sampling_rate,
@ -792,8 +827,6 @@ def autopickstation(wfstream, pickparam, verbose=False, iplot=0):
ax3.set_xlabel('Time [s] after %s' % tr_filt.stats.starttime) ax3.set_xlabel('Time [s] after %s' % tr_filt.stats.starttime)
ax3.set_ylabel('Normalized Counts') ax3.set_ylabel('Normalized Counts')
ax3.set_title(trH2_filt.stats.channel) ax3.set_title(trH2_filt.stats.channel)
key = 'mainFig'
fig_dict[key] = fig
########################################################################## ##########################################################################
# calculate "real" onset times # calculate "real" onset times
if lpickP is not None and lpickP == mpickP: if lpickP is not None and lpickP == mpickP:
@ -840,10 +873,10 @@ def autopickstation(wfstream, pickparam, verbose=False, iplot=0):
snrdb=SNRSdB, weight=Sweight, fm=None, picker=picker, Ao=Ao) snrdb=SNRSdB, weight=Sweight, fm=None, picker=picker, Ao=Ao)
# merge picks into returning dictionary # merge picks into returning dictionary
picks = dict(P=ppick, S=spick, station=zdat[0].stats.station) picks = dict(P=ppick, S=spick, station=zdat[0].stats.station)
return picks, fig_dict return picks
def iteratepicker(wf, NLLocfile, picks, badpicks, pickparameter): def iteratepicker(wf, NLLocfile, picks, badpicks, pickparameter, fig_dict=None):
''' '''
Repicking of bad onsets. Uses theoretical onset times from NLLoc-location file. Repicking of bad onsets. Uses theoretical onset times from NLLoc-location file.
@ -918,7 +951,7 @@ def iteratepicker(wf, NLLocfile, picks, badpicks, pickparameter):
print("zfac: %f => %f" % (zfac_old, pickparameter.get('zfac'))) print("zfac: %f => %f" % (zfac_old, pickparameter.get('zfac')))
# repick station # repick station
newpicks, fig = autopickstation(wf2pick, pickparameter) newpicks = autopickstation(wf2pick, pickparameter, fig_dict=fig_dict)
# replace old dictionary with new one # replace old dictionary with new one
picks[badpicks[i][0]] = newpicks picks[badpicks[i][0]] = newpicks
@ -933,4 +966,4 @@ def iteratepicker(wf, NLLocfile, picks, badpicks, pickparameter):
pickparameter.setParam(noisefactor=noisefactor_old) pickparameter.setParam(noisefactor=noisefactor_old)
pickparameter.setParam(zfac=zfac_old) pickparameter.setParam(zfac=zfac_old)
return picks, fig return picks

View File

@ -34,7 +34,7 @@ class AutoPicker(object):
warnings.simplefilter('ignore') warnings.simplefilter('ignore')
def __init__(self, cf, TSNR, PickWindow, iplot=None, aus=None, Tsmooth=None, Pick1=None): def __init__(self, cf, TSNR, PickWindow, iplot=None, 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
@ -72,7 +72,8 @@ class AutoPicker(object):
self.setaus(aus) self.setaus(aus)
self.setTsmooth(Tsmooth) self.setTsmooth(Tsmooth)
self.setpick1(Pick1) self.setpick1(Pick1)
self.fig = self.calcPick() self.fig = fig
self.calcPick()
def __str__(self): def __str__(self):
return '''\n\t{name} object:\n return '''\n\t{name} object:\n
@ -152,7 +153,6 @@ class AICPicker(AutoPicker):
self.Pick = None self.Pick = None
self.slope = None self.slope = None
self.SNR = None self.SNR = None
fig = None
# find NaN's # find NaN's
nn = np.isnan(self.cf) nn = np.isnan(self.cf)
if len(nn) > 1: if len(nn) > 1:
@ -227,7 +227,10 @@ class AICPicker(AutoPicker):
print('AICPicker: Maximum for slope determination right at the beginning of the window!') print('AICPicker: Maximum for slope determination right at the beginning of the window!')
print('Choose longer slope determination window!') print('Choose longer slope determination window!')
if self.iplot > 1: if self.iplot > 1:
if not self.fig:
fig = plt.figure() #self.iplot) ### WHY? MP MP fig = plt.figure() #self.iplot) ### WHY? MP MP
else:
fig = self.fig
ax = fig.add_subplot(111) ax = fig.add_subplot(111)
x = self.Data[0].data x = self.Data[0].data
ax.plot(self.Tcf, x / max(x), 'k', legend='(HOS-/AR-) Data') ax.plot(self.Tcf, x / max(x), 'k', legend='(HOS-/AR-) Data')
@ -236,7 +239,7 @@ class AICPicker(AutoPicker):
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)
return fig return
islope = islope[0][0:imax] islope = islope[0][0:imax]
dataslope = self.Data[0].data[islope] dataslope = self.Data[0].data[islope]
# calculate slope as polynomal fit of order 1 # calculate slope as polynomal fit of order 1
@ -253,7 +256,10 @@ class AICPicker(AutoPicker):
self.slope = None self.slope = None
if self.iplot > 1: if self.iplot > 1:
if not self.fig:
fig = plt.figure()#self.iplot) fig = plt.figure()#self.iplot)
else:
fig = self.fig
ax1 = fig.add_subplot(211) ax1 = fig.add_subplot(211)
x = self.Data[0].data x = self.Data[0].data
ax1.plot(self.Tcf, x / max(x), 'k', label='(HOS-/AR-) Data') ax1.plot(self.Tcf, x / max(x), 'k', label='(HOS-/AR-) Data')
@ -262,27 +268,33 @@ class AICPicker(AutoPicker):
ax1.plot([self.Pick, self.Pick], [-0.1, 0.5], 'b', linewidth=2, label='AIC-Pick') ax1.plot([self.Pick, self.Pick], [-0.1, 0.5], 'b', linewidth=2, label='AIC-Pick')
ax1.set_xlabel('Time [s] since %s' % self.Data[0].stats.starttime) ax1.set_xlabel('Time [s] since %s' % self.Data[0].stats.starttime)
ax1.set_yticks([]) ax1.set_yticks([])
ax1.set_title(self.Data[0].stats.station)
ax1.legend() ax1.legend()
if self.Pick is not None: if self.Pick is not None:
ax2 = fig.add_subplot(212) ax2 = fig.add_subplot(2,1,2, sharex=ax1)
ax2.plot(self.Tcf, x, 'k', label='Data') ax2.plot(self.Tcf, x, 'k', label='Data')
ax2.plot(self.Tcf[inoise], self.Data[0].data[inoise], label='Noise Window') ax1.axvspan(self.Tcf[inoise[0]],self.Tcf[inoise[-1]], color='y', alpha=0.2, lw=0, label='Noise Window')
ax2.plot(self.Tcf[isignal], self.Data[0].data[isignal], 'r', label='Signal Window') ax1.axvspan(self.Tcf[isignal[0]],self.Tcf[isignal[-1]], color='b', alpha=0.2, lw=0, label='Signal Window')
ax2.plot(self.Tcf[islope], dataslope, 'g--', label='Slope Window') ax1.axvspan(self.Tcf[islope[0]],self.Tcf[islope[-1]], color='g', alpha=0.2, lw=0, label='Slope Window')
ax2.axvspan(self.Tcf[inoise[0]],self.Tcf[inoise[-1]], color='y', alpha=0.2, lw=0, label='Noise Window')
ax2.axvspan(self.Tcf[isignal[0]],self.Tcf[isignal[-1]], color='b', alpha=0.2, lw=0, label='Signal Window')
ax2.axvspan(self.Tcf[islope[0]],self.Tcf[islope[-1]], color='g', alpha=0.2, lw=0, label='Slope Window')
ax2.plot(self.Tcf[islope], datafit, 'g', linewidth=2, label='Slope') ax2.plot(self.Tcf[islope], datafit, 'g', linewidth=2, label='Slope')
ax2.set_title('Station %s, SNR=%7.2f, Slope= %12.2f counts/s' % (self.Data[0].stats.station,
ax1.set_title('Station %s, SNR=%7.2f, Slope= %12.2f counts/s' % (self.Data[0].stats.station,
self.SNR, self.slope)) self.SNR, self.slope))
ax2.set_xlabel('Time [s] since %s' % self.Data[0].stats.starttime) ax2.set_xlabel('Time [s] since %s' % self.Data[0].stats.starttime)
ax2.set_ylabel('Counts') ax2.set_ylabel('Counts')
ax2.set_yticks([]) ax2.set_yticks([])
ax2.legend() ax2.legend()
else:
ax1.set_title(self.Data[0].stats.station)
if self.Pick == None: if self.Pick == None:
print('AICPicker: Could not find minimum, picking window too short?') print('AICPicker: Could not find minimum, picking window too short?')
return fig return
class PragPicker(AutoPicker): class PragPicker(AutoPicker):
@ -375,7 +387,10 @@ class PragPicker(AutoPicker):
pickflag = 0 pickflag = 0
if self.getiplot() > 1: if self.getiplot() > 1:
if not self.fig:
fig = plt.figure()#self.getiplot()) fig = plt.figure()#self.getiplot())
else:
fig = self.fig
ax = fig.add_subplot(111) ax = fig.add_subplot(111)
ax.plot(Tcfpick, cfipick, 'k', 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')
@ -385,7 +400,7 @@ class PragPicker(AutoPicker):
ax.set_yticks([]) ax.set_yticks([])
ax.set_title(self.Data[0].stats.station) ax.set_title(self.Data[0].stats.station)
ax.legend() ax.legend()
return fig return
else: else:
print('PragPicker: No initial onset time given! Check input!') print('PragPicker: No initial onset time given! Check input!')

View File

@ -14,7 +14,7 @@ import numpy as np
from obspy.core import Stream, UTCDateTime from obspy.core import Stream, UTCDateTime
def earllatepicker(X, nfac, TSNR, Pick1, iplot=None, stealth_mode=False): def earllatepicker(X, nfac, TSNR, Pick1, iplot=None, stealth_mode=False, 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,
@ -104,11 +104,12 @@ def earllatepicker(X, nfac, TSNR, Pick1, iplot=None, stealth_mode=False):
PickError = symmetrize_error(diffti_te, diffti_tl) PickError = symmetrize_error(diffti_te, diffti_tl)
if iplot > 1: if iplot > 1:
if not fig:
fig = plt.figure()#iplot) fig = plt.figure()#iplot)
ax = fig.add_subplot(111) ax = fig.add_subplot(111)
ax.plot(t, x, 'k', label='Data') ax.plot(t, x, 'k', label='Data')
ax.plot(t[inoise], x[inoise], label='Noise Window') ax.axvspan(t[inoise[0]], t[inoise[-1]], color='y', alpha=0.2, lw=0, label='Noise Window')
ax.plot(t[isignal], x[isignal], 'r', label='Signal Window') ax.axvspan(t[isignal[0]], t[isignal[-1]], color='b', alpha=0.2, lw=0, label='Signal Window')
ax.plot([t[0], t[int(len(t)) - 1]], [nlevel, nlevel], '--k', label='Noise Level') ax.plot([t[0], t[int(len(t)) - 1]], [nlevel, nlevel], '--k', label='Noise Level')
ax.plot(t[isignal[zc]], np.zeros(len(zc)), '*g', ax.plot(t[isignal[zc]], np.zeros(len(zc)), '*g',
markersize=14, label='Zero Crossings') markersize=14, label='Zero Crossings')
@ -127,13 +128,10 @@ def earllatepicker(X, nfac, TSNR, Pick1, iplot=None, stealth_mode=False):
X[0].stats.station) X[0].stats.station)
ax.legend() ax.legend()
if iplot:
return EPick, LPick, PickError, fig
else:
return EPick, LPick, PickError return EPick, LPick, PickError
def fmpicker(Xraw, Xfilt, pickwin, Pick, iplot=None): def fmpicker(Xraw, Xfilt, pickwin, Pick, iplot=None, 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
@ -278,6 +276,7 @@ def fmpicker(Xraw, Xfilt, pickwin, Pick, iplot=None):
print ("fmpicker: Found polarity %s" % FM) print ("fmpicker: Found polarity %s" % FM)
if iplot > 1: if iplot > 1:
if not fig:
fig = plt.figure()#iplot) fig = plt.figure()#iplot)
ax1 = fig.add_subplot(211) ax1 = fig.add_subplot(211)
ax1.plot(t, xraw, 'k') ax1.plot(t, xraw, 'k')
@ -292,7 +291,7 @@ def fmpicker(Xraw, Xfilt, pickwin, Pick, iplot=None):
ax1.set_title('First-Motion Determination, %s, Unfiltered Data' % Xraw[ ax1.set_title('First-Motion Determination, %s, Unfiltered Data' % Xraw[
0].stats.station) 0].stats.station)
ax2=fig.add_subplot(212) ax2=fig.add_subplot(2,1,2, sharex=ax1)
ax2.set_title('First-Motion Determination, Filtered Data') ax2.set_title('First-Motion Determination, Filtered Data')
ax2.plot(t, xfilt, 'k') ax2.plot(t, xfilt, 'k')
ax2.plot([Pick, Pick], [max(xfilt), -max(xfilt)], 'b', ax2.plot([Pick, Pick], [max(xfilt), -max(xfilt)], 'b',
@ -305,9 +304,6 @@ def fmpicker(Xraw, Xfilt, pickwin, Pick, iplot=None):
ax2.set_xlabel('Time [s] since %s' % Xraw[0].stats.starttime) ax2.set_xlabel('Time [s] since %s' % Xraw[0].stats.starttime)
ax2.set_yticks([]) ax2.set_yticks([])
if iplot:
return FM, fig
else:
return FM return FM
@ -620,7 +616,7 @@ def wadaticheck(pickdic, dttolerance, iplot):
return checkedonsets return checkedonsets
def checksignallength(X, pick, TSNR, minsiglength, nfac, minpercent, iplot): 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,
@ -692,11 +688,12 @@ def checksignallength(X, pick, TSNR, minsiglength, nfac, minpercent, iplot):
returnflag = 0 returnflag = 0
if iplot == 2: if iplot == 2:
if not fig:
fig = plt.figure()#iplot) fig = plt.figure()#iplot)
ax = fig.add_subplot(111) ax = fig.add_subplot(111)
ax.plot(t, rms, 'k', label='RMS Data') ax.plot(t, rms, 'k', label='RMS Data')
ax.plot(t[inoise], rms[inoise], 'c', label='RMS Noise Window') ax.axvspan(t[inoise[0]], t[inoise[-1]], color='y', alpha=0.2, lw=0, label='Noise Window')
ax.plot(t[isignal], rms[isignal], 'r', label='RMS Signal Window') ax.axvspan(t[isignal[0]], t[isignal[-1]], color='b', alpha=0.2, lw=0, label='Signal Window')
ax.plot([t[isignal[0]], t[isignal[len(isignal) - 1]]], ax.plot([t[isignal[0]], t[isignal[len(isignal) - 1]]],
[minsiglevel, minsiglevel], 'g', linewidth=2, label='Minimum Signal Level') [minsiglevel, minsiglevel], 'g', linewidth=2, label='Minimum Signal Level')
ax.plot([pick, pick], [min(rms), max(rms)], 'b', linewidth=2, label='Onset') ax.plot([pick, pick], [min(rms), max(rms)], 'b', linewidth=2, label='Onset')
@ -706,7 +703,7 @@ def checksignallength(X, pick, TSNR, minsiglength, nfac, minpercent, iplot):
ax.set_title('Check for Signal Length, Station %s' % X[0].stats.station) ax.set_title('Check for Signal Length, Station %s' % X[0].stats.station)
ax.set_yticks([]) ax.set_yticks([])
return returnflag, fig return returnflag
def checkPonsets(pickdic, dttolerance, iplot): def checkPonsets(pickdic, dttolerance, iplot):
@ -868,7 +865,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): 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
@ -962,14 +959,14 @@ def checkZ4S(X, pick, zfac, checkwin, iplot):
edat[0].stats.delta) edat[0].stats.delta)
tn = np.arange(0, ndat[0].stats.npts / ndat[0].stats.sampling_rate, tn = np.arange(0, ndat[0].stats.npts / ndat[0].stats.sampling_rate,
ndat[0].stats.delta) ndat[0].stats.delta)
if not fig:
fig = plt.figure() fig = plt.figure()
ax = fig.add_subplot(111) ax = fig.add_subplot(111)
ax.plot(tz, z / max(z), 'k') ax.plot(tz, z / max(z), 'k')
ax.plot(tz[isignal], z[isignal] / max(z), 'r') ax.axvspan(tz[isignal[0]], tz[isignal[-1]], color='b', alpha=0.2,
lw=0, label='Signal Window')
ax.plot(te, edat[0].data / max(edat[0].data) + 1, 'k') ax.plot(te, edat[0].data / max(edat[0].data) + 1, 'k')
ax.plot(te[isignal], edat[0].data[isignal] / max(edat[0].data) + 1, 'r')
ax.plot(tn, ndat[0].data / max(ndat[0].data) + 2, 'k') ax.plot(tn, ndat[0].data / max(ndat[0].data) + 2, 'k')
ax.plot(tn[isignal], ndat[0].data[isignal] / max(ndat[0].data) + 2, 'r')
ax.plot([tz[isignal[0]], tz[isignal[len(isignal) - 1]]], ax.plot([tz[isignal[0]], tz[isignal[len(isignal) - 1]]],
[minsiglevel / max(z), minsiglevel / max(z)], 'g', [minsiglevel / max(z), minsiglevel / max(z)], 'g',
linewidth=2, label='Minimum Signal Level') linewidth=2, label='Minimum Signal Level')
@ -980,7 +977,7 @@ def checkZ4S(X, pick, zfac, checkwin, iplot):
ax.set_title('CheckZ4S, Station %s' % zdat[0].stats.station) ax.set_title('CheckZ4S, Station %s' % zdat[0].stats.station)
ax.legend() ax.legend()
return returnflag, fig return returnflag
if __name__ == '__main__': if __name__ == '__main__':

View File

@ -12,45 +12,54 @@ from pylot.core.util.widgets import PickDlg
plt.interactive(False) plt.interactive(False)
class map_projection(QtGui.QWidget): class map_projection(QtGui.QWidget):
def __init__(self, mainwindow, figure=None): def __init__(self, parent, figure=None):
''' '''
:param: picked, can be False, auto, manual :param: picked, can be False, auto, manual
:value: str :value: str
''' '''
QtGui.QWidget.__init__(self) QtGui.QWidget.__init__(self)
self.pyl_mainwindow = mainwindow self._parent = parent
self.parser = mainwindow.metadata[1] self.parser = parent.metadata[1]
self.picks = None self.picks = None
self.picks_dict = None self.picks_dict = None
self.figure = figure self.figure = figure
self.init_graphics() self.init_graphics()
self.init_basemap(projection='mill', resolution='l')
self.init_map()
#self.show()
def init_map(self):
self.init_stations() self.init_stations()
self.init_lat_lon_dimensions() self.init_lat_lon_dimensions()
self.init_lat_lon_grid() self.init_lat_lon_grid()
self.init_basemap(projection='mill', resolution='l')
self.init_x_y_dimensions() self.init_x_y_dimensions()
self.connectSignals() self.connectSignals()
self.draw_everything() self.draw_everything()
#self.show()
def onpick(self, event): def onpick(self, event):
ind = event.ind ind = event.ind
if ind == []: button = event.mouseevent.button
if ind == [] or not button == 1:
return return
data = self.pyl_mainwindow.get_data().getWFData() data = self._parent.get_data().getWFData()
for index in ind: for index in ind:
station=str(self.station_names[index]) station=str(self.station_names[index])
try: try:
pickDlg = PickDlg(self, infile=self.pyl_mainwindow.getinfile(), pickDlg = PickDlg(self, parameter=self._parent._inputs,
data=data.select(station=station), data=data.select(station=station),
station=station, station=station,
picks=self.pyl_mainwindow.getPicksOnStation(station, 'manual'), picks=self._parent.getCurrentEvent().getPick(station),
autopicks=self.pyl_mainwindow.getPicksOnStation(station, 'auto')) autopicks=self._parent.getCurrentEvent().getAutopick(station))
pyl_mw = self.pyl_mainwindow except Exception as e:
message = 'Could not generate Plot for station {st}.\n{er}'.format(st=station, er=e)
self._warn(message)
print(message, e)
pyl_mw = self._parent
#try:
if pickDlg.exec_(): if pickDlg.exec_():
pyl_mw.setDirty(True) pyl_mw.setDirty(True)
pyl_mw.update_status('picks accepted ({0})'.format(station)) pyl_mw.update_status('picks accepted ({0})'.format(station))
replot = pyl_mw.addPicks(station, pickDlg.getPicks()) replot = pyl_mw.getCurrentEvent().setPick(station, pickDlg.getPicks())
if replot: if replot:
pyl_mw.plotWaveformData() pyl_mw.plotWaveformData()
pyl_mw.drawPicks() pyl_mw.drawPicks()
@ -60,13 +69,26 @@ class map_projection(QtGui.QWidget):
pyl_mw.draw() pyl_mw.draw()
else: else:
pyl_mw.update_status('picks discarded ({0})'.format(station)) pyl_mw.update_status('picks discarded ({0})'.format(station))
except Exception as e: # except Exception as e:
print('Could not generate Plot for station {st}.\n{er}'.format(st=station, er=e)) # message = 'Could not save picks for station {st}.\n{er}'.format(st=station, er=e)
# self._warn(message)
# print(message, e)
def connectSignals(self): def connectSignals(self):
self.comboBox_phase.currentIndexChanged.connect(self._refresh_drawings) self.comboBox_phase.currentIndexChanged.connect(self._refresh_drawings)
def init_graphics(self): def init_graphics(self):
if not self.figure:
if not hasattr(self._parent, 'am_figure'):
self.figure = plt.figure()
self.toolbar = NavigationToolbar(self.figure.canvas, self)
else:
self.figure = self._parent.am_figure
self.toolbar = self._parent.am_toolbar
self.main_ax = self.figure.add_subplot(111)
self.canvas = self.figure.canvas
self.main_box = QtGui.QVBoxLayout() self.main_box = QtGui.QVBoxLayout()
self.setLayout(self.main_box) self.setLayout(self.main_box)
@ -77,25 +99,16 @@ class map_projection(QtGui.QWidget):
self.comboBox_phase.insertItem(0, 'P') self.comboBox_phase.insertItem(0, 'P')
self.comboBox_phase.insertItem(1, 'S') self.comboBox_phase.insertItem(1, 'S')
# self.comboBox_am = QtGui.QComboBox() self.comboBox_am = QtGui.QComboBox()
# self.comboBox_am.insertItem(0, 'auto') self.comboBox_am.insertItem(0, 'auto')
# self.comboBox_am.insertItem(1, 'manual') self.comboBox_am.insertItem(1, 'manual')
self.top_row.addWidget(QtGui.QLabel('Select a phase: ')) self.top_row.addWidget(QtGui.QLabel('Select a phase: '))
self.top_row.addWidget(self.comboBox_phase) self.top_row.addWidget(self.comboBox_phase)
self.top_row.setStretch(1,1) #set stretch of item 1 to 1 self.top_row.setStretch(1,1) #set stretch of item 1 to 1
if not self.figure:
fig = plt.figure()
else:
fig = self.figure
self.main_ax = fig.add_subplot(111)
self.canvas = fig.canvas
self.main_box.addWidget(self.canvas) self.main_box.addWidget(self.canvas)
self.toolbar = NavigationToolbar(self.canvas, self)
self.main_box.addWidget(self.toolbar) self.main_box.addWidget(self.toolbar)
self.figure = fig
def init_stations(self): def init_stations(self):
def get_station_names_lat_lon(parser): def get_station_names_lat_lon(parser):
@ -128,7 +141,11 @@ class map_projection(QtGui.QWidget):
def get_picks_rel(picks): def get_picks_rel(picks):
picks_rel=[] picks_rel=[]
minp = min(picks) picks_utc = []
for pick in picks:
if type(pick) is obspy.core.utcdatetime.UTCDateTime:
picks_utc.append(pick)
minp = min(picks_utc)
for pick in picks: for pick in picks:
if type(pick) is obspy.core.utcdatetime.UTCDateTime: if type(pick) is obspy.core.utcdatetime.UTCDateTime:
pick -= minp pick -= minp
@ -187,7 +204,6 @@ class map_projection(QtGui.QWidget):
self.basemap = basemap self.basemap = basemap
self.figure.tight_layout() self.figure.tight_layout()
def init_lat_lon_grid(self): def init_lat_lon_grid(self):
def get_lat_lon_axis(lat, lon): def get_lat_lon_axis(lat, lon):
steplat = (max(lat)-min(lat))/250 steplat = (max(lat)-min(lat))/250
@ -219,7 +235,18 @@ class map_projection(QtGui.QWidget):
self.cid = self.canvas.mpl_connect('pick_event', self.onpick) self.cid = self.canvas.mpl_connect('pick_event', self.onpick)
def scatter_picked_stations(self): def scatter_picked_stations(self):
self.sc_picked = self.basemap.scatter(self.lon_no_nan, self.lat_no_nan, s=50, facecolor='white', lon = self.lon_no_nan
lat = self.lat_no_nan
#workaround because of an issue with latlon transformation of arrays with len <3
if len(lon) <= 2 and len(lat) <= 2:
self.sc_picked = self.basemap.scatter(lon[0], lat[0], s=50, facecolor='white',
c=self.picks_no_nan[0], latlon=True, zorder=11, label='Picked')
if len(lon) == 2 and len(lat) == 2:
self.sc_picked = self.basemap.scatter(lon[1], lat[1], s=50, facecolor='white',
c=self.picks_no_nan[1], latlon=True, zorder=11)
else:
self.sc_picked = self.basemap.scatter(lon, lat, s=50, facecolor='white',
c=self.picks_no_nan, latlon=True, zorder=11, label='Picked') c=self.picks_no_nan, latlon=True, zorder=11, label='Picked')
def annotate_ax(self): def annotate_ax(self):
@ -248,6 +275,7 @@ class map_projection(QtGui.QWidget):
self.init_picks() self.init_picks()
self.init_picks_active() self.init_picks_active()
self.init_stations_active() self.init_stations_active()
if len(self.picks_no_nan) >= 3:
self.init_picksgrid() self.init_picksgrid()
self.draw_contour_filled() self.draw_contour_filled()
self.scatter_all_stations() self.scatter_all_stations()
@ -291,4 +319,9 @@ class map_projection(QtGui.QWidget):
for annotation in self.annotations: for annotation in self.annotations:
annotation.remove() annotation.remove()
def _warn(self, message):
self.qmb = QtGui.QMessageBox(QtGui.QMessageBox.Icon.Warning,
'Warning', message)
self.qmb.show()

View File

@ -1,7 +1,7 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
import sys import sys
from PySide.QtCore import QThread, Signal, Qt from PySide.QtCore import QThread, Signal, Qt
from PySide.QtGui import QDialog, QProgressBar, QLabel, QVBoxLayout from PySide.QtGui import QDialog, QProgressBar, QLabel, QHBoxLayout
class AutoPickThread(QThread): class AutoPickThread(QThread):
@ -39,39 +39,57 @@ class AutoPickThread(QThread):
class Thread(QThread): class Thread(QThread):
def __init__(self, parent, func, arg=None, progressText=None): message = Signal(str)
def __init__(self, parent, func, arg=None, progressText=None, pb_widget=None, redirect_stdout=False):
QThread.__init__(self, parent) QThread.__init__(self, parent)
self.func = func self.func = func
self.arg = arg self.arg = arg
self.progressText = progressText self.progressText = progressText
self.pbdlg = None self.pb_widget = pb_widget
self.redirect_stdout = redirect_stdout
self.finished.connect(self.hideProgressbar) self.finished.connect(self.hideProgressbar)
self.showProgressbar() self.showProgressbar()
def run(self): def run(self):
if self.redirect_stdout:
sys.stdout = self
try:
if self.arg: if self.arg:
self.data = self.func(self.arg) self.data = self.func(self.arg)
else: else:
self.data = self.func() self.data = self.func()
self._executed = True
except Exception as e:
self._executed = False
self._executedError = e
print(e)
sys.stdout = sys.__stdout__
def __del__(self): def __del__(self):
self.wait() self.wait()
def showProgressbar(self): def showProgressbar(self):
if self.progressText: if self.progressText:
self.pbdlg = QDialog(self.parent()) if not self.pb_widget:
self.pbdlg.setModal(True) self.pb_widget = QDialog(self.parent())
vl = QVBoxLayout() self.pb_widget.setWindowFlags(Qt.SplashScreen)
self.pb_widget.setModal(True)
hl = QHBoxLayout()
pb = QProgressBar() pb = QProgressBar()
pb.setRange(0, 0) pb.setRange(0, 0)
vl.addWidget(pb) hl.addWidget(pb)
vl.addWidget(QLabel(self.progressText)) hl.addWidget(QLabel(self.progressText))
self.pbdlg.setLayout(vl) self.pb_widget.setLayout(hl)
self.pbdlg.setWindowFlags(Qt.SplashScreen) self.pb_widget.show()
self.pbdlg.show()
def hideProgressbar(self): def hideProgressbar(self):
if self.pbdlg: if self.pb_widget:
self.pbdlg.hide() self.pb_widget.hide()
def write(self, text):
self.message.emit(text)
def flush(self):
pass

View File

@ -1,4 +1,4 @@
[]# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
""" """
Created on Wed Mar 19 11:27:35 2014 Created on Wed Mar 19 11:27:35 2014
@ -30,6 +30,7 @@ from PySide.QtGui import QAction, QApplication, QCheckBox, QComboBox, \
from PySide.QtCore import QSettings, Qt, QUrl, Signal, Slot from PySide.QtCore import QSettings, Qt, QUrl, Signal, Slot
from PySide.QtWebKit import QWebView from PySide.QtWebKit import QWebView
from obspy import Stream, UTCDateTime from obspy import Stream, UTCDateTime
from pylot.core.io.data import Data
from pylot.core.io.inputs import FilterOptions, AutoPickParameter from pylot.core.io.inputs import FilterOptions, AutoPickParameter
from pylot.core.pick.utils import getSNR, earllatepicker, getnoisewin, \ from pylot.core.pick.utils import getSNR, earllatepicker, getnoisewin, \
getResolutionWindow getResolutionWindow
@ -39,6 +40,7 @@ from pylot.core.util.defaults import OUTPUTFORMATS, FILTERDEFAULTS, LOCTOOLS, \
from pylot.core.util.utils import prepTimeAxis, full_range, scaleWFData, \ from pylot.core.util.utils import prepTimeAxis, full_range, scaleWFData, \
demeanTrace, isSorted, findComboBoxIndex, clims demeanTrace, isSorted, findComboBoxIndex, clims
from autoPyLoT import autoPyLoT from autoPyLoT import autoPyLoT
from pylot.core.util.thread import Thread
import icons_rc import icons_rc
def getDataType(parent): def getDataType(parent):
@ -513,12 +515,14 @@ class WaveformWidget(FigureCanvas):
class PickDlg(QDialog): class PickDlg(QDialog):
update_picks = QtCore.Signal(dict)
def __init__(self, parent=None, data=None, station=None, picks=None, def __init__(self, parent=None, data=None, station=None, picks=None,
autopicks=None, rotate=False, infile=None): autopicks=None, rotate=False, parameter=None, embedded=False):
super(PickDlg, self).__init__(parent) super(PickDlg, self).__init__(parent)
# initialize attributes # initialize attributes
self.infile = infile self.parameter = parameter
self._embedded = embedded
self.station = station self.station = station
self.rotate = rotate self.rotate = rotate
self.components = 'ZNE' self.components = 'ZNE'
@ -528,12 +532,16 @@ class PickDlg(QDialog):
self._user = settings.value('user/Login', pylot_user) self._user = settings.value('user/Login', pylot_user)
if picks: if picks:
self.picks = picks self.picks = picks
self._init_picks = copy.deepcopy(picks)
else: else:
self.picks = {} self.picks = {}
self._init_picks = {}
if autopicks: if autopicks:
self.autopicks = autopicks self.autopicks = autopicks
self._init_autopicks = copy.deepcopy(autopicks)
else: else:
self.autopicks = {} self.autopicks = {}
self._init_autopicks = {}
self.filteroptions = FILTERDEFAULTS self.filteroptions = FILTERDEFAULTS
self.pick_block = False self.pick_block = False
@ -636,6 +644,11 @@ class PickDlg(QDialog):
self.p_button.setToolTip('Hotkey: "1"') self.p_button.setToolTip('Hotkey: "1"')
self.s_button.setToolTip('Hotkey: "2"') self.s_button.setToolTip('Hotkey: "2"')
# create accept/reject button
self.accept_button = QPushButton('&Accept Picks')
self.reject_button = QPushButton('&Reject Picks')
self.disable_ar_buttons()
# layout the outermost appearance of the Pick Dialog # layout the outermost appearance of the Pick Dialog
_outerlayout = QVBoxLayout() _outerlayout = QVBoxLayout()
_dialtoolbar = QToolBar() _dialtoolbar = QToolBar()
@ -649,6 +662,9 @@ class PickDlg(QDialog):
_dialtoolbar.addAction(self.resetZoomAction) _dialtoolbar.addAction(self.resetZoomAction)
_dialtoolbar.addSeparator() _dialtoolbar.addSeparator()
_dialtoolbar.addAction(self.resetPicksAction) _dialtoolbar.addAction(self.resetPicksAction)
if self._embedded:
_dialtoolbar.addWidget(self.accept_button)
_dialtoolbar.addWidget(self.reject_button)
# layout the innermost widget # layout the innermost widget
_innerlayout = QVBoxLayout() _innerlayout = QVBoxLayout()
@ -659,6 +675,7 @@ class PickDlg(QDialog):
QDialogButtonBox.Cancel) QDialogButtonBox.Cancel)
# merge widgets and layouts to establish the dialog # merge widgets and layouts to establish the dialog
if not self._embedded:
_innerlayout.addWidget(_buttonbox) _innerlayout.addWidget(_buttonbox)
_outerlayout.addWidget(_dialtoolbar) _outerlayout.addWidget(_dialtoolbar)
_outerlayout.addLayout(_innerlayout) _outerlayout.addLayout(_innerlayout)
@ -667,11 +684,16 @@ class PickDlg(QDialog):
# object # object
self.p_button.clicked.connect(self.p_clicked) self.p_button.clicked.connect(self.p_clicked)
self.s_button.clicked.connect(self.s_clicked) self.s_button.clicked.connect(self.s_clicked)
self.accept_button.clicked.connect(self.accept)
self.reject_button.clicked.connect(self.reject)
self.accept_button.clicked.connect(self.disable_ar_buttons)
self.reject_button.clicked.connect(self.disable_ar_buttons)
_buttonbox.accepted.connect(self.accept) _buttonbox.accepted.connect(self.accept)
_buttonbox.rejected.connect(self.reject) _buttonbox.rejected.connect(self.reject)
# finally layout the entire dialog # finally layout the entire dialog
self.setLayout(_outerlayout) self.setLayout(_outerlayout)
self.resize(1280, 720)
def disconnectPressEvent(self): def disconnectPressEvent(self):
widget = self.getPlotWidget() widget = self.getPlotWidget()
@ -709,6 +731,13 @@ class PickDlg(QDialog):
widget = self.getPlotWidget() widget = self.getPlotWidget()
return widget.mpl_connect('button_release_event', slot) return widget.mpl_connect('button_release_event', slot)
def disable_ar_buttons(self):
self.enable_ar_buttons(False)
def enable_ar_buttons(self, bool=True):
self.accept_button.setEnabled(bool)
self.reject_button.setEnabled(bool)
def p_clicked(self): def p_clicked(self):
if self.p_button.isChecked(): if self.p_button.isChecked():
self.s_button.setEnabled(False) self.s_button.setEnabled(False)
@ -771,8 +800,8 @@ class PickDlg(QDialog):
self.cidrelease = self.connectReleaseEvent(self.panRelease) self.cidrelease = self.connectReleaseEvent(self.panRelease)
self.cidscroll = self.connectScrollEvent(self.scrollZoom) self.cidscroll = self.connectScrollEvent(self.scrollZoom)
def getinfile(self): def getParameter(self):
return self.infile return self.parameter
def getStartTime(self): def getStartTime(self):
return self.stime return self.stime
@ -897,7 +926,7 @@ class PickDlg(QDialog):
def setIniPickP(self, gui_event, wfdata, trace_number): def setIniPickP(self, gui_event, wfdata, trace_number):
parameter = AutoPickParameter(self.getinfile()) parameter = self.parameter
ini_pick = gui_event.xdata ini_pick = gui_event.xdata
nfac = parameter.get('nfacP') nfac = parameter.get('nfacP')
@ -946,7 +975,7 @@ class PickDlg(QDialog):
def setIniPickS(self, gui_event, wfdata): def setIniPickS(self, gui_event, wfdata):
parameter = AutoPickParameter(self.getinfile()) parameter = self.parameter
ini_pick = gui_event.xdata ini_pick = gui_event.xdata
nfac = parameter.get('nfacS') nfac = parameter.get('nfacS')
@ -1000,7 +1029,7 @@ class PickDlg(QDialog):
def setPick(self, gui_event): def setPick(self, gui_event):
parameter = AutoPickParameter(self.getinfile()) parameter = self.parameter
# get axes limits # get axes limits
self.updateCurrentLimits() self.updateCurrentLimits()
@ -1069,6 +1098,7 @@ class PickDlg(QDialog):
olpp=olpp) olpp=olpp)
self.disconnectPressEvent() self.disconnectPressEvent()
self.enable_ar_buttons()
self.zoomAction.setEnabled(True) self.zoomAction.setEnabled(True)
self.pick_block = self.togglePickBlocker() self.pick_block = self.togglePickBlocker()
self.leave_picking_mode() self.leave_picking_mode()
@ -1106,6 +1136,7 @@ class PickDlg(QDialog):
if picktype == 'manual': if picktype == 'manual':
ax.fill_between([epp, lpp], ylims[0], ylims[1], ax.fill_between([epp, lpp], ylims[0], ylims[1],
alpha=.25, color=colors[0]) alpha=.25, color=colors[0])
if spe:
ax.plot([mpp - spe, mpp - spe], ylims, colors[1], ax.plot([mpp - spe, mpp - spe], ylims, colors[1],
[mpp, mpp], ylims, colors[2], [mpp, mpp], ylims, colors[2],
[mpp + spe, mpp + spe], ylims, colors[1]) [mpp + spe, mpp + spe], ylims, colors[1])
@ -1261,98 +1292,591 @@ class PickDlg(QDialog):
def apply(self): def apply(self):
picks = self.getPicks() picks = self.getPicks()
self.update_picks.emit(picks)
for pick in picks: for pick in picks:
print(pick, picks[pick]) print(pick, picks[pick])
def discard(self):
picks = self._init_picks
self.picks = picks
self.update_picks.emit(picks)
for pick in picks:
print(pick, picks[pick])
def reject(self):
self.discard()
if not self._embedded:
QDialog.reject(self)
else:
self.resetPlot()
self.qmb = QtGui.QMessageBox(QtGui.QMessageBox.Icon.Information,
'Denied', 'New picks rejected!')
self.qmb.show()
def accept(self): def accept(self):
self.apply() self.apply()
if not self._embedded:
QDialog.accept(self) QDialog.accept(self)
else:
self.qmb = QtGui.QMessageBox(QtGui.QMessageBox.Icon.Information,
'Accepted', 'New picks applied!')
self.qmb.show()
class TuneAutopicker(QWidget): class TuneAutopicker(QWidget):
def __init__(self, ap, parent=None): update = QtCore.Signal(str)
QtGui.QWidget.__init__(self, parent) '''
self.ap = ap QWidget used to modifiy and test picking parameters for autopicking algorithm.
self.station = 'AH11'
self.fd = None :param: parent
self.layout = QtGui.QHBoxLayout() :type: QtPyLoT Mainwindow
self.parameter_layout = QtGui.QVBoxLayout() '''
self.setLayout(self.layout) def __init__(self, parent):
QtGui.QWidget.__init__(self, parent, 1)
self.parent = parent
self.setParent(parent)
self.setWindowTitle('PyLoT - Tune Autopicker')
self.parameter = parent._inputs
self.fig_dict = parent.fig_dict
self.data = Data()
self.init_main_layouts()
self.init_eventlist()
self.init_figure_tabs() self.init_figure_tabs()
self.add_parameter() self.init_stationlist()
self.init_pbwidget()
self.connect_signals()
self.add_parameters()
self.add_buttons() self.add_buttons()
self.add_log()
self.set_stretch() self.set_stretch()
self.resize(1280, 720)
#self.setWindowModality(QtCore.Qt.WindowModality.ApplicationModal)
#self.setWindowFlags(self.windowFlags() | QtCore.Qt.WindowStaysOnTopHint)
def init_main_layouts(self):
self.main_layout = QtGui.QVBoxLayout()
self.tune_layout = QtGui.QHBoxLayout()
self.trace_layout = QtGui.QHBoxLayout()
self.parameter_layout = QtGui.QVBoxLayout()
self.main_layout.addLayout(self.trace_layout)
self.main_layout.addLayout(self.tune_layout)
self.setLayout(self.main_layout)
def init_eventlist(self):
self.eventBox = self.parent.createEventBox()
self.fill_eventbox()
self.eventBox.setCurrentIndex(0)
self.trace_layout.addWidget(self.eventBox)
def init_stationlist(self):
self.stationBox = QtGui.QComboBox()
self.trace_layout.addWidget(self.stationBox)
self.fill_stationbox()
self.figure_tabs.setCurrentIndex(0)
def connect_signals(self):
self.eventBox.activated.connect(self.fill_stationbox)
self.eventBox.activated.connect(self.update_eventID)
self.eventBox.activated.connect(self.fill_tabs)
self.stationBox.activated.connect(self.fill_tabs)
def fill_stationbox(self):
fnames = self.parent.getWFFnames_from_eventbox(eventbox=self.eventBox)
self.data.setWFData(fnames)
self.stationBox.clear()
stations = []
for trace in self.data.getWFData():
station = trace.stats.station
if not station in stations:
stations.append(str(station))
stations.sort()
model = self.stationBox.model()
for station in stations:
item = QtGui.QStandardItem(str(station))
if station in self.get_current_event().picks:
item.setBackground(QtGui.QColor(200, 210, 230, 255))
model.appendRow(item)
def init_figure_tabs(self): def init_figure_tabs(self):
self.main_tabs = QtGui.QTabWidget() self.figure_tabs = QtGui.QTabWidget()
self.p_tabs = QtGui.QTabWidget() self.fill_figure_tabs()
self.s_tabs = QtGui.QTabWidget()
self.layout.insertWidget(0, self.main_tabs)
self.init_tab_names()
self.fill_tabs()
def add_parameter(self): def init_pbwidget(self):
self.parameters = AutoPickParaBox(self.ap) self.pb_widget = QtGui.QWidget()
def init_tab_names(self):
self.ptb_names = ['aicFig', 'slength', 'checkZ4s', 'refPpick', 'el_Ppick', 'fm_picker']
self.stb_names = ['aicARHfig', 'refSpick', 'el_S1pick', 'el_S2pick']
def add_parameters(self):
self.parameters = AutoPickParaBox(self.parameter)
self.parameters.set_tune_mode(True)
self.update_eventID()
self.parameter_layout.addWidget(self.parameters) self.parameter_layout.addWidget(self.parameters)
self.layout.insertLayout(1, self.parameter_layout) self.parameter_layout.addWidget(self.pb_widget)
self.tune_layout.insertLayout(1, self.parameter_layout)
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.clicked.connect(self.call_picker) self.pick_button.clicked.connect(self.call_picker)
self.parameter_layout.addWidget(self.pick_button) self.close_button = QtGui.QPushButton('Close')
self.close_button.clicked.connect(self.hide)
self.trace_layout.addWidget(self.pick_button)
self.trace_layout.setStretch(0, 1)
self.parameter_layout.addWidget(self.close_button)
def call_picker(self): def add_log(self):
self.parameters.update_params() self.listWidget = QtGui.QListWidget()
picks, fig_dict = autoPyLoT(self.ap, fnames='None', iplot=2) self.figure_tabs.insertTab(4, self.listWidget, 'log')
self.main_tabs.setParent(None)
self.fd = fig_dict[self.station]
self.init_figure_tabs()
self.set_stretch()
def set_stretch(self): def add_log_item(self, text):
self.layout.setStretch(0, 3) self.listWidget.addItem(text)
self.layout.setStretch(1, 1) self.listWidget.scrollToBottom()
def init_tab_names(self): def get_current_event(self):
self.ptb_names = ['aicFig', 'slenght', 'checkZ4S', 'refPpick', 'el_Ppick', 'fm_picker'] index = self.eventBox.currentIndex()
self.stb_names = ['aicARHfig', 'refSpick', 'el_S1pick', 'el_S2pick'] return self.eventBox.itemData(index)
def fill_tabs(self): def get_current_event_name(self):
try: return self.eventBox.currentText().split('/')[-1]
main_fig = self.fd['mainFig']
self.main_tabs.addTab(main_fig.canvas, 'Overview') def get_current_event_fp(self):
except Exception as e: return self.eventBox.currentText()
self.main_tabs.addTab(QtGui.QWidget(), 'Overview')
self.main_tabs.addTab(self.p_tabs, 'P') def get_current_event_picks(self, station):
self.main_tabs.addTab(self.s_tabs, 'S') event = self.get_current_event()
self.fill_p_tabs() if station in event.picks.keys():
self.fill_s_tabs() return event.picks[station]
def get_current_event_autopicks(self, station):
event = self.get_current_event()
if event.autopicks:
return event.autopicks[station]
def get_current_station(self):
return str(self.stationBox.currentText())
def gen_tab_widget(self, name, canvas):
widget = QtGui.QWidget()
v_layout = QtGui.QVBoxLayout()
v_layout.addWidget(canvas)
v_layout.addWidget(NavigationToolbar2QT(canvas, self))
widget.setLayout(v_layout)
return widget
def gen_pick_dlg(self):
station = self.get_current_station()
data = self.data.getWFData()
pickDlg = PickDlg(self, data=data.select(station=station),
station=station, parameter=self.parameter,
picks=self.get_current_event_picks(station),
autopicks=self.get_current_event_autopicks(station),
embedded=True)
pickDlg.update_picks.connect(self.picks_from_pickdlg)
pickDlg.update_picks.connect(self.parent.fill_eventbox)
pickDlg.update_picks.connect(self.fill_eventbox)
pickDlg.update_picks.connect(self.fill_stationbox)
self.pickDlg = QtGui.QWidget()
hl = QtGui.QHBoxLayout()
self.pickDlg.setLayout(hl)
hl.addWidget(pickDlg)
def picks_from_pickdlg(self, picks=None):
station = self.get_current_station()
self.get_current_event().setPick(station, picks)
def fill_tabs(self, event=None, picked=False):
self.clear_all()
canvas_dict = self.parent.canvas_dict
self.gen_pick_dlg()
self.overview = self.gen_tab_widget('Overview', canvas_dict['mainFig'])
id0 = self.figure_tabs.insertTab(0, self.pickDlg, 'Traces Plot')
id1 = self.figure_tabs.insertTab(1, self.overview, 'Overview')
id2 = self.figure_tabs.insertTab(2, self.p_tabs, 'P')
id3 = self.figure_tabs.insertTab(3, self.s_tabs, 'S')
if picked:
self.fill_p_tabs(canvas_dict)
self.fill_s_tabs(canvas_dict)
self.toggle_autopickTabs(bool(self.fig_dict['mainFig'].axes))
else:
self.disable_autopickTabs()
try: try:
main_fig.tight_layout() main_fig.tight_layout()
except: except:
pass pass
self.figure_tabs.setCurrentIndex(0)
def fill_p_tabs(self): def fill_p_tabs(self, canvas_dict):
for name in self.ptb_names: for name in self.ptb_names:
id = self.p_tabs.addTab(self.gen_tab_widget(name, canvas_dict[name]), name)
self.p_tabs.setTabEnabled(id, bool(self.fig_dict[name].axes))
try: try:
figure = self.fd[name] self.fig_dict[name].tight_layout()
id = self.p_tabs.addTab(figure.canvas, name) except:
self.p_tabs.setTabEnabled(id, True) pass
figure.tight_layout()
except Exception as e:
id = self.p_tabs.addTab(QtGui.QWidget(), name)
self.p_tabs.setTabEnabled(id, False)
def fill_s_tabs(self): def fill_s_tabs(self, canvas_dict):
for name in self.stb_names: for name in self.stb_names:
id = self.s_tabs.addTab(self.gen_tab_widget(name, canvas_dict[name]), name)
self.s_tabs.setTabEnabled(id, bool(self.fig_dict[name].axes))
try: try:
figure = self.fd[name] self.fig_dict[name].tight_layout()
id = self.s_tabs.addTab(figure.canvas, name) except:
self.s_tabs.setTabEnabled(id, True) pass
figure.tight_layout()
def fill_figure_tabs(self):
self.clear_all()
self.p_tabs = QtGui.QTabWidget()
self.s_tabs = QtGui.QTabWidget()
self.tune_layout.insertWidget(0, self.figure_tabs)
self.init_tab_names()
def fill_eventbox(self):
self.parent.fill_eventbox(self.eventBox, 'ref')
def update_eventID(self):
self.parameters.boxes['eventID'].setText(
self.get_current_event_name())
self.figure_tabs.setCurrentIndex(0)
def call_picker(self):
self.parameter = self.params_from_gui()
station = self.get_current_station()
if not station:
self._warn('No station selected')
return
args = {'parameter': self.parameter,
'station': station,
'fnames': 'None',
'iplot': 2,
'fig_dict': self.fig_dict,
'locflag': 0}
for key in self.fig_dict.keys():
self.fig_dict[key].clear()
self.ap_thread = Thread(self, autoPyLoT, arg=args,
progressText='Picking trace...',
pb_widget=self.pb_widget,
redirect_stdout=True)
self.enable(False)
self.ap_thread.message.connect(self.add_log_item)
self.ap_thread.finished.connect(self.finish_picker)
self.figure_tabs.setCurrentIndex(4)
self.ap_thread.start()
#picks = autoPyLoT(self.parameter, fnames='None', iplot=2, fig_dict=self.fig_dict)
def finish_picker(self):
self.enable(True)
if not self.ap_thread._executed:
self._warn('Could not execute picker:\n{}'.format(
self.ap_thread._executedError))
return
self.picks = self.ap_thread.data
if not self.picks:
self._warn('No picks found. See terminal output.')
return
#renew tabs
#self.fill_figure_tabs()
self.set_stretch()
self.update.emit('Update')
self.figure_tabs.setCurrentIndex(1)
def enable(self, bool):
self.pick_button.setEnabled(bool)
self.parameters.setEnabled(bool)
self.eventBox.setEnabled(bool)
self.stationBox.setEnabled(bool)
self.overview.setEnabled(bool)
self.p_tabs.setEnabled(bool)
self.s_tabs.setEnabled(bool)
def params_from_gui(self):
parameters = self.parameters.params_from_gui()
if self.parent:
self.parent._inputs = parameters
return parameters
def set_stretch(self):
self.tune_layout.setStretch(0, 3)
self.tune_layout.setStretch(1, 1)
def clear_all(self):
if hasattr(self, 'pickDlg'):
self.pickDlg.setParent(None)
del(self.pickDlg)
if hasattr(self, 'overview'):
self.overview.setParent(None)
if hasattr(self, 'p_tabs'):
self.p_tabs.clear()
self.p_tabs.setParent(None)
if hasattr(self, 's_tabs'):
self.s_tabs.clear()
self.s_tabs.setParent(None)
def disable_autopickTabs(self):
self.toggle_autopickTabs(False)
def toggle_autopickTabs(self, bool):
self.figure_tabs.setTabEnabled(1, bool)
self.figure_tabs.setTabEnabled(2, bool)
self.figure_tabs.setTabEnabled(3, bool)
def _warn(self, message):
self.qmb = QtGui.QMessageBox(QtGui.QMessageBox.Icon.Warning,
'Warning', message)
self.qmb.show()
class AutoPickParaBox(QtGui.QWidget):
def __init__(self, parameter, parent=None):
'''
Generate Widget containing parameters for automatic picking algorithm.
:param: parameter
:type: AutoPickParameter (object)
'''
QtGui.QWidget.__init__(self, parent)
self.parameter = parameter
self.tabs = QtGui.QTabWidget()
self.layout = QtGui.QVBoxLayout()
self._init_buttons()
self.layout.addWidget(self.tabs)
self.boxes = {}
self._init_sublayouts()
self.setLayout(self.layout)
self.add_main_parameters_tab()
self.add_special_pick_parameters_tab()
self.params_to_gui()
self._toggle_advanced_settings()
def _init_sublayouts(self):
self._main_layout = QtGui.QVBoxLayout()
self._advanced_layout = QtGui.QVBoxLayout()
self._create_advanced_cb()
def _init_buttons(self):
self._buttons_layout = QtGui.QHBoxLayout()
self.loadButton = QtGui.QPushButton('&Load settings')
self.saveButton = QtGui.QPushButton('&Save settings')
self.defaultsButton = QtGui.QPushButton('&Defaults')
self._buttons_layout.addWidget(self.loadButton)
self._buttons_layout.addWidget(self.saveButton)
self._buttons_layout.addWidget(self.defaultsButton)
self.layout.addLayout(self._buttons_layout)
self.loadButton.clicked.connect(self.openFile)
self.saveButton.clicked.connect(self.saveFile)
self.defaultsButton.clicked.connect(self.restoreDefaults)
def _create_advanced_cb(self):
self._advanced_cb = QtGui.QCheckBox('Enable Advanced Settings')
self._advanced_layout.addWidget(self._advanced_cb)
self._advanced_cb.toggled.connect(self._toggle_advanced_settings)
def _toggle_advanced_settings(self):
if self._advanced_cb.isChecked():
self._enable_advanced(True)
else:
self._enable_advanced(False)
def _enable_advanced(self, enable):
for lst in self.parameter.get_special_para_names().values():
for param in lst:
box = self.boxes[param]
if type(box) is not list:
box.setEnabled(enable)
else:
for b in box:
b.setEnabled(enable)
def set_tune_mode(self, bool):
keys = ['rootpath', 'datapath', 'database',
'eventID', 'invdir', 'nllocbin',
'nllocroot', 'phasefile',
'ctrfile', 'ttpatter', 'outpatter']
for key in keys:
self.boxes[key].setEnabled(not(bool))
def init_boxes(self, parameter_names):
grid = QtGui.QGridLayout()
for index1, name in enumerate(parameter_names):
text = name + ' [?]'
label = QtGui.QLabel(text)
default_item = self.parameter.get_defaults()[name]
tooltip = default_item['tooltip']
tooltip += ' | type: {}'.format(default_item['type'])
if not type(default_item['type']) == tuple:
typ = default_item['type']
box = self.create_box(typ, tooltip)
self.boxes[name] = box
elif type(default_item['type']) == tuple:
boxes = []
values = self.parameter[name]
for index2, val in enumerate(values):
typ = default_item['type'][index2]
boxes.append(self.create_box(typ, tooltip))
box = self.create_multi_box(boxes)
self.boxes[name] = boxes
label.setToolTip(tooltip)
grid.addWidget(label, index1, 1)
grid.addWidget(box, index1, 2)
return grid
def create_box(self, typ, tooltip):
if typ == str:
box = QtGui.QLineEdit()
elif typ == float:
box = QtGui.QDoubleSpinBox()
elif typ == int:
box = QtGui.QSpinBox()
elif typ == bool:
box = QtGui.QCheckBox()
else:
raise TypeError('Unrecognized type {}'.format(typ))
return box
def create_multi_box(self, boxes):
box = QtGui.QWidget()
hl = QtGui.QHBoxLayout()
for b in boxes:
hl.addWidget(b)
box.setLayout(hl)
return box
def add_tab(self, layout, name):
widget = QtGui.QWidget()
scrollA = QtGui.QScrollArea()
scrollA.setWidgetResizable(True)
scrollA.setWidget(widget)
widget.setLayout(layout)
self.tabs.addTab(scrollA, name)
def add_main_parameters_tab(self):
self.add_to_layout(self._main_layout, 'Directories',
self.parameter.get_main_para_names()['dirs'])
self.add_to_layout(self._main_layout, 'NLLoc',
self.parameter.get_main_para_names()['nlloc'])
self.add_to_layout(self._main_layout, 'Seismic Moment',
self.parameter.get_main_para_names()['smoment'])
self.add_to_layout(self._main_layout, 'Focal Mechanism',
self.parameter.get_main_para_names()['focmec'])
self.add_to_layout(self._main_layout, 'Pick Settings',
self.parameter.get_main_para_names()['pick'],
False)
self.add_tab(self._main_layout, 'Main Settings')
def add_special_pick_parameters_tab(self):
self.add_to_layout(self._advanced_layout, 'Z-component',
self.parameter.get_special_para_names()['z'])
self.add_to_layout(self._advanced_layout, 'H-components',
self.parameter.get_special_para_names()['h'])
self.add_to_layout(self._advanced_layout, 'First-motion picker',
self.parameter.get_special_para_names()['fm'])
self.add_to_layout(self._advanced_layout, 'Quality assessment',
self.parameter.get_special_para_names()['quality'],
False)
self.add_tab(self._advanced_layout, 'Advanced Settings')
def gen_h_seperator(self):
seperator = QtGui.QFrame()
seperator.setFrameShape(QtGui.QFrame.HLine)
return seperator
def gen_headline(self, text):
label=QtGui.QLabel(text)
font=QtGui.QFont()
font.setBold(True)
label.setFont(font)
return label
def add_to_layout(self, layout, name, items, seperator=True):
layout.addWidget(self.gen_headline(name))
layout.addLayout(self.init_boxes(items))
if seperator:
layout.addWidget(self.gen_h_seperator())
def params_from_gui(self):
for param in self.parameter.get_all_para_names():
box = self.boxes[param]
value = self.getValue(box)
self.parameter.checkValue(param, value)
self.parameter.setParamKV(param, value)
return self.parameter
def params_to_gui(self):
for param in self.parameter.get_all_para_names():
box = self.boxes[param]
value = self.parameter[param]
#self.parameter.checkValue(param, value)
self.setValue(box, value)
def setValue(self, box, value):
if type(box) == QtGui.QLineEdit:
box.setText(value)
elif type(box) == QtGui.QSpinBox or type(box) == QtGui.QDoubleSpinBox:
box.setMaximum(100*value)
box.setValue(value)
elif type(box) == QtGui.QCheckBox:
if value == 'True':
value = True
if value == 'False':
value = False
box.setChecked(value)
elif type(box) == list:
for index, b in enumerate(box):
self.setValue(b, value[index])
def getValue(self, box):
if type(box) == QtGui.QLineEdit:
value = str(box.text())
elif type(box) == QtGui.QSpinBox or type(box) == QtGui.QDoubleSpinBox:
value = box.value()
elif type(box) == QtGui.QCheckBox:
value = box.isChecked()
elif type(box) == list:
value = []
for b in box:
value.append(self.getValue(b))
value = tuple(value)
return value
def openFile(self):
fd = QtGui.QFileDialog()
fname = fd.getOpenFileName(self, 'Browse for settings file.', '*.in')
if fname[0]:
try:
self.parameter.from_file(fname[0])
self.params_to_gui()
except Exception as e: except Exception as e:
id = self.s_tabs.addTab(QtGui.QWidget(), name) self._warn('Could not open file {}:\n{}'.format(fname[0], e))
self.s_tabs.setTabEnabled(id, False) return
def saveFile(self):
fd = QtGui.QFileDialog()
fname = fd.getSaveFileName(self, 'Browse for settings file.', '*.in')
if fname[0]:
try:
self.params_from_gui()
self.parameter.export2File(fname[0])
except Exception as e:
self._warn('Could not save file {}:\n{}'.format(fname[0], e))
return
def restoreDefaults(self):
try:
self.parameter.reset_defaults()
self.params_to_gui()
except Exception as e:
self._warn('Could not restore defaults:\n{}'.format(e))
return
def _warn(self, message):
self.qmb = QtGui.QMessageBox(QtGui.QMessageBox.Icon.Warning,
'Warning', message)
self.qmb.show()
class PropertiesDlg(QDialog): class PropertiesDlg(QDialog):
@ -1617,193 +2141,6 @@ class LocalisationTab(PropTab):
"nll/binPath": self.binedit.setText("%s" % nllocbin)} "nll/binPath": self.binedit.setText("%s" % nllocbin)}
class AutoPickParaBox(QtGui.QWidget):
def __init__(self, ap, parent=None):
'''
Generate Widget containing parameters for automatic picking algorithm.
:param: ap
:type: AutoPickParameter (object)
'''
QtGui.QWidget.__init__(self, parent)
self.ap = ap
self.tabs = QtGui.QTabWidget()
self.layout = QtGui.QHBoxLayout()
self.layout.addWidget(self.tabs)
self.boxes = {}
self._init_sublayouts()
self.setLayout(self.layout)
self.add_main_parameters_tab()
self.add_special_pick_parameters_tab()
self._toggle_advanced_settings()
def _init_sublayouts(self):
self._main_layout = QtGui.QVBoxLayout()
self._advanced_layout = QtGui.QVBoxLayout()
self._create_advanced_cb()
def _create_advanced_cb(self):
self._advanced_cb = QtGui.QCheckBox('Enable Advanced Settings')
self._advanced_layout.addWidget(self._advanced_cb)
self._advanced_cb.toggled.connect(self._toggle_advanced_settings)
def _toggle_advanced_settings(self):
if self._advanced_cb.isChecked():
self._enable_advanced(True)
else:
self._enable_advanced(False)
def _enable_advanced(self, enable):
for lst in self.ap.get_special_para_names().values():
for param in lst:
box = self.boxes[param]
if type(box) is not list:
box.setEnabled(enable)
else:
for b in box:
b.setEnabled(enable)
def init_boxes(self, parameter_names, defaults=False):
grid = QtGui.QGridLayout()
for index1, name in enumerate(parameter_names):
text = name + ' [?]'
label = QtGui.QLabel(text)
default_item = self.ap.get_defaults()[name]
tooltip = default_item['tooltip']
tooltip += ' | type: {}'.format(default_item['type'])
if not type(default_item['type']) == tuple:
if defaults:
value = default_item['value']
else:
value = self.ap[name]
typ = default_item['type']
box = self.create_box(value, typ, tooltip)
self.boxes[name] = box
elif type(default_item['type']) == tuple:
boxes = []
if defaults:
values = default_item['value']
else:
values = self.ap[name]
for index2, val in enumerate(values):
typ = default_item['type'][index2]
boxes.append(self.create_box(val, typ, tooltip))
box = self.create_multi_box(boxes)
self.boxes[name] = boxes
label.setToolTip(tooltip)
grid.addWidget(label, index1, 1)
grid.addWidget(box, index1, 2)
return grid
def create_box(self, value, typ, tooltip):
if typ == str:
box = QtGui.QLineEdit()
box.setText(value)
elif typ == float:
box = QtGui.QDoubleSpinBox()
box.setMaximum(100*value)
box.setValue(value)
elif typ == int:
box = QtGui.QSpinBox()
box.setMaximum(100*value)
box.setValue(value)
elif typ == bool:
if value == 'True':
value = True
if value == 'False':
value = False
box = QtGui.QCheckBox()
box.setChecked(value)
else:
raise TypeError('Unrecognized type {}'.format(typ))
return box
def create_multi_box(self, boxes):
box = QtGui.QWidget()
hl = QtGui.QHBoxLayout()
for b in boxes:
hl.addWidget(b)
box.setLayout(hl)
return box
def add_tab(self, layout, name):
widget = QtGui.QWidget()
scrollA = QtGui.QScrollArea()
scrollA.setWidgetResizable(True)
scrollA.setWidget(widget)
widget.setLayout(layout)
self.tabs.addTab(scrollA, name)
def add_main_parameters_tab(self):
self.add_to_layout(self._main_layout, 'Directories',
self.ap.get_main_para_names()['dirs'])
self.add_to_layout(self._main_layout, 'NLLoc',
self.ap.get_main_para_names()['nlloc'])
self.add_to_layout(self._main_layout, 'Seismic Moment',
self.ap.get_main_para_names()['smoment'])
self.add_to_layout(self._main_layout, 'Focal Mechanism',
self.ap.get_main_para_names()['focmec'])
self.add_to_layout(self._main_layout, 'Pick Settings',
self.ap.get_main_para_names()['pick'],
False)
self.add_tab(self._main_layout, 'Main Settings')
def add_special_pick_parameters_tab(self):
self.add_to_layout(self._advanced_layout, 'Z-component',
self.ap.get_special_para_names()['z'])
self.add_to_layout(self._advanced_layout, 'H-components',
self.ap.get_special_para_names()['h'])
self.add_to_layout(self._advanced_layout, 'First-motion picker',
self.ap.get_special_para_names()['fm'])
self.add_to_layout(self._advanced_layout, 'Quality assessment',
self.ap.get_special_para_names()['quality'],
False)
self.add_tab(self._advanced_layout, 'Advanced Settings')
def gen_h_seperator(self):
seperator = QtGui.QFrame()
seperator.setFrameShape(QtGui.QFrame.HLine)
return seperator
def gen_headline(self, text):
label=QtGui.QLabel(text)
font=QtGui.QFont()
font.setBold(True)
label.setFont(font)
return label
def add_to_layout(self, layout, name, items, seperator=True):
layout.addWidget(self.gen_headline(name))
layout.addLayout(self.init_boxes(items))
if seperator:
layout.addWidget(self.gen_h_seperator())
def update_params(self):
for param in self.ap.get_all_para_names():
box = self.boxes[param]
value = self.getValue(box)
self.ap.checkValue(param, value)
self.ap.setParam(param, value)
def getValue(self, box):
if type(box) == QtGui.QLineEdit:
value = str(box.text())
elif type(box) == QtGui.QSpinBox or type(box) == QtGui.QDoubleSpinBox:
value = box.value()
elif type(box) == QtGui.QCheckBox:
value = box.isChecked()
elif type(box) == list:
value = []
for b in box:
value.append(self.getValue(b))
value = tuple(value)
return value
class ParametersTab(PropTab): class ParametersTab(PropTab):
def __init__(self, parent=None, infile=None): def __init__(self, parent=None, infile=None):
super(ParametersTab, self).__init__(parent) super(ParametersTab, self).__init__(parent)