Merge branch 'develop' into darius
This commit is contained in:
commit
1dab754811
247
QtPyLoT.py
247
QtPyLoT.py
@ -64,7 +64,7 @@ from pylot.core.io.data import Data
|
||||
from pylot.core.io.inputs import FilterOptions, PylotParameter
|
||||
from autoPyLoT import autoPyLoT
|
||||
from pylot.core.pick.compare import Comparison
|
||||
from pylot.core.pick.utils import symmetrize_error, getQualityfromUncertainty
|
||||
from pylot.core.pick.utils import symmetrize_error, getQualityFromUncertainty
|
||||
from pylot.core.io.phases import picksdict_from_picks
|
||||
import pylot.core.loc.nll as nll
|
||||
from pylot.core.util.defaults import FILTERDEFAULTS, SetChannelComponents
|
||||
@ -74,12 +74,12 @@ from pylot.core.util.connection import checkurl
|
||||
from pylot.core.util.dataprocessing import read_metadata, restitute_data
|
||||
from pylot.core.util.utils import fnConstructor, getLogin, \
|
||||
full_range, readFilterInformation, trim_station_components, check4gaps, make_pen, pick_color_plt, \
|
||||
pick_linestyle_plt, identifyPhase, loopIdentifyPhase, remove_underscores, check4doubled, check4rotated
|
||||
pick_linestyle_plt, remove_underscores, check4doubled, identifyPhaseID, excludeQualityClasses, has_spe
|
||||
from pylot.core.util.event import Event
|
||||
from pylot.core.io.location import create_creation_info, create_event
|
||||
from pylot.core.util.widgets import FilterOptionsDialog, NewEventDlg, \
|
||||
WaveformWidget, WaveformWidgetPG, PropertiesDlg, HelpForm, createAction, PickDlg, \
|
||||
getDataType, ComparisonDialog, TuneAutopicker, PylotParaBox, AutoPickDlg
|
||||
getDataType, ComparisonWidget, TuneAutopicker, PylotParaBox, AutoPickDlg, CanvasWidget, AutoPickWidget
|
||||
from pylot.core.util.map_projection import map_projection
|
||||
from pylot.core.util.structure import DATASTRUCTURE
|
||||
from pylot.core.util.thread import Thread, Worker
|
||||
@ -865,7 +865,7 @@ class MainWindow(QMainWindow):
|
||||
return fnames
|
||||
|
||||
def getPhaseID(self, phase):
|
||||
return identifyPhase(loopIdentifyPhase(phase))
|
||||
return identifyPhaseID(phase)
|
||||
|
||||
def get_current_event(self, eventbox=None):
|
||||
'''
|
||||
@ -1025,6 +1025,11 @@ class MainWindow(QMainWindow):
|
||||
:param: select_events, can be 'all', 'ref'
|
||||
:type: str
|
||||
'''
|
||||
|
||||
# if pick widget is open, refresh tooltips as well
|
||||
if hasattr(self, 'apw'):
|
||||
self.apw.refresh_tooltips()
|
||||
|
||||
if not eventBox:
|
||||
eventBox = self.eventBox
|
||||
index = eventBox.currentIndex()
|
||||
@ -1048,12 +1053,23 @@ class MainWindow(QMainWindow):
|
||||
|
||||
for id, event in enumerate(self.project.eventlist):
|
||||
event_path = event.path
|
||||
event_npicks = 0
|
||||
event_nautopicks = 0
|
||||
if event.pylot_picks:
|
||||
event_npicks = len(event.pylot_picks)
|
||||
if event.pylot_autopicks:
|
||||
event_nautopicks = len(event.pylot_autopicks)
|
||||
phaseErrors = {'P': self._inputs['timeerrorsP'],
|
||||
'S': self._inputs['timeerrorsS']}
|
||||
|
||||
ma_props = {'manual': event.pylot_picks,
|
||||
'auto': event.pylot_autopicks}
|
||||
ma_count = {'manual': 0,
|
||||
'auto': 0}
|
||||
|
||||
for ma in ma_props.keys():
|
||||
if ma_props[ma]:
|
||||
for picks in ma_props[ma].values():
|
||||
for phasename, pick in picks.items():
|
||||
if not type(pick) in [dict, AttribDict]:
|
||||
continue
|
||||
if getQualityFromUncertainty(has_spe(pick), phaseErrors[self.getPhaseID(phasename)]) < 4:
|
||||
ma_count[ma] += 1
|
||||
|
||||
event_ref = event.isRefEvent()
|
||||
event_test = event.isTestEvent()
|
||||
|
||||
@ -1064,9 +1080,9 @@ class MainWindow(QMainWindow):
|
||||
# a=event_nautopicks)
|
||||
|
||||
item_path = QtGui.QStandardItem('{path:{plen}}'.format(path=event_path, plen=plmax))
|
||||
item_nmp = QtGui.QStandardItem(str(event_npicks))
|
||||
item_nmp = QtGui.QStandardItem(str(ma_count['manual']))
|
||||
item_nmp.setIcon(self.manupicksicon_small)
|
||||
item_nap = QtGui.QStandardItem(str(event_nautopicks))
|
||||
item_nap = QtGui.QStandardItem(str(ma_count['auto']))
|
||||
item_nap.setIcon(self.autopicksicon_small)
|
||||
item_ref = QtGui.QStandardItem() # str(event_ref))
|
||||
item_test = QtGui.QStandardItem() # str(event_test))
|
||||
@ -1215,9 +1231,13 @@ class MainWindow(QMainWindow):
|
||||
|
||||
def comparePicks(self):
|
||||
if self.check4Comparison():
|
||||
co = Comparison(auto=self.getPicks('auto'), manu=self.getPicks())
|
||||
compare_dlg = ComparisonDialog(co, self)
|
||||
compare_dlg.exec_()
|
||||
autopicks = excludeQualityClasses(self.getPicks('auto'), [4],
|
||||
self._inputs['timeerrorsP'], self._inputs['timeerrorsS'])
|
||||
manupicks = excludeQualityClasses(self.getPicks('manual'), [4],
|
||||
self._inputs['timeerrorsP'], self._inputs['timeerrorsS'])
|
||||
co = Comparison(auto=autopicks, manu=manupicks)
|
||||
compare_dlg = ComparisonWidget(co, self)
|
||||
compare_dlg.show()
|
||||
|
||||
def getPlotWidget(self):
|
||||
return self.dataPlot
|
||||
@ -1813,16 +1833,8 @@ class MainWindow(QMainWindow):
|
||||
self.listWidget.addItem(text)
|
||||
self.listWidget.scrollToBottom()
|
||||
|
||||
def tune_autopicker(self):
|
||||
'''
|
||||
Initiates TuneAutopicker widget use to interactively
|
||||
tune parameters for autopicking algorithm.
|
||||
'''
|
||||
# figures and canvas have to be iniated from the main GUI
|
||||
# thread to prevent handling of QPixmap objects outside of
|
||||
# the main thread
|
||||
def init_fig_dict(self):
|
||||
self.fig_dict = {}
|
||||
self.canvas_dict = {}
|
||||
self.fig_keys = [
|
||||
'mainFig',
|
||||
'aicFig',
|
||||
@ -1834,12 +1846,45 @@ class MainWindow(QMainWindow):
|
||||
'el_S1pick',
|
||||
'el_S2pick',
|
||||
'refSpick',
|
||||
'aicARHfig',
|
||||
'aicARHfig'
|
||||
]
|
||||
for key in self.fig_keys:
|
||||
fig = Figure()
|
||||
self.fig_dict[key] = fig
|
||||
|
||||
def init_canvas_dict(self):
|
||||
self.canvas_dict = {}
|
||||
for key in self.fig_keys:
|
||||
self.canvas_dict[key] = FigureCanvas(self.fig_dict[key])
|
||||
|
||||
def init_fig_dict_wadatijack(self, eventIDs):
|
||||
self.fig_dict_wadatijack = {}
|
||||
self.fig_keys_wadatijack = [
|
||||
'jackknife',
|
||||
'wadati'
|
||||
]
|
||||
for eventID in eventIDs:
|
||||
self.fig_dict_wadatijack[eventID] = {}
|
||||
for key in self.fig_keys_wadatijack:
|
||||
fig = Figure()
|
||||
self.fig_dict_wadatijack[eventID][key] = fig
|
||||
|
||||
def init_canvas_dict_wadatijack(self):
|
||||
self.canvas_dict_wadatijack = {}
|
||||
for eventID in self.fig_dict_wadatijack.keys():
|
||||
self.canvas_dict_wadatijack[eventID] = {}
|
||||
for key in self.fig_keys_wadatijack:
|
||||
self.canvas_dict_wadatijack[eventID][key] = FigureCanvas(self.fig_dict_wadatijack[eventID][key])
|
||||
|
||||
def tune_autopicker(self):
|
||||
'''
|
||||
Initiates TuneAutopicker widget use to interactively
|
||||
tune parameters for autopicking algorithm.
|
||||
'''
|
||||
# figures and canvas have to be iniated from the main GUI
|
||||
# thread to prevent handling of QPixmap objects outside of
|
||||
# the main thread
|
||||
self.init_fig_dict()
|
||||
#if not self.tap:
|
||||
# init TuneAutopicker object
|
||||
self.tap = TuneAutopicker(self)
|
||||
@ -1858,8 +1903,7 @@ class MainWindow(QMainWindow):
|
||||
'''
|
||||
Create and fill TuneAutopicker tabs with figure canvas.
|
||||
'''
|
||||
for key in self.fig_keys:
|
||||
self.canvas_dict[key] = FigureCanvas(self.fig_dict[key])
|
||||
self.init_canvas_dict()
|
||||
self.tap.fill_tabs(picked=True)
|
||||
|
||||
def autoPick(self):
|
||||
@ -1868,36 +1912,79 @@ class MainWindow(QMainWindow):
|
||||
QMessageBox.warning(self, "PyLoT Warning",
|
||||
"No autoPyLoT output declared!")
|
||||
return
|
||||
event = self.get_current_event()
|
||||
self.saveData(event, event.path, outformats=['.xml'])
|
||||
|
||||
self.pickoptions =[('current event', self.get_current_event),
|
||||
('tune events', self.get_ref_events),
|
||||
('test events', self.get_test_events),
|
||||
('all (picked) events', self.get_manu_picked_events),
|
||||
('all events', self.get_all_events)]
|
||||
|
||||
self.listWidget = QListWidget()
|
||||
self.setDirty(True)
|
||||
self.logDockWidget = QDockWidget("AutoPickLog", self)
|
||||
self.logDockWidget.setObjectName("LogDockWidget")
|
||||
self.logDockWidget.setAllowedAreas(
|
||||
Qt.LeftDockWidgetArea | Qt.RightDockWidgetArea)
|
||||
self.logDockWidget.setWidget(self.listWidget)
|
||||
self.addDockWidget(Qt.LeftDockWidgetArea, self.logDockWidget)
|
||||
self.apw = AutoPickWidget(self, self.pickoptions)
|
||||
self.apw.insert_log_widget(self.listWidget)
|
||||
self.apw.refresh_tooltips()
|
||||
|
||||
# self.logDockWidget = QDockWidget("AutoPickLog", self)
|
||||
# self.logDockWidget.setObjectName("LogDockWidget")
|
||||
# self.logDockWidget.setAllowedAreas(
|
||||
# Qt.LeftDockWidgetArea | Qt.RightDockWidgetArea)
|
||||
# self.logDockWidget.setWidget(self.listWidget)
|
||||
# self.addDockWidget(Qt.LeftDockWidgetArea, self.logDockWidget)
|
||||
# self.addListItem('Loading default values from PyLoT-input file %s'
|
||||
# % self.infile)
|
||||
|
||||
self.apw.start.connect(self.start_autopick)
|
||||
self.apw.show()
|
||||
|
||||
def start_autopick(self):
|
||||
for key, func in self.pickoptions:
|
||||
if self.apw.rb_dict[key].isChecked():
|
||||
# if radio button is checked break for loop and use func
|
||||
break
|
||||
|
||||
events = func()
|
||||
if not type(events) == list:
|
||||
events = [events]
|
||||
eventPaths = self.get_event_paths(events)
|
||||
eventIDs = self.get_event_ids(events)
|
||||
|
||||
self.init_fig_dict_wadatijack(eventIDs)
|
||||
|
||||
if not eventPaths:
|
||||
self.addListItem("No events found for '{}'".format(key))
|
||||
return
|
||||
else:
|
||||
self.addListItem("Picking the following events ({}):".format(key))
|
||||
for eventID in eventPaths:
|
||||
self.addListItem(str(eventID))
|
||||
|
||||
self.apw.enable(False)
|
||||
|
||||
# export current picks etc.
|
||||
self.exportAllEvents(['.xml'])
|
||||
|
||||
# define arguments for picker
|
||||
args = {'parameter': self._inputs,
|
||||
'station': 'all',
|
||||
'fnames': 'None',
|
||||
'eventid': self.get_current_event_path(),
|
||||
'eventid': eventPaths,
|
||||
'iplot': 0,
|
||||
'fig_dict': None,
|
||||
'fig_dict_wadatijack': self.fig_dict_wadatijack,
|
||||
'locflag': 0}
|
||||
|
||||
# init pick thread
|
||||
self.mp_thread = QtCore.QThreadPool()
|
||||
self.mp_worker = Worker(autoPyLoT, args, redirect_stdout=True)
|
||||
self.mp_thread.start(self.mp_worker)
|
||||
|
||||
self.addListItem(str(self._inputs))
|
||||
|
||||
self.mp_worker.signals.message.connect(self.addListItem)
|
||||
self.mp_worker.signals.result.connect(self.finalizeAutoPick)
|
||||
|
||||
self.mp_thread.start(self.mp_worker)
|
||||
|
||||
def autoPickProject(self):
|
||||
if not self.apd_local:
|
||||
self.apd_local = AutoPickDlg(self, sge=False)
|
||||
@ -1909,12 +1996,63 @@ class MainWindow(QMainWindow):
|
||||
self.apd_sge.show()
|
||||
|
||||
def finalizeAutoPick(self, result):
|
||||
self.apw.enable(True)
|
||||
if result:
|
||||
event = self.get_current_event()
|
||||
event.addAutopicks(result)
|
||||
self.init_canvas_dict_wadatijack()
|
||||
for eventID in result.keys():
|
||||
event = self.get_event_from_id(eventID)
|
||||
if not event:
|
||||
continue
|
||||
event.addAutopicks(result[eventID])
|
||||
jkw = CanvasWidget(self, self.canvas_dict_wadatijack[eventID]['jackknife'])
|
||||
wdw = CanvasWidget(self, self.canvas_dict_wadatijack[eventID]['wadati'])
|
||||
self.apw.add_plot_widget(jkw, 'Jackknife', eventID)
|
||||
self.apw.add_plot_widget(wdw, 'Wadati', eventID)
|
||||
self.apw.update_plots()
|
||||
self.drawPicks(picktype='auto')
|
||||
self.draw()
|
||||
|
||||
def get_event_from_id(self, eventID):
|
||||
for event in self.project.eventlist:
|
||||
if event.pylot_id == eventID:
|
||||
return event
|
||||
|
||||
def get_event_paths(self, eventlist):
|
||||
eventPaths = []
|
||||
for event in eventlist:
|
||||
eventPaths.append(event.path)
|
||||
return eventPaths
|
||||
|
||||
def get_event_ids(self, eventlist):
|
||||
eventIDs = []
|
||||
for event in eventlist:
|
||||
eventIDs.append(event.pylot_id)
|
||||
return eventIDs
|
||||
|
||||
def get_all_events(self):
|
||||
return self.project.eventlist
|
||||
|
||||
def get_ref_events(self):
|
||||
events = []
|
||||
for event in self.project.eventlist:
|
||||
if event.isRefEvent():
|
||||
events.append(event)
|
||||
return events
|
||||
|
||||
def get_test_events(self):
|
||||
events = []
|
||||
for event in self.project.eventlist:
|
||||
if event.isTestEvent():
|
||||
events.append(event)
|
||||
return events
|
||||
|
||||
def get_manu_picked_events(self):
|
||||
events = []
|
||||
for event in self.project.eventlist:
|
||||
if len(event.pylot_picks) > 0:
|
||||
events.append(event)
|
||||
return events
|
||||
|
||||
def addPicks(self, station, picks, type='manual'):
|
||||
stat_picks = self.getPicksOnStation(station, type)
|
||||
if not stat_picks:
|
||||
@ -1994,16 +2132,17 @@ class MainWindow(QMainWindow):
|
||||
stime = self.getStime()
|
||||
|
||||
for phase in stat_picks:
|
||||
if phase == 'SPt': continue # wadati SP time
|
||||
picks = stat_picks[phase]
|
||||
if type(stat_picks[phase]) is not dict and type(stat_picks[phase]) is not AttribDict:
|
||||
return
|
||||
|
||||
# get quality classes
|
||||
if self.getPhaseID(phase) == 'P':
|
||||
quality = getQualityfromUncertainty(picks['spe'], self._inputs['timeerrorsP'])
|
||||
quality = getQualityFromUncertainty(picks['spe'], self._inputs['timeerrorsP'])
|
||||
phaseID = 'P'
|
||||
elif self.getPhaseID(phase) == 'S':
|
||||
quality = getQualityfromUncertainty(picks['spe'], self._inputs['timeerrorsS'])
|
||||
quality = getQualityFromUncertainty(picks['spe'], self._inputs['timeerrorsS'])
|
||||
phaseID = 'S'
|
||||
|
||||
mpp = picks['mpp'] - stime
|
||||
@ -2326,12 +2465,22 @@ class MainWindow(QMainWindow):
|
||||
# iterate through eventlist and generate items for table rows
|
||||
self.project._table = []
|
||||
for index, event in enumerate(eventlist):
|
||||
event_npicks = 0
|
||||
event_nautopicks = 0
|
||||
if event.pylot_picks:
|
||||
event_npicks = len(event.pylot_picks)
|
||||
if event.pylot_autopicks:
|
||||
event_nautopicks = len(event.pylot_autopicks)
|
||||
phaseErrors = {'P': self._inputs['timeerrorsP'],
|
||||
'S': self._inputs['timeerrorsS']}
|
||||
|
||||
ma_props = {'manual': event.pylot_picks,
|
||||
'auto': event.pylot_autopicks}
|
||||
ma_count = {'manual': 0,
|
||||
'auto': 0}
|
||||
|
||||
for ma in ma_props.keys():
|
||||
if ma_props[ma]:
|
||||
for picks in ma_props[ma].values():
|
||||
for phasename, pick in picks.items():
|
||||
if not type(pick) in [dict, AttribDict]:
|
||||
continue
|
||||
if getQualityFromUncertainty(has_spe(pick), phaseErrors[self.getPhaseID(phasename)]) < 4:
|
||||
ma_count[ma] += 1
|
||||
|
||||
# init table items for current row
|
||||
item_delete = QtGui.QTableWidgetItem()
|
||||
@ -2342,9 +2491,9 @@ class MainWindow(QMainWindow):
|
||||
item_lon = QtGui.QTableWidgetItem()
|
||||
item_depth = QtGui.QTableWidgetItem()
|
||||
item_mag = QtGui.QTableWidgetItem()
|
||||
item_nmp = QtGui.QTableWidgetItem(str(event_npicks))
|
||||
item_nmp = QtGui.QTableWidgetItem(str(ma_count['manual']))
|
||||
item_nmp.setIcon(self.manupicksicon_small)
|
||||
item_nap = QtGui.QTableWidgetItem(str(event_nautopicks))
|
||||
item_nap = QtGui.QTableWidgetItem(str(ma_count['auto']))
|
||||
item_nap.setIcon(self.autopicksicon_small)
|
||||
item_ref = QtGui.QTableWidgetItem()
|
||||
item_test = QtGui.QTableWidgetItem()
|
||||
|
40
autoPyLoT.py
40
autoPyLoT.py
@ -78,12 +78,17 @@ def autoPyLoT(input_dict=None, parameter=None, inputfile=None, fnames=None, even
|
||||
inputfile = real_None(inputfile)
|
||||
eventid = real_None(eventid)
|
||||
|
||||
fig_dict = None
|
||||
fig_dict_wadatijack = None
|
||||
|
||||
locflag = 1
|
||||
if input_dict and isinstance(input_dict, dict):
|
||||
if 'parameter' in input_dict:
|
||||
parameter = input_dict['parameter']
|
||||
if 'fig_dict' in input_dict:
|
||||
fig_dict = input_dict['fig_dict']
|
||||
if 'fig_dict_wadatijack' in input_dict:
|
||||
fig_dict_wadatijack = input_dict['fig_dict_wadatijack']
|
||||
if 'station' in input_dict:
|
||||
station = input_dict['station']
|
||||
if 'fnames' in input_dict:
|
||||
@ -179,13 +184,14 @@ def autoPyLoT(input_dict=None, parameter=None, inputfile=None, fnames=None, even
|
||||
evID = os.path.split(eventid)[-1]
|
||||
locflag = 2
|
||||
else:
|
||||
# started in tune mode
|
||||
# started in tune or interactive mode
|
||||
datapath = os.path.join(parameter['rootpath'],
|
||||
parameter['datapath'])
|
||||
events = []
|
||||
events.append(os.path.join(datapath,
|
||||
parameter['database'],
|
||||
eventid))
|
||||
for eventID in eventid:
|
||||
events.append(os.path.join(datapath,
|
||||
parameter['database'],
|
||||
eventID))
|
||||
|
||||
if not events:
|
||||
print('autoPyLoT: No events given. Return!')
|
||||
@ -196,6 +202,7 @@ def autoPyLoT(input_dict=None, parameter=None, inputfile=None, fnames=None, even
|
||||
eventpath = eventpath.replace(SEPARATOR, '/')
|
||||
events[index] = eventpath
|
||||
|
||||
allpicks = {}
|
||||
glocflag = locflag
|
||||
for eventpath in events:
|
||||
evID = os.path.split(eventpath)[-1]
|
||||
@ -260,14 +267,12 @@ def autoPyLoT(input_dict=None, parameter=None, inputfile=None, fnames=None, even
|
||||
print(wfdat)
|
||||
##########################################################
|
||||
# !automated picking starts here!
|
||||
if input_dict:
|
||||
if 'fig_dict' in input_dict:
|
||||
fig_dict = input_dict['fig_dict']
|
||||
picks = autopickevent(wfdat, parameter, iplot=iplot, fig_dict=fig_dict,
|
||||
ncores=ncores, metadata=metadata, origin=data.get_evt_data().origins)
|
||||
else:
|
||||
picks = autopickevent(wfdat, parameter, iplot=iplot,
|
||||
ncores=ncores, metadata=metadata, origin=data.get_evt_data().origins)
|
||||
fdwj = None
|
||||
if fig_dict_wadatijack:
|
||||
fdwj = fig_dict_wadatijack[evID]
|
||||
picks = autopickevent(wfdat, parameter, iplot=iplot, fig_dict=fig_dict,
|
||||
fig_dict_wadatijack=fdwj,
|
||||
ncores=ncores, metadata=metadata, origin=data.get_evt_data().origins)
|
||||
##########################################################
|
||||
# locating
|
||||
if locflag > 0:
|
||||
@ -383,7 +388,8 @@ def autoPyLoT(input_dict=None, parameter=None, inputfile=None, fnames=None, even
|
||||
iplot)
|
||||
# update pick with moment property values (w0, fc, Mo)
|
||||
for stats, props in moment_mag.moment_props.items():
|
||||
picks[stats]['P'].update(props)
|
||||
if picks.has_key(stats):
|
||||
picks[stats]['P'].update(props)
|
||||
evt = moment_mag.updated_event()
|
||||
net_mw = moment_mag.net_magnitude()
|
||||
print("Network moment magnitude: %4.1f" % net_mw.mag)
|
||||
@ -394,7 +400,8 @@ def autoPyLoT(input_dict=None, parameter=None, inputfile=None, fnames=None, even
|
||||
parameter.get('sstop'),
|
||||
WAscaling, True, iplot)
|
||||
for stats, amplitude in local_mag.amplitudes.items():
|
||||
picks[stats]['S']['Ao'] = amplitude.generic_amplitude
|
||||
if picks.has_key(stats):
|
||||
picks[stats]['S']['Ao'] = amplitude.generic_amplitude
|
||||
print("Local station magnitudes scaled with:")
|
||||
print("log(Ao) + %f * log(r) + %f * r + %f" % (WAscaling[0],
|
||||
WAscaling[1],
|
||||
@ -452,13 +459,16 @@ def autoPyLoT(input_dict=None, parameter=None, inputfile=None, fnames=None, even
|
||||
if locflag == 0:
|
||||
print("autoPyLoT was running in non-location mode!")
|
||||
|
||||
# save picks for current event ID to dictionary with ALL picks
|
||||
allpicks[evID] = picks
|
||||
|
||||
endsp = '''####################################\n
|
||||
************************************\n
|
||||
*********autoPyLoT terminates*******\n
|
||||
The Python picking and Location Tool\n
|
||||
************************************'''.format(version=_getVersionString())
|
||||
print(endsp)
|
||||
return picks
|
||||
return allpicks
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
@ -879,6 +879,9 @@ def getQualitiesfromxml(xmlnames, ErrorsP, ErrorsS, plotflag=1):
|
||||
Ludger Küperkoch, BESTEC GmbH, 07/2017
|
||||
"""
|
||||
|
||||
from pylot.core.pick.utils import getQualityFromUncertainty
|
||||
from pylot.core.util.utils import loopIdentifyPhase, identifyPhase
|
||||
|
||||
# read all onset weights
|
||||
Pw0 = []
|
||||
Pw1 = []
|
||||
@ -902,14 +905,15 @@ def getQualitiesfromxml(xmlnames, ErrorsP, ErrorsS, plotflag=1):
|
||||
mstation = Pick.waveform_id.station_code
|
||||
mstation_ext = mstation + '_'
|
||||
for mpick in arrivals_copy:
|
||||
if mpick.phase_hint[0] == 'P':
|
||||
phase = identifyPhase(loopIdentifyPhase(Pick.phase_hint))
|
||||
if phase == 'P':
|
||||
if ((mpick.waveform_id.station_code == mstation) or \
|
||||
(mpick.waveform_id.station_code == mstation_ext)) and \
|
||||
((mpick.method_id).split('/')[1] == 'auto') and \
|
||||
(mpick.time_errors['uncertainty'] <= ErrorsP[3]):
|
||||
del mpick
|
||||
break
|
||||
elif mpick.phase_hint[0] == 'S':
|
||||
elif phase == 'S':
|
||||
if ((mpick.waveform_id.station_code == mstation) or \
|
||||
(mpick.waveform_id.station_code == mstation_ext)) and \
|
||||
((mpick.method_id).split('/')[1] == 'auto') and \
|
||||
@ -921,38 +925,31 @@ def getQualitiesfromxml(xmlnames, ErrorsP, ErrorsS, plotflag=1):
|
||||
print("Found manual as well as automatic picks, prefered the {} manual ones!".format(lendiff))
|
||||
|
||||
for Pick in arrivals_copy:
|
||||
if Pick.phase_hint[0] == 'P':
|
||||
if Pick.time_errors.uncertainty <= ErrorsP[0]:
|
||||
phase = identifyPhase(loopIdentifyPhase(Pick.phase_hint))
|
||||
if phase == 'P':
|
||||
Pqual = getQualityFromUncertainty(Pick.time_errors.uncertainty, ErrorsP)
|
||||
if Pqual == 0:
|
||||
Pw0.append(Pick.time_errors.uncertainty)
|
||||
elif (Pick.time_errors.uncertainty > ErrorsP[0]) and \
|
||||
(Pick.time_errors.uncertainty <= ErrorsP[1]):
|
||||
elif Pqual == 1:
|
||||
Pw1.append(Pick.time_errors.uncertainty)
|
||||
elif (Pick.time_errors.uncertainty > ErrorsP[1]) and \
|
||||
(Pick.time_errors.uncertainty <= ErrorsP[2]):
|
||||
elif Pqual == 2:
|
||||
Pw2.append(Pick.time_errors.uncertainty)
|
||||
elif (Pick.time_errors.uncertainty > ErrorsP[2]) and \
|
||||
(Pick.time_errors.uncertainty <= ErrorsP[3]):
|
||||
elif Pqual == 3:
|
||||
Pw3.append(Pick.time_errors.uncertainty)
|
||||
elif Pick.time_errors.uncertainty > ErrorsP[3]:
|
||||
elif Pqual == 4:
|
||||
Pw4.append(Pick.time_errors.uncertainty)
|
||||
else:
|
||||
pass
|
||||
elif Pick.phase_hint[0] == 'S':
|
||||
if Pick.time_errors.uncertainty <= ErrorsS[0]:
|
||||
elif phase == 'S':
|
||||
Squal = getQualityFromUncertainty(Pick.time_errors.uncertainty, ErrorsS)
|
||||
if Squal == 0:
|
||||
Sw0.append(Pick.time_errors.uncertainty)
|
||||
elif (Pick.time_errors.uncertainty > ErrorsS[0]) and \
|
||||
(Pick.time_errors.uncertainty <= ErrorsS[1]):
|
||||
elif Squal == 1:
|
||||
Sw1.append(Pick.time_errors.uncertainty)
|
||||
elif (Pick.time_errors.uncertainty > ErrorsS[1]) and \
|
||||
(Pick.time_errors.uncertainty <= ErrorsS[2]):
|
||||
elif Squal == 2:
|
||||
Sw2.append(Pick.time_errors.uncertainty)
|
||||
elif (Pick.time_errors.uncertainty > ErrorsS[2]) and \
|
||||
(Pick.time_errors.uncertainty <= ErrorsS[3]):
|
||||
elif Squal == 3:
|
||||
Sw3.append(Pick.time_errors.uncertainty)
|
||||
elif Pick.time_errors.uncertainty > ErrorsS[3]:
|
||||
elif Squal == 4:
|
||||
Sw4.append(Pick.time_errors.uncertainty)
|
||||
else:
|
||||
pass
|
||||
else:
|
||||
print("Phase hint not defined for picking!")
|
||||
pass
|
||||
@ -965,45 +962,45 @@ def getQualitiesfromxml(xmlnames, ErrorsP, ErrorsS, plotflag=1):
|
||||
# get percentage of weights
|
||||
numPweights = np.sum([len(Pw0), len(Pw1), len(Pw2), len(Pw3), len(Pw4)])
|
||||
numSweights = np.sum([len(Sw0), len(Sw1), len(Sw2), len(Sw3), len(Sw4)])
|
||||
try:
|
||||
if len(Pw0) > 0:
|
||||
P0perc = 100 / numPweights * len(Pw0)
|
||||
except:
|
||||
else:
|
||||
P0perc = 0
|
||||
try:
|
||||
if len(Pw1) > 0:
|
||||
P1perc = 100 / numPweights * len(Pw1)
|
||||
except:
|
||||
else:
|
||||
P1perc = 0
|
||||
try:
|
||||
if len(Pw2) > 0:
|
||||
P2perc = 100 / numPweights * len(Pw2)
|
||||
except:
|
||||
else:
|
||||
P2perc = 0
|
||||
try:
|
||||
if len(Pw3) > 0:
|
||||
P3perc = 100 / numPweights * len(Pw3)
|
||||
except:
|
||||
else:
|
||||
P3perc = 0
|
||||
try:
|
||||
if len(Pw4) > 0:
|
||||
P4perc = 100 / numPweights * len(Pw4)
|
||||
except:
|
||||
else:
|
||||
P4perc = 0
|
||||
try:
|
||||
if len(Sw0) > 0:
|
||||
S0perc = 100 / numSweights * len(Sw0)
|
||||
except:
|
||||
else:
|
||||
S0perc = 0
|
||||
try:
|
||||
if len(Sw1) > 0:
|
||||
S1perc = 100 / numSweights * len(Sw1)
|
||||
except:
|
||||
else:
|
||||
S1perc = 0
|
||||
try:
|
||||
if len(Sw2) > 0:
|
||||
S2perc = 100 / numSweights * len(Sw2)
|
||||
except:
|
||||
else:
|
||||
S2perc = 0
|
||||
try:
|
||||
if len(Sw3) > 0:
|
||||
S3perc = 100 / numSweights * len(Sw3)
|
||||
except:
|
||||
else:
|
||||
S3perc = 0
|
||||
try:
|
||||
if len(Sw4) > 0:
|
||||
S4perc = 100 / numSweights * len(Sw4)
|
||||
except:
|
||||
else:
|
||||
S4perc = 0
|
||||
|
||||
weights = ('0', '1', '2', '3', '4')
|
||||
|
@ -18,13 +18,13 @@ from pylot.core.pick.charfuns import HOScf, AICcf, ARZcf, ARHcf, AR3Ccf
|
||||
from pylot.core.pick.picker import AICPicker, PragPicker
|
||||
from pylot.core.pick.utils import checksignallength, checkZ4S, earllatepicker, \
|
||||
getSNR, fmpicker, checkPonsets, wadaticheck
|
||||
from pylot.core.util.utils import getPatternLine, gen_Pool, identifyPhase, loopIdentifyPhase, \
|
||||
real_Bool
|
||||
from pylot.core.util.utils import getPatternLine, gen_Pool,\
|
||||
real_Bool, identifyPhaseID
|
||||
|
||||
from obspy.taup import TauPyModel
|
||||
|
||||
|
||||
def autopickevent(data, param, iplot=0, fig_dict=None, ncores=0, metadata=None, origin=None):
|
||||
def autopickevent(data, param, iplot=0, fig_dict=None, fig_dict_wadatijack=None, ncores=0, metadata=None, origin=None):
|
||||
stations = []
|
||||
all_onsets = {}
|
||||
input_tuples = []
|
||||
@ -76,14 +76,15 @@ def autopickevent(data, param, iplot=0, fig_dict=None, ncores=0, metadata=None,
|
||||
pick.pop('station')
|
||||
all_onsets[station] = pick
|
||||
|
||||
all_onsets = checkPonsets(all_onsets, mdttolerance, iplot)
|
||||
return all_onsets
|
||||
#return all_onsets
|
||||
|
||||
# quality control
|
||||
# median check and jackknife on P-onset times
|
||||
jk_checked_onsets = checkPonsets(all_onsets, mdttolerance, iplot)
|
||||
jk_checked_onsets = checkPonsets(all_onsets, mdttolerance, 1, fig_dict_wadatijack)
|
||||
#return jk_checked_onsets
|
||||
# check S-P times (Wadati)
|
||||
return wadaticheck(jk_checked_onsets, wdttolerance, iplot)
|
||||
wadationsets = wadaticheck(jk_checked_onsets, wdttolerance, 1, fig_dict_wadatijack)
|
||||
return wadationsets
|
||||
|
||||
|
||||
def call_autopickstation(input_tuple):
|
||||
@ -255,7 +256,7 @@ def autopickstation(wfstream, pickparam, verbose=False,
|
||||
phases = {'P': [],
|
||||
'S': []}
|
||||
for arr in arrivals:
|
||||
phases[identifyPhase(loopIdentifyPhase(arr.phase.name))].append(arr)
|
||||
phases[identifyPhaseID(arr.phase.name)].append(arr)
|
||||
|
||||
# get first P and S onsets from arrivals list
|
||||
arrP, estFirstP = min([(arr, arr.time) for arr in phases['P']], key = lambda t: t[1])
|
||||
@ -984,9 +985,9 @@ def autopickstation(wfstream, pickparam, verbose=False,
|
||||
##########################################################################
|
||||
# calculate "real" onset times
|
||||
if lpickP is not None and lpickP == mpickP:
|
||||
lpickP += timeerrorsP[0]
|
||||
lpickP += zdat[0].stats.delta
|
||||
if epickP is not None and epickP == mpickP:
|
||||
epickP -= timeerrorsP[0]
|
||||
epickP -= zdat[0].stats.delta
|
||||
if mpickP is not None and epickP is not None and lpickP is not None:
|
||||
lpickP = zdat[0].stats.starttime + lpickP
|
||||
epickP = zdat[0].stats.starttime + epickP
|
||||
@ -998,27 +999,27 @@ def autopickstation(wfstream, pickparam, verbose=False,
|
||||
epickP = zdat[0].stats.starttime - timeerrorsP[3]
|
||||
mpickP = zdat[0].stats.starttime
|
||||
|
||||
if edat:
|
||||
hdat = edat[0]
|
||||
elif ndat:
|
||||
hdat = ndat[0]
|
||||
else:
|
||||
return
|
||||
|
||||
if lpickS is not None and lpickS == mpickS:
|
||||
lpickS += timeerrorsS[0]
|
||||
lpickS += hdat.stats.delta
|
||||
if epickS is not None and epickS == mpickS:
|
||||
epickS -= timeerrorsS[0]
|
||||
epickS -= hdat.stats.delta
|
||||
if mpickS is not None and epickS is not None and lpickS is not None:
|
||||
lpickS = edat[0].stats.starttime + lpickS
|
||||
epickS = edat[0].stats.starttime + epickS
|
||||
mpickS = edat[0].stats.starttime + mpickS
|
||||
lpickS = hdat.stats.starttime + lpickS
|
||||
epickS = hdat.stats.starttime + epickS
|
||||
mpickS = hdat.stats.starttime + mpickS
|
||||
else:
|
||||
# dummy values (start of seismic trace) in order to derive
|
||||
# theoretical onset times for iteratve picking
|
||||
if edat:
|
||||
lpickS = edat[0].stats.starttime + timeerrorsS[3]
|
||||
epickS = edat[0].stats.starttime - timeerrorsS[3]
|
||||
mpickS = edat[0].stats.starttime
|
||||
elif ndat:
|
||||
lpickS = ndat[0].stats.starttime + timeerrorsS[3]
|
||||
epickS = ndat[0].stats.starttime - timeerrorsS[3]
|
||||
mpickS = ndat[0].stats.starttime
|
||||
else:
|
||||
return
|
||||
lpickS = hdat.stats.starttime + timeerrorsS[3]
|
||||
epickS = hdat.stats.starttime - timeerrorsS[3]
|
||||
mpickS = hdat.stats.starttime
|
||||
|
||||
# create dictionary
|
||||
# for P phase
|
||||
@ -1028,12 +1029,8 @@ def autopickstation(wfstream, pickparam, verbose=False,
|
||||
snrdb=SNRPdB, weight=Pweight, fm=FM, w0=None, fc=None, Mo=None,
|
||||
Mw=None, picker=picker, marked=Pmarker)
|
||||
# add S phase
|
||||
try:
|
||||
ccode = edat[0].stats.channel
|
||||
ncode = edat[0].stats.network
|
||||
except:
|
||||
ccode = ndat[0].stats.channel
|
||||
ncode = ndat[0].stats.network
|
||||
ccode = hdat.stats.channel
|
||||
ncode = hdat.stats.network
|
||||
spick = dict(channel=ccode, network=ncode, lpp=lpickS, epp=epickS, mpp=mpickS, spe=Serror, snr=SNRS,
|
||||
snrdb=SNRSdB, weight=Sweight, fm=None, picker=picker, Ao=Ao)
|
||||
# merge picks into returning dictionary
|
||||
|
@ -566,7 +566,7 @@ def select_for_phase(st, phase):
|
||||
return sel_st
|
||||
|
||||
|
||||
def wadaticheck(pickdic, dttolerance, iplot):
|
||||
def wadaticheck(pickdic, dttolerance, iplot=0, fig_dict=None):
|
||||
'''
|
||||
Function to calculate Wadati-diagram from given P and S onsets in order
|
||||
to detect S pick outliers. If a certain S-P time deviates by dttolerance
|
||||
@ -620,7 +620,7 @@ def wadaticheck(pickdic, dttolerance, iplot):
|
||||
ii = 0
|
||||
ibad = 0
|
||||
for key in pickdic:
|
||||
if pickdic[key].has_key('SPt'):
|
||||
if 'SPt' in pickdic[key]:
|
||||
wddiff = abs(pickdic[key]['SPt'] - wdfit[ii])
|
||||
ii += 1
|
||||
# check, if deviation is larger than adjusted
|
||||
@ -664,21 +664,28 @@ def wadaticheck(pickdic, dttolerance, iplot):
|
||||
|
||||
# plot results
|
||||
if iplot > 0:
|
||||
plt.figure() # iplot)
|
||||
f1, = plt.plot(Ppicks, SPtimes, 'ro')
|
||||
if wfitflag == 0:
|
||||
f2, = plt.plot(Ppicks, wdfit, 'k')
|
||||
f3, = plt.plot(checkedPpicks, checkedSPtimes, 'ko')
|
||||
f4, = plt.plot(checkedPpicks, wdfit2, 'g')
|
||||
plt.title('Wadati-Diagram, %d S-P Times, Vp/Vs(raw)=%5.2f,' \
|
||||
'Vp/Vs(checked)=%5.2f' % (len(SPtimes), vpvsr, cvpvsr))
|
||||
plt.legend([f1, f2, f3, f4], ['Skipped S-Picks', 'Wadati 1',
|
||||
'Reliable S-Picks', 'Wadati 2'], loc='best')
|
||||
if fig_dict:
|
||||
fig = fig_dict['wadati']
|
||||
plt_flag = 0
|
||||
else:
|
||||
plt.title('Wadati-Diagram, %d S-P Times' % len(SPtimes))
|
||||
fig = plt.figure()
|
||||
plt_flag = 1
|
||||
ax = fig.add_subplot(111)
|
||||
ax.plot(Ppicks, SPtimes, 'ro', label='Skipped S-Picks')
|
||||
if wfitflag == 0:
|
||||
ax.plot(Ppicks, wdfit, 'k', label='Wadati 1')
|
||||
ax.plot(checkedPpicks, checkedSPtimes, 'ko', label='Reliable S-Picks')
|
||||
ax.plot(checkedPpicks, wdfit2, 'g', label='Wadati 2')
|
||||
ax.set_title('Wadati-Diagram, %d S-P Times, Vp/Vs(raw)=%5.2f,' \
|
||||
'Vp/Vs(checked)=%5.2f' % (len(SPtimes), vpvsr, cvpvsr))
|
||||
ax.legend()
|
||||
else:
|
||||
ax.set_title('Wadati-Diagram, %d S-P Times' % len(SPtimes))
|
||||
|
||||
plt.ylabel('S-P Times [s]')
|
||||
plt.xlabel('P Times [s]')
|
||||
ax.set_ylabel('S-P Times [s]')
|
||||
ax.set_xlabel('P Times [s]')
|
||||
if plt_flag:
|
||||
fig.show()
|
||||
|
||||
return checkedonsets
|
||||
|
||||
@ -796,7 +803,7 @@ def checksignallength(X, pick, TSNR, minsiglength, nfac, minpercent, iplot=0, fi
|
||||
return returnflag
|
||||
|
||||
|
||||
def checkPonsets(pickdic, dttolerance, iplot):
|
||||
def checkPonsets(pickdic, dttolerance, iplot=0, fig_dict=None):
|
||||
'''
|
||||
Function to check statistics of P-onset times: Control deviation from
|
||||
median (maximum adjusted deviation = dttolerance) and apply pseudo-
|
||||
@ -818,17 +825,19 @@ def checkPonsets(pickdic, dttolerance, iplot):
|
||||
# search for good quality P picks
|
||||
Ppicks = []
|
||||
stations = []
|
||||
for key in pickdic:
|
||||
if pickdic[key]['P']['weight'] < 4:
|
||||
for station in pickdic:
|
||||
if pickdic[station]['P']['weight'] < 4:
|
||||
# add P onsets to list
|
||||
UTCPpick = UTCDateTime(pickdic[key]['P']['mpp'])
|
||||
UTCPpick = UTCDateTime(pickdic[station]['P']['mpp'])
|
||||
Ppicks.append(UTCPpick.timestamp)
|
||||
stations.append(key)
|
||||
stations.append(station)
|
||||
|
||||
# apply jackknife bootstrapping on variance of P onsets
|
||||
print("###############################################")
|
||||
print("checkPonsets: Apply jackknife bootstrapping on P-onset times ...")
|
||||
[xjack, PHI_pseudo, PHI_sub] = jackknife(Ppicks, 'VAR', 1)
|
||||
if not xjack:
|
||||
return
|
||||
# get pseudo variances smaller than average variances
|
||||
# (times safety factor), these picks passed jackknife test
|
||||
ij = np.where(PHI_pseudo <= 5 * xjack)
|
||||
@ -872,21 +881,30 @@ def checkPonsets(pickdic, dttolerance, iplot):
|
||||
checkedonsets = pickdic
|
||||
|
||||
if iplot > 0:
|
||||
p1, = plt.plot(np.arange(0, len(Ppicks)), Ppicks, 'ro', markersize=14)
|
||||
if len(badstations) < 1 and len(badjkstations) < 1:
|
||||
p2, = plt.plot(np.arange(0, len(Ppicks)), Ppicks, 'go', markersize=14)
|
||||
if fig_dict:
|
||||
fig = fig_dict['jackknife']
|
||||
plt_flag = 0
|
||||
else:
|
||||
p2, = plt.plot(igood, np.array(Ppicks)[igood], 'go', markersize=14)
|
||||
p3, = plt.plot([0, len(Ppicks) - 1], [pmedian, pmedian], 'g',
|
||||
linewidth=2)
|
||||
for i in range(0, len(Ppicks)):
|
||||
plt.text(i, Ppicks[i] + 0.01, '{0}'.format(stations[i]))
|
||||
fig = plt.figure()
|
||||
plt_flag = 1
|
||||
ax = fig.add_subplot(111)
|
||||
|
||||
plt.xlabel('Number of P Picks')
|
||||
plt.ylabel('Onset Time [s] from 1.1.1970')
|
||||
plt.legend([p1, p2, p3], ['Skipped P Picks', 'Good P Picks', 'Median'],
|
||||
loc='best')
|
||||
plt.title('Jackknifing and Median Tests on P Onsets')
|
||||
ax.plot(np.arange(0, len(Ppicks)), Ppicks, 'ro', markersize=14)
|
||||
if len(badstations) < 1 and len(badjkstations) < 1:
|
||||
ax.plot(np.arange(0, len(Ppicks)), Ppicks, 'go', markersize=14, label='Skipped P Picks')
|
||||
else:
|
||||
ax.plot(igood, np.array(Ppicks)[igood], 'go', markersize=14, label='Good P Picks')
|
||||
ax.plot([0, len(Ppicks) - 1], [pmedian, pmedian], 'g',
|
||||
linewidth=2, label='Median')
|
||||
for i in range(0, len(Ppicks)):
|
||||
ax.text(i, Ppicks[i] + 0.01, '{0}'.format(stations[i]))
|
||||
|
||||
ax.set_xlabel('Number of P Picks')
|
||||
ax.set_ylabel('Onset Time [s] from 1.1.1970')
|
||||
ax.legend()
|
||||
ax.set_title('Jackknifing and Median Tests on P Onsets')
|
||||
if plt_flag:
|
||||
fig.show()
|
||||
|
||||
return checkedonsets
|
||||
|
||||
@ -922,6 +940,7 @@ def jackknife(X, phi, h):
|
||||
print("Choose another size for subgroups!")
|
||||
return PHI_jack, PHI_pseudo, PHI_sub
|
||||
else:
|
||||
g = int(len(X) / h)
|
||||
# estimator of undisturbed spot check
|
||||
if phi == 'MEA':
|
||||
phi_sc = np.mean(X)
|
||||
@ -1100,7 +1119,7 @@ def checkZ4S(X, pick, zfac, checkwin, iplot, fig=None):
|
||||
return returnflag
|
||||
|
||||
|
||||
def getQualityfromUncertainty(uncertainty, Errors):
|
||||
def getQualityFromUncertainty(uncertainty, Errors):
|
||||
'''Script to transform uncertainty into quality classes 0-4
|
||||
regarding adjusted time errors Errors.
|
||||
'''
|
||||
|
@ -74,6 +74,37 @@ def gen_Pool(ncores=0):
|
||||
return pool
|
||||
|
||||
|
||||
def excludeQualityClasses(picks, qClasses, timeerrorsP, timeerrorsS):
|
||||
'''
|
||||
takes PyLoT picks dictionary and returns a new dictionary with certain classes excluded.
|
||||
:param picks: PyLoT picks dictionary
|
||||
:param qClasses: list (or int) of quality classes (0-4) to exclude
|
||||
:param timeerrorsP: time errors for classes (0-4) for P
|
||||
:param timeerrorsS: time errors for classes (0-4) for S
|
||||
:return: new picks dictionary
|
||||
'''
|
||||
from pylot.core.pick.utils import getQualityFromUncertainty
|
||||
|
||||
if type(qClasses) in [int, float]:
|
||||
qClasses = [qClasses]
|
||||
|
||||
picksdict_new = {}
|
||||
|
||||
phaseError = {'P': timeerrorsP,
|
||||
'S': timeerrorsS}
|
||||
|
||||
for station, phases in picks.items():
|
||||
for phase, pick in phases.items():
|
||||
pickerror = phaseError[identifyPhaseID(phase)]
|
||||
quality = getQualityFromUncertainty(pick['spe'], pickerror)
|
||||
if not quality in qClasses:
|
||||
if not station in picksdict_new:
|
||||
picksdict_new[station] = {}
|
||||
picksdict_new[station][phase] = pick
|
||||
|
||||
return picksdict_new
|
||||
|
||||
|
||||
def clims(lim1, lim2):
|
||||
"""
|
||||
takes two pairs of limits and returns one pair of common limts
|
||||
@ -897,6 +928,15 @@ def identifyPhase(phase):
|
||||
return False
|
||||
|
||||
|
||||
def identifyPhaseID(phase):
|
||||
return identifyPhase(loopIdentifyPhase(phase))
|
||||
|
||||
|
||||
def has_spe(pick):
|
||||
if not 'spe' in pick.keys():
|
||||
return None
|
||||
else:
|
||||
return pick['spe']
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
@ -12,6 +12,7 @@ import multiprocessing
|
||||
import os
|
||||
import subprocess
|
||||
import sys
|
||||
import time
|
||||
|
||||
import numpy as np
|
||||
|
||||
@ -22,7 +23,7 @@ except:
|
||||
|
||||
from matplotlib.figure import Figure
|
||||
from pylot.core.util.utils import find_horizontals, identifyPhase, loopIdentifyPhase, trim_station_components, \
|
||||
check4rotated
|
||||
identifyPhaseID
|
||||
|
||||
try:
|
||||
from matplotlib.backends.backend_qt4agg import FigureCanvas
|
||||
@ -45,7 +46,7 @@ from obspy.taup.utils import get_phase_names
|
||||
from pylot.core.io.data import Data
|
||||
from pylot.core.io.inputs import FilterOptions, PylotParameter
|
||||
from pylot.core.pick.utils import getSNR, earllatepicker, getnoisewin, \
|
||||
getResolutionWindow, getQualityfromUncertainty
|
||||
getResolutionWindow, getQualityFromUncertainty
|
||||
from pylot.core.pick.compare import Comparison
|
||||
from pylot.core.util.defaults import OUTPUTFORMATS, FILTERDEFAULTS, \
|
||||
SetChannelComponents
|
||||
@ -119,7 +120,7 @@ def createAction(parent, text, slot=None, shortcut=None, icon=None,
|
||||
return action
|
||||
|
||||
|
||||
class ComparisonDialog(QDialog):
|
||||
class ComparisonWidget(QWidget):
|
||||
def __init__(self, c, parent=None):
|
||||
self._data = c
|
||||
self._stats = c.stations
|
||||
@ -129,8 +130,9 @@ class ComparisonDialog(QDialog):
|
||||
histCheckBox=None)
|
||||
self._phases = 'PS'
|
||||
self._plotprops = dict(station=list(self.stations)[0], phase=list(self.phases)[0])
|
||||
super(ComparisonDialog, self).__init__(parent)
|
||||
super(ComparisonWidget, self).__init__(parent, 1)
|
||||
self.setupUI()
|
||||
self.resize(1280, 720)
|
||||
self.plotcomparison()
|
||||
|
||||
def setupUI(self):
|
||||
@ -162,17 +164,12 @@ class ComparisonDialog(QDialog):
|
||||
_toolbar.addWidget(_phases_combobox)
|
||||
_toolbar.addWidget(_hist_checkbox)
|
||||
|
||||
_buttonbox = QDialogButtonBox(QDialogButtonBox.Close)
|
||||
|
||||
_innerlayout.addWidget(self.canvas)
|
||||
_innerlayout.addWidget(_buttonbox)
|
||||
|
||||
_outerlayout.addWidget(_toolbar)
|
||||
_outerlayout.addLayout(_innerlayout)
|
||||
|
||||
_buttonbox.rejected.connect(self.reject)
|
||||
|
||||
# finally layout the entire dialog
|
||||
# finally layout the entire widget
|
||||
self.setLayout(_outerlayout)
|
||||
|
||||
@property
|
||||
@ -271,6 +268,10 @@ class ComparisonDialog(QDialog):
|
||||
# _axes.cla()
|
||||
station = self.plotprops['station']
|
||||
phase = self.plotprops['phase']
|
||||
if not phase in self.data.comparison[station]:
|
||||
_axes.set_title('No pick found for phase {}.'.format(phase))
|
||||
self.canvas.draw()
|
||||
return
|
||||
pdf = self.data.comparison[station][phase]
|
||||
x, y, std, exp = pdf.axis, pdf.data, pdf.standard_deviation(), \
|
||||
pdf.expectation()
|
||||
@ -1286,7 +1287,7 @@ class PickDlg(QDialog):
|
||||
self.currentPhase = str(self.s_button.text())
|
||||
|
||||
def getPhaseID(self, phase):
|
||||
return identifyPhase(loopIdentifyPhase(phase))
|
||||
return identifyPhaseID(phase)
|
||||
|
||||
def set_button_color(self, button, color=None):
|
||||
if type(color) == QtGui.QColor:
|
||||
@ -1700,7 +1701,7 @@ class PickDlg(QDialog):
|
||||
else:
|
||||
ylims = self.getPlotWidget().getYLims()
|
||||
if self.getPicks(picktype):
|
||||
if phase is not None:
|
||||
if phase is not None and not phase == 'SPt':
|
||||
if (type(self.getPicks(picktype)[phase]) is dict
|
||||
or type(self.getPicks(picktype)[phase]) is AttribDict):
|
||||
picks = self.getPicks(picktype)[phase]
|
||||
@ -1715,10 +1716,10 @@ class PickDlg(QDialog):
|
||||
|
||||
# get quality classes
|
||||
if self.getPhaseID(phase) == 'P':
|
||||
quality = getQualityfromUncertainty(picks['spe'], self.parameter['timeerrorsP'])
|
||||
quality = getQualityFromUncertainty(picks['spe'], self.parameter['timeerrorsP'])
|
||||
phaseID = 'P'
|
||||
elif self.getPhaseID(phase) == 'S':
|
||||
quality = getQualityfromUncertainty(picks['spe'], self.parameter['timeerrorsS'])
|
||||
quality = getQualityFromUncertainty(picks['spe'], self.parameter['timeerrorsS'])
|
||||
phaseID = 'S'
|
||||
|
||||
mpp = picks['mpp'] - self.getStartTime()
|
||||
@ -2011,6 +2012,167 @@ class PhasePlotWidget(FigureCanvas):
|
||||
super(PhasePlotWidget, self).__init__(self.fig)
|
||||
|
||||
|
||||
class CanvasWidget(QWidget):
|
||||
'''
|
||||
'''
|
||||
|
||||
def __init__(self, parent, canvas):
|
||||
QtGui.QWidget.__init__(self, parent)#, 1)
|
||||
self.main_layout = QtGui.QVBoxLayout()
|
||||
self.setLayout(self.main_layout)
|
||||
self.main_layout.addWidget(canvas)
|
||||
|
||||
|
||||
class AutoPickWidget(QWidget):
|
||||
start = Signal()
|
||||
'''
|
||||
'''
|
||||
|
||||
def __init__(self, parent, pickoptions):
|
||||
QtGui.QWidget.__init__(self, parent, 1)
|
||||
self.pickoptions = pickoptions
|
||||
self.setupUi()
|
||||
self.connect_buttons()
|
||||
self.reinitEvents2plot()
|
||||
self.setWindowTitle('Autopick events interactively')
|
||||
# set initial size
|
||||
self.resize(1280, 720)
|
||||
|
||||
def setupUi(self):
|
||||
# init main layout
|
||||
self.main_layout = QtGui.QVBoxLayout()
|
||||
self.setLayout(self.main_layout)
|
||||
# init main splitter
|
||||
self.main_splitter = QtGui.QSplitter()
|
||||
self.main_splitter.setChildrenCollapsible(False)
|
||||
|
||||
self.init_checkboxes()
|
||||
self.init_log_layout()
|
||||
self.init_plot_layout()
|
||||
|
||||
self.eventbox = QtGui.QComboBox()
|
||||
self.button_clear = QtGui.QPushButton('Clear')
|
||||
|
||||
self.main_layout.insertWidget(1, self.main_splitter)
|
||||
|
||||
self.main_layout.setStretch(0, 0)
|
||||
self.main_layout.setStretch(1, 1)
|
||||
self.main_splitter.setStretchFactor(0, 1)
|
||||
self.main_splitter.setStretchFactor(1, 2)
|
||||
|
||||
def connect_buttons(self):
|
||||
self.start_button.clicked.connect(self.start_picker)
|
||||
self.button_clear.clicked.connect(self.reinitEvents2plot)
|
||||
|
||||
def init_checkboxes(self):
|
||||
self.rb_layout = QtGui.QHBoxLayout()
|
||||
|
||||
self.rb_dict = {}
|
||||
|
||||
self.start_button = QtGui.QPushButton('Start')
|
||||
|
||||
for index, (key, func) in enumerate(self.pickoptions):
|
||||
rb = QtGui.QRadioButton(key)
|
||||
if index == 0:
|
||||
rb.setChecked(True)
|
||||
self.rb_dict[key] = rb
|
||||
self.rb_layout.insertWidget(index, rb)
|
||||
self.rb_layout.setStretch(index, 0)
|
||||
|
||||
self.rb_layout.addWidget(self.start_button)
|
||||
|
||||
self.rb_layout.addWidget(QtGui.QWidget())
|
||||
self.rb_layout.setStretch(len(self.pickoptions)+1, 1)
|
||||
|
||||
self.main_layout.insertLayout(0, self.rb_layout)
|
||||
|
||||
def init_plot_layout(self):
|
||||
# init tab widget
|
||||
self.tab_plots = QtGui.QTabWidget()
|
||||
self.gb_plots = QtGui.QGroupBox('Plots')
|
||||
self.gb_plots.setMinimumSize(100, 100)
|
||||
self.main_splitter.insertWidget(1, self.gb_plots)
|
||||
self.plot_layout = QtGui.QVBoxLayout()
|
||||
self.plot_layout.insertWidget(1, self.tab_plots)
|
||||
self.gb_plots.setLayout(self.plot_layout)
|
||||
|
||||
def init_log_layout(self):
|
||||
self.gb_log = QtGui.QGroupBox('Log')
|
||||
self.gb_log.setMinimumSize(100, 100)
|
||||
self.main_splitter.insertWidget(0, self.gb_log)
|
||||
|
||||
def insert_log_widget(self, widget):
|
||||
vl = QtGui.QVBoxLayout()
|
||||
vl.addWidget(widget)
|
||||
self.gb_log.setLayout(vl)
|
||||
|
||||
def add_plot_widget(self, widget, key, eventID):
|
||||
eventID += ' [picked: {}]'.format(time.strftime('%X %x %z'))
|
||||
if not eventID in self.events2plot.keys():
|
||||
self.events2plot[eventID] = {}
|
||||
self.events2plot[eventID][key] = widget
|
||||
|
||||
def generate_combobox(self):
|
||||
self.eventbox.clear()
|
||||
for eventID, widgets in self.events2plot.items():
|
||||
self.eventbox.addItem(str(eventID), widgets)
|
||||
self.eventbox.currentIndexChanged.connect(self.draw_plots)
|
||||
self.draw_plots()
|
||||
|
||||
def draw_plots(self, index=0):
|
||||
self.refresh_plot_tabs()
|
||||
widgets = self.eventbox.itemData(index)
|
||||
if not widgets:
|
||||
return
|
||||
for key, widget in widgets.items():
|
||||
self.tab_plots.addTab(widget, str(key))
|
||||
|
||||
def update_plots(self):
|
||||
self.refresh_plot_tabs()
|
||||
if len(self.events2plot) > 0:
|
||||
self.eventbox_layout = QtGui.QHBoxLayout()
|
||||
self.generate_combobox()
|
||||
self.eventbox_layout.addWidget(self.eventbox)
|
||||
self.eventbox_layout.addWidget(self.button_clear)
|
||||
self.eventbox_layout.setStretch(0, 1)
|
||||
self.plot_layout.insertLayout(0, self.eventbox_layout)
|
||||
|
||||
def reinitEvents2plot(self):
|
||||
self.events2plot = {}
|
||||
self.eventbox.clear()
|
||||
self.refresh_plot_tabs()
|
||||
|
||||
def refresh_plot_tabs(self):
|
||||
self.tab_plots.clear()
|
||||
|
||||
def refresh_tooltips(self):
|
||||
for key, func in self.pickoptions:
|
||||
eventlist = func()
|
||||
if not type(eventlist) == list:
|
||||
eventlist = [eventlist]
|
||||
tooltip=''
|
||||
for index, event in enumerate(eventlist):
|
||||
if not event:
|
||||
continue
|
||||
tooltip += '{}'.format(event.pylot_id)
|
||||
if not index + 1 == len(eventlist):
|
||||
tooltip += '\n'
|
||||
if not tooltip:
|
||||
tooltip = 'No events for this selection'
|
||||
self.rb_dict[key].setToolTip(tooltip)
|
||||
|
||||
def start_picker(self):
|
||||
self.refresh_plot_tabs()
|
||||
self.start.emit()
|
||||
|
||||
def enable(self, bool):
|
||||
for rb in self.rb_dict.values():
|
||||
rb.setEnabled(bool)
|
||||
self.start_button.setEnabled(bool)
|
||||
self.eventbox.setEnabled(bool)
|
||||
self.button_clear.setEnabled(bool)
|
||||
|
||||
|
||||
class TuneAutopicker(QWidget):
|
||||
update = QtCore.Signal(str)
|
||||
'''
|
||||
@ -2343,7 +2505,7 @@ class TuneAutopicker(QWidget):
|
||||
args = {'parameter': self.parameter,
|
||||
'station': station,
|
||||
'fnames': 'None',
|
||||
'eventid': self.get_current_event_fp(),
|
||||
'eventid': [self.get_current_event_fp()],
|
||||
'iplot': 2,
|
||||
'fig_dict': self.fig_dict,
|
||||
'locflag': 0,
|
||||
@ -2369,7 +2531,7 @@ class TuneAutopicker(QWidget):
|
||||
info = self.ap_thread._executedErrorInfo
|
||||
self._warn(msg, info)
|
||||
return
|
||||
self.pylot_picks = self.ap_thread.data
|
||||
self.pylot_picks = self.ap_thread.data[self.get_current_event_name()]
|
||||
if not self.pylot_picks:
|
||||
self._warn('No picks found. See terminal output.')
|
||||
return
|
||||
|
Loading…
x
Reference in New Issue
Block a user