From 3dd65b9cc3c2dfb9cc70372b7079a6065ccd6c8d Mon Sep 17 00:00:00 2001 From: Sebastianw Wehling-Benatelli Date: Thu, 27 Aug 2015 12:55:34 +0200 Subject: [PATCH 1/5] [addresses #167] started fixing the multiple phase saving issue --- QtPyLoT.py | 18 +++++++++++++++--- pylot/core/read/data.py | 7 ++++++- pylot/core/util/errors.py | 4 ++++ 3 files changed, 25 insertions(+), 4 deletions(-) diff --git a/QtPyLoT.py b/QtPyLoT.py index 3d34ac8d..254e88f7 100755 --- a/QtPyLoT.py +++ b/QtPyLoT.py @@ -42,7 +42,8 @@ from pylot.core.read.data import Data from pylot.core.read.inputs import FilterOptions, AutoPickParameter from pylot.core.pick.autopick import autopickevent 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.utils import fnConstructor, createEvent, getLogin,\ createCreationInfo, getGlobalTimes @@ -399,7 +400,18 @@ class MainWindow(QMainWindow): def saveData(self): settings = QSettings() exform = settings.value('data/exportFormat', 'QUAKEML') - self.getData().applyEVTData(self.getPicks()) + try: + self.getData().applyEVTData(self.getPicks()) + except OverwriteError: + msgBox = QMessageBox() + msgBox.setText("Picks have been modified!") + msgBox.setInformativeText("Do you want to overwrite the picks and save?") + msgBox.setStandardButtons(QMessageBox.Save | QMessageBox.Discard | + QMessageBox.Cancel) + msgBox.setDefaultButton(QMessageBox.Save) + ret = msgBox.exec_() + if ret == QMessageBox.Save: + print('Overwrite and Save') try: self.getData().exportEvent(self.fname, exform) except FormatError: @@ -407,7 +419,7 @@ class MainWindow(QMainWindow): except AttributeError, e: print 'warning: {0}'.format(e) 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 ...', directory, file_filter) fbasename, exform = os.path.splitext(fname[0]) diff --git a/pylot/core/read/data.py b/pylot/core/read/data.py index dad3bf56..84142b09 100644 --- a/pylot/core/read/data.py +++ b/pylot/core/read/data.py @@ -9,7 +9,7 @@ from obspy.core.event import Event, ResourceIdentifier, Pick, WaveformStreamID from pylot.core.read.io import readPILOTEvent 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): @@ -143,6 +143,9 @@ class Data(object): self.wfdata = self.getOriginalWFData().copy() self.dirty = False + def resetPicks(self): + self.getEvtData().picks = [] + def restituteWFData(self, fninventory): st = self.getWFData() inv = read_inventory(fninventory) @@ -157,6 +160,8 @@ class Data(object): def applyPicks(picks): firstonset = None + if self.getEvtData().picks: + raise OverwriteError('Actual picks would be overwritten!') for station, onsets in picks.items(): print 'Reading picks on station %s' % station for label, phase in onsets.items(): diff --git a/pylot/core/util/errors.py b/pylot/core/util/errors.py index 6239a512..daf21d46 100644 --- a/pylot/core/util/errors.py +++ b/pylot/core/util/errors.py @@ -16,3 +16,7 @@ class FormatError(Exception): class DatastructureError(Exception): pass + + +class OverwriteError(IOError): + pass From 6597c881a6ae7cec3204a8a6809805c9b1c23b28 Mon Sep 17 00:00:00 2001 From: Sebastian Wehling-Benatelli Date: Thu, 27 Aug 2015 15:42:51 +0200 Subject: [PATCH 2/5] reformatting code --- pylot/core/read/data.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/pylot/core/read/data.py b/pylot/core/read/data.py index 5c9df06e..35332e9f 100644 --- a/pylot/core/read/data.py +++ b/pylot/core/read/data.py @@ -145,7 +145,7 @@ class Data(object): self.wfdata = self.getOriginalWFData().copy() self.dirty = False -def resetPicks(self): + def resetPicks(self): self.getEvtData().picks = [] def restituteWFData(self, invdlpath, streams=None): @@ -156,7 +156,7 @@ def resetPicks(self): for tr in st: # remove underscores - if tr.stats.station[3] == '_': + if tr.stats.station[3] == '_': tr.stats.station = tr.stats.station[0:3] dlp = '%s/*.dless' % invdlpath invp = '%s/*.xml' % invdlpath @@ -192,7 +192,7 @@ def resetPicks(self): vmsg = '{0}'.format(e) print vmsg else: - print "Trace has already been corrected!" + print "Trace has already been corrected!" # check for inventory-xml file if len(invfile) >= 1: print "Found inventory-xml file(s)!" @@ -220,7 +220,7 @@ def resetPicks(self): vmsg = '{0}'.format(e) print vmsg else: - print "Trace has already been corrected!" + print "Trace has already been corrected!" # check for RESP-file if len(respfile) >= 1: print "Found response file(s)!" @@ -248,7 +248,7 @@ def resetPicks(self): vmsg = '{0}'.format(e) print vmsg 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: print "No dataless-SEED file,inventory-xml file nor RESP-file found!" From 038caf4d54ad9536baea857b9f2eaca18f769f87 Mon Sep 17 00:00:00 2001 From: Sebastian Wehling-Benatelli Date: Fri, 28 Aug 2015 09:05:50 +0200 Subject: [PATCH 3/5] reformat code --- pylot/core/read/data.py | 311 ++++++++++++++++++++++++++++++++-------- 1 file changed, 254 insertions(+), 57 deletions(-) diff --git a/pylot/core/read/data.py b/pylot/core/read/data.py index 35332e9f..d5962b92 100644 --- a/pylot/core/read/data.py +++ b/pylot/core/read/data.py @@ -3,7 +3,6 @@ import os import glob -import matplotlib.pyplot as plt from obspy.xseed import Parser from obspy.core import read, Stream, UTCDateTime from obspy import readEvents, read_inventory @@ -57,31 +56,61 @@ class Data(object): return str(self.wfdata) def getParent(self): + """ + + + :return: + """ return self._parent def isNew(self): + """ + + + :return: + """ return self.newevent def getCutTimes(self): + """ + + + :return: + """ if self.cuttimes is None: self.updateCutTimes() return self.cuttimes def updateCutTimes(self): + """ + + + """ self.cuttimes = getGlobalTimes(self.getWFData()) def getEventFileName(self): + """ + + + :return: + """ ID = self.getID() # handle forbidden filenames especially on windows systems return fnConstructor(str(ID)) def exportEvent(self, fnout, fnext='.xml'): + """ + + :param fnout: + :param fnext: + :raise KeyError: + """ from pylot.core.util.defaults import OUTPUTFORMATS try: evtformat = OUTPUTFORMATS[fnext] - except KeyError, e: + except KeyError as e: errmsg = '{0}; selected file extension {1} not ' \ 'supported'.format(e, fnext) raise FormatError(errmsg) @@ -89,24 +118,42 @@ class Data(object): # try exporting event via ObsPy try: self.getEvtData().write(fnout + fnext, format=evtformat) - except KeyError, e: + except KeyError as e: raise KeyError('''{0} export format not implemented: {1}'''.format(evtformat, e)) def getComp(self): + """ + + + :return: + """ return self.comp def getID(self): + """ + + + :return: + """ try: return self.evtdata.get('resource_id').id except: return None def filterWFData(self, kwargs): + """ + + :param kwargs: + """ self.getWFData().filter(**kwargs) self.dirty = True def setWFData(self, fnames): + """ + + :param fnames: + """ self.wfdata = Stream() self.wforiginal = None if fnames is not None: @@ -115,6 +162,10 @@ class Data(object): self.dirty = False def appendWFData(self, fnames): + """ + + :param fnames: + """ assert isinstance(fnames, list), "input parameter 'fnames' is " \ "supposed to be of type 'list' " \ "but is actually {0}".format(type( @@ -129,27 +180,51 @@ class Data(object): except TypeError: try: self.wfdata += read(fname, format='GSE2') - except Exception, e: + except Exception as e: warnmsg += '{0}\n{1}\n'.format(fname, e) if warnmsg: warnmsg = 'WARNING: unable to read\n' + warnmsg - print warnmsg + print(warnmsg) def getWFData(self): + """ + + + :return: + """ return self.wfdata def getOriginalWFData(self): + """ + + + :return: + """ return self.wforiginal def resetWFData(self): + """ + + + """ self.wfdata = self.getOriginalWFData().copy() self.dirty = False def resetPicks(self): + """ + + + """ self.getEvtData().picks = [] def restituteWFData(self, invdlpath, streams=None): - if streams == None: + """ + + :param invdlpath: + :param streams: + :return: + """ + if streams is None: st = self.getWFData() else: st = streams @@ -157,7 +232,7 @@ class Data(object): for tr in st: # remove underscores if tr.stats.station[3] == '_': - tr.stats.station = tr.stats.station[0:3] + tr.stats.station = tr.stats.station[0:3] dlp = '%s/*.dless' % invdlpath invp = '%s/*.xml' % invdlpath respp = '%s/*.resp' % invdlpath @@ -167,47 +242,52 @@ class Data(object): # check for dataless-SEED file if len(dlfile) >= 1: - print "Found dataless-SEED file(s)!" - print "Reading meta data information ..." + print("Found dataless-SEED file(s)!") + print("Reading meta data information ...") for j in range(len(dlfile)): - print "Found dataless-SEED file %s" % dlfile[j] - parser = Parser('%s' % dlfile[j]) - for i in range(len(st)): + print("Found dataless-SEED file %s" % dlfile[j]) + parser = Parser('%s' % dlfile[j]) + for i in range(len(st)): # check, whether this trace has already been corrected try: st[i].stats.processing except: - try: - print "Correcting %s, %s for instrument response ..." \ - % (st[i].stats.station, st[i].stats.channel) + try: + print( + "Correcting %s, %s for instrument response ..." \ + % (st[i].stats.station, st[i].stats.channel)) # get corner frequencies for pre-filtering fny = st[i].stats.sampling_rate / 2 fc21 = fny - (fny * 0.05) fc22 = fny - (fny * 0.02) prefilt = [0.5, 0.9, fc21, fc22] # instrument correction - st[i].simulate(pre_filt=prefilt, seedresp={'filename': parser, \ - 'date': st[i].stats.starttime, 'units': "VEL"}) - except ValueError, e: - vmsg = '{0}'.format(e) - print vmsg + st[i].simulate(pre_filt=prefilt, + seedresp={'filename': parser, \ + 'date': st[ + i].stats.starttime, + 'units': "VEL"}) + except ValueError as e: + vmsg = '{0}'.format(e) + print(vmsg) else: - print "Trace has already been corrected!" + print("Trace has already been corrected!") # check for inventory-xml file if len(invfile) >= 1: - print "Found inventory-xml file(s)!" - print "Reading meta data information ..." + print("Found inventory-xml file(s)!") + print("Reading meta data information ...") 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") - for i in range(len(st)): + for i in range(len(st)): # check, whether this trace has already been corrected try: st[i].stats.processing except: - try: - print "Correcting %s, %s for instrument response ..." \ - % (st[i].stats.station, st[i].stats.channel) + try: + print( + "Correcting %s, %s for instrument response ..." \ + % (st[i].stats.station, st[i].stats.channel)) # get corner frequencies for pre-filtering fny = st[i].stats.sampling_rate / 2 fc21 = fny - (fny * 0.05) @@ -216,57 +296,78 @@ class Data(object): # instrument correction st[i].attach_response(inv) st[i].remove_response(output='VEL', pre_filt=prefilt) - except ValueError, e: - vmsg = '{0}'.format(e) - print vmsg - else: - print "Trace has already been corrected!" + except ValueError as e: + vmsg = '{0}'.format(e) + print(vmsg) + else: + print("Trace has already been corrected!") # check for RESP-file if len(respfile) >= 1: - print "Found response file(s)!" - print "Reading meta data information ..." + print("Found response file(s)!") + print("Reading meta data information ...") for j in range(len(respfile)): - print "Found RESP-file %s" % respfile[j] - for i in range(len(st)): + print("Found RESP-file %s" % respfile[j]) + for i in range(len(st)): # check, whether this trace has already been corrected try: st[i].stats.processing except: - try: - print "Correcting %s, %s for instrument response ..." \ - % (st[i].stats.station, st[i].stats.channel) + try: + print( + "Correcting %s, %s for instrument response ..." \ + % (st[i].stats.station, st[i].stats.channel)) # get corner frequencies for pre-filtering fny = st[i].stats.sampling_rate / 2 fc21 = fny - (fny * 0.05) fc22 = fny - (fny * 0.02) prefilt = [0.5, 0.9, fc21, fc22] # instrument correction - seedresp={'filename': respfile[0], 'date': st[0].stats.starttime, \ - 'units': "VEL"} + seedresp={'filename': respfile[0], 'date': st[0].stats.starttime, \ + 'units': "VEL"} st[i].simulate(paz_remove=None, pre_filt=prefilt, seedresp=seedresp) - except ValueError, e: - vmsg = '{0}'.format(e) - print vmsg - else: - print "Trace has already been corrected!" + except ValueError as e: + vmsg = '{0}'.format(e) + print(vmsg) + else: + print("Trace has already been corrected!") 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 "Go on processing data without source parameter determination!" + print( + "No dataless-SEED file,inventory-xml file nor RESP-file found!") + print( + "Go on processing data without source parameter determination!") return st def getEvtData(self): + """ + + + :return: + """ return self.evtdata def applyEVTData(self, data, type='pick', authority_id='rub'): + """ + + :param data: + :param type: + :param authority_id: + :raise OverwriteError: + """ + def applyPicks(picks): + """ + + :param picks: + :raise OverwriteError: + """ firstonset = None if self.getEvtData().picks: raise OverwriteError('Actual picks would be overwritten!') 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(): onset = phase['mpp'] epp = phase['epp'] @@ -282,8 +383,8 @@ class Data(object): self.getEvtData().picks.append(pick) try: polarity = phase['fm'] - except KeyError, e: - print 'No polarity information found for %s' % phase + except KeyError as e: + print('No polarity information found for %s' % phase) if firstonset is None or firstonset > onset: firstonset = onset @@ -294,9 +395,17 @@ class Data(object): self.getEvtData().resource_id = ID def applyArrivals(arrivals): + """ + + :param arrivals: + """ pass def applyEvent(event): + """ + + :param event: + """ pass applydata = {'pick': applyPicks, @@ -322,6 +431,10 @@ class GenericDataStructure(object): def modifyFields(self, **kwargs): + """ + + :param kwargs: + """ assert isinstance(kwargs, dict), 'dictionary type object expected' if not self.extraAllowed(): @@ -337,37 +450,67 @@ class GenericDataStructure(object): value = str(value) try: self.setFieldValue(key, value) - except KeyError, e: + except KeyError as e: errmsg = '' errmsg += 'WARNING:\n' errmsg += 'unable to set values for datastructure fields\n' errmsg += '%s; desired value was: %s\n' % (e, value) - print errmsg + print(errmsg) def isField(self, key): + """ + + :param key: + :return: + """ return key in self.getFields().keys() def getFieldValue(self, key): + """ + + :param key: + :return: + """ if self.isField(key): return self.getFields()[key] else: return def setFieldValue(self, key, value): + """ + + :param key: + :param value: + :raise KeyError: + """ if not self.extraAllowed() and key not in self.getAllowed(): raise KeyError else: if not self.isField(key): - print 'creating new field "%s"' % key + print('creating new field "%s"' % key) self.getFields()[key] = value def getFields(self): + """ + + + :return: + """ return self.dsFields def getExpandFields(self): + """ + + + :return: + """ return self.expandFields def setExpandFields(self, keys): + """ + + :param keys: + """ expandFields = [] for key in keys: if self.isField(key): @@ -375,18 +518,38 @@ class GenericDataStructure(object): self.expandFields = expandFields def getAllowed(self): + """ + + + :return: + """ return self.allowedFields def extraAllowed(self): + """ + + + :return: + """ return not self.allowedFields def updateNotAllowed(self, kwargs): + """ + + :param kwargs: + :return: + """ for key in kwargs: if key not in self.getAllowed(): kwargs.__delitem__(key) return kwargs def hasSuffix(self): + """ + + + :return: + """ try: self.getFieldValue('suffix') except KeyError: @@ -397,6 +560,11 @@ class GenericDataStructure(object): return False def expandDataPath(self): + """ + + + :return: + """ expandList = [] for item in self.getExpandFields(): expandList.append(self.getFieldValue(item)) @@ -405,6 +573,11 @@ class GenericDataStructure(object): return os.path.join(*expandList) def getCatalogName(self): + """ + + + :return: + """ return os.path.join(self.getFieldValue('root'), 'catalog.qml') @@ -463,6 +636,10 @@ class SeiscompDataStructure(GenericDataStructure): self.modifiyFields(**kwargs) def modifiyFields(self, **kwargs): + """ + + :param kwargs: + """ if kwargs and isinstance(kwargs, dict): for key, value in kwargs.iteritems(): key = str(key) @@ -473,14 +650,19 @@ class SeiscompDataStructure(GenericDataStructure): value = str(value) try: self.setField(key, value) - except KeyError, e: + except KeyError as e: errmsg = '' errmsg += 'WARNING:\n' errmsg += 'unable to set values for SDS fields\n' errmsg += '%s; desired value was: %s\n' % (e, value) - print errmsg + print(errmsg) def setFieldValue(self, key, value): + """ + + :param key: + :param value: + """ if self.isField(key): self.getFields()[key] = value else: @@ -488,12 +670,27 @@ class SeiscompDataStructure(GenericDataStructure): '{field}'.format(field=key)) def getFields(self): + """ + + + :return: + """ return self.__sdsFields def getName(self): + """ + + + :return: + """ return self.__name def expandDataPath(self): + """ + + + :return: + """ fullChan = '{0}.{1}'.format(self.getFields()['CHAN'], self.getType()) dataPath = os.path.join(self.getFields()['SDSdir'], self.getFields()['YEAR'], From 497ca39c91b1a7622e6ccca7c727c4ae3cf213d3 Mon Sep 17 00:00:00 2001 From: Sebastian Wehling-Benatelli Date: Fri, 28 Aug 2015 10:15:28 +0200 Subject: [PATCH 4/5] reformatted data.py to meet coding conventions --- pylot/core/read/data.py | 79 +++++++++++++++++------------------------ 1 file changed, 32 insertions(+), 47 deletions(-) diff --git a/pylot/core/read/data.py b/pylot/core/read/data.py index d5962b92..f3e07d30 100644 --- a/pylot/core/read/data.py +++ b/pylot/core/read/data.py @@ -14,20 +14,17 @@ from pylot.core.util.errors import FormatError, OverwriteError class Data(object): - ''' + """ Data container with attributes wfdata holding ~obspy.core.stream. :type parent: PySide.QtGui.QWidget object, optional :param parent: A PySide.QtGui.QWidget object utilized when called by a GUI to display a PySide.QtGui.QMessageBox instead of printing 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 :param evtdata ~obspy.core.event.Event object containing all derived or loaded event. Container object holding, e.g. phase arrivals, etc. - ''' + """ def __init__(self, parent=None, evtdata=None): self._parent = parent @@ -168,8 +165,8 @@ class Data(object): """ assert isinstance(fnames, list), "input parameter 'fnames' is " \ "supposed to be of type 'list' " \ - "but is actually {0}".format(type( - fnames)) + "but is actually" \ + " {0}".format(type(fnames)) if self.dirty: self.resetWFData() @@ -254,8 +251,9 @@ class Data(object): except: try: print( - "Correcting %s, %s for instrument response ..." \ - % (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 fny = st[i].stats.sampling_rate / 2 fc21 = fny - (fny * 0.05) @@ -263,7 +261,7 @@ class Data(object): prefilt = [0.5, 0.9, fc21, fc22] # instrument correction st[i].simulate(pre_filt=prefilt, - seedresp={'filename': parser, \ + seedresp={'filename': parser, 'date': st[ i].stats.starttime, 'units': "VEL"}) @@ -285,9 +283,9 @@ class Data(object): st[i].stats.processing except: try: - print( - "Correcting %s, %s for instrument response ..." \ - % (st[i].stats.station, st[i].stats.channel)) + print("Correcting %s, %s for instrument response " + "..." % (st[i].stats.station, + st[i].stats.channel)) # get corner frequencies for pre-filtering fny = st[i].stats.sampling_rate / 2 fc21 = fny - (fny * 0.05) @@ -295,7 +293,8 @@ class Data(object): prefilt = [0.5, 0.9, fc21, fc22] # instrument correction st[i].attach_response(inv) - st[i].remove_response(output='VEL', pre_filt=prefilt) + st[i].remove_response(output='VEL', + pre_filt=prefilt) except ValueError as e: vmsg = '{0}'.format(e) print(vmsg) @@ -313,18 +312,20 @@ class Data(object): st[i].stats.processing except: try: - print( - "Correcting %s, %s for instrument response ..." \ - % (st[i].stats.station, st[i].stats.channel)) + print("Correcting %s, %s for instrument response " + "..." % (st[i].stats.station, + st[i].stats.channel)) # get corner frequencies for pre-filtering fny = st[i].stats.sampling_rate / 2 fc21 = fny - (fny * 0.05) fc22 = fny - (fny * 0.02) prefilt = [0.5, 0.9, fc21, fc22] # instrument correction - seedresp={'filename': respfile[0], 'date': st[0].stats.starttime, \ - 'units': "VEL"} - st[i].simulate(paz_remove=None, pre_filt=prefilt, seedresp=seedresp) + seedresp = {'filename': respfile[0], + 'date': st[0].stats.starttime, + 'units': "VEL"} + st[i].simulate(paz_remove=None, pre_filt=prefilt, + seedresp=seedresp) except ValueError as e: vmsg = '{0}'.format(e) print(vmsg) @@ -332,10 +333,10 @@ class Data(object): print("Trace has already been corrected!") 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( - "Go on processing data without source parameter determination!") + print("No dataless-SEED file,inventory-xml file nor RESP-file " + "found!") + print("Go on processing data without source parameter " + "determination!") return st @@ -416,10 +417,10 @@ class Data(object): class GenericDataStructure(object): - ''' + """ GenericDataBase type holds all information about the current data- base working on. - ''' + """ def __init__(self, **kwargs): @@ -582,10 +583,10 @@ class GenericDataStructure(object): class PilotDataStructure(GenericDataStructure): - ''' + """ Object containing the data access information for the old PILOT data structure. - ''' + """ def __init__(self, **fields): if not fields: @@ -598,14 +599,14 @@ class PilotDataStructure(GenericDataStructure): class SeiscompDataStructure(GenericDataStructure): - ''' + """ Dictionary containing the data access information for an SDS data archive: :param str dataType: Desired data type. Default: ``'waveform'`` :param sdate, edate: Either date string or an instance of :class:`obspy.core.utcdatetime.UTCDateTime. Default: ``None`` :type sdate, edate: str or UTCDateTime or None - ''' + """ def __init__(self, rootpath='/data/SDS', dataformat='MSEED', filesuffix=None, **kwargs): @@ -649,7 +650,7 @@ class SeiscompDataStructure(GenericDataStructure): else: value = str(value) try: - self.setField(key, value) + self.setFieldValue(key, value) except KeyError as e: errmsg = '' errmsg += 'WARNING:\n' @@ -669,22 +670,6 @@ class SeiscompDataStructure(GenericDataStructure): print('Warning: trying to set value of non-existent field ' '{field}'.format(field=key)) - def getFields(self): - """ - - - :return: - """ - return self.__sdsFields - - def getName(self): - """ - - - :return: - """ - return self.__name - def expandDataPath(self): """ From 1f7049691c5ed78145836165668bf2d5dc6c6f5f Mon Sep 17 00:00:00 2001 From: Sebastianw Wehling-Benatelli Date: Fri, 28 Aug 2015 16:01:42 +0200 Subject: [PATCH 5/5] [addresses #167] started fixing the multiple phase saving issue --- QtPyLoT.py | 13 +++++++++---- pylot/RELEASE-VERSION | 2 +- pylot/core/read/data.py | 13 +++++++++++-- 3 files changed, 21 insertions(+), 7 deletions(-) diff --git a/QtPyLoT.py b/QtPyLoT.py index 254e88f7..d14c51a0 100755 --- a/QtPyLoT.py +++ b/QtPyLoT.py @@ -405,13 +405,16 @@ class MainWindow(QMainWindow): except OverwriteError: msgBox = QMessageBox() msgBox.setText("Picks have been modified!") - msgBox.setInformativeText("Do you want to overwrite the picks and save?") - msgBox.setStandardButtons(QMessageBox.Save | QMessageBox.Discard | - QMessageBox.Cancel) + 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: - print('Overwrite and Save') + self.getData().resetPicks() + self.saveData() + elif ret == QMessageBox.Cancel: + return False try: self.getData().exportEvent(self.fname, exform) except FormatError: @@ -425,6 +428,8 @@ class MainWindow(QMainWindow): fbasename, exform = os.path.splitext(fname[0]) if not fbasename: return False + elif not exform: + exform = fname[1].split('*')[1][:-1] self.getData().exportEvent(fbasename, exform) return True diff --git a/pylot/RELEASE-VERSION b/pylot/RELEASE-VERSION index 52c00f77..541bd94d 100644 --- a/pylot/RELEASE-VERSION +++ b/pylot/RELEASE-VERSION @@ -1 +1 @@ -1abc-dirty +497c-dirty diff --git a/pylot/core/read/data.py b/pylot/core/read/data.py index f3e07d30..3c83e9aa 100644 --- a/pylot/core/read/data.py +++ b/pylot/core/read/data.py @@ -52,6 +52,13 @@ class Data(object): def __str__(self): 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): """ @@ -360,9 +367,11 @@ class Data(object): 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: + :raise OverwriteError: raises an OverwriteError if the picks list is + not empty. The GUI will then ask for a decision. """ firstonset = None if self.getEvtData().picks: