Merge branch 'develop' of ariadne.geophysik.ruhr-uni-bochum.de:/data/git/pylot into develop
This commit is contained in:
commit
e341994825
183
QtPyLoT.py
183
QtPyLoT.py
@ -23,11 +23,10 @@ https://www.iconfinder.com/iconsets/flavour
|
|||||||
(http://www.gnu.org/copyleft/lesser.html)
|
(http://www.gnu.org/copyleft/lesser.html)
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
import matplotlib
|
||||||
import os
|
import os
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
import matplotlib
|
|
||||||
|
|
||||||
matplotlib.use('Qt4Agg')
|
matplotlib.use('Qt4Agg')
|
||||||
matplotlib.rcParams['backend.qt4'] = 'PySide'
|
matplotlib.rcParams['backend.qt4'] = 'PySide'
|
||||||
|
|
||||||
@ -45,12 +44,12 @@ from pylot.core.io.inputs import FilterOptions, AutoPickParameter
|
|||||||
from pylot.core.pick.autopick import autopickevent
|
from pylot.core.pick.autopick import autopickevent
|
||||||
from pylot.core.io.phases import picksdict_from_picks
|
from pylot.core.io.phases import picksdict_from_picks
|
||||||
from pylot.core.loc.nll import locate as locateNll
|
from pylot.core.loc.nll import locate as locateNll
|
||||||
from pylot.core.util.defaults import FILTERDEFAULTS, COMPNAME_MAP,\
|
from pylot.core.util.defaults import FILTERDEFAULTS, COMPNAME_MAP, \
|
||||||
AUTOMATIC_DEFAULTS
|
AUTOMATIC_DEFAULTS
|
||||||
from pylot.core.util.errors import FormatError, DatastructureError, \
|
from pylot.core.util.errors import FormatError, DatastructureError, \
|
||||||
OverwriteError
|
OverwriteError
|
||||||
from pylot.core.util.connection import checkurl
|
from pylot.core.util.connection import checkurl
|
||||||
from pylot.core.util.utils import fnConstructor, createEvent, getLogin, \
|
from pylot.core.util.utils import fnConstructor, getLogin, \
|
||||||
getGlobalTimes
|
getGlobalTimes
|
||||||
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, \
|
||||||
@ -81,8 +80,8 @@ class MainWindow(QMainWindow):
|
|||||||
"Enter authority name (e.g. BUG):",
|
"Enter authority name (e.g. BUG):",
|
||||||
"Authority")
|
"Authority")
|
||||||
settings.setValue("agency_id", agency)
|
settings.setValue("agency_id", agency)
|
||||||
self.recentEvents = settings.value("data/recentEvents", [])
|
self.recentfiles = settings.value("data/recentEvents", [])
|
||||||
self.fname = None
|
self.fname = dict(manual=None, auto=None, loc=None)
|
||||||
self.fnames = None
|
self.fnames = None
|
||||||
structure_setting = settings.value("data/Structure", "PILOT")
|
structure_setting = settings.value("data/Structure", "PILOT")
|
||||||
self.dataStructure = DATASTRUCTURE[structure_setting]()
|
self.dataStructure = DATASTRUCTURE[structure_setting]()
|
||||||
@ -104,7 +103,7 @@ class MainWindow(QMainWindow):
|
|||||||
self.setupUi()
|
self.setupUi()
|
||||||
|
|
||||||
# initialize event data
|
# initialize event data
|
||||||
if self.recentEvents:
|
if self.recentfiles:
|
||||||
lastEvent = self.getLastEvent()
|
lastEvent = self.getLastEvent()
|
||||||
self.data = Data(self, lastEvent)
|
self.data = Data(self, lastEvent)
|
||||||
else:
|
else:
|
||||||
@ -112,7 +111,7 @@ class MainWindow(QMainWindow):
|
|||||||
|
|
||||||
# load and display waveform data
|
# load and display waveform data
|
||||||
self.dirty = False
|
self.dirty = False
|
||||||
self.loadData()
|
self.load_data()
|
||||||
if self.loadWaveformData():
|
if self.loadWaveformData():
|
||||||
self.updateFilterOptions()
|
self.updateFilterOptions()
|
||||||
else:
|
else:
|
||||||
@ -149,7 +148,10 @@ class MainWindow(QMainWindow):
|
|||||||
lambda event: self.tutorUser())
|
lambda event: self.tutorUser())
|
||||||
_layout.addWidget(self.DataPlot)
|
_layout.addWidget(self.DataPlot)
|
||||||
|
|
||||||
openIcon = self.style().standardIcon(QStyle.SP_DirOpenIcon)
|
manupicksicon = self.style().standardIcon(QStyle.SP_DialogYesButton)
|
||||||
|
autopicksicon = self.style().standardIcon(QStyle.SP_DialogNoButton)
|
||||||
|
locactionicon = self.style().standardIcon(QStyle.SP_DirOpenIcon)
|
||||||
|
loadpiloticon = self.style().standardIcon(QStyle.SP_ComputerIcon)
|
||||||
quitIcon = self.style().standardIcon(QStyle.SP_MediaStop)
|
quitIcon = self.style().standardIcon(QStyle.SP_MediaStop)
|
||||||
saveIcon = self.style().standardIcon(QStyle.SP_DriveHDIcon)
|
saveIcon = self.style().standardIcon(QStyle.SP_DriveHDIcon)
|
||||||
helpIcon = self.style().standardIcon(QStyle.SP_DialogHelpButton)
|
helpIcon = self.style().standardIcon(QStyle.SP_DialogHelpButton)
|
||||||
@ -179,18 +181,40 @@ class MainWindow(QMainWindow):
|
|||||||
self.createNewEvent,
|
self.createNewEvent,
|
||||||
QKeySequence.New, newIcon,
|
QKeySequence.New, newIcon,
|
||||||
"Create a new event.")
|
"Create a new event.")
|
||||||
openEventAction = self.createAction(self, "&Open event ...",
|
openmanualpicksaction = self.createAction(self, "Load &picks ...",
|
||||||
self.loadData, QKeySequence.Open,
|
self.load_data,
|
||||||
openIcon, "Open an event.")
|
QKeySequence.Open,
|
||||||
openEventAction.setData(None)
|
manupicksicon,
|
||||||
|
"Load pick data for "
|
||||||
|
"the actual event.")
|
||||||
|
openmanualpicksaction.setData(None)
|
||||||
|
openautopicksaction = self.createAction(self, "Load &automatic picks "
|
||||||
|
"...",
|
||||||
|
self.load_autopicks,
|
||||||
|
"Ctrl+A",
|
||||||
|
autopicksicon,
|
||||||
|
"Load automatic pick data "
|
||||||
|
"for the actual event.")
|
||||||
|
openautopicksaction.setData(None)
|
||||||
|
|
||||||
|
loadlocationaction = self.createAction(self, "Load &location ...",
|
||||||
|
self.load_loc, "Ctrl+L",
|
||||||
|
locactionicon,
|
||||||
|
"Load location information on "
|
||||||
|
"the actual event.")
|
||||||
|
loadpilotevent = self.createAction(self, "Load PILOT &event ...",
|
||||||
|
self.load_pilotevent, "Ctrl+E",
|
||||||
|
loadpiloticon,
|
||||||
|
"Load PILOT event from information "
|
||||||
|
"Matlab binary collections.")
|
||||||
saveEventAction = self.createAction(self, "&Save event ...",
|
saveEventAction = self.createAction(self, "&Save event ...",
|
||||||
self.saveData, QKeySequence.Save,
|
self.saveData, QKeySequence.Save,
|
||||||
saveIcon, "Save actual event data.")
|
saveIcon, "Save actual event data.")
|
||||||
openWFDataAction = self.createAction(self, "Open &waveforms ...",
|
openWFDataAction = self.createAction(self, "Open &waveforms ...",
|
||||||
self.loadWaveformData,
|
self.loadWaveformData,
|
||||||
"Ctrl+W", QIcon(":/wfIcon.png"),
|
"Ctrl+W", QIcon(":/wfIcon.png"),
|
||||||
"""Open waveform data (event will
|
"Open waveform data (event will "
|
||||||
be closed).""")
|
"be closed)")
|
||||||
prefsEventAction = self.createAction(self, "Preferences",
|
prefsEventAction = self.createAction(self, "Preferences",
|
||||||
self.PyLoTprefs,
|
self.PyLoTprefs,
|
||||||
QKeySequence.Preferences,
|
QKeySequence.Preferences,
|
||||||
@ -228,7 +252,7 @@ class MainWindow(QMainWindow):
|
|||||||
homepage (internet connection available),
|
homepage (internet connection available),
|
||||||
or shipped documentation files.""")
|
or shipped documentation files.""")
|
||||||
self.fileMenu = self.menuBar().addMenu('&File')
|
self.fileMenu = self.menuBar().addMenu('&File')
|
||||||
self.fileMenuActions = (newEventAction, openEventAction,
|
self.fileMenuActions = (newEventAction, openmanualpicksaction,
|
||||||
saveEventAction, openWFDataAction, None,
|
saveEventAction, openWFDataAction, None,
|
||||||
prefsEventAction, quitAction)
|
prefsEventAction, quitAction)
|
||||||
self.fileMenu.aboutToShow.connect(self.updateFileMenu)
|
self.fileMenu.aboutToShow.connect(self.updateFileMenu)
|
||||||
@ -245,7 +269,9 @@ class MainWindow(QMainWindow):
|
|||||||
self.addActions(self.helpMenu, helpActions)
|
self.addActions(self.helpMenu, helpActions)
|
||||||
|
|
||||||
fileToolBar = self.addToolBar("FileTools")
|
fileToolBar = self.addToolBar("FileTools")
|
||||||
fileToolActions = (newEventAction, openEventAction, saveEventAction)
|
fileToolActions = (newEventAction, openmanualpicksaction,
|
||||||
|
openautopicksaction, loadlocationaction,
|
||||||
|
loadpilotevent, saveEventAction)
|
||||||
fileToolBar.setObjectName("FileTools")
|
fileToolBar.setObjectName("FileTools")
|
||||||
self.addActions(fileToolBar, fileToolActions)
|
self.addActions(fileToolBar, fileToolActions)
|
||||||
|
|
||||||
@ -299,8 +325,10 @@ class MainWindow(QMainWindow):
|
|||||||
# self.addActions(pickToolBar, pickToolActions)
|
# self.addActions(pickToolBar, pickToolActions)
|
||||||
|
|
||||||
locateEvent = self.createAction(parent=self, text='locateEvent',
|
locateEvent = self.createAction(parent=self, text='locateEvent',
|
||||||
slot=self.locateEvent, shortcut='Alt+Ctrl+L',
|
slot=self.locateEvent,
|
||||||
icon=locate_icon, tip='Locate the event using '
|
shortcut='Alt+Ctrl+L',
|
||||||
|
icon=locate_icon,
|
||||||
|
tip='Locate the event using '
|
||||||
'the picked arrivals.')
|
'the picked arrivals.')
|
||||||
|
|
||||||
locationToolBar = self.addToolBar("LocationTools")
|
locationToolBar = self.addToolBar("LocationTools")
|
||||||
@ -333,12 +361,12 @@ class MainWindow(QMainWindow):
|
|||||||
except AttributeError:
|
except AttributeError:
|
||||||
current = None
|
current = None
|
||||||
recentEvents = []
|
recentEvents = []
|
||||||
for eventID in self.recentEvents:
|
for eventID in self.recentfiles:
|
||||||
fname = fnConstructor(eventID)
|
fname = fnConstructor(eventID)
|
||||||
if eventID != current and QFile.exists(fname):
|
if eventID != current and QFile.exists(fname):
|
||||||
recentEvents.append(eventID)
|
recentEvents.append(eventID)
|
||||||
recentEvents.reverse()
|
recentEvents.reverse()
|
||||||
self.recentEvents = recentEvents[0:5]
|
self.recentfiles = recentEvents[0:5]
|
||||||
settings = QSettings()
|
settings = QSettings()
|
||||||
settings.setValue()
|
settings.setValue()
|
||||||
if recentEvents:
|
if recentEvents:
|
||||||
@ -350,7 +378,7 @@ class MainWindow(QMainWindow):
|
|||||||
self)
|
self)
|
||||||
action.setData(fname)
|
action.setData(fname)
|
||||||
self.connect(action, Signal("triggered()"),
|
self.connect(action, Signal("triggered()"),
|
||||||
self.loadData)
|
self.load_data)
|
||||||
self.fileMenu.addAction(action)
|
self.fileMenu.addAction(action)
|
||||||
self.fileMenu.addSeparator()
|
self.fileMenu.addSeparator()
|
||||||
self.fileMenu.addAction(self.fileMenuActions[-1])
|
self.fileMenu.addAction(self.fileMenuActions[-1])
|
||||||
@ -359,34 +387,54 @@ class MainWindow(QMainWindow):
|
|||||||
settings = QSettings()
|
settings = QSettings()
|
||||||
return settings.value("data/dataRoot")
|
return settings.value("data/dataRoot")
|
||||||
|
|
||||||
def loadAutoPicks(self):
|
def load_autopicks(self, fname=None):
|
||||||
self.loadData(type='auto')
|
self.load_data(fname, type='auto')
|
||||||
|
|
||||||
def loadData(self, fname=None, type='manual'):
|
def load_loc(self, fname=None):
|
||||||
|
self.load_data(fname, type='loc')
|
||||||
|
|
||||||
|
def load_pilotevent(self):
|
||||||
|
filt = "PILOT location files (*.mat)"
|
||||||
|
caption = "Select PILOT loaction file"
|
||||||
|
fn_loc = QFileDialog().getOpenFileName(self, caption=caption,
|
||||||
|
filter=filt, dir=self.getRoot())
|
||||||
|
fn_loc = fn_loc[0]
|
||||||
|
loc_dir = os.path.split(fn_loc)[0]
|
||||||
|
filt = "PILOT phases files (*.mat)"
|
||||||
|
caption = "Select PILOT phases file"
|
||||||
|
fn_phases = QFileDialog().getOpenFileName(self, caption=caption,
|
||||||
|
filter=filt, dir=loc_dir)
|
||||||
|
fn_phases = fn_phases[0]
|
||||||
|
type = QInputDialog().getItem(self, self.tr("Select phases type"),
|
||||||
|
self.tr("Type:"), [self.tr("manual"),
|
||||||
|
self.tr("automatic")])
|
||||||
|
|
||||||
|
if type[0].startswith('auto'):
|
||||||
|
type = 'auto'
|
||||||
|
else:
|
||||||
|
type = type[0]
|
||||||
|
|
||||||
|
fname_dict = dict(phasfn=fn_phases, locfn=fn_loc)
|
||||||
|
self.load_data(fname_dict, type=type)
|
||||||
|
|
||||||
|
def load_data(self, fname=None, type='manual'):
|
||||||
if not self.okToContinue():
|
if not self.okToContinue():
|
||||||
return
|
return
|
||||||
if fname is None:
|
if fname is None:
|
||||||
action = self.sender()
|
action = self.sender()
|
||||||
if isinstance(action, QAction):
|
if isinstance(action, QAction):
|
||||||
if action.data() is None:
|
fname = self.filename_from_action(action)
|
||||||
filt = "Supported event formats (*.mat *.qml *.xml *.kor *.evt)"
|
self.set_fname(fname, type)
|
||||||
caption = "Open an event file"
|
self.data += Data(self, evtdata=fname)
|
||||||
fname = QFileDialog().getOpenFileName(self,
|
if 'loc' not in type:
|
||||||
caption=caption,
|
|
||||||
filter=filt)
|
|
||||||
fname = fname[0]
|
|
||||||
else:
|
|
||||||
fname = str(action.data().toString())
|
|
||||||
self.setFileName(fname)
|
|
||||||
self.data += Data(self, evtdata=self.getFileName())
|
|
||||||
self.updatePicks(type=type)
|
self.updatePicks(type=type)
|
||||||
self.drawPicks()
|
self.drawPicks()
|
||||||
|
|
||||||
def getLastEvent(self):
|
def getLastEvent(self):
|
||||||
return self.recentEvents[0]
|
return self.recentfiles[0]
|
||||||
|
|
||||||
def addRecentEvent(self, event):
|
def add_recentfile(self, event):
|
||||||
self.recentEvents.insert(0, event)
|
self.recentfiles.insert(0, event)
|
||||||
|
|
||||||
def getWFFnames(self):
|
def getWFFnames(self):
|
||||||
try:
|
try:
|
||||||
@ -422,27 +470,44 @@ class MainWindow(QMainWindow):
|
|||||||
else:
|
else:
|
||||||
return
|
return
|
||||||
|
|
||||||
def getFileName(self):
|
def filename_from_action(self, action):
|
||||||
|
if action.data() is None:
|
||||||
|
filt = "Supported file formats" \
|
||||||
|
" (*.mat *.qml *.xml *.kor *.evt)"
|
||||||
|
caption = "Open an event file"
|
||||||
|
fname = QFileDialog().getOpenFileName(self,
|
||||||
|
caption=caption,
|
||||||
|
filter=filt)
|
||||||
|
fname = fname[0]
|
||||||
|
else:
|
||||||
|
fname = str(action.data().toString())
|
||||||
|
return fname
|
||||||
|
|
||||||
|
def get_fnames(self):
|
||||||
return self.fname
|
return self.fname
|
||||||
|
|
||||||
def setFileName(self, fname):
|
def set_fname(self, fname, type):
|
||||||
if self.getFileName() is not None:
|
if self.get_fnames()[type] is not None:
|
||||||
self.addRecentEvent(self.getFileName())
|
self.add_recentfile(self.get_fnames())
|
||||||
self.fname = fname
|
self.fname[type] = fname
|
||||||
|
|
||||||
def getEventFileName(self):
|
def getEventFileName(self):
|
||||||
if self.getFileName() is None:
|
if self.get_fnames() is None:
|
||||||
self.setFileName(self.getData().getEventFileName())
|
self.set_fname(self.getData().getEventFileName())
|
||||||
return self.getFileName()
|
return self.get_fnames()
|
||||||
|
|
||||||
def saveData(self):
|
def saveData(self):
|
||||||
|
|
||||||
def getSavePath(e):
|
def getSavePath(e):
|
||||||
print('warning: {0}'.format(e))
|
print('warning: {0}'.format(e))
|
||||||
directory = os.path.join(self.getRoot(), self.getEventFileName())
|
directory = os.path.join(self.getRoot(), self.getEventFileName())
|
||||||
file_filter = "QuakeML file (*.xml);;VELEST observation file format (*.cnv);;NonLinLoc observation file (*.obs)"
|
file_filter = "QuakeML file (*.xml);;VELEST observation file " \
|
||||||
fname, selected_filter = QFileDialog.getSaveFileName(self, 'Save event data ...',
|
"format (*.cnv);;NonLinLoc observation file (*.obs)"
|
||||||
directory, file_filter)
|
title = 'Save event data ...'
|
||||||
|
fname, selected_filter = QFileDialog.getSaveFileName(self,
|
||||||
|
title,
|
||||||
|
directory,
|
||||||
|
file_filter)
|
||||||
|
|
||||||
fbasename, exform = os.path.splitext(fname)
|
fbasename, exform = os.path.splitext(fname)
|
||||||
|
|
||||||
@ -459,7 +524,8 @@ class MainWindow(QMainWindow):
|
|||||||
except OverwriteError:
|
except OverwriteError:
|
||||||
msgBox = QMessageBox()
|
msgBox = QMessageBox()
|
||||||
msgBox.setText("Picks have been modified!")
|
msgBox.setText("Picks have been modified!")
|
||||||
msgBox.setInformativeText("Do you want to save the changes and overwrite the picks?")
|
msgBox.setInformativeText(
|
||||||
|
"Do you want to save the changes and overwrite the picks?")
|
||||||
msgBox.setDetailedText(self.getData().getPicksStr())
|
msgBox.setDetailedText(self.getData().getPicksStr())
|
||||||
msgBox.setStandardButtons(QMessageBox.Save | QMessageBox.Cancel)
|
msgBox.setStandardButtons(QMessageBox.Save | QMessageBox.Cancel)
|
||||||
msgBox.setDefaultButton(QMessageBox.Save)
|
msgBox.setDefaultButton(QMessageBox.Save)
|
||||||
@ -488,7 +554,9 @@ class MainWindow(QMainWindow):
|
|||||||
def setComponent(self, component):
|
def setComponent(self, component):
|
||||||
self.dispComponent = component
|
self.dispComponent = component
|
||||||
|
|
||||||
def getData(self):
|
def getData(self, type='manual'):
|
||||||
|
if type == 'auto':
|
||||||
|
return self.autodata
|
||||||
return self.data
|
return self.data
|
||||||
|
|
||||||
def getPicks(self, type='manual'):
|
def getPicks(self, type='manual'):
|
||||||
@ -687,7 +755,8 @@ class MainWindow(QMainWindow):
|
|||||||
self.setDirty(True)
|
self.setDirty(True)
|
||||||
self.logDockWidget = QDockWidget("AutoPickLog", self)
|
self.logDockWidget = QDockWidget("AutoPickLog", self)
|
||||||
self.logDockWidget.setObjectName("LogDockWidget")
|
self.logDockWidget.setObjectName("LogDockWidget")
|
||||||
self.logDockWidget.setAllowedAreas(Qt.LeftDockWidgetArea | Qt.RightDockWidgetArea)
|
self.logDockWidget.setAllowedAreas(
|
||||||
|
Qt.LeftDockWidgetArea | Qt.RightDockWidgetArea)
|
||||||
self.logDockWidget.setWidget(self.listWidget)
|
self.logDockWidget.setWidget(self.listWidget)
|
||||||
self.addDockWidget(Qt.LeftDockWidgetArea, self.logDockWidget)
|
self.addDockWidget(Qt.LeftDockWidgetArea, self.logDockWidget)
|
||||||
self.addListItem('loading default values for local data ...')
|
self.addListItem('loading default values for local data ...')
|
||||||
@ -736,7 +805,7 @@ class MainWindow(QMainWindow):
|
|||||||
return rval
|
return rval
|
||||||
|
|
||||||
def updatePicks(self, type='manual'):
|
def updatePicks(self, type='manual'):
|
||||||
picks = picksdict_from_picks(evt=self.getData().getEvtData())
|
picks = picksdict_from_picks(evt=self.getData(type).getEvtData())
|
||||||
if type == 'manual':
|
if type == 'manual':
|
||||||
self.picks.update(picks)
|
self.picks.update(picks)
|
||||||
elif type == 'auto':
|
elif type == 'auto':
|
||||||
@ -752,8 +821,10 @@ class MainWindow(QMainWindow):
|
|||||||
plotID = self.getStationID(station)
|
plotID = self.getStationID(station)
|
||||||
ax = self.getPlotWidget().axes
|
ax = self.getPlotWidget().axes
|
||||||
ylims = np.array([-.5, +.5]) + plotID
|
ylims = np.array([-.5, +.5]) + plotID
|
||||||
phase_col = {'P': ('c', 'c--', 'b-', 'bv', 'b^'),
|
phase_col = {
|
||||||
'S': ('m', 'm--', 'r-', 'rv', 'r^')}
|
'P': ('c', 'c--', 'b-', 'bv', 'b^'),
|
||||||
|
'S': ('m', 'm--', 'r-', 'rv', 'r^')
|
||||||
|
}
|
||||||
|
|
||||||
stat_picks = self.getPicks(type=picktype)[station]
|
stat_picks = self.getPicks(type=picktype)[station]
|
||||||
|
|
||||||
|
3
inputs/PILOT_TimeErrors.in
Normal file
3
inputs/PILOT_TimeErrors.in
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
## default time errors for old PILOT phases
|
||||||
|
0.04 0.08 0.16 0.32 #timeerrorsP# %discrete time errors [s] corresponding to picking weights [0 1 2 3] for P
|
||||||
|
0.04 0.08 0.16 0.32 #timeerrorsS# %discrete time errors [s] corresponding to picking weights [0 1 2 3] for S
|
@ -1,17 +1,17 @@
|
|||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
import os
|
|
||||||
import glob
|
import glob
|
||||||
|
import os
|
||||||
from obspy.io.xseed import Parser
|
|
||||||
from obspy.core import read, Stream, UTCDateTime
|
|
||||||
from obspy import read_events, read_inventory
|
from obspy import read_events, read_inventory
|
||||||
from obspy.core.event import Event, ResourceIdentifier, Pick, WaveformStreamID
|
from obspy.core import read, Stream, UTCDateTime
|
||||||
|
from obspy.core.event import Event
|
||||||
|
from obspy.io.xseed import Parser
|
||||||
|
|
||||||
from pylot.core.io.phases import readPILOTEvent, picks_from_picksdict
|
from pylot.core.io.phases import readPILOTEvent, picks_from_picksdict, \
|
||||||
from pylot.core.util.utils import fnConstructor, getGlobalTimes
|
picksdict_from_pilot
|
||||||
from pylot.core.util.errors import FormatError, OverwriteError
|
from pylot.core.util.errors import FormatError, OverwriteError
|
||||||
|
from pylot.core.util.utils import fnConstructor, getGlobalTimes
|
||||||
|
|
||||||
|
|
||||||
class Data(object):
|
class Data(object):
|
||||||
@ -36,17 +36,36 @@ class Data(object):
|
|||||||
self.wfdata = Stream()
|
self.wfdata = Stream()
|
||||||
self._new = False
|
self._new = False
|
||||||
if isinstance(evtdata, Event):
|
if isinstance(evtdata, Event):
|
||||||
self.evtdata = evtdata
|
pass
|
||||||
elif isinstance(evtdata, dict):
|
elif isinstance(evtdata, dict):
|
||||||
evt = readPILOTEvent(**evtdata)
|
evt = readPILOTEvent(**evtdata)
|
||||||
self.evtdata = evt
|
evtdata = evt
|
||||||
elif evtdata:
|
elif isinstance(evtdata, str):
|
||||||
|
try:
|
||||||
cat = read_events(evtdata)
|
cat = read_events(evtdata)
|
||||||
self.evtdata = cat[0]
|
if len(cat) is not 1:
|
||||||
|
raise ValueError('ambiguous event information for file: '
|
||||||
|
'{file}'.format(file=evtdata))
|
||||||
|
evtdata = cat[0]
|
||||||
|
except TypeError as e:
|
||||||
|
if 'Unknown format for file' in e.message:
|
||||||
|
if 'PHASES' in evtdata:
|
||||||
|
picks = picksdict_from_pilot(evtdata)
|
||||||
|
evtdata = Event()
|
||||||
|
evtdata.picks = picks_from_picksdict(picks)
|
||||||
|
elif 'LOC' in evtdata:
|
||||||
|
raise NotImplementedError('PILOT location information '
|
||||||
|
'read support not yet '
|
||||||
|
'implemeted.')
|
||||||
|
else:
|
||||||
|
raise e
|
||||||
|
else:
|
||||||
|
raise e
|
||||||
else: # create an empty Event object
|
else: # create an empty Event object
|
||||||
self.setNew()
|
self.setNew()
|
||||||
self.evtdata = Event()
|
evtdata = Event()
|
||||||
self.getEvtData().picks = []
|
evtdata.picks = []
|
||||||
|
self.evtdata = evtdata
|
||||||
self.wforiginal = None
|
self.wforiginal = None
|
||||||
self.cuttimes = None
|
self.cuttimes = None
|
||||||
self.dirty = False
|
self.dirty = False
|
||||||
|
@ -68,8 +68,8 @@ def create_creation_info(agency_id=None, creation_time=None, author=None):
|
|||||||
creation_time=creation_time)
|
creation_time=creation_time)
|
||||||
|
|
||||||
|
|
||||||
def create_event(origintime, cinfo, originloc=None, etype=None, resID=None,
|
def create_event(origintime, cinfo, originloc=None, etype='earthquake',
|
||||||
authority_id=None):
|
resID=None, authority_id=None):
|
||||||
'''
|
'''
|
||||||
create_event - funtion to create an ObsPy Event
|
create_event - funtion to create an ObsPy Event
|
||||||
|
|
||||||
@ -90,14 +90,12 @@ def create_event(origintime, cinfo, originloc=None, etype=None, resID=None,
|
|||||||
:type authority_id: str
|
:type authority_id: str
|
||||||
:return: An ObsPy :class: `~obspy.core.event.Event` object
|
:return: An ObsPy :class: `~obspy.core.event.Event` object
|
||||||
'''
|
'''
|
||||||
etype = ope.EventType(etype)
|
|
||||||
if originloc is not None:
|
if originloc is not None:
|
||||||
o = create_origin(origintime, cinfo,
|
o = create_origin(origintime, cinfo,
|
||||||
originloc[0], originloc[1], originloc[2])
|
originloc[0], originloc[1], originloc[2])
|
||||||
else:
|
else:
|
||||||
o = None
|
o = None
|
||||||
if etype is None:
|
|
||||||
etype = ope.EventType('earthquake') # defaults to 'earthquake'
|
|
||||||
if not resID:
|
if not resID:
|
||||||
resID = create_resourceID(origintime, etype, authority_id)
|
resID = create_resourceID(origintime, etype, authority_id)
|
||||||
elif isinstance(resID, str):
|
elif isinstance(resID, str):
|
||||||
@ -216,7 +214,7 @@ def create_resourceID(timetohash, restype, authority_id=None, hrstr=None):
|
|||||||
if hrstr is None:
|
if hrstr is None:
|
||||||
resID = ope.ResourceIdentifier(restype + '/' + hid[0:6])
|
resID = ope.ResourceIdentifier(restype + '/' + hid[0:6])
|
||||||
else:
|
else:
|
||||||
resID = ope.ResourceIdentifier(restype + '/' + hrstr + '_' + hid[0:6])
|
resID = ope.ResourceIdentifier(restype + '/' + hrstr)
|
||||||
if authority_id is not None:
|
if authority_id is not None:
|
||||||
resID.convertIDToQuakeMLURI(authority_id=authority_id)
|
resID.convertIDToQuakeMLURI(authority_id=authority_id)
|
||||||
return resID
|
return resID
|
@ -8,13 +8,14 @@ import scipy.io as sio
|
|||||||
import warnings
|
import warnings
|
||||||
from obspy.core import UTCDateTime
|
from obspy.core import UTCDateTime
|
||||||
|
|
||||||
|
from pylot.core.io.inputs import AutoPickParameter
|
||||||
from pylot.core.io.location import create_arrival, create_event, \
|
from pylot.core.io.location import create_arrival, create_event, \
|
||||||
create_magnitude, create_origin, create_pick
|
create_magnitude, create_origin, create_pick
|
||||||
from pylot.core.pick.utils import select_for_phase
|
from pylot.core.pick.utils import select_for_phase
|
||||||
from pylot.core.util.utils import getOwner, getGlobalTimes
|
from pylot.core.util.utils import getOwner, getGlobalTimes, four_digits
|
||||||
|
|
||||||
|
|
||||||
def readPILOTEvent(phasfn=None, locfn=None, authority_id=None, **kwargs):
|
def readPILOTEvent(phasfn=None, locfn=None, authority_id='RUB', **kwargs):
|
||||||
"""
|
"""
|
||||||
readPILOTEvent - function
|
readPILOTEvent - function
|
||||||
|
|
||||||
@ -30,7 +31,6 @@ def readPILOTEvent(phasfn=None, locfn=None, authority_id=None, **kwargs):
|
|||||||
:param locfn: filename of the old PILOT Matlab LOC file
|
:param locfn: filename of the old PILOT Matlab LOC file
|
||||||
:return event: event object containing event and phase information
|
:return event: event object containing event and phase information
|
||||||
"""
|
"""
|
||||||
sdir = os.path.split(phasfn)[0]
|
|
||||||
if phasfn is not None and os.path.isfile(phasfn):
|
if phasfn is not None and os.path.isfile(phasfn):
|
||||||
phases = sio.loadmat(phasfn)
|
phases = sio.loadmat(phasfn)
|
||||||
phasctime = UTCDateTime(os.path.getmtime(phasfn))
|
phasctime = UTCDateTime(os.path.getmtime(phasfn))
|
||||||
@ -53,9 +53,8 @@ def readPILOTEvent(phasfn=None, locfn=None, authority_id=None, **kwargs):
|
|||||||
loccinfo = ope.CreationInfo(agency_id=authority_id,
|
loccinfo = ope.CreationInfo(agency_id=authority_id,
|
||||||
author=locauthor,
|
author=locauthor,
|
||||||
creation_time=locctime)
|
creation_time=locctime)
|
||||||
np = 0
|
|
||||||
try:
|
eventNum = str(loc['ID'][0])
|
||||||
eventNum = loc['ID'][0]
|
|
||||||
|
|
||||||
# retrieve eventID for the actual database
|
# retrieve eventID for the actual database
|
||||||
idsplit = eventNum.split('.')
|
idsplit = eventNum.split('.')
|
||||||
@ -67,82 +66,42 @@ def readPILOTEvent(phasfn=None, locfn=None, authority_id=None, **kwargs):
|
|||||||
minute = int(loc['mm'])
|
minute = int(loc['mm'])
|
||||||
second = int(loc['ss'])
|
second = int(loc['ss'])
|
||||||
|
|
||||||
if year + 2000 < UTCDateTime.utcnow().year:
|
year = four_digits(year)
|
||||||
year += 2000
|
|
||||||
else:
|
|
||||||
year += 1900
|
|
||||||
|
|
||||||
eventDate = UTCDateTime(year=year, julday=julday, hour=hour,
|
eventDate = UTCDateTime(year=year, julday=julday, hour=hour,
|
||||||
minute=minute, second=second)
|
minute=minute, second=second)
|
||||||
|
|
||||||
stations = [stat for stat in phases['stat'][0:-1:3]]
|
stations = [stat for stat in phases['stat'][0:-1:3]]
|
||||||
|
|
||||||
event = create_event(eventDate, loccinfo, etype='earthquake', resID=eventNum,
|
|
||||||
authority_id=authority_id)
|
|
||||||
|
|
||||||
lat = float(loc['LAT'])
|
lat = float(loc['LAT'])
|
||||||
lon = float(loc['LON'])
|
lon = float(loc['LON'])
|
||||||
dep = float(loc['DEP'])
|
dep = float(loc['DEP'])
|
||||||
|
|
||||||
origin = create_origin(eventDate, loccinfo, lat, lon, dep)
|
event = create_event(eventDate, loccinfo, originloc=(lat, lon, dep),
|
||||||
for n, pick in enumerate(phases['Ptime']):
|
etype='earthquake', resID=eventNum,
|
||||||
if pick[0] > 0:
|
authority_id=authority_id)
|
||||||
kwargs = {'year': int(pick[0]),
|
|
||||||
'month': int(pick[1]),
|
|
||||||
'day': int(pick[2]),
|
|
||||||
'hour': int(pick[3]),
|
|
||||||
'minute': int(pick[4]),
|
|
||||||
'second': int(str(pick[5]).split('.')[0]),
|
|
||||||
'microsecond': int(str(pick[5]).split('.')[1][0:6])}
|
|
||||||
spick = phases['Stime'][n]
|
|
||||||
if spick[0] > 0:
|
|
||||||
skwargs = {'year': int(spick[0]),
|
|
||||||
'month': int(spick[1]),
|
|
||||||
'day': int(spick[2]),
|
|
||||||
'hour': int(spick[3]),
|
|
||||||
'minute': int(spick[4]),
|
|
||||||
'second': int(str(spick[5]).split('.')[0]),
|
|
||||||
'microsecond': int(str(spick[5]).split('.')[1][0:6])}
|
|
||||||
spicktime = UTCDateTime(**skwargs)
|
|
||||||
else:
|
|
||||||
spicktime = None
|
|
||||||
ppicktime = UTCDateTime(**kwargs)
|
|
||||||
|
|
||||||
for picktime, phase in [(ppicktime, 'P'), (spicktime, 'S')]:
|
picks = picksdict_from_pilot(phasfn)
|
||||||
if picktime is not None:
|
|
||||||
if phase == 'P':
|
|
||||||
wffn = os.path.join(sdir, '{0}*{1}*'.format(
|
|
||||||
stations[n].strip(), 'z'))
|
|
||||||
else:
|
|
||||||
wffn = os.path.join(sdir, '{0}*{1}*'.format(
|
|
||||||
stations[n].strip(), '[ne]'))
|
|
||||||
print(wffn)
|
|
||||||
pick = create_pick(eventDate, np, picktime, eventNum, pickcinfo,
|
|
||||||
phase, stations[n], wffn, authority_id)
|
|
||||||
event.picks.append(pick)
|
|
||||||
pickID = pick.get('id')
|
|
||||||
arrival = create_arrival(pickID, pickcinfo, phase)
|
|
||||||
origin.arrivals.append(arrival)
|
|
||||||
np += 1
|
|
||||||
|
|
||||||
|
event.picks = picks_from_picksdict(picks, creation_info=pickcinfo)
|
||||||
|
|
||||||
|
if event.origins:
|
||||||
|
origin = event.origins[0]
|
||||||
magnitude = create_magnitude(origin.get('id'), loccinfo)
|
magnitude = create_magnitude(origin.get('id'), loccinfo)
|
||||||
magnitude.mag = float(loc['Mnet'])
|
magnitude.mag = float(loc['Mnet'])
|
||||||
magnitude.magnitude_type = 'Ml'
|
magnitude.magnitude_type = 'Ml'
|
||||||
|
|
||||||
event.picks.append(pick)
|
|
||||||
event.origins.append(origin)
|
|
||||||
event.magnitudes.append(magnitude)
|
event.magnitudes.append(magnitude)
|
||||||
return event
|
return event
|
||||||
|
|
||||||
except AttributeError as e:
|
|
||||||
raise AttributeError('{0} - Matlab LOC files {1} and {2} contains \
|
|
||||||
insufficient data!'.format(e, phasfn, locfn))
|
|
||||||
|
|
||||||
|
def picksdict_from_pilot(fn):
|
||||||
def picks_from_pilot(fn):
|
from pylot.core.util.defaults import TIMEERROR_DEFAULTS
|
||||||
picks = dict()
|
picks = dict()
|
||||||
phases_pilot = sio.loadmat(fn)
|
phases_pilot = sio.loadmat(fn)
|
||||||
stations = stations_from_pilot(phases_pilot['stat'])
|
stations = stations_from_pilot(phases_pilot['stat'])
|
||||||
|
params = AutoPickParameter(TIMEERROR_DEFAULTS)
|
||||||
|
timeerrors = dict(P=params.get('timeerrorsP'),
|
||||||
|
S=params.get('timeerrorsS'))
|
||||||
for n, station in enumerate(stations):
|
for n, station in enumerate(stations):
|
||||||
phases = dict()
|
phases = dict()
|
||||||
for onset_name in 'PS':
|
for onset_name in 'PS':
|
||||||
@ -151,7 +110,14 @@ def picks_from_pilot(fn):
|
|||||||
if not pick[0]:
|
if not pick[0]:
|
||||||
continue
|
continue
|
||||||
pick = convert_pilot_times(pick)
|
pick = convert_pilot_times(pick)
|
||||||
phases[onset_name] = dict(mpp=pick)
|
uncertainty_label = '{0}weight'.format(onset_name.lower())
|
||||||
|
ierror = phases_pilot[uncertainty_label][0, n]
|
||||||
|
try:
|
||||||
|
spe = timeerrors[onset_name][ierror]
|
||||||
|
except IndexError as e:
|
||||||
|
print(e.message + '\ntake two times the largest default error value')
|
||||||
|
spe = timeerrors[onset_name][-1] * 2
|
||||||
|
phases[onset_name] = dict(mpp=pick, spe=spe)
|
||||||
picks[station] = phases
|
picks[station] = phases
|
||||||
|
|
||||||
return picks
|
return picks
|
||||||
@ -231,27 +197,31 @@ def picksdict_from_picks(evt):
|
|||||||
picks[station] = onsets.copy()
|
picks[station] = onsets.copy()
|
||||||
return picks
|
return picks
|
||||||
|
|
||||||
def picks_from_picksdict(picks):
|
def picks_from_picksdict(picks, creation_info=None):
|
||||||
picks_list = list()
|
picks_list = list()
|
||||||
for station, onsets in picks.items():
|
for station, onsets in picks.items():
|
||||||
#print('Reading picks on station %s' % station)
|
|
||||||
for label, phase in onsets.items():
|
for label, phase in onsets.items():
|
||||||
if not isinstance(phase, dict) or len(phase) < 3:
|
if not isinstance(phase, dict):
|
||||||
continue
|
continue
|
||||||
onset = phase['mpp']
|
onset = phase['mpp']
|
||||||
|
pick = ope.Pick()
|
||||||
|
if creation_info:
|
||||||
|
pick.creation_info = creation_info
|
||||||
|
pick.time = onset
|
||||||
|
error = phase['spe']
|
||||||
|
pick.time_errors.uncertainty = error
|
||||||
|
try:
|
||||||
epp = phase['epp']
|
epp = phase['epp']
|
||||||
lpp = phase['lpp']
|
lpp = phase['lpp']
|
||||||
error = phase['spe']
|
pick.time_errors.lower_uncertainty = onset - epp
|
||||||
|
pick.time_errors.upper_uncertainty = lpp - onset
|
||||||
|
except KeyError as e:
|
||||||
|
warnings.warn(e.message, RuntimeWarning)
|
||||||
try:
|
try:
|
||||||
picker = phase['picker']
|
picker = phase['picker']
|
||||||
except KeyError as e:
|
except KeyError as e:
|
||||||
warnings.warn(str(e), Warning)
|
warnings.warn(e.message, RuntimeWarning)
|
||||||
picker = 'Unknown'
|
picker = 'Unknown'
|
||||||
pick = ope.Pick()
|
|
||||||
pick.time = onset
|
|
||||||
pick.time_errors.lower_uncertainty = onset - epp
|
|
||||||
pick.time_errors.upper_uncertainty = lpp - onset
|
|
||||||
pick.time_errors.uncertainty = error
|
|
||||||
pick.phase_hint = label
|
pick.phase_hint = label
|
||||||
pick.method_id = ope.ResourceIdentifier(id=picker)
|
pick.method_id = ope.ResourceIdentifier(id=picker)
|
||||||
pick.waveform_id = ope.WaveformStreamID(station_code=station)
|
pick.waveform_id = ope.WaveformStreamID(station_code=station)
|
||||||
@ -303,7 +273,7 @@ def reassess_pilot_event(root_dir, db_dir, event_id, out_dir=None, fn_param=None
|
|||||||
return
|
return
|
||||||
if verbosity > 1:
|
if verbosity > 1:
|
||||||
print('Opening PILOT phases file: {fn}'.format(fn=phases_file[0]))
|
print('Opening PILOT phases file: {fn}'.format(fn=phases_file[0]))
|
||||||
picks_dict = picks_from_pilot(phases_file[0])
|
picks_dict = picksdict_from_pilot(phases_file[0])
|
||||||
if verbosity > 0:
|
if verbosity > 0:
|
||||||
print('Dictionary read from PHASES.mat:\n{0}'.format(picks_dict))
|
print('Dictionary read from PHASES.mat:\n{0}'.format(picks_dict))
|
||||||
datacheck = list()
|
datacheck = list()
|
||||||
|
@ -47,6 +47,10 @@ AUTOMATIC_DEFAULTS = os.path.join(os.path.expanduser('~'),
|
|||||||
'.pylot',
|
'.pylot',
|
||||||
'autoPyLoT.in')
|
'autoPyLoT.in')
|
||||||
|
|
||||||
|
TIMEERROR_DEFAULTS = os.path.join(os.path.expanduser('~'),
|
||||||
|
'.pylot',
|
||||||
|
'PILOT_TimeErrors.in')
|
||||||
|
|
||||||
OUTPUTFORMATS = {'.xml': 'QUAKEML',
|
OUTPUTFORMATS = {'.xml': 'QUAKEML',
|
||||||
'.cnv': 'CNV',
|
'.cnv': 'CNV',
|
||||||
'.obs': 'NLLOC_OBS'}
|
'.obs': 'NLLOC_OBS'}
|
||||||
|
@ -22,8 +22,8 @@ def worker(func, input, cores='max', async=False):
|
|||||||
|
|
||||||
if cores == 'max':
|
if cores == 'max':
|
||||||
cores = multiprocessing.cpu_count()
|
cores = multiprocessing.cpu_count()
|
||||||
pool = multiprocessing.Pool(cores)
|
|
||||||
|
|
||||||
|
pool = multiprocessing.Pool(cores)
|
||||||
if async == True:
|
if async == True:
|
||||||
result = pool.map_async(func, input)
|
result = pool.map_async(func, input)
|
||||||
else:
|
else:
|
||||||
@ -93,6 +93,14 @@ def fnConstructor(s):
|
|||||||
return fn
|
return fn
|
||||||
|
|
||||||
|
|
||||||
|
def four_digits(year):
|
||||||
|
if year + 2000 < UTCDateTime.utcnow().year:
|
||||||
|
year += 2000
|
||||||
|
else:
|
||||||
|
year += 1900
|
||||||
|
return year
|
||||||
|
|
||||||
|
|
||||||
def getGlobalTimes(stream):
|
def getGlobalTimes(stream):
|
||||||
'''
|
'''
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user