Data object restructured for convenience; fixed problems in the class logic; restructured imports
This commit is contained in:
parent
2b8c60a3d4
commit
fa6db084b8
10
QtPyLoT.py
10
QtPyLoT.py
@ -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]
|
||||||
|
@ -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
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -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:
|
else:
|
||||||
self.comp = 'Z'
|
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:
|
|
||||||
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
|
||||||
@ -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:
|
||||||
|
Loading…
Reference in New Issue
Block a user