Merge branch 'develop' of ariadne.geophysik.ruhr-uni-bochum.de:/data/git/pylot into develop

This commit is contained in:
Marcel Paffrath 2016-05-31 11:15:38 +02:00
commit e341994825
7 changed files with 239 additions and 166 deletions

View File

@ -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'
@ -50,7 +49,7 @@ from pylot.core.util.defaults import FILTERDEFAULTS, COMPNAME_MAP,\
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]

View 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

View File

@ -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

View File

@ -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

View File

@ -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()

View File

@ -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'}

View File

@ -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):
''' '''