Data object restructured for convenience; fixed problems in the class logic; restructured imports

This commit is contained in:
Sebastian Wehling-Benatelli 2015-02-16 10:30:35 +01:00
parent 2b8c60a3d4
commit fa6db084b8
3 changed files with 65 additions and 58 deletions

View File

@ -258,23 +258,25 @@ class MainWindow(QMainWindow):
def loadData(self, fname=None): def loadData(self, fname=None):
if fname is None: if fname is None:
try: try:
self.data = Data(evtdata=self.fname) self.data = Data(self, evtdata=self.fname)
except AttributeError: except AttributeError:
action = self.sender() action = self.sender()
if isinstance(action, QAction): if isinstance(action, QAction):
if action.data() is None: if action.data() is None:
filt = """Supported event formats (*.mat *.qml *.xml *.kor *.evt)""" filt = "Supported event formats (*.mat *.qml *.xml " \
"*.kor *.evt)"
caption = 'Select event to open' caption = 'Select event to open'
self.fname = QFileDialog().getOpenFileName(self, fname, = QFileDialog().getOpenFileName(self,
caption=caption, caption=caption,
filter=filt) filter=filt)
self.fname = fname
else: else:
self.fname = unicode(action.data().toString()) self.fname = unicode(action.data().toString())
if not self.okToContinue(): if not self.okToContinue():
return return
else: else:
self.fname = fname self.fname = fname
self.data = Data(evtdata=self.fname) self.data = Data(self, evtdata=self.fname)
def getLastEvent(self): def getLastEvent(self):
return self.recentEvents[0] return self.recentEvents[0]

View File

@ -1,8 +1,6 @@
from pylot.core.read.inputs import AutoPickParameter from pylot.core.read.inputs import AutoPickParameter, FilterOptions
from pylot.core.read.inputs import FilterOptions from pylot.core.read.io import readPILOTEvent
from pylot.core.read.data import GenericDataStructure from pylot.core.read.data import GenericDataStructure, SeiscompDataStructure, \
from pylot.core.read.data import SeiscompDataStructure PilotDataStructure, Data
from pylot.core.read.data import PilotDataStructure
from pylot.core.read.data import Data

View File

@ -2,13 +2,15 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
import os import os
import numpy as np import numpy as np
from PySide.QtGui import QMessageBox
from obspy.core import (read, Stream, UTCDateTime) from obspy.core import (read, Stream, UTCDateTime)
from obspy import readEvents from obspy import readEvents
from obspy.core.event import (Event, Catalog) from obspy.core.event import (Event, Catalog)
from pylot.core.util import fnConstructor
from pylot.core.util.errors import FormatError from pylot.core.read import readPILOTEvent
from pylot.core.util import fnConstructor, createEvent, FormatError
class Data(object): class Data(object):
@ -28,26 +30,10 @@ class Data(object):
''' '''
def __init__(self, parent=None, evtdata=None): def __init__(self, parent=None, evtdata=None):
try: if parent:
if parent: self.comp = parent.getComponent()
self.comp = parent.getComponent()
else:
self.comp = 'Z'
except IOError, e:
msg = 'An I/O error occured while loading data!'
inform = 'Variable wfdata will be empty.'
details = '{0}'.format(e)
if parent is not None:
warnio = QMessageBox(parent=parent)
warnio.setText(msg)
warnio.setDetailedText(details)
warnio.setInformativeText(inform)
warnio.setStandarButtons(QMessageBox.Ok)
warnio.setIcon(QMessageBox.Warning)
else:
print msg, "\n", details
self.wfdata = Stream()
else: else:
self.comp = 'Z'
self.wfdata = Stream() self.wfdata = Stream()
self.newevent = False self.newevent = False
if evtdata is not None and isinstance(evtdata, Event): if evtdata is not None and isinstance(evtdata, Event):
@ -56,26 +42,32 @@ class Data(object):
cat = readEvents(evtdata) cat = readEvents(evtdata)
self.evtdata = cat[0] self.evtdata = cat[0]
elif evtdata is not None: elif evtdata is not None:
cat = self.readPILOTEvent(**evtdata) cat = readPILOTEvent(**evtdata)
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.orig = self.wfdata.copy() self.wforiginal = None
self.cuttimes = None
self.dirty = False
def isNew(self):
return self.newevent
def getCutTimes(self):
if self.cuttimes is None:
self.updateCutTimes()
return self.cuttimes
def updateCutTimes(self):
min_start = UTCDateTime() min_start = UTCDateTime()
max_end = None max_end = None
for trace in self.getWFData().select(component = self.getComp()): for trace in self.getWFData().select(component=self.getComp()):
if trace.stats.starttime < min_start: if trace.stats.starttime < min_start:
min_start = trace.stats.starttime min_start = trace.stats.starttime
if max_end is None or trace.stats.endtime > max_end: if max_end is None or trace.stats.endtime > max_end:
max_end = trace.stats.endtime max_end = trace.stats.endtime
self.cuttimes = [min_start, max_end] self.cuttimes = [min_start, max_end]
def isNew(self):
return self.newevent
def readMatPhases(self, fname):
pass
def exportEvent(self, fnout=None, evtformat='QUAKEML'): def exportEvent(self, fnout=None, evtformat='QUAKEML'):
from pylot.core.util.defaults import OUTPUTFORMATS from pylot.core.util.defaults import OUTPUTFORMATS
@ -95,7 +87,7 @@ class Data(object):
# establish catalog object (event object has no write method) # establish catalog object (event object has no write method)
cat = Catalog() cat = Catalog()
cat.append(self.event) cat.append(self.getEvtData())
# try exporting event via ObsPy # try exporting event via ObsPy
try: try:
cat.write(fnout + evtformat.lower(), format=evtformat) cat.write(fnout + evtformat.lower(), format=evtformat)
@ -104,23 +96,22 @@ class Data(object):
not implemented: {1}'''.format(evtformat, e)) not implemented: {1}'''.format(evtformat, e))
def plotData(self, widget): def plotData(self, widget):
wfst = self.getWFData().select(component = self.getComp()) wfst = self.getWFData().select(component=self.getComp())
for n, trace in enumerate(wfst): for n, trace in enumerate(wfst):
stime = trace.stats.starttime - self.cuttimes[0] stime = trace.stats.starttime - self.getCutTimes()[0]
etime = trace.stats.endtime - self.cuttimes[1] etime = trace.stats.endtime - self.getCutTimes()[1]
srate = trace.stats.sampling_rate srate = trace.stats.sampling_rate
nsamp = len(trace.data) nsamp = len(trace.data)
tincr = trace.stats.delta tincr = trace.stats.delta
time_ax = np.arange(stime, nsamp / srate, tincr) time_ax = np.arange(stime, nsamp / srate, tincr)
trace.normalize() trace.normalize()
widget.axes.plot(time_ax, trace.data + n, 'k') widget.axes.plot(time_ax, trace.data + n, 'k')
xlabel = 'seconds since {0}'.format(self.cuttimes[0]) xlabel = 'seconds since {0}'.format(self.getCutTimes()[0])
ylabel = '' ylabel = ''
zne_text = {'Z':'vertical', 'N':'north-south', 'E':'east-west'} zne_text = {'Z': 'vertical', 'N': 'north-south', 'E': 'east-west'}
title = 'overview: {0} components'.format(zne_text[self.getComp()]) title = 'overview: {0} components'.format(zne_text[self.getComp()])
widget.updateWidget(xlabel, ylabel, title) widget.updateWidget(xlabel, ylabel, title)
def getComp(self): def getComp(self):
return self.comp return self.comp
@ -132,21 +123,35 @@ class Data(object):
def filter(self, kwargs): def filter(self, kwargs):
self.getWFData().filter(**kwargs) self.getWFData().filter(**kwargs)
self.dirty = True
def setWFData(self, fnames): def setWFData(self, fnames):
for fname in fnames[0]: self.wfdata = Stream()
self.wforiginal = None
if fnames is not None:
self.appendWFData(fnames)
self.orig = self.getWFData().copy()
self.dirty = False
def appendWFData(self, fnames):
if self.dirty is not False:
self.resetWFData()
for fname in fnames:
try: try:
self.wfdata += read(fname) self.wfdata += read(fname)
except TypeError: except TypeError:
self.wfdata += read(fname, format='GSE2') self.wfdata += read(fname, format='GSE2')
def appenWFData(self, fnames):
for fname in fnames:
self.wfdata += read(fname)
def getWFData(self): def getWFData(self):
return self.wfdata return self.wfdata
def getOriginalWFData(self):
return self.wforiginal
def resetWFData(self):
self.wfdata = self.getOriginalWFData().copy()
self.dirty = False
def getEvtData(self): def getEvtData(self):
return self.evtdata return self.evtdata
@ -176,7 +181,7 @@ class GenericDataStructure(object):
structExpression.reverse() structExpression.reverse()
self.folderDepth = folderdepth self.folderDepth = folderdepth
self.__gdsFields = {'ROOT':rootExpression} self.__gdsFields = {'ROOT': rootExpression}
self.modifyFields(**kwargs) self.modifyFields(**kwargs)
def modifyFields(self, **kwargs): def modifyFields(self, **kwargs):
@ -190,6 +195,7 @@ class GenericDataStructure(object):
def expandDataPath(self): def expandDataPath(self):
return os.path.join(*self.getFields().values()) return os.path.join(*self.getFields().values())
class PilotDataStructure(object): class PilotDataStructure(object):
''' '''
Object containing the data access information for the old PILOT data Object containing the data access information for the old PILOT data
@ -201,8 +207,8 @@ class PilotDataStructure(object):
**kwargs): **kwargs):
self.dataType = dataformat self.dataType = dataformat
self.__pdsFields = {'ROOT': root, self.__pdsFields = {'ROOT': root,
'DATABASE': database, 'DATABASE': database,
'SUFFIX': fsuffix 'SUFFIX': fsuffix
} }
self.modifiyFields(**kwargs) self.modifiyFields(**kwargs)
@ -240,6 +246,7 @@ class PilotDataStructure(object):
"*{0}".format(self.getFields()['SUFFIX'])) "*{0}".format(self.getFields()['SUFFIX']))
return datapath return datapath
class SeiscompDataStructure(object): class SeiscompDataStructure(object):
''' '''
Dictionary containing the data access information for an SDS data archive: Dictionary containing the data access information for an SDS data archive: