Merge branch 'develop' of ariadne.geophysik.rub.de:/data/git/pylot into develop

This commit is contained in:
Ludger Küperkoch 2015-08-31 09:02:16 +02:00
commit 69c17f9fdb
4 changed files with 301 additions and 84 deletions

View File

@ -42,7 +42,8 @@ from pylot.core.read.data import Data
from pylot.core.read.inputs import FilterOptions, AutoPickParameter from pylot.core.read.inputs import FilterOptions, AutoPickParameter
from pylot.core.pick.autopick import autopickevent from pylot.core.pick.autopick import autopickevent
from pylot.core.util.defaults import FILTERDEFAULTS from pylot.core.util.defaults import FILTERDEFAULTS
from pylot.core.util.errors import FormatError, DatastructureError from pylot.core.util.errors import FormatError, DatastructureError,\
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, createEvent, getLogin,\
createCreationInfo, getGlobalTimes createCreationInfo, getGlobalTimes
@ -399,7 +400,21 @@ class MainWindow(QMainWindow):
def saveData(self): def saveData(self):
settings = QSettings() settings = QSettings()
exform = settings.value('data/exportFormat', 'QUAKEML') exform = settings.value('data/exportFormat', 'QUAKEML')
try:
self.getData().applyEVTData(self.getPicks()) self.getData().applyEVTData(self.getPicks())
except OverwriteError:
msgBox = QMessageBox()
msgBox.setText("Picks have been modified!")
msgBox.setInformativeText("Do you want to save the changes and overwrite the picks?")
msgBox.setDetailedText(self.getData().getPicksStr())
msgBox.setStandardButtons(QMessageBox.Save | QMessageBox.Cancel)
msgBox.setDefaultButton(QMessageBox.Save)
ret = msgBox.exec_()
if ret == QMessageBox.Save:
self.getData().resetPicks()
self.saveData()
elif ret == QMessageBox.Cancel:
return False
try: try:
self.getData().exportEvent(self.fname, exform) self.getData().exportEvent(self.fname, exform)
except FormatError: except FormatError:
@ -407,12 +422,14 @@ class MainWindow(QMainWindow):
except AttributeError, e: except AttributeError, 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 = "Seismic observation files (*.cnv *.obs *.xml)" file_filter = "QuakeML file (*.xml);;VELEST observation file format (*.cnv);;NonLinLoc observation file (*.obs)"
fname = QFileDialog.getSaveFileName(self, 'Save event data ...', fname = QFileDialog.getSaveFileName(self, 'Save event data ...',
directory, file_filter) directory, file_filter)
fbasename, exform = os.path.splitext(fname[0]) fbasename, exform = os.path.splitext(fname[0])
if not fbasename: if not fbasename:
return False return False
elif not exform:
exform = fname[1].split('*')[1][:-1]
self.getData().exportEvent(fbasename, exform) self.getData().exportEvent(fbasename, exform)
return True return True

View File

@ -1 +1 @@
1abc-dirty 497c-dirty

View File

@ -3,7 +3,6 @@
import os import os
import glob import glob
import matplotlib.pyplot as plt
from obspy.xseed import Parser from obspy.xseed import Parser
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
@ -11,24 +10,21 @@ 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
from pylot.core.util.errors import FormatError from pylot.core.util.errors import FormatError, OverwriteError
class Data(object): class Data(object):
''' """
Data container with attributes wfdata holding ~obspy.core.stream. Data container with attributes wfdata holding ~obspy.core.stream.
:type parent: PySide.QtGui.QWidget object, optional :type parent: PySide.QtGui.QWidget object, optional
:param parent: A PySide.QtGui.QWidget object utilized when :param parent: A PySide.QtGui.QWidget object utilized when
called by a GUI to display a PySide.QtGui.QMessageBox instead of printing called by a GUI to display a PySide.QtGui.QMessageBox instead of printing
to standard out. to standard out.
:type wfdata: ~obspy.core.stream.Stream object, optional
:param wfdata: ~obspy.core.stream.Stream object containing all available
waveform data for the actual event
:type evtdata: ~obspy.core.event.Event object, optional :type evtdata: ~obspy.core.event.Event object, optional
:param evtdata ~obspy.core.event.Event object containing all derived or :param evtdata ~obspy.core.event.Event object containing all derived or
loaded event. Container object holding, e.g. phase arrivals, etc. loaded event. Container object holding, e.g. phase arrivals, etc.
''' """
def __init__(self, parent=None, evtdata=None): def __init__(self, parent=None, evtdata=None):
self._parent = parent self._parent = parent
@ -56,32 +52,69 @@ class Data(object):
def __str__(self): def __str__(self):
return str(self.wfdata) return str(self.wfdata)
def getPicksStr(self):
picks_str = ''
for pick in self.getEvtData().picks:
picks_str += str(pick) + '\n'
return picks_str
def getParent(self): def getParent(self):
"""
:return:
"""
return self._parent return self._parent
def isNew(self): def isNew(self):
"""
:return:
"""
return self.newevent return self.newevent
def getCutTimes(self): def getCutTimes(self):
"""
:return:
"""
if self.cuttimes is None: if self.cuttimes is None:
self.updateCutTimes() self.updateCutTimes()
return self.cuttimes return self.cuttimes
def updateCutTimes(self): def updateCutTimes(self):
"""
"""
self.cuttimes = getGlobalTimes(self.getWFData()) self.cuttimes = getGlobalTimes(self.getWFData())
def getEventFileName(self): def getEventFileName(self):
"""
:return:
"""
ID = self.getID() ID = self.getID()
# handle forbidden filenames especially on windows systems # handle forbidden filenames especially on windows systems
return fnConstructor(str(ID)) return fnConstructor(str(ID))
def exportEvent(self, fnout, fnext='.xml'): def exportEvent(self, fnout, fnext='.xml'):
"""
:param fnout:
:param fnext:
:raise KeyError:
"""
from pylot.core.util.defaults import OUTPUTFORMATS from pylot.core.util.defaults import OUTPUTFORMATS
try: try:
evtformat = OUTPUTFORMATS[fnext] evtformat = OUTPUTFORMATS[fnext]
except KeyError, e: except KeyError as e:
errmsg = '{0}; selected file extension {1} not ' \ errmsg = '{0}; selected file extension {1} not ' \
'supported'.format(e, fnext) 'supported'.format(e, fnext)
raise FormatError(errmsg) raise FormatError(errmsg)
@ -89,24 +122,42 @@ class Data(object):
# try exporting event via ObsPy # try exporting event via ObsPy
try: try:
self.getEvtData().write(fnout + fnext, format=evtformat) self.getEvtData().write(fnout + fnext, format=evtformat)
except KeyError, e: except KeyError as e:
raise KeyError('''{0} export format raise KeyError('''{0} export format
not implemented: {1}'''.format(evtformat, e)) not implemented: {1}'''.format(evtformat, e))
def getComp(self): def getComp(self):
"""
:return:
"""
return self.comp return self.comp
def getID(self): def getID(self):
"""
:return:
"""
try: try:
return self.evtdata.get('resource_id').id return self.evtdata.get('resource_id').id
except: except:
return None return None
def filterWFData(self, kwargs): def filterWFData(self, kwargs):
"""
:param kwargs:
"""
self.getWFData().filter(**kwargs) self.getWFData().filter(**kwargs)
self.dirty = True self.dirty = True
def setWFData(self, fnames): def setWFData(self, fnames):
"""
:param fnames:
"""
self.wfdata = Stream() self.wfdata = Stream()
self.wforiginal = None self.wforiginal = None
if fnames is not None: if fnames is not None:
@ -115,10 +166,14 @@ class Data(object):
self.dirty = False self.dirty = False
def appendWFData(self, fnames): def appendWFData(self, fnames):
"""
:param fnames:
"""
assert isinstance(fnames, list), "input parameter 'fnames' is " \ assert isinstance(fnames, list), "input parameter 'fnames' is " \
"supposed to be of type 'list' " \ "supposed to be of type 'list' " \
"but is actually {0}".format(type( "but is actually" \
fnames)) " {0}".format(type(fnames))
if self.dirty: if self.dirty:
self.resetWFData() self.resetWFData()
@ -129,24 +184,51 @@ class Data(object):
except TypeError: except TypeError:
try: try:
self.wfdata += read(fname, format='GSE2') self.wfdata += read(fname, format='GSE2')
except Exception, e: except Exception as e:
warnmsg += '{0}\n{1}\n'.format(fname, e) warnmsg += '{0}\n{1}\n'.format(fname, e)
if warnmsg: if warnmsg:
warnmsg = 'WARNING: unable to read\n' + warnmsg warnmsg = 'WARNING: unable to read\n' + warnmsg
print warnmsg print(warnmsg)
def getWFData(self): def getWFData(self):
"""
:return:
"""
return self.wfdata return self.wfdata
def getOriginalWFData(self): def getOriginalWFData(self):
"""
:return:
"""
return self.wforiginal return self.wforiginal
def resetWFData(self): def resetWFData(self):
"""
"""
self.wfdata = self.getOriginalWFData().copy() self.wfdata = self.getOriginalWFData().copy()
self.dirty = False self.dirty = False
def resetPicks(self):
"""
"""
self.getEvtData().picks = []
def restituteWFData(self, invdlpath, streams=None): def restituteWFData(self, invdlpath, streams=None):
if streams == None: """
:param invdlpath:
:param streams:
:return:
"""
if streams is None:
st = self.getWFData() st = self.getWFData()
else: else:
st = streams st = streams
@ -164,10 +246,10 @@ class Data(object):
# check for dataless-SEED file # check for dataless-SEED file
if len(dlfile) >= 1: if len(dlfile) >= 1:
print "Found dataless-SEED file(s)!" print("Found dataless-SEED file(s)!")
print "Reading meta data information ..." print("Reading meta data information ...")
for j in range(len(dlfile)): for j in range(len(dlfile)):
print "Found dataless-SEED file %s" % dlfile[j] print("Found dataless-SEED file %s" % dlfile[j])
parser = Parser('%s' % dlfile[j]) parser = Parser('%s' % dlfile[j])
for i in range(len(st)): for i in range(len(st)):
# check, whether this trace has already been corrected # check, whether this trace has already been corrected
@ -175,27 +257,32 @@ class Data(object):
st[i].stats.processing st[i].stats.processing
except: except:
try: try:
print "Correcting %s, %s for instrument response ..." \ print(
% (st[i].stats.station, st[i].stats.channel) "Correcting %s, %s for instrument response "
"..." % (st[i].stats.station,
st[i].stats.channel))
# get corner frequencies for pre-filtering # get corner frequencies for pre-filtering
fny = st[i].stats.sampling_rate / 2 fny = st[i].stats.sampling_rate / 2
fc21 = fny - (fny * 0.05) fc21 = fny - (fny * 0.05)
fc22 = fny - (fny * 0.02) fc22 = fny - (fny * 0.02)
prefilt = [0.5, 0.9, fc21, fc22] prefilt = [0.5, 0.9, fc21, fc22]
# instrument correction # instrument correction
st[i].simulate(pre_filt=prefilt, seedresp={'filename': parser, \ st[i].simulate(pre_filt=prefilt,
'date': st[i].stats.starttime, 'units': "VEL"}) seedresp={'filename': parser,
except ValueError, e: 'date': st[
i].stats.starttime,
'units': "VEL"})
except ValueError as e:
vmsg = '{0}'.format(e) vmsg = '{0}'.format(e)
print vmsg print(vmsg)
else: else:
print "Trace has already been corrected!" print("Trace has already been corrected!")
# check for inventory-xml file # check for inventory-xml file
if len(invfile) >= 1: if len(invfile) >= 1:
print "Found inventory-xml file(s)!" print("Found inventory-xml file(s)!")
print "Reading meta data information ..." print("Reading meta data information ...")
for j in range(len(invfile)): for j in range(len(invfile)):
print "Found inventory-xml file %s" % invfile[j] print("Found inventory-xml file %s" % invfile[j])
inv = read_inventory(invfile[j], format="STATIONXML") inv = read_inventory(invfile[j], format="STATIONXML")
for i in range(len(st)): for i in range(len(st)):
# check, whether this trace has already been corrected # check, whether this trace has already been corrected
@ -203,8 +290,9 @@ class Data(object):
st[i].stats.processing st[i].stats.processing
except: except:
try: try:
print "Correcting %s, %s for instrument response ..." \ print("Correcting %s, %s for instrument response "
% (st[i].stats.station, st[i].stats.channel) "..." % (st[i].stats.station,
st[i].stats.channel))
# get corner frequencies for pre-filtering # get corner frequencies for pre-filtering
fny = st[i].stats.sampling_rate / 2 fny = st[i].stats.sampling_rate / 2
fc21 = fny - (fny * 0.05) fc21 = fny - (fny * 0.05)
@ -212,56 +300,84 @@ class Data(object):
prefilt = [0.5, 0.9, fc21, fc22] prefilt = [0.5, 0.9, fc21, fc22]
# instrument correction # instrument correction
st[i].attach_response(inv) st[i].attach_response(inv)
st[i].remove_response(output='VEL', pre_filt=prefilt) st[i].remove_response(output='VEL',
except ValueError, e: pre_filt=prefilt)
except ValueError as e:
vmsg = '{0}'.format(e) vmsg = '{0}'.format(e)
print vmsg print(vmsg)
else: else:
print "Trace has already been corrected!" print("Trace has already been corrected!")
# check for RESP-file # check for RESP-file
if len(respfile) >= 1: if len(respfile) >= 1:
print "Found response file(s)!" print("Found response file(s)!")
print "Reading meta data information ..." print("Reading meta data information ...")
for j in range(len(respfile)): for j in range(len(respfile)):
print "Found RESP-file %s" % respfile[j] print("Found RESP-file %s" % respfile[j])
for i in range(len(st)): for i in range(len(st)):
# check, whether this trace has already been corrected # check, whether this trace has already been corrected
try: try:
st[i].stats.processing st[i].stats.processing
except: except:
try: try:
print "Correcting %s, %s for instrument response ..." \ print("Correcting %s, %s for instrument response "
% (st[i].stats.station, st[i].stats.channel) "..." % (st[i].stats.station,
st[i].stats.channel))
# get corner frequencies for pre-filtering # get corner frequencies for pre-filtering
fny = st[i].stats.sampling_rate / 2 fny = st[i].stats.sampling_rate / 2
fc21 = fny - (fny * 0.05) fc21 = fny - (fny * 0.05)
fc22 = fny - (fny * 0.02) fc22 = fny - (fny * 0.02)
prefilt = [0.5, 0.9, fc21, fc22] prefilt = [0.5, 0.9, fc21, fc22]
# instrument correction # instrument correction
seedresp={'filename': respfile[0], 'date': st[0].stats.starttime, \ seedresp = {'filename': respfile[0],
'date': st[0].stats.starttime,
'units': "VEL"} 'units': "VEL"}
st[i].simulate(paz_remove=None, pre_filt=prefilt, seedresp=seedresp) st[i].simulate(paz_remove=None, pre_filt=prefilt,
except ValueError, e: seedresp=seedresp)
except ValueError as e:
vmsg = '{0}'.format(e) vmsg = '{0}'.format(e)
print vmsg print(vmsg)
else: else:
print "Trace has already been corrected!" print("Trace has already been corrected!")
if len(respfile) < 1 and len(invfile) < 1 and len(dlfile) < 1: if len(respfile) < 1 and len(invfile) < 1 and len(dlfile) < 1:
print "No dataless-SEED file,inventory-xml file nor RESP-file found!" print("No dataless-SEED file,inventory-xml file nor RESP-file "
print "Go on processing data without source parameter determination!" "found!")
print("Go on processing data without source parameter "
"determination!")
return st return st
def getEvtData(self): def getEvtData(self):
"""
:return:
"""
return self.evtdata return self.evtdata
def applyEVTData(self, data, type='pick', authority_id='rub'): def applyEVTData(self, data, type='pick', authority_id='rub'):
"""
:param data:
:param type:
:param authority_id:
:raise OverwriteError:
"""
def applyPicks(picks): def applyPicks(picks):
"""
Creates ObsPy pick objects and append it to the picks list from the
PyLoT dictionary contain all picks.
:param picks:
:raise OverwriteError: raises an OverwriteError if the picks list is
not empty. The GUI will then ask for a decision.
"""
firstonset = None firstonset = None
if self.getEvtData().picks:
raise OverwriteError('Actual picks would be overwritten!')
for station, onsets in picks.items(): for station, onsets in picks.items():
print 'Reading picks on station %s' % station print('Reading picks on station %s' % station)
for label, phase in onsets.items(): for label, phase in onsets.items():
onset = phase['mpp'] onset = phase['mpp']
epp = phase['epp'] epp = phase['epp']
@ -277,8 +393,8 @@ class Data(object):
self.getEvtData().picks.append(pick) self.getEvtData().picks.append(pick)
try: try:
polarity = phase['fm'] polarity = phase['fm']
except KeyError, e: except KeyError as e:
print 'No polarity information found for %s' % phase print('No polarity information found for %s' % phase)
if firstonset is None or firstonset > onset: if firstonset is None or firstonset > onset:
firstonset = onset firstonset = onset
@ -289,9 +405,17 @@ class Data(object):
self.getEvtData().resource_id = ID self.getEvtData().resource_id = ID
def applyArrivals(arrivals): def applyArrivals(arrivals):
"""
:param arrivals:
"""
pass pass
def applyEvent(event): def applyEvent(event):
"""
:param event:
"""
pass pass
applydata = {'pick': applyPicks, applydata = {'pick': applyPicks,
@ -302,10 +426,10 @@ class Data(object):
class GenericDataStructure(object): class GenericDataStructure(object):
''' """
GenericDataBase type holds all information about the current data- GenericDataBase type holds all information about the current data-
base working on. base working on.
''' """
def __init__(self, **kwargs): def __init__(self, **kwargs):
@ -317,6 +441,10 @@ class GenericDataStructure(object):
def modifyFields(self, **kwargs): def modifyFields(self, **kwargs):
"""
:param kwargs:
"""
assert isinstance(kwargs, dict), 'dictionary type object expected' assert isinstance(kwargs, dict), 'dictionary type object expected'
if not self.extraAllowed(): if not self.extraAllowed():
@ -332,37 +460,67 @@ class GenericDataStructure(object):
value = str(value) value = str(value)
try: try:
self.setFieldValue(key, value) self.setFieldValue(key, value)
except KeyError, e: except KeyError as e:
errmsg = '' errmsg = ''
errmsg += 'WARNING:\n' errmsg += 'WARNING:\n'
errmsg += 'unable to set values for datastructure fields\n' errmsg += 'unable to set values for datastructure fields\n'
errmsg += '%s; desired value was: %s\n' % (e, value) errmsg += '%s; desired value was: %s\n' % (e, value)
print errmsg print(errmsg)
def isField(self, key): def isField(self, key):
"""
:param key:
:return:
"""
return key in self.getFields().keys() return key in self.getFields().keys()
def getFieldValue(self, key): def getFieldValue(self, key):
"""
:param key:
:return:
"""
if self.isField(key): if self.isField(key):
return self.getFields()[key] return self.getFields()[key]
else: else:
return return
def setFieldValue(self, key, value): def setFieldValue(self, key, value):
"""
:param key:
:param value:
:raise KeyError:
"""
if not self.extraAllowed() and key not in self.getAllowed(): if not self.extraAllowed() and key not in self.getAllowed():
raise KeyError raise KeyError
else: else:
if not self.isField(key): if not self.isField(key):
print 'creating new field "%s"' % key print('creating new field "%s"' % key)
self.getFields()[key] = value self.getFields()[key] = value
def getFields(self): def getFields(self):
"""
:return:
"""
return self.dsFields return self.dsFields
def getExpandFields(self): def getExpandFields(self):
"""
:return:
"""
return self.expandFields return self.expandFields
def setExpandFields(self, keys): def setExpandFields(self, keys):
"""
:param keys:
"""
expandFields = [] expandFields = []
for key in keys: for key in keys:
if self.isField(key): if self.isField(key):
@ -370,18 +528,38 @@ class GenericDataStructure(object):
self.expandFields = expandFields self.expandFields = expandFields
def getAllowed(self): def getAllowed(self):
"""
:return:
"""
return self.allowedFields return self.allowedFields
def extraAllowed(self): def extraAllowed(self):
"""
:return:
"""
return not self.allowedFields return not self.allowedFields
def updateNotAllowed(self, kwargs): def updateNotAllowed(self, kwargs):
"""
:param kwargs:
:return:
"""
for key in kwargs: for key in kwargs:
if key not in self.getAllowed(): if key not in self.getAllowed():
kwargs.__delitem__(key) kwargs.__delitem__(key)
return kwargs return kwargs
def hasSuffix(self): def hasSuffix(self):
"""
:return:
"""
try: try:
self.getFieldValue('suffix') self.getFieldValue('suffix')
except KeyError: except KeyError:
@ -392,6 +570,11 @@ class GenericDataStructure(object):
return False return False
def expandDataPath(self): def expandDataPath(self):
"""
:return:
"""
expandList = [] expandList = []
for item in self.getExpandFields(): for item in self.getExpandFields():
expandList.append(self.getFieldValue(item)) expandList.append(self.getFieldValue(item))
@ -400,14 +583,19 @@ class GenericDataStructure(object):
return os.path.join(*expandList) return os.path.join(*expandList)
def getCatalogName(self): def getCatalogName(self):
"""
:return:
"""
return os.path.join(self.getFieldValue('root'), 'catalog.qml') return os.path.join(self.getFieldValue('root'), 'catalog.qml')
class PilotDataStructure(GenericDataStructure): class PilotDataStructure(GenericDataStructure):
''' """
Object containing the data access information for the old PILOT data Object containing the data access information for the old PILOT data
structure. structure.
''' """
def __init__(self, **fields): def __init__(self, **fields):
if not fields: if not fields:
@ -420,14 +608,14 @@ class PilotDataStructure(GenericDataStructure):
class SeiscompDataStructure(GenericDataStructure): class SeiscompDataStructure(GenericDataStructure):
''' """
Dictionary containing the data access information for an SDS data archive: Dictionary containing the data access information for an SDS data archive:
:param str dataType: Desired data type. Default: ``'waveform'`` :param str dataType: Desired data type. Default: ``'waveform'``
:param sdate, edate: Either date string or an instance of :param sdate, edate: Either date string or an instance of
:class:`obspy.core.utcdatetime.UTCDateTime. Default: ``None`` :class:`obspy.core.utcdatetime.UTCDateTime. Default: ``None``
:type sdate, edate: str or UTCDateTime or None :type sdate, edate: str or UTCDateTime or None
''' """
def __init__(self, rootpath='/data/SDS', dataformat='MSEED', def __init__(self, rootpath='/data/SDS', dataformat='MSEED',
filesuffix=None, **kwargs): filesuffix=None, **kwargs):
@ -458,6 +646,10 @@ class SeiscompDataStructure(GenericDataStructure):
self.modifiyFields(**kwargs) self.modifiyFields(**kwargs)
def modifiyFields(self, **kwargs): def modifiyFields(self, **kwargs):
"""
:param kwargs:
"""
if kwargs and isinstance(kwargs, dict): if kwargs and isinstance(kwargs, dict):
for key, value in kwargs.iteritems(): for key, value in kwargs.iteritems():
key = str(key) key = str(key)
@ -467,28 +659,32 @@ class SeiscompDataStructure(GenericDataStructure):
else: else:
value = str(value) value = str(value)
try: try:
self.setField(key, value) self.setFieldValue(key, value)
except KeyError, e: except KeyError as e:
errmsg = '' errmsg = ''
errmsg += 'WARNING:\n' errmsg += 'WARNING:\n'
errmsg += 'unable to set values for SDS fields\n' errmsg += 'unable to set values for SDS fields\n'
errmsg += '%s; desired value was: %s\n' % (e, value) errmsg += '%s; desired value was: %s\n' % (e, value)
print errmsg print(errmsg)
def setFieldValue(self, key, value): def setFieldValue(self, key, value):
"""
:param key:
:param value:
"""
if self.isField(key): if self.isField(key):
self.getFields()[key] = value self.getFields()[key] = value
else: else:
print('Warning: trying to set value of non-existent field ' print('Warning: trying to set value of non-existent field '
'{field}'.format(field=key)) '{field}'.format(field=key))
def getFields(self):
return self.__sdsFields
def getName(self):
return self.__name
def expandDataPath(self): def expandDataPath(self):
"""
:return:
"""
fullChan = '{0}.{1}'.format(self.getFields()['CHAN'], self.getType()) fullChan = '{0}.{1}'.format(self.getFields()['CHAN'], self.getType())
dataPath = os.path.join(self.getFields()['SDSdir'], dataPath = os.path.join(self.getFields()['SDSdir'],
self.getFields()['YEAR'], self.getFields()['YEAR'],

View File

@ -16,3 +16,7 @@ class FormatError(Exception):
class DatastructureError(Exception): class DatastructureError(Exception):
pass pass
class OverwriteError(IOError):
pass