Merge branch 'export-and-save-picks' into develop

This commit is contained in:
Sebastian Wehling-Benatelli 2015-07-18 16:13:37 +02:00
commit 0b02e8c213
3 changed files with 87 additions and 45 deletions

View File

@ -23,7 +23,7 @@ https://www.iconfinder.com/iconsets/flavour
(http://www.gnu.org/copyleft/lesser.html) (http://www.gnu.org/copyleft/lesser.html)
""" """
import sys import os, sys
import matplotlib import matplotlib
matplotlib.use('Qt4Agg') matplotlib.use('Qt4Agg')
@ -64,7 +64,6 @@ class MainWindow(QMainWindow):
super(MainWindow, self).__init__(parent) super(MainWindow, self).__init__(parent)
self.createAction = createAction self.createAction = createAction
self.dirty = False
settings = QSettings() settings = QSettings()
if settings.value("user/FullName", None) is None: if settings.value("user/FullName", None) is None:
fulluser = QInputDialog.getText(self, "Enter Name:", "Full name") fulluser = QInputDialog.getText(self, "Enter Name:", "Full name")
@ -102,8 +101,8 @@ class MainWindow(QMainWindow):
self.data = Data(self) self.data = Data(self)
# load and display waveform data # load and display waveform data
self.loadWaveformData()
self.dirty = False self.dirty = False
self.loadWaveformData()
self.loadData() self.loadData()
self.updateFilterOptions() self.updateFilterOptions()
@ -333,6 +332,10 @@ class MainWindow(QMainWindow):
self.fileMenu.addSeparator() self.fileMenu.addSeparator()
self.fileMenu.addAction(self.fileMenuActions[-1]) self.fileMenu.addAction(self.fileMenuActions[-1])
def getRoot(self):
settings = QSettings()
return settings.value("data/dataRoot")
def loadData(self, fname=None): def loadData(self, fname=None):
if fname is None: if fname is None:
try: try:
@ -390,18 +393,27 @@ class MainWindow(QMainWindow):
else: else:
return return
def getEventFileName(self):
return self.getData().getEventFileName()
def saveData(self): def saveData(self):
settings = QSettings() settings = QSettings()
exform = settings.value('data/exportFormat', 'QUAKEML') exform = settings.value('data/exportFormat', 'QUAKEML')
self.getData().applyEVTData(self.getPicks())
try: try:
self.data.exportEvent(self.fname, exform) self.getData().exportEvent(self.fname, exform)
except FormatError: except FormatError:
return False return False
except AttributeError, e: except AttributeError, e:
print 'warning: {0}'.format(e) print 'warning: {0}'.format(e)
fname = QFileDialog.getSaveFileName(self, 'Save event') directory = os.path.join(self.getRoot(), self.getEventFileName())
fname = fname[0] file_filter = "Seismic observation files (*.cnv *.obs *.xml)"
self.getData().exportEvent(fname, exform) fname = QFileDialog.getSaveFileName(self, 'Save event data ...',
directory, file_filter)
fbasename, exform = os.path.splitext(fname[0])
if not fbasename:
return False
self.getData().exportEvent(fbasename, exform)
return True return True
def getComponent(self): def getComponent(self):
@ -455,7 +467,7 @@ class MainWindow(QMainWindow):
def loadWaveformData(self): def loadWaveformData(self):
if self.fnames and self.okToContinue(): if self.fnames and self.okToContinue():
self.dirty = True self.setDirty(True)
self.data.setWFData(self.fnames) self.data.setWFData(self.fnames)
elif self.fnames is None and self.okToContinue(): elif self.fnames is None and self.okToContinue():
self.data.setWFData(self.getWFFnames()) self.data.setWFData(self.getWFFnames())
@ -585,6 +597,7 @@ class MainWindow(QMainWindow):
station=station, station=station,
picks=self.getPicksOnStation(station)) picks=self.getPicksOnStation(station))
if pickDlg.exec_(): if pickDlg.exec_():
self.setDirty(True)
self.updateStatus('picks accepted ({0})'.format(station)) self.updateStatus('picks accepted ({0})'.format(station))
self.addPicks(station, pickDlg.getPicks()) self.addPicks(station, pickDlg.getPicks())
self.drawPicks(station) self.drawPicks(station)
@ -593,6 +606,7 @@ class MainWindow(QMainWindow):
def autoPick(self): def autoPick(self):
list = QListWidget() list = QListWidget()
self.setDirty(True)
logDockWidget = QDockWidget("AutoPickLog", self) logDockWidget = QDockWidget("AutoPickLog", self)
logDockWidget.setObjectName("LogDockWidget") logDockWidget.setObjectName("LogDockWidget")
logDockWidget.setAllowedAreas(Qt.LeftDockWidgetArea) logDockWidget.setAllowedAreas(Qt.LeftDockWidgetArea)
@ -700,11 +714,14 @@ class MainWindow(QMainWindow):
cinfo = createCreationInfo(agency_id=self.agency) cinfo = createCreationInfo(agency_id=self.agency)
event = createEvent(evtpar['origintime'], cinfo) event = createEvent(evtpar['origintime'], cinfo)
self.data = Data(self, evtdata=event) self.data = Data(self, evtdata=event)
self.dirty = True self.setDirty(True)
def draw(self): def draw(self):
self.getPlotWidget().draw() self.getPlotWidget().draw()
def setDirty(self, value):
self.dirty = value
def closeEvent(self, event): def closeEvent(self, event):
if self.okToContinue(): if self.okToContinue():
self.closing.emit() self.closing.emit()

View File

@ -3,9 +3,9 @@
import os import os
from obspy.core import (read, Stream, UTCDateTime) from obspy.core import read, Stream, UTCDateTime
from obspy import readEvents, read_inventory from obspy import readEvents, read_inventory
from obspy.core.event import (Event, Catalog) from obspy.core.event import Event, ResourceIdentifier, Pick, WaveformStreamID
from pylot.core.read.io import readPILOTEvent from pylot.core.read.io import readPILOTEvent
from pylot.core.util.utils import fnConstructor, getGlobalTimes from pylot.core.util.utils import fnConstructor, getGlobalTimes
@ -46,6 +46,7 @@ class Data(object):
else: # create an empty Event object else: # create an empty Event object
self.newevent = True self.newevent = True
self.evtdata = Event() self.evtdata = Event()
self.getEvtData().picks = []
self.wforiginal = None self.wforiginal = None
self.cuttimes = None self.cuttimes = None
self.dirty = False self.dirty = False
@ -67,29 +68,25 @@ class Data(object):
def updateCutTimes(self): def updateCutTimes(self):
self.cuttimes = getGlobalTimes(self.getWFData()) self.cuttimes = getGlobalTimes(self.getWFData())
def exportEvent(self, fnout=None, evtformat='QUAKEML'): def getEventFileName(self):
ID = self.getID()
# handle forbidden filenames especially on windows systems
return fnConstructor(str(ID))
def exportEvent(self, fnout, fnext='.xml'):
from pylot.core.util.defaults import OUTPUTFORMATS from pylot.core.util.defaults import OUTPUTFORMATS
if evtformat.strip() not in OUTPUTFORMATS.values(): try:
errmsg = 'selected format {0} not available'.format(evtformat) evtformat = OUTPUTFORMATS[fnext]
except KeyError, e:
errmsg = '{0}; selected file extension {1} not ' \
'supported'.format(e, fnext)
raise FormatError(errmsg) raise FormatError(errmsg)
if fnout is None:
ID = self.getID()
# handle forbidden filenames especially on windows systems
fnout = fnConstructor(str(ID))
else:
fnout = fnConstructor(str(fnout))
evtformat = evtformat.upper().strip()
# establish catalog object (event object has no write method)
cat = Catalog()
cat.append(self.getEvtData())
# try exporting event via ObsPy # try exporting event via ObsPy
try: try:
cat.write(fnout + evtformat.lower(), format=evtformat) self.getEvtData().write(fnout + fnext, format=evtformat)
except KeyError, e: except KeyError, e:
raise KeyError('''{0} export format raise KeyError('''{0} export format
not implemented: {1}'''.format(evtformat, e)) not implemented: {1}'''.format(evtformat, e))
@ -156,21 +153,51 @@ class Data(object):
def getEvtData(self): def getEvtData(self):
return self.evtdata return self.evtdata
def applyEVTData(self, data, type='pick'): def applyEVTData(self, data, type='pick', authority_id='rub'):
def applyPicks(picks): def applyPicks(picks):
pass firstonset = None
for station, onsets in picks.items():
print 'Reading picks on station %s' % station
for label, phase in onsets.items():
onset = phase['mpp']
epp = phase['epp']
lpp = phase['lpp']
error = phase['spe']
pick = 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.waveform_id = WaveformStreamID(station_code=station)
self.getEvtData().picks.append(pick)
try:
polarity = phase['fm']
except KeyError, e:
print 'No polarity information found for %s' % phase
if firstonset is None or firstonset > onset:
firstonset = onset
if 'smi:local' in self.getID():
fonset_str = firstonset.strftime('%Y_%m_%d_%H_%M_%S')
ID = ResourceIdentifier('event/' + fonset_str)
ID.convertIDToQuakeMLURI(authority_id=authority_id)
self.getEvtData().resource_id = ID
def applyArrivals(arrivals): def applyArrivals(arrivals):
pass pass
def applyEvent(event): def applyEvent(event):
pass pass
applydata = {'pick':applyPicks, applydata = {'pick': applyPicks,
'arrival':applyArrivals, 'arrival': applyArrivals,
'event':applyEvent} 'event': applyEvent}
applydata[type](data) applydata[type](data)
class GenericDataStructure(object): class GenericDataStructure(object):
''' '''
GenericDataBase type holds all information about the current data- GenericDataBase type holds all information about the current data-
@ -280,14 +307,13 @@ class PilotDataStructure(GenericDataStructure):
''' '''
def __init__(self, **fields): def __init__(self, **fields):
if not fields: if not fields:
fields = {'database':'2006.01', fields = {'database': '2006.01',
'root':'/data/Egelados/EVENT_DATA/LOCAL'} 'root': '/data/Egelados/EVENT_DATA/LOCAL'}
GenericDataStructure.__init__(self, **fields) GenericDataStructure.__init__(self, **fields)
self.setExpandFields(['root','database']) self.setExpandFields(['root', 'database'])
class SeiscompDataStructure(GenericDataStructure): class SeiscompDataStructure(GenericDataStructure):
@ -304,7 +330,6 @@ class SeiscompDataStructure(GenericDataStructure):
filesuffix=None, **kwargs): filesuffix=None, **kwargs):
super(GenericDataStructure, self).__init__() super(GenericDataStructure, self).__init__()
edate = UTCDateTime() edate = UTCDateTime()
halfyear = UTCDateTime('1970-07-01') halfyear = UTCDateTime('1970-07-01')
sdate = UTCDateTime(edate - halfyear) sdate = UTCDateTime(edate - halfyear)

View File

@ -13,6 +13,6 @@ FILTERDEFAULTS = {'P': {'filtertype': None,
'order': 4, 'order': 4,
'freq': [.5, 5]}} 'freq': [.5, 5]}}
OUTPUTFORMATS = {'QuakeML':'QUAKEML', OUTPUTFORMATS = {'.xml':'QUAKEML',
'VelEst':'CNV', '.cnv':'CNV',
'NonLinLoc':'NLLOC_OBS'} '.obs':'NLLOC_OBS'}