From 4d3b300e1728e71a6b9cd65cacae5202020c1c79 Mon Sep 17 00:00:00 2001 From: Marcel Date: Thu, 19 Apr 2018 16:51:29 +0200 Subject: [PATCH 001/169] [removed] check4gaps/doubled, plotting merged instead --- PyLoT.py | 9 +++++---- pylot/core/io/data.py | 3 --- pylot/core/util/widgets.py | 19 ++++++++++++++++++- 3 files changed, 23 insertions(+), 8 deletions(-) diff --git a/PyLoT.py b/PyLoT.py index cd3c849d..9d73bd32 100755 --- a/PyLoT.py +++ b/PyLoT.py @@ -1753,13 +1753,14 @@ class MainWindow(QMainWindow): def finish_pg_plot(self): self.getPlotWidget().updateWidget() - plots = self.wfp_thread.data + plots, gaps = self.wfp_thread.data for times, data, times_syn, data_syn in plots: self.dataPlot.plotWidget.getPlotItem().plot(times, data, pen=self.dataPlot.pen_linecolor) if len(data_syn) > 0: self.dataPlot.plotWidget.getPlotItem().plot(times_syn, data_syn, pen=self.dataPlot.pen_linecolor_syn) + self.dataPlot.reinitMoveProxy() self.dataPlot.plotWidget.showAxis('left') self.dataPlot.plotWidget.showAxis('bottom') @@ -1900,9 +1901,9 @@ class MainWindow(QMainWindow): self.plot_method = 'fast' else: self.plot_method = 'normal' - plots = plotWidget.plotWFData(wfdata=wfst, wfsyn=wfsyn, title=title, mapping=False, component=comp, - nth_sample=int(nth_sample), method=self.plot_method) - return plots + plots, gaps = plotWidget.plotWFData(wfdata=wfst, wfsyn=wfsyn, title=title, mapping=False, component=comp, + nth_sample=int(nth_sample), method=self.plot_method) + return plots, gaps def adjustPlotHeight(self): if self.pg: diff --git a/pylot/core/io/data.py b/pylot/core/io/data.py index a7cb85d5..50e7a961 100644 --- a/pylot/core/io/data.py +++ b/pylot/core/io/data.py @@ -398,9 +398,6 @@ class Data(object): # various pre-processing steps: # remove possible underscores in station names self.wfdata = remove_underscores(self.wfdata) - # check for gaps and doubled channels - check4gaps(self.wfdata) - check4doubled(self.wfdata) # check for stations with rotated components if checkRotated and metadata is not None: self.wfdata = check4rotated(self.wfdata, metadata, verbosity=0) diff --git a/pylot/core/util/widgets.py b/pylot/core/util/widgets.py index 56dc16dd..d31a2a6e 100644 --- a/pylot/core/util/widgets.py +++ b/pylot/core/util/widgets.py @@ -464,6 +464,7 @@ class WaveformWidgetPG(QtGui.QWidget): self.wfstart, self.wfend = 0, 0 self.pen_multicursor = self.pg.mkPen(self.parent()._style['multicursor']['rgba']) self.pen_linecolor = self.pg.mkPen(self.parent()._style['linecolor']['rgba']) + self.pen_linecolor_highlight = self.pg.mkPen((255, 100, 100, 255)) self.pen_linecolor_syn = self.pg.mkPen((100, 0, 255, 255)) self.reinitMoveProxy() self._proxy = self.pg.SignalProxy(self.plotWidget.scene().sigMouseMoved, rateLimit=60, slot=self.mouseMoved) @@ -529,6 +530,14 @@ class WaveformWidgetPG(QtGui.QWidget): else: st_select = wfdata + gaps = st_select.get_gaps() + if gaps: + merged = ['{}.{}.{}.{}'.format(*gap[:4]) for gap in gaps] + st_select.merge() + print('Merged the following stations because of gaps:') + for merged_station in merged: + print(merged_station) + # list containing tuples of network, station, channel (for sorting) nsc = [] for trace in st_select: @@ -590,7 +599,7 @@ class WaveformWidgetPG(QtGui.QWidget): self.ylabel = '' self.setXLims([0, self.wfend - self.wfstart]) self.setYLims([0.5, nmax + 0.5]) - return plots + return plots, gaps def minMax(self, trace, time_ax): ''' @@ -1013,6 +1022,14 @@ class PylotCanvas(FigureCanvas): if mapping: plot_positions = self.calcPlotPositions(st_select, compclass) + gaps = st_select.get_gaps() + if gaps: + merged = ['{}.{}.{}.{}'.format(*gap[:4]) for gap in gaps] + st_select.merge() + print('Merged the following stations because of gaps:') + for merged_station in merged: + print(merged_station) + # list containing tuples of network, station, channel and plot position (for sorting) nsc = [] for plot_pos, trace in enumerate(st_select): From 9b0ef55b702d63f74d027077c93194dd35cb9f65 Mon Sep 17 00:00:00 2001 From: Marcel Date: Fri, 20 Apr 2018 13:51:21 +0200 Subject: [PATCH 002/169] [bugfix] wasnt using processed data --- pylot/core/io/data.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/pylot/core/io/data.py b/pylot/core/io/data.py index 50e7a961..77b24a3d 100644 --- a/pylot/core/io/data.py +++ b/pylot/core/io/data.py @@ -379,7 +379,10 @@ class Data(object): self.wfsyn = Stream() wffnames = None wffnames_syn = None - wfdir = 'processed' if 'processed' in [fname.split('/')[-1] for fname in fnames] else 'raw' + wfdir = 'raw' + for fname in fnames: + if fname.endswith('processed'): + wfdir = 'processed' if obspy_dmt: for fpath in fnames: if fpath.endswith(wfdir): From 0320ad67b98b6b2ef40f5955bf5a0a48dd5466f6 Mon Sep 17 00:00:00 2001 From: Marcel Date: Fri, 20 Apr 2018 14:53:15 +0200 Subject: [PATCH 003/169] [new] station highlighting by middle mouseclick --- PyLoT.py | 44 +++++++++++++++++++++++++++++++++++++++----- 1 file changed, 39 insertions(+), 5 deletions(-) diff --git a/PyLoT.py b/PyLoT.py index 9d73bd32..5ff59b30 100755 --- a/PyLoT.py +++ b/PyLoT.py @@ -138,6 +138,7 @@ class MainWindow(QMainWindow): self._eventChanged = [False, False] self.apd_local = None self.apd_sge = None + self.stations_highlighted = [] self.poS_id = None self.ae_id = None @@ -1764,6 +1765,7 @@ class MainWindow(QMainWindow): self.dataPlot.reinitMoveProxy() self.dataPlot.plotWidget.showAxis('left') self.dataPlot.plotWidget.showAxis('bottom') + self.highlight_stations() def finishWaveformDataPlot(self): self.comparable = self.checkEvents4comparison() @@ -2132,10 +2134,12 @@ class MainWindow(QMainWindow): def pickOnStation(self, gui_event): if self.pg: - if not gui_event.button() == 1: + button = gui_event.button() + if not button in [1, 4]: return else: - if not gui_event.button == 1: + button = gui_event.button + if not button == 1: return if self.pg: @@ -2146,12 +2150,42 @@ class MainWindow(QMainWindow): wfID = self.getWFID(ycoord) if wfID is None: return - self.pickDialog(wfID) - def pickDialog(self, wfID, nextStation=False): - station = self.getStationName(wfID) network = self.getNetworkName(wfID) + station = self.getStationName(wfID) + if button == 1: + self.pickDialog(wfID, network, station) + elif button == 4: + self.toggle_station_color(wfID, network, station) + + def toggle_station_color(self, wfID, network, station): + black_pen = pg.mkPen((0, 0, 0)) + red_pen = pg.mkPen((200, 50, 50)) + line_item = self.dataPlot.plotWidget.getPlotItem().listDataItems()[wfID - 1] + current_pen = line_item.opts['pen'] + nwst = '{}.{}'.format(network, station) + if current_pen == black_pen: + line_item.setPen(red_pen) + if not nwst in self.stations_highlighted: + self.stations_highlighted.append(nwst) + else: + line_item.setPen(black_pen) + if nwst in self.stations_highlighted: + self.stations_highlighted.pop(self.stations_highlighted.index(nwst)) + + def highlight_stations(self): + for wfID, value in self.getPlotWidget().getPlotDict().items(): + station, channel, network = value + nwst = '{}.{}'.format(network, station) + if nwst in self.stations_highlighted: + self.toggle_station_color(wfID, network, station) + + def pickDialog(self, wfID, network=None, station=None, nextStation=False): + if not network: + network = self.getNetworkName(wfID) if not station: + station = self.getStationName(wfID) + if not station or not network: return self.update_status('picking on station {0}'.format(station)) data = self.get_data().getOriginalWFData().copy() From 36a4f0df8a8375d871be186dd5f66b842442329f Mon Sep 17 00:00:00 2001 From: Marcel Date: Mon, 23 Apr 2018 13:33:05 +0200 Subject: [PATCH 004/169] [bugfix] error when there is nothing to plot --- PyLoT.py | 5 +++-- pylot/core/util/widgets.py | 4 ++++ 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/PyLoT.py b/PyLoT.py index 5ff59b30..6d56c19f 100755 --- a/PyLoT.py +++ b/PyLoT.py @@ -1903,8 +1903,9 @@ class MainWindow(QMainWindow): self.plot_method = 'fast' else: self.plot_method = 'normal' - plots, gaps = plotWidget.plotWFData(wfdata=wfst, wfsyn=wfsyn, title=title, mapping=False, component=comp, - nth_sample=int(nth_sample), method=self.plot_method) + rval = plotWidget.plotWFData(wfdata=wfst, wfsyn=wfsyn, title=title, mapping=False, component=comp, + nth_sample=int(nth_sample), method=self.plot_method) + plots, gaps = rval if rval else ([], []) return plots, gaps def adjustPlotHeight(self): diff --git a/pylot/core/util/widgets.py b/pylot/core/util/widgets.py index d31a2a6e..89bc851c 100644 --- a/pylot/core/util/widgets.py +++ b/pylot/core/util/widgets.py @@ -447,6 +447,10 @@ class WaveformWidgetPG(QtGui.QWidget): self.orig_parent = parent # attribute plotdict is a dictionary connecting position and a name self.plotdict = dict() + # init labels + self.xlabel = None + self.ylabel = None + self.title = None # create plot self.main_layout = QtGui.QVBoxLayout() self.label_layout = QtGui.QHBoxLayout() From e6648a3cecd879380c32a8a924fe30e80a569c94 Mon Sep 17 00:00:00 2001 From: Marcel Date: Mon, 23 Apr 2018 16:49:01 +0200 Subject: [PATCH 005/169] [add] read event info from obsDMT pickle file --- pylot/core/io/data.py | 4 +++- pylot/core/util/event.py | 14 ++++++++++++++ pylot/core/util/obspyDMT_interface.py | 18 +++++++++++++++++- 3 files changed, 34 insertions(+), 2 deletions(-) diff --git a/pylot/core/io/data.py b/pylot/core/io/data.py index 77b24a3d..aa42738b 100644 --- a/pylot/core/io/data.py +++ b/pylot/core/io/data.py @@ -15,7 +15,7 @@ from pylot.core.util.event import Event from pylot.core.util.utils import fnConstructor, full_range, remove_underscores, check4gaps, check4doubled, \ check4rotated, trim_station_components import pylot.core.loc.velest as velest - +from pylot.core.util.obspyDMT_interface import qml_from_obspyDMT class Data(object): """ @@ -60,6 +60,8 @@ class Data(object): raise NotImplementedError('PILOT location information ' 'read support not yet ' 'implemeted.') + elif 'event.pkl' in evtdata: + evtdata = qml_from_obspyDMT(evtdata) else: raise e else: diff --git a/pylot/core/util/event.py b/pylot/core/util/event.py index 4ded8d50..a4f1e9cb 100644 --- a/pylot/core/util/event.py +++ b/pylot/core/util/event.py @@ -7,6 +7,7 @@ from obspy import UTCDateTime from obspy.core.event import Event as ObsPyEvent from obspy.core.event import Origin, ResourceIdentifier from pylot.core.io.phases import picks_from_picksdict +from pylot.core.util.obspyDMT_interface import qml_from_obspyDMT class Event(ObsPyEvent): @@ -33,6 +34,7 @@ class Event(ObsPyEvent): self._testEvent = False self._refEvent = False self.get_notes() + self.get_obspy_event_info() def get_notes_path(self): """ @@ -43,6 +45,18 @@ class Event(ObsPyEvent): notesfile = os.path.join(self.path, 'notes.txt') return notesfile + def get_obspy_event_info(self): + infile_pickle = os.path.join(self.path, 'info/event.pkl') + if not os.path.isfile(infile_pickle): + return + try: + event_dmt = qml_from_obspyDMT(infile_pickle) + except Exception as e: + print('Could not get obspy event info: {}'.format(e)) + return + self.magnitudes = event_dmt.magnitudes + self.origins = event_dmt.origins + def get_notes(self): """ set self.note attribute to content of notes file diff --git a/pylot/core/util/obspyDMT_interface.py b/pylot/core/util/obspyDMT_interface.py index 661e4f5b..47d5c687 100644 --- a/pylot/core/util/obspyDMT_interface.py +++ b/pylot/core/util/obspyDMT_interface.py @@ -25,4 +25,20 @@ def check_obspydmt_eventfolder(folder): except Exception as e: return False, e -check_obspydmt_eventfolder('20110311_054623.a') \ No newline at end of file +def qml_from_obspyDMT(path): + import pickle + from obspy.core.event import Event, Magnitude, Origin + + if not os.path.exists(path): + return IOError('Could not find Event at {}'.format(path)) + infile = open(path, 'rb') + event_dmt = pickle.load(infile) + ev = Event(resource_id=event_dmt['event_id']) + origin = Origin(resource_id=event_dmt['origin_id'], time=event_dmt['datetime'], longitude=event_dmt['longitude'], + latitude=event_dmt['latitude'], depth=event_dmt['depth']) + mag = Magnitude(mag=event_dmt['magnitude'], magnitude_type=event_dmt['magnitude_type'], + origin_id=event_dmt['origin_id']) + ev.magnitudes.append(mag) + ev.origins.append(origin) + return ev + From d3de33a12bc569750ccd2ffc50569858edba548b Mon Sep 17 00:00:00 2001 From: Marcel Date: Mon, 23 Apr 2018 17:00:09 +0200 Subject: [PATCH 006/169] [add] lineEdit showing if using processed/raw data --- PyLoT.py | 20 ++++++++++++++++++-- pylot/core/io/data.py | 12 ++++++++---- pylot/core/util/widgets.py | 25 ++++++++++++++++++------- 3 files changed, 44 insertions(+), 13 deletions(-) diff --git a/PyLoT.py b/PyLoT.py index 6d56c19f..f713d4b1 100755 --- a/PyLoT.py +++ b/PyLoT.py @@ -1667,6 +1667,21 @@ class MainWindow(QMainWindow): metadata=self.metadata, obspy_dmt=obspy_dmt) + def setWFstatus(self): + ''' + show status of current data, can be either 'raw' or 'processed' + :param status: + :return: + ''' + status = self.data.processed + wf_stat_color = {True: 'green', + False: 'black', + None: None} + wf_stat = {True: 'processed', + False: 'raw', + None: None} + self.dataPlot.setPermTextRight(wf_stat[status], wf_stat_color[status]) + def check_plot_quantity(self): settings = QSettings() nth_sample = int(settings.value("nth_sample")) if settings.value("nth_sample") else 1 @@ -1807,6 +1822,7 @@ class MainWindow(QMainWindow): if True in self.comparable.values(): self.compare_action.setEnabled(True) self.draw() + self.setWFstatus() def checkEvent4comparison(self, event): if event.pylot_picks and event.pylot_autopicks: @@ -3212,9 +3228,9 @@ class MainWindow(QMainWindow): self.fill_eventbox() self.getPlotWidget().draw() if self.plot_method == 'fast': - self.dataPlot.setPermText('MIN/MAX plot', color='red') + self.dataPlot.setPermTextMid('MIN/MAX plot', color='red') else: - self.dataPlot.setPermText() + self.dataPlot.setPermTextMid() def _setDirty(self): self.setDirty(True) diff --git a/pylot/core/io/data.py b/pylot/core/io/data.py index aa42738b..cd06a9b5 100644 --- a/pylot/core/io/data.py +++ b/pylot/core/io/data.py @@ -74,6 +74,7 @@ class Data(object): self.wforiginal = None self.cuttimes = None self.dirty = False + self.processed = None def __str__(self): return str(self.wfdata) @@ -381,11 +382,14 @@ class Data(object): self.wfsyn = Stream() wffnames = None wffnames_syn = None - wfdir = 'raw' - for fname in fnames: - if fname.endswith('processed'): - wfdir = 'processed' if obspy_dmt: + wfdir = 'raw' + self.processed = False + for fname in fnames: + if fname.endswith('processed'): + wfdir = 'processed' + self.processed = True + break for fpath in fnames: if fpath.endswith(wfdir): wffnames = [os.path.join(fpath, fname) for fname in os.listdir(fpath)] diff --git a/pylot/core/util/widgets.py b/pylot/core/util/widgets.py index 89bc851c..b6b8a07d 100644 --- a/pylot/core/util/widgets.py +++ b/pylot/core/util/widgets.py @@ -454,14 +454,13 @@ class WaveformWidgetPG(QtGui.QWidget): # create plot self.main_layout = QtGui.QVBoxLayout() self.label_layout = QtGui.QHBoxLayout() - self.status_label = QtGui.QLabel() - self.perm_label = QtGui.QLabel() - self.setLayout(self.main_layout) + self.add_labels() self.plotWidget = self.pg.PlotWidget(self.parent(), title=title) self.main_layout.addWidget(self.plotWidget) self.main_layout.addLayout(self.label_layout) self.label_layout.addWidget(self.status_label) - self.label_layout.addWidget(self.perm_label) + self.label_layout.addWidget(self.perm_label_mid) + self.label_layout.addWidget(self.perm_label_right) self.plotWidget.showGrid(x=False, y=True, alpha=0.3) self.plotWidget.hideAxis('bottom') self.plotWidget.hideAxis('left') @@ -494,12 +493,24 @@ class WaveformWidgetPG(QtGui.QWidget): self.vLine.setPos(mousePoint.x()) self.hLine.setPos(mousePoint.y()) + def add_labels(self): + self.status_label = QtGui.QLabel() + self.perm_label_mid = QtGui.QLabel() + self.perm_label_mid.setAlignment(4) + self.perm_label_right = QtGui.QLabel() + self.perm_label_right.setAlignment(2) + self.setLayout(self.main_layout) + def getPlotDict(self): return self.plotdict - def setPermText(self, text=None, color='black'): - self.perm_label.setText(text) - self.perm_label.setStyleSheet('color: {}'.format(color)) + def setPermTextMid(self, text=None, color='black'): + self.perm_label_mid.setText(text) + self.perm_label_mid.setStyleSheet('color: {}'.format(color)) + + def setPermTextRight(self, text=None, color='black'): + self.perm_label_right.setText(text) + self.perm_label_right.setStyleSheet('color: {}'.format(color)) def setPlotDict(self, key, value): self.plotdict[key] = value From 073a71e1503e60fd0eec4414c2353044a00c0fc4 Mon Sep 17 00:00:00 2001 From: Marcel Date: Tue, 24 Apr 2018 15:37:15 +0200 Subject: [PATCH 007/169] [add] origin/mag to eventBox --- PyLoT.py | 23 +++++++++++++++++++++-- pylot/core/util/widgets.py | 10 +++++++--- 2 files changed, 28 insertions(+), 5 deletions(-) diff --git a/PyLoT.py b/PyLoT.py index f713d4b1..9dc7de29 100755 --- a/PyLoT.py +++ b/PyLoT.py @@ -1250,6 +1250,17 @@ class MainWindow(QMainWindow): event_ref = event.isRefEvent() event_test = event.isTestEvent() + time = lat = lon = depth = mag = None + if len(event.origins) == 1: + origin = event.origins[0] + time = origin.time + 0 # add 0 because there was an exception for time = 0s + lat = origin.latitude + lon = origin.longitude + depth = origin.depth + if len(event.magnitudes) == 1: + magnitude = event.magnitudes[0] + mag = magnitude.mag + # text = '{path:{plen}} | manual: [{p:3d}] | auto: [{a:3d}]' # text = text.format(path=event_path, # plen=plmax, @@ -1257,6 +1268,11 @@ class MainWindow(QMainWindow): # a=event_nautopicks) item_path = QtGui.QStandardItem('{path:{plen}}'.format(path=event_path, plen=plmax)) + item_time = QtGui.QStandardItem('{}'.format(time)) + item_lat = QtGui.QStandardItem('{}'.format(lat)) + item_lon = QtGui.QStandardItem('{}'.format(lon)) + item_depth = QtGui.QStandardItem('{}'.format(depth)) + item_mag = QtGui.QStandardItem('{}'.format(mag)) item_nmp = QtGui.QStandardItem(str(ma_count['manual'])) item_nmp.setIcon(self.manupicksicon_small) item_nap = QtGui.QStandardItem(str(ma_count['auto'])) @@ -1282,7 +1298,10 @@ class MainWindow(QMainWindow): # item.setFont(font) # item2.setForeground(QtGui.QColor('black')) # item2.setFont(font) - itemlist = [item_path, item_nmp, item_nap, item_ref, item_test, item_notes] + itemlist = [item_path, item_time, item_lat, item_lon, item_depth, + item_mag, item_nmp, item_nap, item_ref, item_test, item_notes] + for item in itemlist: + item.setTextAlignment(Qt.AlignCenter) if event_test and select_events == 'ref': for item in itemlist: item.setEnabled(False) @@ -2935,7 +2954,7 @@ class MainWindow(QMainWindow): if hasattr(event, 'origins'): if event.origins: origin = event.origins[0] - item_time.setText(str(origin.time).split('.')[0]) + item_time.setText(str(origin.time + 0).split('.')[0]) # +0 as workaround in case time=0s item_lon.setText(str(origin.longitude)) item_lat.setText(str(origin.latitude)) item_depth.setText(str(origin.depth)) diff --git a/pylot/core/util/widgets.py b/pylot/core/util/widgets.py index b6b8a07d..5f9c9c03 100644 --- a/pylot/core/util/widgets.py +++ b/pylot/core/util/widgets.py @@ -576,6 +576,8 @@ class WaveformWidgetPG(QtGui.QWidget): st_syn = wfsyn.select(network=network, station=station, channel=channel) if st_syn: trace_syn = st_syn[0].copy() + else: + trace_syn = Trace() if mapping: comp = channel[-1] n = compclass.getPlotPosition(str(comp)) @@ -592,7 +594,9 @@ class WaveformWidgetPG(QtGui.QWidget): time_ax_syn = prepTimeAxis(stime_syn, trace_syn) if method == 'fast': - trace.data, time_ax = self.minMax(trace, time_ax) + trace.data, time_ax = self.minMax(trace, time_ax) + if trace_syn: + trace_syn.data, time_ax_syn = self.minMax(trace_syn, time_ax_syn) if time_ax not in [None, []]: if not scaleddata: @@ -605,10 +609,10 @@ class WaveformWidgetPG(QtGui.QWidget): times = np.array([time for index, time in enumerate(time_ax) if not index % nth_sample]) times_syn = np.array([time for index, time in enumerate(time_ax_syn) if not index % nth_sample] if st_syn else []) trace.data = np.array([datum + n for index, datum in enumerate(trace.data) if not index % nth_sample]) - trace.data_syn = np.array([datum + n for index, datum in enumerate(trace.data_syn) + trace_syn.data = np.array([datum + n for index, datum in enumerate(trace_syn.data) if not index % nth_sample] if st_syn else []) plots.append((times, trace.data, - times_syn, trace.data_syn)) + times_syn, trace_syn.data)) self.setPlotDict(n, (station, channel, network)) self.xlabel = 'seconds since {0}'.format(self.wfstart) self.ylabel = '' From d6150c5d1a3c201b380e499dc092c99c6e6172b1 Mon Sep 17 00:00:00 2001 From: Marcel Date: Wed, 25 Apr 2018 13:48:06 +0200 Subject: [PATCH 008/169] [new] disable event selection of folder is empty --- PyLoT.py | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/PyLoT.py b/PyLoT.py index 9dc7de29..ffe69bf3 100755 --- a/PyLoT.py +++ b/PyLoT.py @@ -1302,7 +1302,7 @@ class MainWindow(QMainWindow): item_mag, item_nmp, item_nap, item_ref, item_test, item_notes] for item in itemlist: item.setTextAlignment(Qt.AlignCenter) - if event_test and select_events == 'ref': + if event_test and select_events == 'ref' or self.isEmpty(event_path): for item in itemlist: item.setEnabled(False) model.appendRow(itemlist) @@ -1316,6 +1316,16 @@ class MainWindow(QMainWindow): eventBox.setCurrentIndex(index) self.refreshRefTestButtons() + def isEmpty(self, event_path): + wf_stat = {True: 'processed', + False: 'raw', + None: None} + + wf_dir = wf_stat[self.data.processed] + if wf_dir is not None: + event_path = os.path.join(event_path, wf_dir) + return not bool(os.listdir(event_path)) + def filename_from_action(self, action): if action.data() is None: filt = "Supported file formats" \ From 644470f1567582d7df6229981dd3dfabff2f8c53 Mon Sep 17 00:00:00 2001 From: Marcel Date: Wed, 25 Apr 2018 14:01:05 +0200 Subject: [PATCH 009/169] [bugfix] was only checking current data processing state --- PyLoT.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/PyLoT.py b/PyLoT.py index ffe69bf3..80e2b15a 100755 --- a/PyLoT.py +++ b/PyLoT.py @@ -1321,9 +1321,12 @@ class MainWindow(QMainWindow): False: 'raw', None: None} + # self.data.processed is only None for PyLoT datastructure, else True or False wf_dir = wf_stat[self.data.processed] if wf_dir is not None: event_path = os.path.join(event_path, wf_dir) + if wf_dir is 'processed' and not os.path.exists(event_path): + event_path = os.path.join(event_path, 'raw') return not bool(os.listdir(event_path)) def filename_from_action(self, action): From be82706413195d39a3043b83b9c6ab1265f2b394 Mon Sep 17 00:00:00 2001 From: Marcel Date: Wed, 25 Apr 2018 14:04:31 +0200 Subject: [PATCH 010/169] [bugfix] event_path overwritten --- PyLoT.py | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/PyLoT.py b/PyLoT.py index 80e2b15a..de4c879f 100755 --- a/PyLoT.py +++ b/PyLoT.py @@ -1324,10 +1324,14 @@ class MainWindow(QMainWindow): # self.data.processed is only None for PyLoT datastructure, else True or False wf_dir = wf_stat[self.data.processed] if wf_dir is not None: - event_path = os.path.join(event_path, wf_dir) - if wf_dir is 'processed' and not os.path.exists(event_path): - event_path = os.path.join(event_path, 'raw') - return not bool(os.listdir(event_path)) + wf_path = os.path.join(event_path, wf_dir) + if wf_dir is 'processed' and not os.path.exists(wf_path): + wf_path = os.path.join(event_path, 'raw') + else: + wf_path = event_path + if not os.path.exists(wf_path): + return True + return not bool(os.listdir(wf_path)) def filename_from_action(self, action): if action.data() is None: From c90a2f6ae19326b5edb27192a39a67355741d47d Mon Sep 17 00:00:00 2001 From: Marcel Date: Thu, 26 Apr 2018 14:50:18 +0200 Subject: [PATCH 011/169] [bugfix] forgot to replace PyQt4 with PySide --- icons_rc_2.py | 2 +- icons_rc_3.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/icons_rc_2.py b/icons_rc_2.py index bcf764af..9f36b183 100644 --- a/icons_rc_2.py +++ b/icons_rc_2.py @@ -7,7 +7,7 @@ # # WARNING! All changes made in this file will be lost! -from PyQt4 import QtCore +from PySide import QtCore qt_resource_data = "\ \x00\x00\x9e\x04\ diff --git a/icons_rc_3.py b/icons_rc_3.py index a437650d..963cf353 100644 --- a/icons_rc_3.py +++ b/icons_rc_3.py @@ -7,7 +7,7 @@ # # WARNING! All changes made in this file will be lost! -from PyQt4 import QtCore +from PySide import QtCore qt_resource_data = "\ \x00\x00\x9e\x04\ From 4c42d34adcee8916925af89482ac662f7e81c1ec Mon Sep 17 00:00:00 2001 From: Marcel Date: Thu, 26 Apr 2018 14:52:17 +0200 Subject: [PATCH 012/169] [bugfix] check for time_ax not working this way --- pylot/core/util/widgets.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pylot/core/util/widgets.py b/pylot/core/util/widgets.py index 5f9c9c03..5bd3cc52 100644 --- a/pylot/core/util/widgets.py +++ b/pylot/core/util/widgets.py @@ -598,7 +598,7 @@ class WaveformWidgetPG(QtGui.QWidget): if trace_syn: trace_syn.data, time_ax_syn = self.minMax(trace_syn, time_ax_syn) - if time_ax not in [None, []]: + if len(time_ax) > 0: if not scaleddata: trace.detrend('constant') trace.normalize(np.max(np.abs(trace.data)) * 2) From b02a0e8f9a84923bd06cec25efb6038ed967e112 Mon Sep 17 00:00:00 2001 From: Marcel Date: Thu, 26 Apr 2018 15:00:40 +0200 Subject: [PATCH 013/169] [bugfix] os.getlogin not working on all OS/python versions --- pylot/core/util/utils.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/pylot/core/util/utils.py b/pylot/core/util/utils.py index 79872e31..a973f622 100644 --- a/pylot/core/util/utils.py +++ b/pylot/core/util/utils.py @@ -454,7 +454,8 @@ def getLogin(): :return: login ID :rtype: str """ - return os.getlogin() + import getpass + return getpass.getuser() def getOwner(fn): From 18926610cf729c8ce190b2ecbb9c9a00a7d080de Mon Sep 17 00:00:00 2001 From: Marcel Date: Thu, 26 Apr 2018 16:19:12 +0200 Subject: [PATCH 014/169] [add] colorized table --- PyLoT.py | 23 ++++++++++++++++++++--- 1 file changed, 20 insertions(+), 3 deletions(-) diff --git a/PyLoT.py b/PyLoT.py index 51b13f70..7c718c10 100755 --- a/PyLoT.py +++ b/PyLoT.py @@ -2817,6 +2817,16 @@ class MainWindow(QMainWindow): event.addNotes(notes) self.fill_eventbox() + def set_background_color(items, color): + for item in items: + item.setBackground(color) + + def set_foreground_color(items, color): + for item in items: + item.setForeground(color) + + current_event = self.get_current_event() + # generate delete icon del_icon = QIcon() del_icon.addPixmap(QPixmap(':/icons/delete.png')) @@ -2880,9 +2890,6 @@ class MainWindow(QMainWindow): item_test = QtGui.QTableWidgetItem() item_notes = QtGui.QTableWidgetItem() - # manipulate items - item_ref.setBackground(self._ref_test_colors['ref']) - item_test.setBackground(self._ref_test_colors['test']) item_path.setText(event.path) if hasattr(event, 'origins'): if event.origins: @@ -2921,6 +2928,16 @@ class MainWindow(QMainWindow): item_nmp, item_nap, item_ref, item_test, item_notes] self.project._table.append(column) + if index%2: + set_background_color(column, QtGui.QColor(*(245, 245, 245, 255))) + + if event == current_event: + set_foreground_color(column, QtGui.QColor(*(0, 143, 143, 255))) + + # manipulate items + item_ref.setBackground(self._ref_test_colors['ref']) + item_test.setBackground(self._ref_test_colors['test']) + for r_index, row in enumerate(self.project._table): for c_index, item in enumerate(row): if type(item) == QtGui.QTableWidgetItem: From 8073a872c1d11536dad0b740a4266cbdd7e98c44 Mon Sep 17 00:00:00 2001 From: Marcel Date: Thu, 26 Apr 2018 16:26:03 +0200 Subject: [PATCH 015/169] [add] event colored grey if folder isEmpty --- PyLoT.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/PyLoT.py b/PyLoT.py index 1fa99970..b27a6536 100755 --- a/PyLoT.py +++ b/PyLoT.py @@ -3019,6 +3019,9 @@ class MainWindow(QMainWindow): if index%2: set_background_color(column, QtGui.QColor(*(245, 245, 245, 255))) + if self.isEmpty(event.path): + set_foreground_color(column, QtGui.QColor(*(180, 180, 180, 255))) + if event == current_event: set_foreground_color(column, QtGui.QColor(*(0, 143, 143, 255))) From 2554f6ca7e74851472dc55bf4cc21ca4cd027df8 Mon Sep 17 00:00:00 2001 From: Marcel Date: Thu, 26 Apr 2018 16:32:05 +0200 Subject: [PATCH 016/169] [new] dont show plot if no data --- pylot/core/util/widgets.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/pylot/core/util/widgets.py b/pylot/core/util/widgets.py index 5bd3cc52..57f26899 100644 --- a/pylot/core/util/widgets.py +++ b/pylot/core/util/widgets.py @@ -524,7 +524,9 @@ class WaveformWidgetPG(QtGui.QWidget): method='normal'): if not wfdata: print('Nothing to plot.') + self.setVisible(False) return + self.setVisible(True) self.title = title self.clearPlotDict() self.wfstart, self.wfend = full_range(wfdata) From 65f0d23f072c7212b0e569c28cd90dd58446d4aa Mon Sep 17 00:00:00 2001 From: Marcel Date: Thu, 26 Apr 2018 16:37:57 +0200 Subject: [PATCH 017/169] [revert] changes not working due to Thread --- pylot/core/util/widgets.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/pylot/core/util/widgets.py b/pylot/core/util/widgets.py index 57f26899..5bd3cc52 100644 --- a/pylot/core/util/widgets.py +++ b/pylot/core/util/widgets.py @@ -524,9 +524,7 @@ class WaveformWidgetPG(QtGui.QWidget): method='normal'): if not wfdata: print('Nothing to plot.') - self.setVisible(False) return - self.setVisible(True) self.title = title self.clearPlotDict() self.wfstart, self.wfend = full_range(wfdata) From ae4c345fa7c14045f100fbec366deedc1f8a33a9 Mon Sep 17 00:00:00 2001 From: Marcel Date: Thu, 26 Apr 2018 16:40:46 +0200 Subject: [PATCH 018/169] [update] same functionality but within main thread --- PyLoT.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/PyLoT.py b/PyLoT.py index b27a6536..286d06cf 100755 --- a/PyLoT.py +++ b/PyLoT.py @@ -1810,13 +1810,14 @@ class MainWindow(QMainWindow): def finish_pg_plot(self): self.getPlotWidget().updateWidget() plots, gaps = self.wfp_thread.data + # do not show plot if no data are given + self.dataPlot.setVisible(len(plots) > 0) for times, data, times_syn, data_syn in plots: self.dataPlot.plotWidget.getPlotItem().plot(times, data, pen=self.dataPlot.pen_linecolor) if len(data_syn) > 0: self.dataPlot.plotWidget.getPlotItem().plot(times_syn, data_syn, pen=self.dataPlot.pen_linecolor_syn) - self.dataPlot.reinitMoveProxy() self.dataPlot.plotWidget.showAxis('left') self.dataPlot.plotWidget.showAxis('bottom') From f49d323c1342c35a221cdf18ae8200f03c49d942 Mon Sep 17 00:00:00 2001 From: Marcel Date: Fri, 27 Apr 2018 10:45:20 +0200 Subject: [PATCH 019/169] [add] no data label --- PyLoT.py | 19 ++++++++++++------- pylot/core/util/widgets.py | 2 -- 2 files changed, 12 insertions(+), 9 deletions(-) diff --git a/PyLoT.py b/PyLoT.py index 286d06cf..ad25169f 100755 --- a/PyLoT.py +++ b/PyLoT.py @@ -616,6 +616,10 @@ class MainWindow(QMainWindow): # add scroll area used in case number of traces gets too high self.wf_scroll_area = QtGui.QScrollArea(self) + self.wf_scroll_area.setVisible(False) + self.no_data_label = QLabel('No Data') + self.no_data_label.setStyleSheet('color: red') + self.no_data_label.setAlignment(Qt.AlignCenter) # create central matplotlib figure canvas widget self.init_wfWidget() @@ -638,6 +642,7 @@ class MainWindow(QMainWindow): self.tabs.addTab(array_tab, 'Array Map') self.tabs.addTab(events_tab, 'Eventlist') + self.wf_layout.addWidget(self.no_data_label) self.wf_layout.addWidget(self.wf_scroll_area) self.wf_scroll_area.setWidgetResizable(True) self.init_array_tab() @@ -1811,7 +1816,8 @@ class MainWindow(QMainWindow): self.getPlotWidget().updateWidget() plots, gaps = self.wfp_thread.data # do not show plot if no data are given - self.dataPlot.setVisible(len(plots) > 0) + self.wf_scroll_area.setVisible(len(plots) > 0) + self.no_data_label.setVisible(not len(plots) > 0) for times, data, times_syn, data_syn in plots: self.dataPlot.plotWidget.getPlotItem().plot(times, data, pen=self.dataPlot.pen_linecolor) @@ -1819,8 +1825,6 @@ class MainWindow(QMainWindow): self.dataPlot.plotWidget.getPlotItem().plot(times_syn, data_syn, pen=self.dataPlot.pen_linecolor_syn) self.dataPlot.reinitMoveProxy() - self.dataPlot.plotWidget.showAxis('left') - self.dataPlot.plotWidget.showAxis('bottom') self.highlight_stations() def finishWaveformDataPlot(self): @@ -1898,12 +1902,10 @@ class MainWindow(QMainWindow): comparable[event.pylot_id] = self.checkEvent4comparison(event) return comparable - def clearWaveformDataPlot(self): + def clearWaveformDataPlot(self, refresh_plot=False): self.disconnectWFplotEvents() if self.pg: self.dataPlot.plotWidget.getPlotItem().clear() - self.dataPlot.plotWidget.hideAxis('bottom') - self.dataPlot.plotWidget.hideAxis('left') else: for ax in self.dataPlot.axes: ax.cla() @@ -1919,6 +1921,9 @@ class MainWindow(QMainWindow): self.openEventAction.setEnabled(False) self.openEventsAutoAction.setEnabled(False) self.loadpilotevent.setEnabled(False) + if not refresh_plot: + self.wf_scroll_area.setVisible(False) + self.no_data_label.setVisible(True) self.disableSaveEventAction() self.draw() @@ -1927,7 +1932,7 @@ class MainWindow(QMainWindow): Open a modal thread to plot current waveform data. ''' self.check_plot_quantity() - self.clearWaveformDataPlot() + self.clearWaveformDataPlot(refresh_plot=True) self.wfp_thread = Thread(self, self.plotWaveformData, arg=filter, progressText='Plotting waveform data...', diff --git a/pylot/core/util/widgets.py b/pylot/core/util/widgets.py index 5bd3cc52..da4adbe0 100644 --- a/pylot/core/util/widgets.py +++ b/pylot/core/util/widgets.py @@ -462,8 +462,6 @@ class WaveformWidgetPG(QtGui.QWidget): self.label_layout.addWidget(self.perm_label_mid) self.label_layout.addWidget(self.perm_label_right) self.plotWidget.showGrid(x=False, y=True, alpha=0.3) - self.plotWidget.hideAxis('bottom') - self.plotWidget.hideAxis('left') self.wfstart, self.wfend = 0, 0 self.pen_multicursor = self.pg.mkPen(self.parent()._style['multicursor']['rgba']) self.pen_linecolor = self.pg.mkPen(self.parent()._style['linecolor']['rgba']) From 756b5d67da5b5fbdf222d19a29b9d00bb402c429 Mon Sep 17 00:00:00 2001 From: Darius Arnold Date: Tue, 29 May 2018 18:27:15 +0200 Subject: [PATCH 020/169] [bugfix] getQualityFromUncertainty giving worst quality for uncertainty values between two classes Now the quality classes are exclusive lower bound and inclusive upper bound. --- pylot/core/pick/utils.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/pylot/core/pick/utils.py b/pylot/core/pick/utils.py index 3f5bcdcb..803524c3 100644 --- a/pylot/core/pick/utils.py +++ b/pylot/core/pick/utils.py @@ -1193,13 +1193,13 @@ def getQualityFromUncertainty(uncertainty, Errors): if uncertainty <= Errors[0]: quality = 0 elif (uncertainty > Errors[0]) and \ - (uncertainty < Errors[1]): + (uncertainty <= Errors[1]): quality = 1 elif (uncertainty > Errors[1]) and \ - (uncertainty < Errors[2]): + (uncertainty <= Errors[2]): quality = 2 elif (uncertainty > Errors[2]) and \ - (uncertainty < Errors[3]): + (uncertainty <= Errors[3]): quality = 3 elif uncertainty > Errors[3]: quality = 4 From 20eb54e9c5675aa1684545e4625014ce86934927 Mon Sep 17 00:00:00 2001 From: Marcel Date: Tue, 5 Jun 2018 13:47:00 +0200 Subject: [PATCH 021/169] [minor] gitignore modification --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index c99398e7..78b6b4e7 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ *.pyc *~ pylot/RELEASE-VERSION +*.idea From cbba41f16a9d5101cf507e42730b5befa2932d5e Mon Sep 17 00:00:00 2001 From: Marcel Date: Tue, 5 Jun 2018 14:24:00 +0200 Subject: [PATCH 022/169] [bugfix] autoPickWidget not enabled again after Error --- PyLoT.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/PyLoT.py b/PyLoT.py index ad25169f..c143e036 100755 --- a/PyLoT.py +++ b/PyLoT.py @@ -2457,6 +2457,7 @@ class MainWindow(QMainWindow): self.mp_worker.signals.message.connect(self.addListItem) self.mp_worker.signals.result.connect(self.finalizeAutoPick) + self.mp_worker.signals.finished.connect(self.enableAutoPickWidget) self.mp_thread.start(self.mp_worker) @@ -2471,7 +2472,6 @@ class MainWindow(QMainWindow): self.apd_sge.show() def finalizeAutoPick(self, result): - self.apw.enable(True) if result: self.init_canvas_dict_wadatijack() for eventID in result.keys(): @@ -2487,6 +2487,9 @@ class MainWindow(QMainWindow): self.drawPicks(picktype='auto') self.draw() + def enableAutoPickWidget(self, event=None): + self.apw.enable(True) + def get_event_from_id(self, eventID): for event in self.project.eventlist: if event.pylot_id == eventID: From d695c0016aebf2980c0258a8eeaf1d9038c65b02 Mon Sep 17 00:00:00 2001 From: Marcel Date: Tue, 5 Jun 2018 15:06:33 +0200 Subject: [PATCH 023/169] [bugfix] delete_later not caused tuneAutoPicker to malfunction --- pylot/core/util/widgets.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pylot/core/util/widgets.py b/pylot/core/util/widgets.py index da4adbe0..01c02bd3 100644 --- a/pylot/core/util/widgets.py +++ b/pylot/core/util/widgets.py @@ -1282,6 +1282,7 @@ class PickDlg(QDialog): event=None, filteroptions=None, model='iasp91'): super(PickDlg, self).__init__(parent, 1) self.orig_parent = parent + self.setAttribute(Qt.WA_DeleteOnClose) # initialize attributes self.parameter = parameter @@ -1414,7 +1415,6 @@ class PickDlg(QDialog): self.setWindowTitle('Pickwindow on station: {}'.format(self.getStation())) self.setWindowState(QtCore.Qt.WindowMaximized) - self.deleteLater() def setupUi(self): menuBar = QtGui.QMenuBar(self) From 9b5fe3baba151edf3963367594ee7c7cf94af941 Mon Sep 17 00:00:00 2001 From: Marcel Date: Tue, 5 Jun 2018 15:07:06 +0200 Subject: [PATCH 024/169] [bugfix] saving xml when tuning autopicker unnecessary (and caused id mismatch) --- PyLoT.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/PyLoT.py b/PyLoT.py index c143e036..e5c02e7a 100755 --- a/PyLoT.py +++ b/PyLoT.py @@ -2348,7 +2348,7 @@ class MainWindow(QMainWindow): def tune_autopicker(self): ''' - Initiates TuneAutopicker widget use to interactively + Initiates TuneAutopicker widget used to interactively tune parameters for autopicking algorithm. ''' # figures and canvas have to be iniated from the main GUI @@ -2447,7 +2447,8 @@ class MainWindow(QMainWindow): 'iplot': 0, 'fig_dict': None, 'fig_dict_wadatijack': self.fig_dict_wadatijack, - 'locflag': 0} + 'locflag': 0, + 'savexml': False} # init pick thread self.mp_thread = QtCore.QThreadPool() From 5e161d308af5d7f397c2857af901fad48749117b Mon Sep 17 00:00:00 2001 From: Marcel Date: Tue, 5 Jun 2018 15:11:43 +0200 Subject: [PATCH 025/169] [bugfix] trying to access station not in autopicks dictionary --- pylot/core/util/widgets.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/pylot/core/util/widgets.py b/pylot/core/util/widgets.py index 01c02bd3..9d20d9b6 100644 --- a/pylot/core/util/widgets.py +++ b/pylot/core/util/widgets.py @@ -3127,7 +3127,8 @@ class TuneAutopicker(QWidget): def get_current_event_autopicks(self, station): event = self.get_current_event() if event.pylot_autopicks: - return event.pylot_autopicks[station] + if station in event.pylot_autopicks: + return event.pylot_autopicks[station] def get_current_station(self): return str(self.stationBox.currentText()).split('.')[-1] From 8155389b3d2ca793210c41b2387242485b02cdd0 Mon Sep 17 00:00:00 2001 From: Marcel Date: Fri, 8 Jun 2018 14:18:28 +0200 Subject: [PATCH 026/169] [new] add qcombobox for raw/processed selection --- PyLoT.py | 59 ++++++++++++++++++++++++-------------- pylot/core/io/data.py | 42 +++++++++++++-------------- pylot/core/util/widgets.py | 24 ++++++++++++---- 3 files changed, 76 insertions(+), 49 deletions(-) diff --git a/PyLoT.py b/PyLoT.py index e5c02e7a..c4837690 100755 --- a/PyLoT.py +++ b/PyLoT.py @@ -1001,6 +1001,7 @@ class MainWindow(QMainWindow): # TODO: add dataStructure class for obspyDMT here, this is just a workaround! eventpath = self.get_current_event_path(eventbox) basepath = eventpath.split(os.path.basename(eventpath))[0] + obspy_dmt = check_obspydmt_structure(basepath) if self.dataStructure: if not eventpath: return @@ -1659,10 +1660,10 @@ class MainWindow(QMainWindow): if self._eventChanged[1]: self.refresh_array_map() if not plotted and self._eventChanged[0]: - # newWF(False) = load data without plotting + # newWF(plot=False) = load data without plotting self.newWF(plot=False) - def newWF(self, plot=True): + def newWF(self, event=None, plot=True): ''' Load new data and plot if necessary. ''' @@ -1703,25 +1704,42 @@ class MainWindow(QMainWindow): eventpath = self.get_current_event_path() basepath = eventpath.split(os.path.basename(eventpath))[0] obspy_dmt = check_obspydmt_structure(basepath) - self.data.setWFData(self.fnames, - checkRotated=True, - metadata=self.metadata, - obspy_dmt=obspy_dmt) + if obspy_dmt: + self.prepareObspyDMT_data(eventpath) - def setWFstatus(self): - ''' - show status of current data, can be either 'raw' or 'processed' - :param status: - :return: - ''' - status = self.data.processed - wf_stat_color = {True: 'green', - False: 'black', - None: None} - wf_stat = {True: 'processed', - False: 'raw', - None: None} - self.dataPlot.setPermTextRight(wf_stat[status], wf_stat_color[status]) + self.data.setWFData(self.fnames, + self.fnames_syn, + checkRotated=True, + metadata=self.metadata) + + def prepareObspyDMT_data(self, eventpath): + qcbox_processed = self.dataPlot.perm_qcbox_right + qcbox_processed.setEnabled(False) + for fpath in os.listdir(eventpath): + fpath = fpath.split('/')[-1] + if 'syngine' in fpath: + eventpath_syn = os.path.join(eventpath, fpath) + self.fnames_syn = [os.path.join(eventpath_syn, filename) for filename in os.listdir(eventpath_syn)] + if 'processed' in fpath: + qcbox_processed.setEnabled(True) + wftype = qcbox_processed.currentText() if qcbox_processed.isEnabled() else 'raw' + eventpath_dmt = os.path.join(eventpath, wftype) + self.fnames = [os.path.join(eventpath_dmt, filename) for filename in os.listdir(eventpath_dmt)] + + # def setWFstatus(self): + # ''' + # show status of current data, can be either 'raw' or 'processed' + # :param status: + # :return: + # ''' + # status = self.data.processed + # wf_stat_color = {True: 'green', + # False: 'black', + # None: None} + # wf_stat = {True: 'processed', + # False: 'raw', + # None: None} + # self.dataPlot.setQCboxItem(wf_stat[status]) def check_plot_quantity(self): """ @@ -1867,7 +1885,6 @@ class MainWindow(QMainWindow): if True in self.comparable.values(): self.compare_action.setEnabled(True) self.draw() - self.setWFstatus() def checkEvent4comparison(self, event): if event.pylot_picks and event.pylot_autopicks: diff --git a/pylot/core/io/data.py b/pylot/core/io/data.py index cd06a9b5..f10242db 100644 --- a/pylot/core/io/data.py +++ b/pylot/core/io/data.py @@ -371,7 +371,7 @@ class Data(object): data.filter(**kwargs) self.dirty = True - def setWFData(self, fnames, checkRotated=False, metadata=None, obspy_dmt=False): + def setWFData(self, fnames, fnames_syn=None, checkRotated=False, metadata=None): """ Clear current waveform data and set given waveform data :param fnames: waveform data names to append @@ -380,27 +380,25 @@ class Data(object): self.wfdata = Stream() self.wforiginal = None self.wfsyn = Stream() - wffnames = None - wffnames_syn = None - if obspy_dmt: - wfdir = 'raw' - self.processed = False - for fname in fnames: - if fname.endswith('processed'): - wfdir = 'processed' - self.processed = True - break - for fpath in fnames: - if fpath.endswith(wfdir): - wffnames = [os.path.join(fpath, fname) for fname in os.listdir(fpath)] - if 'syngine' in fpath.split('/')[-1]: - wffnames_syn = [os.path.join(fpath, fname) for fname in os.listdir(fpath)] - else: - wffnames = fnames - if wffnames is not None: - self.appendWFData(wffnames) - if wffnames_syn is not None: - self.appendWFData(wffnames_syn, synthetic=True) + # if obspy_dmt: + # wfdir = 'raw' + # self.processed = False + # for fname in fnames: + # if fname.endswith('processed'): + # wfdir = 'processed' + # self.processed = True + # break + # for fpath in fnames: + # if fpath.endswith(wfdir): + # wffnames = [os.path.join(fpath, fname) for fname in os.listdir(fpath)] + # if 'syngine' in fpath.split('/')[-1]: + # wffnames_syn = [os.path.join(fpath, fname) for fname in os.listdir(fpath)] + # else: + # wffnames = fnames + if fnames is not None: + self.appendWFData(fnames) + if fnames_syn is not None: + self.appendWFData(fnames_syn, synthetic=True) else: return False diff --git a/pylot/core/util/widgets.py b/pylot/core/util/widgets.py index 9d20d9b6..a3defac9 100644 --- a/pylot/core/util/widgets.py +++ b/pylot/core/util/widgets.py @@ -455,12 +455,13 @@ class WaveformWidgetPG(QtGui.QWidget): self.main_layout = QtGui.QVBoxLayout() self.label_layout = QtGui.QHBoxLayout() self.add_labels() + self.connect_signals() self.plotWidget = self.pg.PlotWidget(self.parent(), title=title) self.main_layout.addWidget(self.plotWidget) self.main_layout.addLayout(self.label_layout) self.label_layout.addWidget(self.status_label) self.label_layout.addWidget(self.perm_label_mid) - self.label_layout.addWidget(self.perm_label_right) + self.label_layout.addWidget(self.perm_qcbox_right) self.plotWidget.showGrid(x=False, y=True, alpha=0.3) self.wfstart, self.wfend = 0, 0 self.pen_multicursor = self.pg.mkPen(self.parent()._style['multicursor']['rgba']) @@ -491,12 +492,17 @@ class WaveformWidgetPG(QtGui.QWidget): self.vLine.setPos(mousePoint.x()) self.hLine.setPos(mousePoint.y()) + def connect_signals(self): + self.perm_qcbox_right.currentIndexChanged.connect(self.parent().newWF) + def add_labels(self): self.status_label = QtGui.QLabel() self.perm_label_mid = QtGui.QLabel() self.perm_label_mid.setAlignment(4) - self.perm_label_right = QtGui.QLabel() - self.perm_label_right.setAlignment(2) + self.perm_qcbox_right = QtGui.QComboBox() + self.addQCboxItem('raw', 'black') + self.addQCboxItem('processed', 'green') + #self.perm_qcbox_right.setAlignment(2) self.setLayout(self.main_layout) def getPlotDict(self): @@ -506,9 +512,15 @@ class WaveformWidgetPG(QtGui.QWidget): self.perm_label_mid.setText(text) self.perm_label_mid.setStyleSheet('color: {}'.format(color)) - def setPermTextRight(self, text=None, color='black'): - self.perm_label_right.setText(text) - self.perm_label_right.setStyleSheet('color: {}'.format(color)) + def addQCboxItem(self, text=None, color='black'): + item = QtGui.QStandardItem(text) + model = self.perm_qcbox_right.model() + model.appendRow(item) + item.setForeground(QtGui.QColor('{}'.format(color))) + + def setQCboxItem(self, text): + index = self.perm_qcbox_right.findText(text) + self.perm_qcbox_right.setCurrentIndex(index) def setPlotDict(self, key, value): self.plotdict[key] = value From 083e5c8fe910e581a54b70eee36aac6b3cfc39cd Mon Sep 17 00:00:00 2001 From: Marcel Date: Fri, 8 Jun 2018 14:27:43 +0200 Subject: [PATCH 027/169] [new] synthetics checkbox --- PyLoT.py | 7 ++++++- pylot/core/util/widgets.py | 3 +++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/PyLoT.py b/PyLoT.py index c4837690..d3367cfa 100755 --- a/PyLoT.py +++ b/PyLoT.py @@ -1701,6 +1701,7 @@ class MainWindow(QMainWindow): # else: # ans = False self.fnames = self.getWFFnames_from_eventbox() + self.fnames_syn = [] eventpath = self.get_current_event_path() basepath = eventpath.split(os.path.basename(eventpath))[0] obspy_dmt = check_obspydmt_structure(basepath) @@ -1714,12 +1715,16 @@ class MainWindow(QMainWindow): def prepareObspyDMT_data(self, eventpath): qcbox_processed = self.dataPlot.perm_qcbox_right + qcheckb_syn = self.dataPlot.syn_checkbox qcbox_processed.setEnabled(False) + qcheckb_syn.setEnabled(False) for fpath in os.listdir(eventpath): fpath = fpath.split('/')[-1] if 'syngine' in fpath: eventpath_syn = os.path.join(eventpath, fpath) - self.fnames_syn = [os.path.join(eventpath_syn, filename) for filename in os.listdir(eventpath_syn)] + qcheckb_syn.setEnabled(True) + if self.dataPlot.syn_checkbox.isChecked(): + self.fnames_syn = [os.path.join(eventpath_syn, filename) for filename in os.listdir(eventpath_syn)] if 'processed' in fpath: qcbox_processed.setEnabled(True) wftype = qcbox_processed.currentText() if qcbox_processed.isEnabled() else 'raw' diff --git a/pylot/core/util/widgets.py b/pylot/core/util/widgets.py index a3defac9..c53333eb 100644 --- a/pylot/core/util/widgets.py +++ b/pylot/core/util/widgets.py @@ -461,6 +461,7 @@ class WaveformWidgetPG(QtGui.QWidget): self.main_layout.addLayout(self.label_layout) self.label_layout.addWidget(self.status_label) self.label_layout.addWidget(self.perm_label_mid) + self.label_layout.addWidget(self.syn_checkbox) self.label_layout.addWidget(self.perm_qcbox_right) self.plotWidget.showGrid(x=False, y=True, alpha=0.3) self.wfstart, self.wfend = 0, 0 @@ -494,12 +495,14 @@ class WaveformWidgetPG(QtGui.QWidget): def connect_signals(self): self.perm_qcbox_right.currentIndexChanged.connect(self.parent().newWF) + self.syn_checkbox.clicked.connect(self.parent().newWF) def add_labels(self): self.status_label = QtGui.QLabel() self.perm_label_mid = QtGui.QLabel() self.perm_label_mid.setAlignment(4) self.perm_qcbox_right = QtGui.QComboBox() + self.syn_checkbox = QtGui.QCheckBox('synthetics') self.addQCboxItem('raw', 'black') self.addQCboxItem('processed', 'green') #self.perm_qcbox_right.setAlignment(2) From f50e38241e9de4337d6f53294fbf202ef8e7ee91 Mon Sep 17 00:00:00 2001 From: Marcel Date: Fri, 8 Jun 2018 15:01:05 +0200 Subject: [PATCH 028/169] [minor] tweaks and finalization of obspyDMT options --- PyLoT.py | 26 +++++++++++++++++--------- pylot/core/util/widgets.py | 31 ++++++++++++++++++++++--------- 2 files changed, 39 insertions(+), 18 deletions(-) diff --git a/PyLoT.py b/PyLoT.py index d3367cfa..32d4b0b2 100755 --- a/PyLoT.py +++ b/PyLoT.py @@ -1677,6 +1677,7 @@ class MainWindow(QMainWindow): call modal plot thread method when finished. ''' if load: + self.prepareLoadWaveformData() self.wfd_thread = Thread(self, self.loadWaveformData, progressText='Reading data input...', pb_widget=self.mainProgressBarWidget) @@ -1689,6 +1690,16 @@ class MainWindow(QMainWindow): if plot and not load: self.plotWaveformDataThread() + def prepareLoadWaveformData(self): + self.fnames = self.getWFFnames_from_eventbox() + self.fnames_syn = [] + eventpath = self.get_current_event_path() + basepath = eventpath.split(os.path.basename(eventpath))[0] + obspy_dmt = check_obspydmt_structure(basepath) + self.dataPlot.activateObspyDMToptions(obspy_dmt) + if obspy_dmt: + self.prepareObspyDMT_data(eventpath) + def loadWaveformData(self): ''' Load waveform data corresponding to current selected event. @@ -1700,13 +1711,6 @@ class MainWindow(QMainWindow): # ans = self.data.setWFData(self.getWFFnames()) # else: # ans = False - self.fnames = self.getWFFnames_from_eventbox() - self.fnames_syn = [] - eventpath = self.get_current_event_path() - basepath = eventpath.split(os.path.basename(eventpath))[0] - obspy_dmt = check_obspydmt_structure(basepath) - if obspy_dmt: - self.prepareObspyDMT_data(eventpath) self.data.setWFData(self.fnames, self.fnames_syn, @@ -1714,7 +1718,7 @@ class MainWindow(QMainWindow): metadata=self.metadata) def prepareObspyDMT_data(self, eventpath): - qcbox_processed = self.dataPlot.perm_qcbox_right + qcbox_processed = self.dataPlot.qcombo_processed qcheckb_syn = self.dataPlot.syn_checkbox qcbox_processed.setEnabled(False) qcheckb_syn.setEnabled(False) @@ -1727,7 +1731,11 @@ class MainWindow(QMainWindow): self.fnames_syn = [os.path.join(eventpath_syn, filename) for filename in os.listdir(eventpath_syn)] if 'processed' in fpath: qcbox_processed.setEnabled(True) - wftype = qcbox_processed.currentText() if qcbox_processed.isEnabled() else 'raw' + if qcbox_processed.isEnabled(): + wftype = qcbox_processed.currentText() + else: + wftype = 'raw' + qcbox_processed.setCurrentIndex(qcbox_processed.findText(wftype)) eventpath_dmt = os.path.join(eventpath, wftype) self.fnames = [os.path.join(eventpath_dmt, filename) for filename in os.listdir(eventpath_dmt)] diff --git a/pylot/core/util/widgets.py b/pylot/core/util/widgets.py index c53333eb..0df1b784 100644 --- a/pylot/core/util/widgets.py +++ b/pylot/core/util/widgets.py @@ -459,10 +459,8 @@ class WaveformWidgetPG(QtGui.QWidget): self.plotWidget = self.pg.PlotWidget(self.parent(), title=title) self.main_layout.addWidget(self.plotWidget) self.main_layout.addLayout(self.label_layout) - self.label_layout.addWidget(self.status_label) - self.label_layout.addWidget(self.perm_label_mid) - self.label_layout.addWidget(self.syn_checkbox) - self.label_layout.addWidget(self.perm_qcbox_right) + self.init_labels() + self.activateObspyDMToptions(False) self.plotWidget.showGrid(x=False, y=True, alpha=0.3) self.wfstart, self.wfend = 0, 0 self.pen_multicursor = self.pg.mkPen(self.parent()._style['multicursor']['rgba']) @@ -494,14 +492,25 @@ class WaveformWidgetPG(QtGui.QWidget): self.hLine.setPos(mousePoint.y()) def connect_signals(self): - self.perm_qcbox_right.currentIndexChanged.connect(self.parent().newWF) + self.qcombo_processed.activated.connect(self.parent().newWF) self.syn_checkbox.clicked.connect(self.parent().newWF) + def init_labels(self): + self.label_layout.addWidget(self.status_label) + self.label_layout.addWidget(self.perm_label_mid) + self.label_layout.addWidget(self.syn_checkbox) + self.label_layout.addWidget(self.qcombo_processed) + self.syn_checkbox.setLayoutDirection(Qt.RightToLeft) + self.label_layout.setStretch(0, 4) + self.label_layout.setStretch(1, 2) + self.label_layout.setStretch(2, 3) + self.label_layout.setStretch(3, 1) + def add_labels(self): self.status_label = QtGui.QLabel() self.perm_label_mid = QtGui.QLabel() self.perm_label_mid.setAlignment(4) - self.perm_qcbox_right = QtGui.QComboBox() + self.qcombo_processed = QtGui.QComboBox() self.syn_checkbox = QtGui.QCheckBox('synthetics') self.addQCboxItem('raw', 'black') self.addQCboxItem('processed', 'green') @@ -511,19 +520,23 @@ class WaveformWidgetPG(QtGui.QWidget): def getPlotDict(self): return self.plotdict + def activateObspyDMToptions(self, activate): + self.syn_checkbox.setVisible(activate) + self.qcombo_processed.setVisible(activate) + def setPermTextMid(self, text=None, color='black'): self.perm_label_mid.setText(text) self.perm_label_mid.setStyleSheet('color: {}'.format(color)) def addQCboxItem(self, text=None, color='black'): item = QtGui.QStandardItem(text) - model = self.perm_qcbox_right.model() + model = self.qcombo_processed.model() model.appendRow(item) item.setForeground(QtGui.QColor('{}'.format(color))) def setQCboxItem(self, text): - index = self.perm_qcbox_right.findText(text) - self.perm_qcbox_right.setCurrentIndex(index) + index = self.qcombo_processed.findText(text) + self.qcombo_processed.setCurrentIndex(index) def setPlotDict(self, key, value): self.plotdict[key] = value From 06cacdd4cb29515f2369320346b494b508cd106d Mon Sep 17 00:00:00 2001 From: Marcel Date: Wed, 13 Jun 2018 17:01:05 +0200 Subject: [PATCH 029/169] [update] major improvements of array_map, code restyled, increased flexibility --- PyLoT.py | 9 +- .../util/{map_projection.py => array_map.py} | 269 ++++++++++-------- 2 files changed, 158 insertions(+), 120 deletions(-) rename pylot/core/util/{map_projection.py => array_map.py} (56%) diff --git a/PyLoT.py b/PyLoT.py index 32d4b0b2..96c30e4a 100755 --- a/PyLoT.py +++ b/PyLoT.py @@ -86,7 +86,7 @@ from pylot.core.util.widgets import FilterOptionsDialog, NewEventDlg, \ PylotCanvas, WaveformWidgetPG, PropertiesDlg, HelpForm, createAction, PickDlg, \ getDataType, ComparisonWidget, TuneAutopicker, PylotParaBox, AutoPickDlg, CanvasWidget, AutoPickWidget, \ CompareEventsWidget -from pylot.core.util.map_projection import map_projection +from pylot.core.util.array_map import Array_map from pylot.core.util.structure import DATASTRUCTURE from pylot.core.util.thread import Thread, Worker from pylot.core.util.version import get_git_version as _getVersionString @@ -2850,9 +2850,9 @@ class MainWindow(QMainWindow): if not self.metadata: return self.am_figure = Figure() - self.am_canvas = FigureCanvas(self.am_figure) + self.am_canvas = PylotCanvas(self.am_figure, parent=self, panZoomX=False, panZoomY=False) self.am_toolbar = NavigationToolbar(self.am_canvas, self) - self.array_map = map_projection(self) + self.array_map = Array_map(self) # self.array_map_thread() self.array_layout.addWidget(self.array_map) self.tabs.setCurrentIndex(index) @@ -2891,7 +2891,8 @@ class MainWindow(QMainWindow): lon = event.origins[0].longitude self.array_map.eventLoc = (lat, lon) if self.get_current_event(): - self.array_map.refresh_drawings(self.get_current_event().getPicks()) + self.array_map.refresh_drawings(self.get_current_event().getPicks(), + self.get_current_event().getAutopicks(),) self._eventChanged[1] = False def init_event_table(self, tabindex=2): diff --git a/pylot/core/util/map_projection.py b/pylot/core/util/array_map.py similarity index 56% rename from pylot/core/util/map_projection.py rename to pylot/core/util/array_map.py index 66cfb5ce..39e4f1ad 100644 --- a/pylot/core/util/map_projection.py +++ b/pylot/core/util/array_map.py @@ -13,19 +13,20 @@ from scipy.interpolate import griddata plt.interactive(False) -class map_projection(QtGui.QWidget): +class Array_map(QtGui.QWidget): def __init__(self, parent, figure=None): ''' - - :param: picked, can be False, auto, manual - :value: str + Create a map of the array. + :param parent: PyLoT Mainwindow class + :param figure: ''' QtGui.QWidget.__init__(self) self._parent = parent - self.metadata = parent.metadata - self.parser = parent.metadata[1] + self.metadata_type = parent.metadata[0] + self.metadata = parent.metadata[1] self.picks = None self.picks_dict = None + self.autopicks_dict = None self.eventLoc = None self.figure = figure self.init_graphics() @@ -49,9 +50,9 @@ class map_projection(QtGui.QWidget): return data = self._parent.get_data().getWFData() for index in ind: - station = str(self.station_names[index].split('.')[-1]) + station = str(self._station_onpick_ids[index].split('.')[-1]) try: - pickDlg = PickDlg(self, parameter=self._parent._inputs, + pickDlg = PickDlg(self._parent, parameter=self._parent._inputs, data=data.select(station=station), station=station, picks=self._parent.get_current_event().getPick(station), @@ -84,7 +85,29 @@ class map_projection(QtGui.QWidget): def connectSignals(self): self.comboBox_phase.currentIndexChanged.connect(self._refresh_drawings) - self.zoom_id = self.basemap.ax.figure.canvas.mpl_connect('scroll_event', self.zoom) + self.comboBox_am.currentIndexChanged.connect(self._refresh_drawings) + #self.zoom_id = self.basemap.ax.figure.canvas.mpl_connect('scroll_event', self.zoom) + + def _from_dict(self, function, key): + return function(self.stations_dict.values(), key=lambda x: x[key])[key] + + def get_min_from_stations(self, key): + return self._from_dict(min, key) + + def get_max_from_stations(self, key): + return self._from_dict(max, key) + + def get_min_from_picks(self): + return min(self.picks_rel.values()) + + def get_max_from_picks(self): + return max(self.picks_rel.values()) + + def current_picks_dict(self): + picktype = self.comboBox_am.currentText() + auto_manu = {'auto': self.autopicks_dict, + 'manual': self.picks_dict} + return auto_manu[picktype] def init_graphics(self): if not self.figure: @@ -115,103 +138,97 @@ class map_projection(QtGui.QWidget): self.top_row.addWidget(QtGui.QLabel('Select a phase: ')) self.top_row.addWidget(self.comboBox_phase) self.top_row.setStretch(1, 1) # set stretch of item 1 to 1 + self.top_row.addWidget(QtGui.QLabel('Pick type: ')) + self.top_row.addWidget(self.comboBox_am) + self.top_row.setStretch(3, 1) # set stretch of item 1 to 1 self.main_box.addWidget(self.canvas) self.main_box.addWidget(self.toolbar) + def init_stations(self): - def get_station_names_lat_lon(parser): - station_names = [] - lat = [] - lon = [] + def stat_info_from_parser(parser): + stations_dict = {} for station in parser.stations: station_name = station[0].station_call_letters - network = station[0].network_code - if not station_name in station_names: - station_names.append(network + '.' + station_name) - lat.append(station[0].latitude) - lon.append(station[0].longitude) - return station_names, lat, lon + network_name = station[0].network_code + if not station_name in stations_dict.keys(): + st_id = network_name + '.' + station_name + stations_dict[st_id] = {'latitude': station[0].latitude, + 'longitude': station[0].longitude} + return stations_dict - station_names, lat, lon = get_station_names_lat_lon(self.parser) - self.station_names = station_names - self.lat = lat - self.lon = lon + def stat_info_from_inventory(inventory): + stations_dict = {} + for network in inventory.networks: + for station in network.stations: + station_name = station.code + network_name = network_name.code + if not station_name in stations_dict.keys(): + st_id = network_name + '.' + station_name + stations_dict[st_id] = {'latitude': station[0].latitude, + 'longitude': station[0].longitude} + return stations_dict + + read_stat = {'xml': stat_info_from_inventory, + 'dless': stat_info_from_parser} + + self.stations_dict = read_stat[self.metadata_type](self.metadata) + self.latmin = self.get_min_from_stations('latitude') + self.lonmin = self.get_min_from_stations('longitude') + self.latmax = self.get_max_from_stations('latitude') + self.lonmax = self.get_max_from_stations('longitude') def init_picks(self): - phase = self.comboBox_phase.currentText() - - def get_picks(station_names): - picks = [] - for station in station_names: + def get_picks(station_dict): + picks = {} + phase = self.comboBox_phase.currentText() + for st_id in station_dict.keys(): try: - station = station.split('.')[-1] - picks.append(self.picks_dict[station][phase]['mpp']) - except: - picks.append(np.nan) + station_name = st_id.split('.')[-1] + picks[st_id] = self.current_picks_dict()[station_name][phase]['mpp'] + except KeyError: + continue + except Exception as e: + print('Cannot display pick for station {}. Reason: {}'.format(station_name, e)) return picks def get_picks_rel(picks): - picks_rel = [] + picks_rel = {} picks_utc = [] - for pick in picks: + for pick in picks.values(): if type(pick) is obspy.core.utcdatetime.UTCDateTime: picks_utc.append(pick) minp = min(picks_utc) - for pick in picks: + for st_id, pick in picks.items(): if type(pick) is obspy.core.utcdatetime.UTCDateTime: pick -= minp - picks_rel.append(pick) + picks_rel[st_id] = pick return picks_rel - self.picks = get_picks(self.station_names) + self.picks = get_picks(self.stations_dict) self.picks_rel = get_picks_rel(self.picks) - def init_picks_active(self): - def remove_nan_picks(picks): - picks_no_nan = [] - for pick in picks: - if not np.isnan(pick): - picks_no_nan.append(pick) - return picks_no_nan - - self.picks_no_nan = remove_nan_picks(self.picks_rel) - - def init_stations_active(self): - def remove_nan_lat_lon(picks, lat, lon): - lat_no_nan = [] - lon_no_nan = [] - for index, pick in enumerate(picks): - if not np.isnan(pick): - lat_no_nan.append(lat[index]) - lon_no_nan.append(lon[index]) - return lat_no_nan, lon_no_nan - - self.lat_no_nan, self.lon_no_nan = remove_nan_lat_lon(self.picks_rel, self.lat, self.lon) - def init_lat_lon_dimensions(self): - def get_lon_lat_dim(lon, lat): - londim = max(lon) - min(lon) - latdim = max(lat) - min(lat) - return londim, latdim - - self.londim, self.latdim = get_lon_lat_dim(self.lon, self.lat) + # init minimum and maximum lon and lat dimensions + self.londim = self.lonmax - self.lonmin + self.latdim = self.latmax - self.latmin def init_x_y_dimensions(self): - def get_x_y_dim(x, y): - xdim = max(x) - min(x) - ydim = max(y) - min(y) - return xdim, ydim + # transformation of lat/lon to ax coordinate system + for st_id, coords in self.stations_dict.items(): + lat, lon = coords['latitude'], coords['longitude'] + coords['x'], coords['y'] = self.basemap(lon, lat) - self.x, self.y = self.basemap(self.lon, self.lat) - self.xdim, self.ydim = get_x_y_dim(self.x, self.y) + self.xdim = self.get_max_from_stations('x') - self.get_min_from_stations('x') + self.ydim = self.get_max_from_stations('y') - self.get_min_from_stations('y') def init_basemap(self, resolution='l'): # basemap = Basemap(projection=projection, resolution = resolution, ax=self.main_ax) basemap = Basemap(projection='lcc', resolution=resolution, ax=self.main_ax, width=5e6, height=2e6, - lat_0=(min(self.lat) + max(self.lat)) / 2., - lon_0=(min(self.lon) + max(self.lon)) / 2.) + lat_0=(self.latmin + self.latmax) / 2., + lon_0=(self.lonmin + self.lonmax) / 2.) # basemap.fillcontinents(color=None, lake_color='aqua',zorder=1) basemap.drawmapboundary(zorder=2) # fill_color='darkblue') @@ -222,60 +239,81 @@ class map_projection(QtGui.QWidget): self.basemap = basemap self.figure.tight_layout() - def init_lat_lon_grid(self): - def get_lat_lon_axis(lat, lon): - steplat = (max(lat) - min(lat)) / 250 - steplon = (max(lon) - min(lon)) / 250 - - lataxis = np.arange(min(lat), max(lat), steplat) - lonaxis = np.arange(min(lon), max(lon), steplon) - return lataxis, lonaxis - - def get_lat_lon_grid(lataxis, lonaxis): - longrid, latgrid = np.meshgrid(lonaxis, lataxis) - return latgrid, longrid - - self.lataxis, self.lonaxis = get_lat_lon_axis(self.lat, self.lon) - self.latgrid, self.longrid = get_lat_lon_grid(self.lataxis, self.lonaxis) + def init_lat_lon_grid(self, nstep=250): + # create a regular grid to display colormap + lataxis = np.linspace(self.latmin, self.latmax, nstep) + lonaxis = np.linspace(self.lonmin, self.lonmax, nstep) + self.longrid, self.latgrid = np.meshgrid(lonaxis, lataxis) def init_picksgrid(self): - self.picksgrid_no_nan = griddata((self.lat_no_nan, self.lon_no_nan), - self.picks_no_nan, (self.latgrid, self.longrid), - method='linear') ################## + picks, lats, lons = self.get_picks_lat_lon() + self.picksgrid_active = griddata((lats, lons), picks, (self.latgrid, self.longrid), + method='linear') + + def get_st_lat_lon_for_plot(self): + stations = [] + latitudes = [] + longitudes = [] + for st_id, coords in self.stations_dict.items(): + stations.append(st_id) + latitudes.append(coords['latitude']) + longitudes.append(coords['longitude']) + return stations, latitudes, longitudes + + def get_st_x_y_for_plot(self): + stations = [] + xs = [] + ys = [] + for st_id, coords in self.stations_dict.items(): + stations.append(st_id) + xs.append(coords['x']) + ys.append(coords['y']) + return stations, xs, ys + + def get_picks_lat_lon(self): + picks = [] + latitudes = [] + longitudes = [] + for st_id, pick in self.picks_rel.items(): + picks.append(pick) + latitudes.append(self.stations_dict[st_id]['latitude']) + longitudes.append(self.stations_dict[st_id]['longitude']) + return picks, latitudes, longitudes def draw_contour_filled(self, nlevel='50'): - levels = np.linspace(min(self.picks_no_nan), max(self.picks_no_nan), nlevel) - self.contourf = self.basemap.contourf(self.longrid, self.latgrid, self.picksgrid_no_nan, + levels = np.linspace(self.get_min_from_picks(), self.get_max_from_picks(), nlevel) + self.contourf = self.basemap.contourf(self.longrid, self.latgrid, self.picksgrid_active, levels, latlon=True, zorder=9, alpha=0.5) def scatter_all_stations(self): - self.sc = self.basemap.scatter(self.lon, self.lat, s=50, facecolor='none', latlon=True, + stations, lats, lons = self.get_st_lat_lon_for_plot() + self.sc = self.basemap.scatter(lons, lats, s=50, facecolor='none', latlon=True, zorder=10, picker=True, edgecolor='m', label='Not Picked') self.cid = self.canvas.mpl_connect('pick_event', self.onpick) + self._station_onpick_ids = stations if self.eventLoc: - lat, lon = self.eventLoc - self.sc_event = self.basemap.scatter(lon, lat, s=100, facecolor='red', + lats, lons = self.eventLoc + self.sc_event = self.basemap.scatter(lons, lats, s=100, facecolor='red', latlon=True, zorder=11, label='Event (might be outside map region)') def scatter_picked_stations(self): - lon = self.lon_no_nan - lat = self.lat_no_nan - + picks, lats, lons = self.get_picks_lat_lon() # workaround because of an issue with latlon transformation of arrays with len <3 - if len(lon) <= 2 and len(lat) <= 2: - self.sc_picked = self.basemap.scatter(lon[0], lat[0], s=50, facecolor='white', - c=self.picks_no_nan[0], latlon=True, zorder=11, label='Picked') - if len(lon) == 2 and len(lat) == 2: - self.sc_picked = self.basemap.scatter(lon[1], lat[1], s=50, facecolor='white', - c=self.picks_no_nan[1], latlon=True, zorder=11) + if len(lons) <= 2 and len(lats) <= 2: + self.sc_picked = self.basemap.scatter(lons[0], lats[0], s=50, facecolor='white', + c=picks[0], latlon=True, zorder=11, label='Picked') + if len(lons) == 2 and len(lats) == 2: + self.sc_picked = self.basemap.scatter(lons[1], lats[1], s=50, facecolor='white', + c=picks[1], latlon=True, zorder=11) else: - self.sc_picked = self.basemap.scatter(lon, lat, s=50, facecolor='white', - c=self.picks_no_nan, latlon=True, zorder=11, label='Picked') + self.sc_picked = self.basemap.scatter(lons, lats, s=50, facecolor='white', + c=picks, latlon=True, zorder=11, label='Picked') def annotate_ax(self): self.annotations = [] - for index, name in enumerate(self.station_names): - self.annotations.append(self.main_ax.annotate(' %s' % name, xy=(self.x[index], self.y[index]), + stations, xs, ys = self.get_st_x_y_for_plot() + for st, x, y in zip(stations, xs, ys): + self.annotations.append(self.main_ax.annotate(' %s' % st, xy=(x, y), fontsize='x-small', color='white', zorder=12)) self.legend = self.main_ax.legend(loc=1) @@ -284,8 +322,9 @@ class map_projection(QtGui.QWidget): cbar.set_label(label) return cbar - def refresh_drawings(self, picks=None): + def refresh_drawings(self, picks=None, autopicks=None): self.picks_dict = picks + self.autopicks_dict = autopicks self._refresh_drawings() def _refresh_drawings(self): @@ -295,9 +334,7 @@ class map_projection(QtGui.QWidget): def draw_everything(self): if self.picks_dict: self.init_picks() - self.init_picks_active() - self.init_stations_active() - if len(self.picks_no_nan) >= 3: + if len(self.picks) >= 3: self.init_picksgrid() self.draw_contour_filled() self.scatter_all_stations() @@ -311,15 +348,15 @@ class map_projection(QtGui.QWidget): self.canvas.draw() def remove_drawings(self): + if hasattr(self, 'cbar'): + self.cbar.remove() + del (self.cbar) if hasattr(self, 'sc_picked'): self.sc_picked.remove() del (self.sc_picked) if hasattr(self, 'sc_event'): self.sc_event.remove() del (self.sc_event) - if hasattr(self, 'cbar'): - self.cbar.remove() - del (self.cbar) if hasattr(self, 'contourf'): self.remove_contourf() del (self.contourf) From fe0e4be43d63ac066127cc795be5bc6e5275a41c Mon Sep 17 00:00:00 2001 From: Marcel Date: Thu, 14 Jun 2018 14:08:25 +0200 Subject: [PATCH 030/169] [update] array_map uses PylotCanvas now, added grid and labels --- PyLoT.py | 3 --- pylot/core/util/array_map.py | 22 ++++++++++++---------- 2 files changed, 12 insertions(+), 13 deletions(-) diff --git a/PyLoT.py b/PyLoT.py index 96c30e4a..456f7671 100755 --- a/PyLoT.py +++ b/PyLoT.py @@ -2849,9 +2849,6 @@ class MainWindow(QMainWindow): self.init_metadata() if not self.metadata: return - self.am_figure = Figure() - self.am_canvas = PylotCanvas(self.am_figure, parent=self, panZoomX=False, panZoomY=False) - self.am_toolbar = NavigationToolbar(self.am_canvas, self) self.array_map = Array_map(self) # self.array_map_thread() self.array_layout.addWidget(self.array_map) diff --git a/pylot/core/util/array_map.py b/pylot/core/util/array_map.py index 39e4f1ad..c2464066 100644 --- a/pylot/core/util/array_map.py +++ b/pylot/core/util/array_map.py @@ -5,9 +5,9 @@ import matplotlib.pyplot as plt import numpy as np import obspy from PySide import QtGui -from matplotlib.backends.backend_qt4agg import NavigationToolbar2QT as NavigationToolbar from mpl_toolkits.basemap import Basemap -from pylot.core.util.widgets import PickDlg +from matplotlib.figure import Figure +from pylot.core.util.widgets import PickDlg, PylotCanvas from scipy.interpolate import griddata plt.interactive(False) @@ -42,6 +42,7 @@ class Array_map(QtGui.QWidget): self.init_x_y_dimensions() self.connectSignals() self.draw_everything() + self.canvas.setZoomBorders2content() def onpick(self, event): ind = event.ind @@ -111,15 +112,12 @@ class Array_map(QtGui.QWidget): def init_graphics(self): if not self.figure: - if not hasattr(self._parent, 'am_figure'): - self.figure = plt.figure() - self.toolbar = NavigationToolbar(self.figure.canvas, self) - else: - self.figure = self._parent.am_figure - self.toolbar = self._parent.am_toolbar + self.figure = Figure() self.main_ax = self.figure.add_subplot(111) - self.canvas = self.figure.canvas + self.canvas = PylotCanvas(self.figure, parent=self._parent, multicursor=True, + panZoomX=False, panZoomY=False) + #self.canvas.setZoomBorders2content() self.main_box = QtGui.QVBoxLayout() self.setLayout(self.main_box) @@ -143,7 +141,6 @@ class Array_map(QtGui.QWidget): self.top_row.setStretch(3, 1) # set stretch of item 1 to 1 self.main_box.addWidget(self.canvas) - self.main_box.addWidget(self.toolbar) def init_stations(self): @@ -236,6 +233,11 @@ class Array_map(QtGui.QWidget): basemap.drawcountries(zorder=4) basemap.drawstates(zorder=5) basemap.drawcoastlines(zorder=6) + # labels = [left,right,top,bottom] + parallels = np.arange(-90, 90, 5.) + basemap.drawparallels(parallels, labels=[True, True, False, False], zorder=7) + meridians = np.arange(-180, 180, 5.) + basemap.drawmeridians(meridians, labels=[False, False, True, True], zorder=7) self.basemap = basemap self.figure.tight_layout() From 46a6cdcc00b40fc2c500d477d95c6c907d320464 Mon Sep 17 00:00:00 2001 From: Marcel Date: Thu, 14 Jun 2018 15:50:44 +0200 Subject: [PATCH 031/169] [bugfix] remove autopicks weight>3 --- pylot/core/util/array_map.py | 31 ++++++++++++++++++++++--------- pylot/core/util/widgets.py | 2 +- 2 files changed, 23 insertions(+), 10 deletions(-) diff --git a/pylot/core/util/array_map.py b/pylot/core/util/array_map.py index c2464066..e6d6646f 100644 --- a/pylot/core/util/array_map.py +++ b/pylot/core/util/array_map.py @@ -53,11 +53,16 @@ class Array_map(QtGui.QWidget): for index in ind: station = str(self._station_onpick_ids[index].split('.')[-1]) try: + data = data.select(station=station) + if not data: + self._warn('No data for station {}'.format(station)) + return pickDlg = PickDlg(self._parent, parameter=self._parent._inputs, - data=data.select(station=station), + data=data, station=station, picks=self._parent.get_current_event().getPick(station), - autopicks=self._parent.get_current_event().getAutopick(station)) + autopicks=self._parent.get_current_event().getAutopick(station), + filteroptions=self._parent.filteroptions) except Exception as e: message = 'Could not generate Plot for station {st}.\n {er}'.format(st=station, er=e) self._warn(message) @@ -183,7 +188,11 @@ class Array_map(QtGui.QWidget): for st_id in station_dict.keys(): try: station_name = st_id.split('.')[-1] - picks[st_id] = self.current_picks_dict()[station_name][phase]['mpp'] + pick = self.current_picks_dict()[station_name][phase] + if pick['picker'] == 'auto': + if pick['weight'] > 3: + continue + picks[st_id] = pick['mpp'] except KeyError: continue except Exception as e: @@ -196,10 +205,10 @@ class Array_map(QtGui.QWidget): for pick in picks.values(): if type(pick) is obspy.core.utcdatetime.UTCDateTime: picks_utc.append(pick) - minp = min(picks_utc) + self._earliest_picktime = min(picks_utc) for st_id, pick in picks.items(): if type(pick) is obspy.core.utcdatetime.UTCDateTime: - pick -= minp + pick -= self._earliest_picktime picks_rel[st_id] = pick return picks_rel @@ -239,7 +248,8 @@ class Array_map(QtGui.QWidget): meridians = np.arange(-180, 180, 5.) basemap.drawmeridians(meridians, labels=[False, False, True, True], zorder=7) self.basemap = basemap - self.figure.tight_layout() + self.figure._tight = True + self.figure.tight_layout(1.15) def init_lat_lon_grid(self, nstep=250): # create a regular grid to display colormap @@ -249,8 +259,11 @@ class Array_map(QtGui.QWidget): def init_picksgrid(self): picks, lats, lons = self.get_picks_lat_lon() - self.picksgrid_active = griddata((lats, lons), picks, (self.latgrid, self.longrid), - method='linear') + try: + self.picksgrid_active = griddata((lats, lons), picks, (self.latgrid, self.longrid), + method='linear') + except Exception as e: + self._warn('Could not init picksgrid: {}'.format(e)) def get_st_lat_lon_for_plot(self): stations = [] @@ -342,7 +355,7 @@ class Array_map(QtGui.QWidget): self.scatter_all_stations() if self.picks_dict: self.scatter_picked_stations() - self.cbar = self.add_cbar(label='Time relative to first onset [s]') + self.cbar = self.add_cbar(label='Time relative to first onset ({}) [s]'.format(self._earliest_picktime)) self.comboBox_phase.setEnabled(True) else: self.comboBox_phase.setEnabled(False) diff --git a/pylot/core/util/widgets.py b/pylot/core/util/widgets.py index 0df1b784..28480ef7 100644 --- a/pylot/core/util/widgets.py +++ b/pylot/core/util/widgets.py @@ -1368,7 +1368,7 @@ class PickDlg(QDialog): self.cur_ylim = None # set attribute holding data - if data is None: + if data is None or not data: try: data = parent.get_data().getWFData().copy() self.data = data.select(station=station) From 0168d8923d2e1dd02cefa07a777731c2758d4333 Mon Sep 17 00:00:00 2001 From: Marcel Date: Thu, 14 Jun 2018 16:17:06 +0200 Subject: [PATCH 032/169] [minor] tighten PyLoT tabs layouts --- PyLoT.py | 5 +++++ pylot/styles/bright.qss | 6 +++--- pylot/styles/dark.qss | 6 +++--- 3 files changed, 11 insertions(+), 6 deletions(-) diff --git a/PyLoT.py b/PyLoT.py index 456f7671..afa17c7d 100755 --- a/PyLoT.py +++ b/PyLoT.py @@ -637,6 +637,11 @@ class MainWindow(QMainWindow): array_tab.setLayout(self.array_layout) events_tab.setLayout(self.events_layout) + # tighten up layouts inside tabs + for layout in [self.wf_layout, self.array_layout, self.events_layout]: + layout.setSpacing(0) + layout.setContentsMargins(0, 0, 0, 0) + # add tabs to main tab widget self.tabs.addTab(wf_tab, 'Waveform Plot') self.tabs.addTab(array_tab, 'Array Map') diff --git a/pylot/styles/bright.qss b/pylot/styles/bright.qss index 71e5c5a3..5f3de6a7 100644 --- a/pylot/styles/bright.qss +++ b/pylot/styles/bright.qss @@ -179,9 +179,9 @@ background-color:transparent; QTabWidget::pane{ background-color:rgba(0, 0, 0, 255); -border-style:solid; -border-color:rgba(245, 245, 245, 255); -border-width:1px; +margin: 0px, 0px, 0px, 0px; +padding: 0px; +border-width:0px; } QTabWidget::tab{ diff --git a/pylot/styles/dark.qss b/pylot/styles/dark.qss index fc866e20..0ca4cd46 100644 --- a/pylot/styles/dark.qss +++ b/pylot/styles/dark.qss @@ -178,9 +178,9 @@ background-color:transparent; QTabWidget::pane{ background-color:rgba(70, 70, 80, 255); -border-style:solid; -border-color:rgba(70, 70, 80, 255); -border-width:1px; +margin: 0px, 0px, 0px, 0px; +padding: 0px; +border-width:0px; } QTabWidget::tab{ From 7c0de4497466dd0221189dad81535b7517d94df3 Mon Sep 17 00:00:00 2001 From: Marcel Date: Fri, 15 Jun 2018 14:49:26 +0200 Subject: [PATCH 033/169] [update] array_map legend inaxes, add lat/lon status, some fixes and improvements --- pylot/core/util/array_map.py | 47 +++++++++++++++++++++++++++++------- 1 file changed, 38 insertions(+), 9 deletions(-) diff --git a/pylot/core/util/array_map.py b/pylot/core/util/array_map.py index e6d6646f..91dee54e 100644 --- a/pylot/core/util/array_map.py +++ b/pylot/core/util/array_map.py @@ -7,6 +7,7 @@ import obspy from PySide import QtGui from mpl_toolkits.basemap import Basemap from matplotlib.figure import Figure +from mpl_toolkits.axes_grid1.inset_locator import inset_axes from pylot.core.util.widgets import PickDlg, PylotCanvas from scipy.interpolate import griddata @@ -92,6 +93,7 @@ class Array_map(QtGui.QWidget): def connectSignals(self): self.comboBox_phase.currentIndexChanged.connect(self._refresh_drawings) self.comboBox_am.currentIndexChanged.connect(self._refresh_drawings) + self.canvas.mpl_connect('motion_notify_event', self.mouse_moved) #self.zoom_id = self.basemap.ax.figure.canvas.mpl_connect('scroll_event', self.zoom) def _from_dict(self, function, key): @@ -109,6 +111,14 @@ class Array_map(QtGui.QWidget): def get_max_from_picks(self): return max(self.picks_rel.values()) + def mouse_moved(self, event): + if not event.inaxes == self.main_ax: + return + x = event.xdata + y = event.ydata + lat, lon = self.basemap(x, y, inverse=True) + self.status_label.setText('Latitude: {}, Longitude: {}'.format(lat, lon)) + def current_picks_dict(self): picktype = self.comboBox_am.currentText() auto_manu = {'auto': self.autopicks_dict, @@ -119,16 +129,17 @@ class Array_map(QtGui.QWidget): if not self.figure: self.figure = Figure() + self.status_label = QtGui.QLabel() + self.main_ax = self.figure.add_subplot(111) self.canvas = PylotCanvas(self.figure, parent=self._parent, multicursor=True, panZoomX=False, panZoomY=False) - #self.canvas.setZoomBorders2content() self.main_box = QtGui.QVBoxLayout() self.setLayout(self.main_box) self.top_row = QtGui.QHBoxLayout() - self.main_box.addLayout(self.top_row) + self.main_box.addLayout(self.top_row, 1) self.comboBox_phase = QtGui.QComboBox() self.comboBox_phase.insertItem(0, 'P') @@ -145,7 +156,8 @@ class Array_map(QtGui.QWidget): self.top_row.addWidget(self.comboBox_am) self.top_row.setStretch(3, 1) # set stretch of item 1 to 1 - self.main_box.addWidget(self.canvas) + self.main_box.addWidget(self.canvas, 1) + self.main_box.addWidget(self.status_label, 0) def init_stations(self): @@ -231,8 +243,10 @@ class Array_map(QtGui.QWidget): def init_basemap(self, resolution='l'): # basemap = Basemap(projection=projection, resolution = resolution, ax=self.main_ax) + width = 5e6 + height = 2e6 basemap = Basemap(projection='lcc', resolution=resolution, ax=self.main_ax, - width=5e6, height=2e6, + width=width, height=height, lat_0=(self.latmin + self.latmax) / 2., lon_0=(self.lonmin + self.lonmax) / 2.) @@ -244,12 +258,16 @@ class Array_map(QtGui.QWidget): basemap.drawcoastlines(zorder=6) # labels = [left,right,top,bottom] parallels = np.arange(-90, 90, 5.) - basemap.drawparallels(parallels, labels=[True, True, False, False], zorder=7) + parallels_small = np.arange(-90, 90, 2.5) + basemap.drawparallels(parallels_small, linewidth=0.5, zorder=7) + basemap.drawparallels(parallels, zorder=7) meridians = np.arange(-180, 180, 5.) - basemap.drawmeridians(meridians, labels=[False, False, True, True], zorder=7) + meridians_small = np.arange(-180, 180, 2.5) + basemap.drawmeridians(meridians_small, linewidth=0.5, zorder=7) + basemap.drawmeridians(meridians, zorder=7) self.basemap = basemap self.figure._tight = True - self.figure.tight_layout(1.15) + self.figure.tight_layout() def init_lat_lon_grid(self, nstep=250): # create a regular grid to display colormap @@ -331,10 +349,20 @@ class Array_map(QtGui.QWidget): self.annotations.append(self.main_ax.annotate(' %s' % st, xy=(x, y), fontsize='x-small', color='white', zorder=12)) self.legend = self.main_ax.legend(loc=1) + self.legend.get_frame().set_facecolor((1, 1, 1, 0.75)) def add_cbar(self, label): - cbar = self.main_ax.figure.colorbar(self.sc_picked, fraction=0.025) + self.cbax_bg = inset_axes(self.main_ax, width="6%", height="75%", loc=5) + cbax = inset_axes(self.main_ax, width='2%', height='70%', loc=5) + cbar = self.main_ax.figure.colorbar(self.sc_picked, cax = cbax) cbar.set_label(label) + cbax.yaxis.tick_left() + cbax.yaxis.set_label_position('left') + for spine in self.cbax_bg.spines.values(): + spine.set_visible(False) + self.cbax_bg.yaxis.set_ticks([]) + self.cbax_bg.xaxis.set_ticks([]) + self.cbax_bg.patch.set_facecolor((1, 1, 1, 0.75)) return cbar def refresh_drawings(self, picks=None, autopicks=None): @@ -365,7 +393,8 @@ class Array_map(QtGui.QWidget): def remove_drawings(self): if hasattr(self, 'cbar'): self.cbar.remove() - del (self.cbar) + self.cbax_bg.remove() + del (self.cbar, self.cbax_bg) if hasattr(self, 'sc_picked'): self.sc_picked.remove() del (self.sc_picked) From ec32981787df4af32dead5803912695c116467d7 Mon Sep 17 00:00:00 2001 From: Marcel Date: Tue, 19 Jun 2018 10:26:17 +0200 Subject: [PATCH 034/169] [minor] improve current event highlighting --- PyLoT.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/PyLoT.py b/PyLoT.py index afa17c7d..71386963 100755 --- a/PyLoT.py +++ b/PyLoT.py @@ -3066,7 +3066,7 @@ class MainWindow(QMainWindow): set_foreground_color(column, QtGui.QColor(*(180, 180, 180, 255))) if event == current_event: - set_foreground_color(column, QtGui.QColor(*(0, 143, 143, 255))) + set_background_color(column, QtGui.QColor(*(0, 143, 143, 255))) # manipulate items item_ref.setBackground(self._ref_test_colors['ref']) From ca886d4355acad3e4bc6e0af70f617f3ffe90fc7 Mon Sep 17 00:00:00 2001 From: Marcel Date: Tue, 19 Jun 2018 10:35:34 +0200 Subject: [PATCH 035/169] [update] on obspyDMT compatibility (WIP) --- PyLoT.py | 11 ++++++----- pylot/core/util/widgets.py | 33 ++++++++++++++++++--------------- 2 files changed, 24 insertions(+), 20 deletions(-) diff --git a/PyLoT.py b/PyLoT.py index 71386963..44d27fed 100755 --- a/PyLoT.py +++ b/PyLoT.py @@ -139,6 +139,7 @@ class MainWindow(QMainWindow): self.apd_local = None self.apd_sge = None self.stations_highlighted = [] + self.obspy_dmt = False self.poS_id = None self.ae_id = None @@ -1006,7 +1007,6 @@ class MainWindow(QMainWindow): # TODO: add dataStructure class for obspyDMT here, this is just a workaround! eventpath = self.get_current_event_path(eventbox) basepath = eventpath.split(os.path.basename(eventpath))[0] - obspy_dmt = check_obspydmt_structure(basepath) if self.dataStructure: if not eventpath: return @@ -1700,9 +1700,9 @@ class MainWindow(QMainWindow): self.fnames_syn = [] eventpath = self.get_current_event_path() basepath = eventpath.split(os.path.basename(eventpath))[0] - obspy_dmt = check_obspydmt_structure(basepath) - self.dataPlot.activateObspyDMToptions(obspy_dmt) - if obspy_dmt: + self.obspy_dmt = check_obspydmt_structure(basepath) + self.dataPlot.activateObspyDMToptions(self.obspy_dmt) + if self.obspy_dmt: self.prepareObspyDMT_data(eventpath) def loadWaveformData(self): @@ -2392,7 +2392,8 @@ class MainWindow(QMainWindow): self.init_fig_dict() #if not self.tap: # init TuneAutopicker object - self.tap = TuneAutopicker(self) + wftype = self.dataPlot.qcombo_processed.currentText() if self.obspy_dmt else None + self.tap = TuneAutopicker(self, wftype) # first call of update to init tabs with empty canvas self.update_autopicker() # connect update signal of TuneAutopicker with update function diff --git a/pylot/core/util/widgets.py b/pylot/core/util/widgets.py index 28480ef7..4320232e 100644 --- a/pylot/core/util/widgets.py +++ b/pylot/core/util/widgets.py @@ -3008,13 +3008,13 @@ class TuneAutopicker(QWidget): :type: PyLoT Mainwindow ''' - def __init__(self, parent): + def __init__(self, parent, wftype=None): QtGui.QWidget.__init__(self, parent, 1) self._style = parent._style self.setWindowTitle('PyLoT - Tune Autopicker') self.parameter = self.parent()._inputs self.fig_dict = self.parent().fig_dict - self.data = Data() + self.wftype = wftype self.pdlg_widget = None self.pylot_picks = None self.init_main_layouts() @@ -3072,18 +3072,19 @@ class TuneAutopicker(QWidget): self.stationBox.activated.connect(self.fill_tabs) def fill_stationbox(self): - fnames = self.parent().getWFFnames_from_eventbox(eventbox=self.eventBox) - self.data.setWFData(fnames) + #fnames = self.parent().fnames #getWFFnames_from_eventbox(eventbox=self.eventBox) + #self.data.setWFData(fnames) + self.data = self.parent().data wfdat = self.data.getWFData() # all available streams # remove possible underscores in station names - wfdat = remove_underscores(wfdat) - # rotate misaligned stations to ZNE - # check for gaps and doubled channels - check4gaps(wfdat) - check4doubled(wfdat) - wfdat = check4rotated(wfdat, self.parent().metadata, verbosity=0) - # trim station components to same start value - trim_station_components(wfdat, trim_start=True, trim_end=False) + # wfdat = remove_underscores(wfdat) + # # rotate misaligned stations to ZNE + # # check for gaps and doubled channels + # check4gaps(wfdat) + # check4doubled(wfdat) + # wfdat = check4rotated(wfdat, self.parent().metadata, verbosity=0) + # # trim station components to same start value + # trim_station_components(wfdat, trim_start=True, trim_end=False) self.stationBox.clear() stations = [] for trace in self.data.getWFData(): @@ -3145,7 +3146,9 @@ class TuneAutopicker(QWidget): return self.eventBox.currentText().split('/')[-1] def get_current_event_fp(self): - return self.eventBox.currentText() + wfext = self.wftype if self.wftype else '' + fp = os.path.join(self.eventBox.currentText(), wfext) + return fp def get_current_event_picks(self, station): event = self.get_current_event() @@ -3175,11 +3178,11 @@ class TuneAutopicker(QWidget): self.pdlg_widget = None return station = self.get_current_station() - data = self.data.getWFData() + wfdata = self.data.getWFData() metadata = self.parent().metadata event = self.get_current_event() filteroptions = self.parent().filteroptions - self.pickDlg = PickDlg(self.parent(), data=data.select(station=station), + self.pickDlg = PickDlg(self.parent(), data=wfdata.select(station=station).copy(), station=station, parameter=self.parameter, picks=self.get_current_event_picks(station), autopicks=self.get_current_event_autopicks(station), From 7de8c2ee8b6db3a8bc8a2916a3f3491fe6251b04 Mon Sep 17 00:00:00 2001 From: Marcel Date: Tue, 19 Jun 2018 11:03:43 +0200 Subject: [PATCH 036/169] [minor] info on number of traces for main plot --- PyLoT.py | 6 ++++-- pylot/core/util/widgets.py | 25 ++++++++++++++++--------- 2 files changed, 20 insertions(+), 11 deletions(-) diff --git a/PyLoT.py b/PyLoT.py index 44d27fed..ce5120cd 100755 --- a/PyLoT.py +++ b/PyLoT.py @@ -3332,9 +3332,11 @@ class MainWindow(QMainWindow): self.fill_eventbox() self.getPlotWidget().draw() if self.plot_method == 'fast': - self.dataPlot.setPermTextMid('MIN/MAX plot', color='red') + self.dataPlot.setPermText(1, ' MIN/MAX plot ', color='red') else: - self.dataPlot.setPermTextMid() + self.dataPlot.setPermText(1) + self.dataPlot.setPermText(0, '| Number of traces: {} |'.format(len(self.getPlotWidget().getPlotDict()))) + def _setDirty(self): self.setDirty(True) diff --git a/pylot/core/util/widgets.py b/pylot/core/util/widgets.py index 4320232e..fd3b1f26 100644 --- a/pylot/core/util/widgets.py +++ b/pylot/core/util/widgets.py @@ -497,19 +497,24 @@ class WaveformWidgetPG(QtGui.QWidget): def init_labels(self): self.label_layout.addWidget(self.status_label) - self.label_layout.addWidget(self.perm_label_mid) + for label in self.perm_labels: + self.label_layout.addWidget(label) self.label_layout.addWidget(self.syn_checkbox) self.label_layout.addWidget(self.qcombo_processed) self.syn_checkbox.setLayoutDirection(Qt.RightToLeft) self.label_layout.setStretch(0, 4) - self.label_layout.setStretch(1, 2) - self.label_layout.setStretch(2, 3) - self.label_layout.setStretch(3, 1) + self.label_layout.setStretch(1, 0) + self.label_layout.setStretch(2, 0) + self.label_layout.setStretch(3, 0) + self.label_layout.setStretch(4, 3) + self.label_layout.setStretch(5, 1) def add_labels(self): self.status_label = QtGui.QLabel() - self.perm_label_mid = QtGui.QLabel() - self.perm_label_mid.setAlignment(4) + self.perm_labels = [] + for index in range(3): + label = QtGui.QLabel() + self.perm_labels.append(label) self.qcombo_processed = QtGui.QComboBox() self.syn_checkbox = QtGui.QCheckBox('synthetics') self.addQCboxItem('raw', 'black') @@ -524,9 +529,11 @@ class WaveformWidgetPG(QtGui.QWidget): self.syn_checkbox.setVisible(activate) self.qcombo_processed.setVisible(activate) - def setPermTextMid(self, text=None, color='black'): - self.perm_label_mid.setText(text) - self.perm_label_mid.setStyleSheet('color: {}'.format(color)) + def setPermText(self, number, text=None, color='black'): + if not 0 <= number < len(self.perm_labels): + raise ValueError('No label for number {}'.format(number)) + self.perm_labels[number].setText(text) + self.perm_labels[number].setStyleSheet('color: {}'.format(color)) def addQCboxItem(self, text=None, color='black'): item = QtGui.QStandardItem(text) From 47d6aeabff94270ed89c340d089a0031da3f5099 Mon Sep 17 00:00:00 2001 From: Marcel Date: Tue, 19 Jun 2018 11:28:41 +0200 Subject: [PATCH 037/169] [minor] used event highlighting of eventlist also for eventbox --- PyLoT.py | 41 +++++++++++++++++++++++++---------------- 1 file changed, 25 insertions(+), 16 deletions(-) diff --git a/PyLoT.py b/PyLoT.py index ce5120cd..9dac4716 100755 --- a/PyLoT.py +++ b/PyLoT.py @@ -1229,6 +1229,8 @@ class MainWindow(QMainWindow): tv.verticalHeader().hide() tv.setSelectionBehavior(QtGui.QAbstractItemView.SelectRows) + current_event = self.get_current_event() + eventBox.setView(tv) eventBox.clear() model = eventBox.model() @@ -1316,6 +1318,10 @@ class MainWindow(QMainWindow): if event_test and select_events == 'ref' or self.isEmpty(event_path): for item in itemlist: item.setEnabled(False) + + #item color + self.setItemColor(itemlist, id, event, current_event) + model.appendRow(itemlist) if not event.path == self.eventBox.itemText(id).strip(): message = ('Path missmatch creating eventbox.\n' @@ -2949,14 +2955,6 @@ class MainWindow(QMainWindow): event.addNotes(notes) self.fill_eventbox() - def set_background_color(items, color): - for item in items: - item.setBackground(color) - - def set_foreground_color(items, color): - for item in items: - item.setForeground(color) - current_event = self.get_current_event() # generate delete icon @@ -3060,14 +3058,7 @@ class MainWindow(QMainWindow): item_nmp, item_nap, item_ref, item_test, item_notes] self.project._table.append(column) - if index%2: - set_background_color(column, QtGui.QColor(*(245, 245, 245, 255))) - - if self.isEmpty(event.path): - set_foreground_color(column, QtGui.QColor(*(180, 180, 180, 255))) - - if event == current_event: - set_background_color(column, QtGui.QColor(*(0, 143, 143, 255))) + self.setItemColor(column, index, event, current_event) # manipulate items item_ref.setBackground(self._ref_test_colors['ref']) @@ -3089,6 +3080,24 @@ class MainWindow(QMainWindow): self.events_layout.addWidget(self.event_table) self.tabs.setCurrentIndex(tabindex) + def setItemColor(self, item_list, index, event, current_event): + def set_background_color(items, color): + for item in items: + item.setBackground(color) + + def set_foreground_color(items, color): + for item in items: + item.setForeground(color) + + if index % 2: + set_background_color(item_list, QtGui.QColor(*(245, 245, 245, 255))) + + if self.isEmpty(event.path): + set_foreground_color(item_list, QtGui.QColor(*(180, 180, 180, 255))) + + if event == current_event: + set_background_color(item_list, QtGui.QColor(*(0, 143, 143, 255))) + def read_metadata_thread(self, fninv): self.rm_thread = Thread(self, read_metadata, arg=fninv, progressText='Reading metadata...', pb_widget=self.mainProgressBarWidget) From 08124174b1a8fab1d0aa362050d91d931a834e1f Mon Sep 17 00:00:00 2001 From: Marcel Date: Wed, 20 Jun 2018 11:47:10 +0200 Subject: [PATCH 038/169] [update] autopicker - obspyDMT (WIP) --- autoPyLoT.py | 42 ++++++++++++++++++++++++++----------- pylot/core/pick/autopick.py | 2 ++ pylot/core/pick/charfuns.py | 2 +- 3 files changed, 33 insertions(+), 13 deletions(-) diff --git a/autoPyLoT.py b/autoPyLoT.py index eb355609..79486fc5 100755 --- a/autoPyLoT.py +++ b/autoPyLoT.py @@ -34,7 +34,7 @@ __version__ = _getVersionString() def autoPyLoT(input_dict=None, parameter=None, inputfile=None, fnames=None, eventid=None, savepath=None, - savexml=True, station='all', iplot=0, ncores=0): + savexml=True, station='all', iplot=0, ncores=0, obspyDMT_wfpath=False): """ Determine phase onsets automatically utilizing the automatic picking algorithms by Kueperkoch et al. 2010/2012. @@ -114,6 +114,8 @@ def autoPyLoT(input_dict=None, parameter=None, inputfile=None, fnames=None, even locflag = input_dict['locflag'] if 'savexml' in input_dict: savexml = input_dict['savexml'] + if 'obspyDMT_wfpath' in input_dict: + obspyDMT_wfpath = input_dict['obspyDMT_wfpath'] if not parameter: if inputfile: @@ -175,6 +177,14 @@ def autoPyLoT(input_dict=None, parameter=None, inputfile=None, fnames=None, even print("!!No source parameter estimation possible!!") print(" !!! ") + wfpath_extension = '' + if obspyDMT_wfpath not in [None, False]: + wfpath_extension = obspyDMT_wfpath + print('Using obspyDMT structure. There will be no restitution, as pre-processed data are expected.') + if wfpath_extension != 'processed': + print('WARNING: Expecting wfpath_extension to be "processed" for' + ' pre-processed data but received "{}" instead!!!'.format(wfpath_extension)) + if not input_dict: # started in production mode datapath = datastructure.expandDataPath() @@ -184,16 +194,16 @@ def autoPyLoT(input_dict=None, parameter=None, inputfile=None, fnames=None, even events = [events for events in glob.glob(os.path.join(datapath, '*')) if os.path.isdir(events)] elif fnames == 'None' and parameter['eventID'] is not '*' and not type(parameter['eventID']) == list: # single event processing - events = glob.glob(os.path.join(datapath, parameter['eventID'])) + events = glob.glob(os.path.join(datapath, parameter['eventID'], wfpath_extension)) elif fnames == 'None' and type(parameter['eventID']) == list: # multiple event processing events = [] for eventID in parameter['eventID']: - events.append(os.path.join(datapath, eventID)) + events.append(os.path.join(datapath, eventID, wfpath_extension)) else: # autoPyLoT was initialized from GUI events = [] - events.append(eventid) + events.append(os.path.join(eventid, wfpath_extension)) evID = os.path.split(eventid)[-1] locflag = 2 else: @@ -204,7 +214,8 @@ def autoPyLoT(input_dict=None, parameter=None, inputfile=None, fnames=None, even for eventID in eventid: events.append(os.path.join(datapath, parameter['database'], - eventID)) + eventID, + wfpath_extension)) if not events: print('autoPyLoT: No events given. Return!') @@ -218,7 +229,10 @@ def autoPyLoT(input_dict=None, parameter=None, inputfile=None, fnames=None, even allpicks = {} glocflag = locflag for eventpath in events: - evID = os.path.split(eventpath)[-1] + if not wfpath_extension: + evID = os.path.split(eventpath)[-1] + else: + evID = os.path.split(os.path.split(eventpath)[0])[-1] fext = '.xml' filename = os.path.join(eventpath, 'PyLoT_' + evID + fext) try: @@ -267,13 +281,17 @@ def autoPyLoT(input_dict=None, parameter=None, inputfile=None, fnames=None, even wfdat = check4gaps(wfdat) wfdat = check4doubled(wfdat) wfdat = trim_station_components(wfdat, trim_start=True, trim_end=False) - metadata = read_metadata(parameter.get('invdir')) - # rotate stations to ZNE - wfdat = check4rotated(wfdat, metadata) + if not wfpath_extension: + metadata = read_metadata(parameter.get('invdir')) + else: + metadata = None corr_dat = None - if locflag: - print("Restitute data ...") - corr_dat = restitute_data(wfdat.copy(), *metadata, ncores=ncores) + if metadata: + # rotate stations to ZNE + wfdat = check4rotated(wfdat, metadata) + if locflag: + print("Restitute data ...") + corr_dat = restitute_data(wfdat.copy(), *metadata, ncores=ncores) if not corr_dat and locflag: locflag = 2 print('Working on event %s. Stations: %s' % (eventpath, station)) diff --git a/pylot/core/pick/autopick.py b/pylot/core/pick/autopick.py index c1a5704c..00810447 100644 --- a/pylot/core/pick/autopick.py +++ b/pylot/core/pick/autopick.py @@ -283,6 +283,8 @@ def autopickstation(wfstream, pickparam, verbose=False, if use_taup is True: Lc = np.inf print('autopickstation: use_taup flag active.') + if not metadata: + metadata = [None, None] if not metadata[1]: print('Warning: Could not use TauPy to estimate onsets as there are no metadata given.') else: diff --git a/pylot/core/pick/charfuns.py b/pylot/core/pick/charfuns.py index a62870eb..f3aa8a64 100644 --- a/pylot/core/pick/charfuns.py +++ b/pylot/core/pick/charfuns.py @@ -78,7 +78,7 @@ class CharacteristicFunction(object): return self.cut def setCut(self, cut): - self.cut = cut + self.cut = (int(cut[0]), int(cut[1])) def getTime1(self): return self.t1 From 910ed6667658f4bf34d9beddbbbc7dec7426ae66 Mon Sep 17 00:00:00 2001 From: Marcel Date: Wed, 20 Jun 2018 13:49:27 +0200 Subject: [PATCH 039/169] [new] only load relevant waveforms into TAP widget --- PyLoT.py | 6 +-- pylot/core/util/widgets.py | 104 +++++++++++++++++++++++++------------ 2 files changed, 73 insertions(+), 37 deletions(-) diff --git a/PyLoT.py b/PyLoT.py index 9dac4716..3cee4ef9 100755 --- a/PyLoT.py +++ b/PyLoT.py @@ -2294,13 +2294,14 @@ class MainWindow(QMainWindow): self.update_status('picking on station {0}'.format(station)) data = self.get_data().getOriginalWFData().copy() event = self.get_current_event() + wftype = self.dataPlot.qcombo_processed.currentText() if self.obspy_dmt else None pickDlg = PickDlg(self, parameter=self._inputs, data=data.select(station=station), station=station, network=network, picks=self.getPicksOnStation(station, 'manual'), autopicks=self.getPicksOnStation(station, 'auto'), metadata=self.metadata, event=event, - filteroptions=self.filteroptions) + filteroptions=self.filteroptions, wftype=wftype) if self.filterActionP.isChecked() or self.filterActionS.isChecked(): pickDlg.currentPhase = self.getSeismicPhase() pickDlg.filterWFData() @@ -2398,8 +2399,7 @@ class MainWindow(QMainWindow): self.init_fig_dict() #if not self.tap: # init TuneAutopicker object - wftype = self.dataPlot.qcombo_processed.currentText() if self.obspy_dmt else None - self.tap = TuneAutopicker(self, wftype) + self.tap = TuneAutopicker(self, self.obspy_dmt) # first call of update to init tabs with empty canvas self.update_autopicker() # connect update signal of TuneAutopicker with update function diff --git a/pylot/core/util/widgets.py b/pylot/core/util/widgets.py index fd3b1f26..dd9de3c6 100644 --- a/pylot/core/util/widgets.py +++ b/pylot/core/util/widgets.py @@ -26,6 +26,7 @@ from matplotlib.backends.backend_qt4agg import NavigationToolbar2QT from matplotlib.widgets import MultiCursor from matplotlib.tight_layout import get_renderer, get_subplotspec_list, get_tight_layout_figure from scipy.signal import argrelmin, argrelmax +from obspy import read from PySide import QtCore, QtGui from PySide.QtGui import QAction, QApplication, QCheckBox, QComboBox, \ @@ -1314,7 +1315,7 @@ class PickDlg(QDialog): def __init__(self, parent=None, data=None, station=None, network=None, picks=None, autopicks=None, rotate=False, parameter=None, embedded=False, metadata=None, - event=None, filteroptions=None, model='iasp91'): + event=None, filteroptions=None, model='iasp91', wftype=None): super(PickDlg, self).__init__(parent, 1) self.orig_parent = parent self.setAttribute(Qt.WA_DeleteOnClose) @@ -1326,6 +1327,7 @@ class PickDlg(QDialog): self.network = network self.rotate = rotate self.metadata = metadata + self.wftype = wftype self.pylot_event = event self.components = 'ZNE' self.currentPhase = None @@ -1415,8 +1417,12 @@ class PickDlg(QDialog): actionS.setChecked(self.getChannelSettingsS(channel)) # plot data + title = self.getStation() + if self.wftype is not None: + title += ' | ({})'.format(self.wftype) + self.multicompfig.plotWFData(wfdata=self.getWFData(), - title=self.getStation()) + title=title) self.multicompfig.setZoomBorders2content() @@ -2583,6 +2589,9 @@ class PickDlg(QDialog): filtops_str = transformFilteroptions2String(filtoptions) title += ' | Filteroptions: {}'.format(filtops_str) + if self.wftype is not None: + title += ' | ({})'.format(self.wftype) + plot_additional = bool(self.compareChannel.currentText()) additional_channel = self.compareChannel.currentText() scale_channel = self.scaleChannel.currentText() @@ -3015,13 +3024,15 @@ class TuneAutopicker(QWidget): :type: PyLoT Mainwindow ''' - def __init__(self, parent, wftype=None): + def __init__(self, parent, obspy_dmt=False): QtGui.QWidget.__init__(self, parent, 1) self._style = parent._style self.setWindowTitle('PyLoT - Tune Autopicker') self.parameter = self.parent()._inputs self.fig_dict = self.parent().fig_dict - self.wftype = wftype + self.data = Data() + self.obspy_dmt = obspy_dmt + self.wftype = None self.pdlg_widget = None self.pylot_picks = None self.init_main_layouts() @@ -3078,36 +3089,57 @@ class TuneAutopicker(QWidget): self.eventBox.activated.connect(self.fill_tabs) self.stationBox.activated.connect(self.fill_tabs) + def catch_station_ids(self): + self.station_ids = {} + eventpath = self.get_current_event_fp() + self.wftype = 'processed' if self.obspy_dmt else '' + wf_path = os.path.join(eventpath, self.wftype) + if not os.path.exists(wf_path) and self.obspy_dmt: + self.wftype = 'raw' + wf_path = os.path.join(eventpath, self.wftype) + for filename in os.listdir(wf_path): + filename = os.path.join(eventpath, self.wftype, filename) + try: + st = read(filename, headonly=True) + except Exception as e: + print('Warning: Could not read file {} as a stream object: {}'.format(filename, e)) + continue + for trace in st: + network = trace.stats.network + station = trace.stats.station + location = trace.stats.location + station_id = '{}.{}.{}'.format(network, station, location) + if not station_id in self.station_ids: + self.station_ids[station_id] = [] + self.station_ids[station_id].append(filename) + def fill_stationbox(self): - #fnames = self.parent().fnames #getWFFnames_from_eventbox(eventbox=self.eventBox) - #self.data.setWFData(fnames) - self.data = self.parent().data - wfdat = self.data.getWFData() # all available streams - # remove possible underscores in station names - # wfdat = remove_underscores(wfdat) - # # rotate misaligned stations to ZNE - # # check for gaps and doubled channels - # check4gaps(wfdat) - # check4doubled(wfdat) - # wfdat = check4rotated(wfdat, self.parent().metadata, verbosity=0) - # # trim station components to same start value - # trim_station_components(wfdat, trim_start=True, trim_end=False) self.stationBox.clear() - stations = [] - for trace in self.data.getWFData(): - station = trace.stats.station - network = trace.stats.network - ns_tup = (str(network), str(station)) - if not ns_tup in stations: - stations.append(ns_tup) - stations.sort() model = self.stationBox.model() - for network, station in stations: - item = QtGui.QStandardItem(network + '.' + station) - if station in self.get_current_event().pylot_picks: + + self.catch_station_ids() + st_ids_list = list(self.station_ids.keys()) + st_ids_list.sort() + for station_id in st_ids_list: + item = QtGui.QStandardItem(station_id) + if station_id.split('.')[1] in self.get_current_event().pylot_picks: item.setBackground(self.parent()._ref_test_colors['ref']) model.appendRow(item) + def load_wf_data(self): + fnames = self.station_ids[self.get_current_station_id()] + self.data.setWFData(fnames) + wfdat = self.data.getWFData() # all available streams + # remove possible underscores in station names + wfdat = remove_underscores(wfdat) + # rotate misaligned stations to ZNE + # check for gaps and doubled channels + check4gaps(wfdat) + check4doubled(wfdat) + wfdat = check4rotated(wfdat, self.parent().metadata, verbosity=0) + # trim station components to same start value + trim_station_components(wfdat, trim_start=True, trim_end=False) + def init_figure_tabs(self): self.figure_tabs = QtGui.QTabWidget() self.fill_figure_tabs() @@ -3153,9 +3185,7 @@ class TuneAutopicker(QWidget): return self.eventBox.currentText().split('/')[-1] def get_current_event_fp(self): - wfext = self.wftype if self.wftype else '' - fp = os.path.join(self.eventBox.currentText(), wfext) - return fp + return self.eventBox.currentText() def get_current_event_picks(self, station): event = self.get_current_event() @@ -3169,7 +3199,10 @@ class TuneAutopicker(QWidget): return event.pylot_autopicks[station] def get_current_station(self): - return str(self.stationBox.currentText()).split('.')[-1] + return str(self.stationBox.currentText()).split('.')[1] + + def get_current_station_id(self): + return str(self.stationBox.currentText()) def gen_tab_widget(self, name, canvas): widget = QtGui.QWidget() @@ -3184,17 +3217,19 @@ class TuneAutopicker(QWidget): self.pdlg_widget.setParent(None) self.pdlg_widget = None return + self.load_wf_data() station = self.get_current_station() wfdata = self.data.getWFData() metadata = self.parent().metadata event = self.get_current_event() filteroptions = self.parent().filteroptions + wftype = self.wftype if self.obspy_dmt else '' self.pickDlg = PickDlg(self.parent(), data=wfdata.select(station=station).copy(), station=station, parameter=self.parameter, picks=self.get_current_event_picks(station), autopicks=self.get_current_event_autopicks(station), metadata=metadata, event=event, filteroptions=filteroptions, - embedded=True) + embedded=True, wftype=wftype) self.pickDlg.update_picks.connect(self.picks_from_pickdlg) self.pickDlg.update_picks.connect(self.fill_eventbox) self.pickDlg.update_picks.connect(self.fill_stationbox) @@ -3381,7 +3416,8 @@ class TuneAutopicker(QWidget): 'iplot': 2, 'fig_dict': self.fig_dict, 'locflag': 0, - 'savexml': False} + 'savexml': False, + 'obspyDMT_wfpath': self.obspy_dmt} for key in self.fig_dict.keys(): if not key == 'plot_style': self.fig_dict[key].clear() From 7ad36c2305e8cfa61c554a75889b02953ba39a2e Mon Sep 17 00:00:00 2001 From: Marcel Date: Wed, 20 Jun 2018 13:55:59 +0200 Subject: [PATCH 040/169] [bugfix] take width of mainwindow for min/max plot estimation before width was only 80px for initial plot --- pylot/core/util/widgets.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pylot/core/util/widgets.py b/pylot/core/util/widgets.py index dd9de3c6..af41dcdb 100644 --- a/pylot/core/util/widgets.py +++ b/pylot/core/util/widgets.py @@ -659,7 +659,7 @@ class WaveformWidgetPG(QtGui.QWidget): create min/max array for fast plotting (approach based on obspy __plot_min_max function) :returns data, time_ax ''' - npixel = self.width() + npixel = self.orig_parent.width() ndata = len(trace.data) pts_per_pixel = ndata/npixel if pts_per_pixel < 2: From 2a8efd09043ee386dfdab65d4516723aa8c39b15 Mon Sep 17 00:00:00 2001 From: Marcel Date: Thu, 21 Jun 2018 13:24:24 +0200 Subject: [PATCH 041/169] [bugfix] autoPyLoT <-> obspyDMT --- PyLoT.py | 5 +++-- pylot/core/util/widgets.py | 3 ++- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/PyLoT.py b/PyLoT.py index 3cee4ef9..b5e5788b 100755 --- a/PyLoT.py +++ b/PyLoT.py @@ -2481,6 +2481,7 @@ class MainWindow(QMainWindow): # export current picks etc. self.exportAllEvents(['.xml']) + wfpath = self.dataPlot.qcombo_processed.currentText() if self.obspy_dmt else '' # define arguments for picker args = {'parameter': self._inputs, 'station': 'all', @@ -2490,8 +2491,8 @@ class MainWindow(QMainWindow): 'fig_dict': None, 'fig_dict_wadatijack': self.fig_dict_wadatijack, 'locflag': 0, - 'savexml': False} - + 'savexml': False, + 'obspyDMT_wfpath': wfpath} # init pick thread self.mp_thread = QtCore.QThreadPool() self.mp_worker = Worker(autoPyLoT, args, redirect_stdout=True) diff --git a/pylot/core/util/widgets.py b/pylot/core/util/widgets.py index af41dcdb..1c902c4d 100644 --- a/pylot/core/util/widgets.py +++ b/pylot/core/util/widgets.py @@ -3409,6 +3409,7 @@ class TuneAutopicker(QWidget): if not station: self._warn('No station selected') return + wfpath = self.wftype if self.obspy_dmt else '' args = {'parameter': self.parameter, 'station': station, 'fnames': 'None', @@ -3417,7 +3418,7 @@ class TuneAutopicker(QWidget): 'fig_dict': self.fig_dict, 'locflag': 0, 'savexml': False, - 'obspyDMT_wfpath': self.obspy_dmt} + 'obspyDMT_wfpath': wfpath} for key in self.fig_dict.keys(): if not key == 'plot_style': self.fig_dict[key].clear() From a5667c1e06f9972051de7c082510d9a8d7ec8578 Mon Sep 17 00:00:00 2001 From: Marcel Date: Thu, 21 Jun 2018 14:23:52 +0200 Subject: [PATCH 042/169] [bugfix] nextStation not working with deleted PickDlg --- PyLoT.py | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/PyLoT.py b/PyLoT.py index b5e5788b..0ff010ea 100755 --- a/PyLoT.py +++ b/PyLoT.py @@ -140,6 +140,7 @@ class MainWindow(QMainWindow): self.apd_sge = None self.stations_highlighted = [] self.obspy_dmt = False + self.nextStation = False self.poS_id = None self.ae_id = None @@ -2284,7 +2285,7 @@ class MainWindow(QMainWindow): if nwst in self.stations_highlighted: self.toggle_station_color(wfID, network, station) - def pickDialog(self, wfID, network=None, station=None, nextStation=False): + def pickDialog(self, wfID, network=None, station=None): if not network: network = self.getNetworkName(wfID) if not station: @@ -2305,7 +2306,8 @@ class MainWindow(QMainWindow): if self.filterActionP.isChecked() or self.filterActionS.isChecked(): pickDlg.currentPhase = self.getSeismicPhase() pickDlg.filterWFData() - pickDlg.nextStation.setChecked(nextStation) + pickDlg.nextStation.setChecked(self.nextStation) + pickDlg.nextStation.stateChanged.connect(self.toggle_next_station) if pickDlg.exec_(): if pickDlg._dirty: self.setDirty(True) @@ -2315,13 +2317,13 @@ class MainWindow(QMainWindow): self.enableSaveEventAction() if replot1 or replot2: self.plotWaveformDataThread() - self.drawPicks() + self.draw() else: self.drawPicks(station) self.draw() - if pickDlg.nextStation.isChecked(): - self.pickDialog(wfID - 1, nextStation=pickDlg.nextStation.isChecked()) + if self.nextStation: + self.pickDialog(wfID - 1) else: self.update_status('picks discarded ({0})'.format(station)) if not self.get_loc_flag() and self.check4Loc(): @@ -2330,6 +2332,9 @@ class MainWindow(QMainWindow): elif self.get_loc_flag() and not self.check4Loc(): self.set_loc_flag(False) + def toggle_next_station(self, signal): + self.nextStation = bool(signal) + def addListItem(self, text): self.listWidget.addItem(text) self.listWidget.scrollToBottom() From 1b5f58bbbd0dcd914badd167b66d592837179aec Mon Sep 17 00:00:00 2001 From: Marcel Date: Thu, 21 Jun 2018 14:24:15 +0200 Subject: [PATCH 043/169] [minor] prefer processed data on init --- pylot/core/util/widgets.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pylot/core/util/widgets.py b/pylot/core/util/widgets.py index 1c902c4d..23525d5c 100644 --- a/pylot/core/util/widgets.py +++ b/pylot/core/util/widgets.py @@ -518,8 +518,8 @@ class WaveformWidgetPG(QtGui.QWidget): self.perm_labels.append(label) self.qcombo_processed = QtGui.QComboBox() self.syn_checkbox = QtGui.QCheckBox('synthetics') - self.addQCboxItem('raw', 'black') self.addQCboxItem('processed', 'green') + self.addQCboxItem('raw', 'black') #self.perm_qcbox_right.setAlignment(2) self.setLayout(self.main_layout) From 34508fc4a31e83ab61fa487490361117ac5e8110 Mon Sep 17 00:00:00 2001 From: Marcel Date: Thu, 21 Jun 2018 15:04:58 +0200 Subject: [PATCH 044/169] [bugfix] addressing PyLoTCanvas already deleted setParent(None) -> del(widget), not fully working on autopickwidget --- pylot/core/util/widgets.py | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/pylot/core/util/widgets.py b/pylot/core/util/widgets.py index 23525d5c..95d42fca 100644 --- a/pylot/core/util/widgets.py +++ b/pylot/core/util/widgets.py @@ -16,6 +16,9 @@ import time import numpy as np +import matplotlib +matplotlib.use('QT4Agg') + from matplotlib.figure import Figure try: @@ -1400,7 +1403,7 @@ class PickDlg(QDialog): # fill compare and scale channels self.compareChannel.addItem('-', None) - self.scaleChannel.addItem('normalized', None) + self.scaleChannel.addItem('individual', None) for trace in self.getWFData(): channel = trace.stats.channel @@ -1601,7 +1604,7 @@ class PickDlg(QDialog): _dialtoolbar.addWidget(QtGui.QLabel('Compare to channel: ')) _dialtoolbar.addWidget(self.compareChannel) _dialtoolbar.addSeparator() - _dialtoolbar.addWidget(QtGui.QLabel('Scale by: ')) + _dialtoolbar.addWidget(QtGui.QLabel('Scaling: ')) _dialtoolbar.addWidget(self.scaleChannel) # layout the innermost widget @@ -2942,7 +2945,7 @@ class AutoPickWidget(MultiEventWidget): def reinitEvents2plot(self): for eventID, eventDict in self.events2plot.items(): for widget_key, widget in eventDict.items(): - widget.setParent(None) + del(widget) self.events2plot = {} self.eventbox.clear() self.refresh_plot_tabs() @@ -3473,9 +3476,7 @@ class TuneAutopicker(QWidget): def clear_all(self): if hasattr(self, 'pdlg_widget'): if self.pdlg_widget: - self.pdlg_widget.setParent(None) - # TODO: removing widget by parent deletion raises exception when activating stationbox: - # RuntimeError: Internal C++ object (PylotCanvas) already deleted. + del(self.pdlg_widget) if hasattr(self, 'overview'): self.overview.setParent(None) if hasattr(self, 'p_tabs'): From b607da7262a7a2fd47c4a110fdf4e542102d0f4f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ludger=20K=C3=BCperkoch?= Date: Mon, 25 Jun 2018 10:30:36 +0200 Subject: [PATCH 045/169] [Bugfix] it was not sure that enough waveform remains for processing after cutting with improper cut times --- pylot/core/pick/autopick.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pylot/core/pick/autopick.py b/pylot/core/pick/autopick.py index 00810447..ca1a6d07 100644 --- a/pylot/core/pick/autopick.py +++ b/pylot/core/pick/autopick.py @@ -333,7 +333,7 @@ def autopickstation(wfstream, pickparam, verbose=False, return Ldiff = Lwf - abs(Lc) - if Ldiff < 0 or pstop <= pstart: + if Ldiff <= 0 or pstop <= pstart or pstop - pstart <= thosmw: msg = 'autopickstation: Cutting times are too large for actual ' \ 'waveform!\nUsing entire waveform instead!' if verbose: print(msg) From 04e75abcf5dd09ca443bfd2e532df7723532c935 Mon Sep 17 00:00:00 2001 From: Marcel Date: Mon, 25 Jun 2018 14:21:34 +0200 Subject: [PATCH 046/169] [bugfix] read_metadata obspyDMT --- autoPyLoT.py | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/autoPyLoT.py b/autoPyLoT.py index 79486fc5..3c88742f 100755 --- a/autoPyLoT.py +++ b/autoPyLoT.py @@ -178,7 +178,7 @@ def autoPyLoT(input_dict=None, parameter=None, inputfile=None, fnames=None, even print(" !!! ") wfpath_extension = '' - if obspyDMT_wfpath not in [None, False]: + if obspyDMT_wfpath not in [None, False, 'False']: wfpath_extension = obspyDMT_wfpath print('Using obspyDMT structure. There will be no restitution, as pre-processed data are expected.') if wfpath_extension != 'processed': @@ -281,10 +281,12 @@ def autoPyLoT(input_dict=None, parameter=None, inputfile=None, fnames=None, even wfdat = check4gaps(wfdat) wfdat = check4doubled(wfdat) wfdat = trim_station_components(wfdat, trim_start=True, trim_end=False) - if not wfpath_extension: - metadata = read_metadata(parameter.get('invdir')) - else: - metadata = None + metadata = read_metadata(parameter.get('invdir')) + # TODO: (idea) read metadata from obspy_dmt database + # if not wfpath_extension: + # metadata = read_metadata(parameter.get('invdir')) + # else: + # metadata = None corr_dat = None if metadata: # rotate stations to ZNE @@ -530,9 +532,12 @@ if __name__ == "__main__": parser.add_argument('-c', '-C', '--ncores', type=int, action='store', default=0, help='''optional, number of CPU cores used for parallel processing (default: all available(=0))''') + parser.add_argument('-dmt', '-DMT', '--obspy_dmt_wfpath', type=str, + action='store', default=False, + help='''optional, wftype (raw, processed) used for obspyDMT database structure''') cla = parser.parse_args() picks = autoPyLoT(inputfile=str(cla.inputfile), fnames=str(cla.fnames), eventid=str(cla.eventid), savepath=str(cla.spath), - ncores=cla.ncores, iplot=int(cla.iplot)) + ncores=cla.ncores, iplot=int(cla.iplot), obspyDMT_wfpath=str(cla.obspy_dmt_wfpath)) From 77b4458ab5dab15b561a6753ae542577bdce0ecc Mon Sep 17 00:00:00 2001 From: Marcel Date: Mon, 25 Jun 2018 14:22:14 +0200 Subject: [PATCH 047/169] [idea] change read_metadata to also read files without specific file ending --- pylot/core/util/dataprocessing.py | 63 +++++++++++++++++++++++++++++++ 1 file changed, 63 insertions(+) diff --git a/pylot/core/util/dataprocessing.py b/pylot/core/util/dataprocessing.py index 6b952164..a83d3f1e 100644 --- a/pylot/core/util/dataprocessing.py +++ b/pylot/core/util/dataprocessing.py @@ -196,6 +196,69 @@ def read_metadata(path_to_inventory): return invtype, robj +# idea to optimize read_metadata +# def read_metadata_new(path_to_inventory): +# metadata_objects = [] +# # read multiple files from directory +# if os.path.isdir(path_to_inventory): +# fnames = os.listdir(path_to_inventory) +# # read single file +# elif os.path.isfile(path_to_inventory): +# fnames = [path_to_inventory] +# else: +# print("Neither dataless-SEED file, inventory-xml file nor " +# "RESP-file found!") +# print("!!WRONG CALCULATION OF SOURCE PARAMETERS!!") +# fnames = [] +# +# for fname in fnames: +# path_to_inventory_filename = os.path.join(path_to_inventory, fname) +# try: +# ftype, robj = read_metadata_file(path_to_inventory_filename) +# metadata_objects.append((ftype, robj)) +# except Exception as e: +# print('Could not read metadata file {} ' +# 'because of the following Exception: {}'.format(path_to_inventory_filename, e)) +# return metadata_objects + + +# def read_metadata_file(path_to_inventory_filename): +# # functions used to read metadata for different file endings (or file types) +# read_functions = {'dless': _read_dless, +# 'dseed': _read_dless, +# 'xml': _read_inventory_file, +# 'resp': _read_inventory_file} +# file_ending = path_to_inventory_filename.split('.')[-1] +# if file_ending in read_functions.keys(): +# robj, exc = read_functions[file_ending](path_to_inventory_filename) +# if exc is not None: +# raise exc +# return file_ending, robj +# # in case file endings did not match the above keys, try and error +# for file_type in ['dless', 'xml']: +# robj, exc = read_functions[file_type](path_to_inventory_filename) +# if exc is None: +# return file_type, robj +# +# +# def _read_dless(path_to_inventory): +# exc = None +# try: +# parser = Parser(path_to_inventory) +# except Exception as exc: +# parser = None +# return parser, exc +# +# +# def _read_inventory_file(path_to_inventory): +# exc = None +# try: +# inv = read_inventory(path_to_inventory) +# except Exception as exc: +# inv = None +# return inv, exc + + def restitute_trace(input_tuple): tr, invtype, inobj, unit, force = input_tuple From b18298c4db7c8b8cfc96e437c988f07a43d805a9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ludger=20K=C3=BCperkoch?= Date: Mon, 25 Jun 2018 15:24:36 +0200 Subject: [PATCH 048/169] Additional screen output of derived onset time, [Bugfix] Use of argrelmax not reliable. --- pylot/core/pick/autopick.py | 3 +-- pylot/core/pick/picker.py | 10 ++++++---- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/pylot/core/pick/autopick.py b/pylot/core/pick/autopick.py index ca1a6d07..40357c7a 100644 --- a/pylot/core/pick/autopick.py +++ b/pylot/core/pick/autopick.py @@ -564,7 +564,6 @@ def autopickstation(wfstream, pickparam, verbose=False, SNRPdB, FM) print(msg) - msg = 'autopickstation: Refined P-Pick: {} s | P-Error: {} s'.format(mpickP, Perror) print(msg) Sflag = 1 @@ -843,7 +842,7 @@ def autopickstation(wfstream, pickparam, verbose=False, lpickS = lpick[ipick] Serror = pickerr[ipick] - msg = 'autopickstation: Refined S-Pick: {} s | S-Error: {} s'.format(mpickS, Serror) + msg = 'autopickstation: Refined S-Pick: {} s | S-Error: {} s'.format(hdat[0].stats.starttime + mpickS, Serror) print(msg) # get SNR diff --git a/pylot/core/pick/picker.py b/pylot/core/pick/picker.py index 3c0714bc..381000b0 100644 --- a/pylot/core/pick/picker.py +++ b/pylot/core/pick/picker.py @@ -253,13 +253,15 @@ class AICPicker(AutoPicker): except IndexError: print("Slope Calculation: empty array islope, check signal window") return - if len(dataslope) <= 1: + if len(dataslope) <= 2: print('No or not enough data in slope window found!') return - imaxs, = argrelmax(dataslope) - if imaxs.size: + try: + imaxs, = argrelmax(dataslope) + imaxs.size imax = imaxs[0] - else: + except ValueError as e: + print(e, 'picker: argrelmax not working!') imax = np.argmax(dataslope) iislope = islope[0][0:imax + 1] if len(iislope) < 2: From 7d175a4bc9424b4740c93e6e086d6762daa2bba5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ludger=20K=C3=BCperkoch?= Date: Mon, 25 Jun 2018 15:30:10 +0200 Subject: [PATCH 049/169] Accidently screen output got lost. --- pylot/core/pick/autopick.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/pylot/core/pick/autopick.py b/pylot/core/pick/autopick.py index 40357c7a..8afcaade 100644 --- a/pylot/core/pick/autopick.py +++ b/pylot/core/pick/autopick.py @@ -564,6 +564,8 @@ def autopickstation(wfstream, pickparam, verbose=False, SNRPdB, FM) print(msg) + msg = 'autopickstation: Refind P-Pick: {} s | P-Error: {} s'.format(zdat[0].stats.starttime \ + + mpickP, Perror) print(msg) Sflag = 1 From d4b76bdecb6c251fc55ef9653fa21c3e9c70451e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ludger=20K=C3=BCperkoch?= Date: Mon, 25 Jun 2018 15:31:58 +0200 Subject: [PATCH 050/169] Cosmetics --- pylot/core/pick/autopick.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/pylot/core/pick/autopick.py b/pylot/core/pick/autopick.py index 8afcaade..aecd6251 100644 --- a/pylot/core/pick/autopick.py +++ b/pylot/core/pick/autopick.py @@ -844,7 +844,8 @@ def autopickstation(wfstream, pickparam, verbose=False, lpickS = lpick[ipick] Serror = pickerr[ipick] - msg = 'autopickstation: Refined S-Pick: {} s | S-Error: {} s'.format(hdat[0].stats.starttime + mpickS, Serror) + msg = 'autopickstation: Refined S-Pick: {} s | S-Error: {} s'.format(hdat[0].stats.starttime \ + + mpickS, Serror) print(msg) # get SNR From 3845e7291ea52fcc47f94910d6a01e4ef4a3011b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ludger=20K=C3=BCperkoch?= Date: Mon, 25 Jun 2018 15:56:15 +0200 Subject: [PATCH 051/169] Relaxed condition for slope determination, plot interims results even if picking failed. --- pylot/core/pick/picker.py | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/pylot/core/pick/picker.py b/pylot/core/pick/picker.py index 381000b0..56db3df2 100644 --- a/pylot/core/pick/picker.py +++ b/pylot/core/pick/picker.py @@ -253,7 +253,7 @@ class AICPicker(AutoPicker): except IndexError: print("Slope Calculation: empty array islope, check signal window") return - if len(dataslope) <= 2: + if len(dataslope) < 2: print('No or not enough data in slope window found!') return try: @@ -300,8 +300,9 @@ class AICPicker(AutoPicker): datafit = np.polyval(P, xslope) if datafit[0] >= datafit[-1]: print('AICPicker: Negative slope, bad onset skipped!') - return - self.slope = 1 / (len(dataslope) * self.Data[0].stats.delta) * (datafit[-1] - datafit[0]) + #return + else: + self.slope = 1 / (len(dataslope) * self.Data[0].stats.delta) * (datafit[-1] - datafit[0]) else: self.SNR = None @@ -342,8 +343,11 @@ class AICPicker(AutoPicker): label='Slope Window') ax2.plot(self.Tcf[iislope], datafit, 'g', linewidth=2, label='Slope') - ax1.set_title('Station %s, SNR=%7.2f, Slope= %12.2f counts/s' % (self.Data[0].stats.station, - self.SNR, self.slope)) + if self.slope is not None: + ax1.set_title('Station %s, SNR=%7.2f, Slope= %12.2f counts/s' % (self.Data[0].stats.station, + self.SNR, self.slope)) + else: + ax1.set_title('Station %s, SNR=%7.2f' % (self.Data[0].stats.station, self.SNR)) ax2.set_xlabel('Time [s] since %s' % self.Data[0].stats.starttime) ax2.set_ylabel('Counts') ax2.set_yticks([]) From 8487d696c6c3facbc8983018e241f5b3b992550f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ludger=20K=C3=BCperkoch?= Date: Mon, 25 Jun 2018 15:59:52 +0200 Subject: [PATCH 052/169] Cosmetics --- pylot/core/pick/picker.py | 1 - 1 file changed, 1 deletion(-) diff --git a/pylot/core/pick/picker.py b/pylot/core/pick/picker.py index 56db3df2..3ec82b6c 100644 --- a/pylot/core/pick/picker.py +++ b/pylot/core/pick/picker.py @@ -300,7 +300,6 @@ class AICPicker(AutoPicker): datafit = np.polyval(P, xslope) if datafit[0] >= datafit[-1]: print('AICPicker: Negative slope, bad onset skipped!') - #return else: self.slope = 1 / (len(dataslope) * self.Data[0].stats.delta) * (datafit[-1] - datafit[0]) From 88ddbc1efc67bd5383969e13ea58f55891f4d9cc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ludger=20K=C3=BCperkoch?= Date: Tue, 26 Jun 2018 10:51:39 +0200 Subject: [PATCH 053/169] [Bugfix] Time array improper calculated (rounding errors?) --- pylot/core/analysis/magnitude.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/pylot/core/analysis/magnitude.py b/pylot/core/analysis/magnitude.py index 1983bf7c..7f813172 100644 --- a/pylot/core/analysis/magnitude.py +++ b/pylot/core/analysis/magnitude.py @@ -6,6 +6,7 @@ Revised/extended summer 2017. :author: Ludger Küperkoch / MAGS2 EP3 working group """ + import matplotlib.pyplot as plt import numpy as np import obspy.core.event as ope @@ -219,7 +220,7 @@ class LocalMagnitude(Magnitude): sqH = np.sqrt(power_sum) # get time array - th = np.arange(0, len(sqH) * dt, dt) + th=np.arange(0, st[0].stats.npts/st[0].stats.sampling_rate, st[0].stats.delta) # get maximum peak within pick window iwin = getsignalwin(th, t0 - stime, self.calc_win) ii = min([iwin[len(iwin) - 1], len(th)]) From f43478d0c081d588acde18a7016a9a48ec0277db Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ludger=20K=C3=BCperkoch?= Date: Tue, 26 Jun 2018 11:58:08 +0200 Subject: [PATCH 054/169] Consistent calculation of SNR, using maximum (not mean) of signal window, more stable! --- pylot/core/pick/picker.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pylot/core/pick/picker.py b/pylot/core/pick/picker.py index 3ec82b6c..5328ca90 100644 --- a/pylot/core/pick/picker.py +++ b/pylot/core/pick/picker.py @@ -239,7 +239,7 @@ class AICPicker(AutoPicker): print(msg) return # calculate SNR from CF - self.SNR = max(abs(self.Data[0].data[isignal] - np.mean(self.Data[0].data[isignal]))) / \ + self.SNR = max(abs(self.Data[0].data[isignal])) / \ max(abs(self.Data[0].data[inoise] - np.mean(self.Data[0].data[inoise]))) # calculate slope from CF after initial pick # get slope window From 4d1c3985f4ab14148ffba5084e7edea8c8c55ad3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ludger=20K=C3=BCperkoch?= Date: Tue, 26 Jun 2018 12:25:03 +0200 Subject: [PATCH 055/169] [Bugfix] Input argument iplot was fixed to 1. --- pylot/core/pick/autopick.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pylot/core/pick/autopick.py b/pylot/core/pick/autopick.py index aecd6251..baa450e1 100644 --- a/pylot/core/pick/autopick.py +++ b/pylot/core/pick/autopick.py @@ -100,9 +100,9 @@ def autopickevent(data, param, iplot=0, fig_dict=None, fig_dict_wadatijack=None, # quality control # median check and jackknife on P-onset times - jk_checked_onsets = checkPonsets(all_onsets, mdttolerance, jackfactor, 1, fig_dict_wadatijack) + jk_checked_onsets = checkPonsets(all_onsets, mdttolerance, jackfactor, iplot, fig_dict_wadatijack) # check S-P times (Wadati) - wadationsets = wadaticheck(jk_checked_onsets, wdttolerance, 1, fig_dict_wadatijack) + wadationsets = wadaticheck(jk_checked_onsets, wdttolerance, iplot, fig_dict_wadatijack) return wadationsets From 19f943627a88d3777a05b1a304ca1896d8fcf0b5 Mon Sep 17 00:00:00 2001 From: Marcel Date: Tue, 26 Jun 2018 17:07:38 +0200 Subject: [PATCH 056/169] [bugfixes] autopylot --- autoPyLoT.py | 18 +++--- pylot/core/io/data.py | 2 +- pylot/core/util/dataprocessing.py | 101 +++++++++++++++++++----------- pylot/core/util/widgets.py | 1 + 4 files changed, 76 insertions(+), 46 deletions(-) diff --git a/autoPyLoT.py b/autoPyLoT.py index 3c88742f..bf482d1f 100755 --- a/autoPyLoT.py +++ b/autoPyLoT.py @@ -194,16 +194,16 @@ def autoPyLoT(input_dict=None, parameter=None, inputfile=None, fnames=None, even events = [events for events in glob.glob(os.path.join(datapath, '*')) if os.path.isdir(events)] elif fnames == 'None' and parameter['eventID'] is not '*' and not type(parameter['eventID']) == list: # single event processing - events = glob.glob(os.path.join(datapath, parameter['eventID'], wfpath_extension)) + events = glob.glob(os.path.join(datapath, parameter['eventID'])) elif fnames == 'None' and type(parameter['eventID']) == list: # multiple event processing events = [] for eventID in parameter['eventID']: - events.append(os.path.join(datapath, eventID, wfpath_extension)) + events.append(os.path.join(datapath, eventID)) else: # autoPyLoT was initialized from GUI events = [] - events.append(os.path.join(eventid, wfpath_extension)) + events.append(eventid) evID = os.path.split(eventid)[-1] locflag = 2 else: @@ -214,8 +214,7 @@ def autoPyLoT(input_dict=None, parameter=None, inputfile=None, fnames=None, even for eventID in eventid: events.append(os.path.join(datapath, parameter['database'], - eventID, - wfpath_extension)) + eventID)) if not events: print('autoPyLoT: No events given. Return!') @@ -229,10 +228,9 @@ def autoPyLoT(input_dict=None, parameter=None, inputfile=None, fnames=None, even allpicks = {} glocflag = locflag for eventpath in events: - if not wfpath_extension: - evID = os.path.split(eventpath)[-1] - else: - evID = os.path.split(os.path.split(eventpath)[0])[-1] + evID = os.path.split(eventpath)[-1] + if wfpath_extension: + event_datapath = os.path.join(eventpath, wfpath_extension) fext = '.xml' filename = os.path.join(eventpath, 'PyLoT_' + evID + fext) try: @@ -245,7 +243,7 @@ def autoPyLoT(input_dict=None, parameter=None, inputfile=None, fnames=None, even pylot_event = Event(eventpath) # event should be path to event directory data.setEvtData(pylot_event) if fnames == 'None': - data.setWFData(glob.glob(os.path.join(datapath, eventpath, '*'))) + data.setWFData(glob.glob(os.path.join(datapath, event_datapath, '*'))) # the following is necessary because within # multiple event processing no event ID is provided # in autopylot.in diff --git a/pylot/core/io/data.py b/pylot/core/io/data.py index f10242db..e84badea 100644 --- a/pylot/core/io/data.py +++ b/pylot/core/io/data.py @@ -43,7 +43,7 @@ class Data(object): elif isinstance(evtdata, dict): evt = readPILOTEvent(**evtdata) evtdata = evt - elif isinstance(evtdata, str): + elif type(evtdata) in [str, unicode]: try: cat = read_events(evtdata) if len(cat) is not 1: diff --git a/pylot/core/util/dataprocessing.py b/pylot/core/util/dataprocessing.py index a83d3f1e..cd8cd004 100644 --- a/pylot/core/util/dataprocessing.py +++ b/pylot/core/util/dataprocessing.py @@ -222,41 +222,72 @@ def read_metadata(path_to_inventory): # return metadata_objects -# def read_metadata_file(path_to_inventory_filename): -# # functions used to read metadata for different file endings (or file types) -# read_functions = {'dless': _read_dless, -# 'dseed': _read_dless, -# 'xml': _read_inventory_file, -# 'resp': _read_inventory_file} -# file_ending = path_to_inventory_filename.split('.')[-1] -# if file_ending in read_functions.keys(): -# robj, exc = read_functions[file_ending](path_to_inventory_filename) -# if exc is not None: -# raise exc -# return file_ending, robj -# # in case file endings did not match the above keys, try and error -# for file_type in ['dless', 'xml']: -# robj, exc = read_functions[file_type](path_to_inventory_filename) -# if exc is None: -# return file_type, robj -# -# -# def _read_dless(path_to_inventory): -# exc = None -# try: -# parser = Parser(path_to_inventory) -# except Exception as exc: -# parser = None -# return parser, exc -# -# -# def _read_inventory_file(path_to_inventory): -# exc = None -# try: -# inv = read_inventory(path_to_inventory) -# except Exception as exc: -# inv = None -# return inv, exc +def read_metadata_iterator(path_to_inventory, station_seed_id): + ''' + # search for metadata for a specific station iteratively + ''' + station, network, location, channel = station_seed_id.split('.') + fnames = glob.glob(os.path.join(path_to_inventory, '*' + station_seed_id + '*')) + if not fnames: + # search for station name in filename + fnames = glob.glob(os.path.join(path_to_inventory, '*' + station + '*')) + if not fnames: + # search for network name in filename + fnames = glob.glob(os.path.join(path_to_inventory, '*' + network + '*')) + if not fnames: + print('Could not find filenames matching station name, network name or seed id') + return + for fname in fnames: + invtype, robj = read_metadata_file(os.path.join(path_to_inventory, fname)) + try: + robj.get_coordinates(station_seed_id) + return invtype, robj + except Exception as e: + continue + print('Could not find metadata for station_seed_id {} in path {}'.format(station_seed_id, path_to_inventory)) + + + +def read_metadata_file(path_to_inventory_filename): + ''' + function reading metadata files (either dataless seed, xml or resp) + :param path_to_inventory_filename: + :return: file type/ending, inventory object (Parser or Inventory) + ''' + # functions used to read metadata for different file endings (or file types) + read_functions = {'dless': _read_dless, + 'dseed': _read_dless, + 'xml': _read_inventory_file, + 'resp': _read_inventory_file} + file_ending = path_to_inventory_filename.split('.')[-1] + if file_ending in read_functions.keys(): + robj, exc = read_functions[file_ending](path_to_inventory_filename) + if exc is not None: + raise exc + return file_ending, robj + # in case file endings did not match the above keys, try and error + for file_type in ['dless', 'xml']: + robj, exc = read_functions[file_type](path_to_inventory_filename) + if exc is None: + return file_type, robj + + +def _read_dless(path_to_inventory): + exc = None + try: + parser = Parser(path_to_inventory) + except Exception as exc: + parser = None + return parser, exc + + +def _read_inventory_file(path_to_inventory): + exc = None + try: + inv = read_inventory(path_to_inventory) + except Exception as exc: + inv = None + return inv, exc def restitute_trace(input_tuple): diff --git a/pylot/core/util/widgets.py b/pylot/core/util/widgets.py index 95d42fca..b94998eb 100644 --- a/pylot/core/util/widgets.py +++ b/pylot/core/util/widgets.py @@ -3476,6 +3476,7 @@ class TuneAutopicker(QWidget): def clear_all(self): if hasattr(self, 'pdlg_widget'): if self.pdlg_widget: + self.pdlg_widget.setParent(None) del(self.pdlg_widget) if hasattr(self, 'overview'): self.overview.setParent(None) From 3a66ec1c95447e0e812cab67d7d6d44461fd6abe Mon Sep 17 00:00:00 2001 From: Marcel Date: Wed, 27 Jun 2018 14:20:11 +0200 Subject: [PATCH 057/169] [bugfix] print a warning in case saveData fails --- PyLoT.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/PyLoT.py b/PyLoT.py index 0ff010ea..86199243 100755 --- a/PyLoT.py +++ b/PyLoT.py @@ -1428,7 +1428,10 @@ class MainWindow(QMainWindow): def exportAllEvents(self, outformats=['.xml']): for event in self.project.eventlist: self.get_data().setEvtData(event) - self.saveData(event, event.path, outformats) + try: + self.saveData(event, event.path, outformats) + except Exception as e: + print('WARNING! Could not save event {}. Reason: {}'.format(event.path, e)) def enableSaveEventAction(self): self.saveEventAction.setEnabled(True) From 8ae0449c0160264e2c710426a0427d84b915a466 Mon Sep 17 00:00:00 2001 From: Marcel Date: Wed, 27 Jun 2018 14:21:20 +0200 Subject: [PATCH 058/169] [new] metadata class (WIP) --- pylot/core/util/dataprocessing.py | 247 ++++++++++++++++++++++-------- 1 file changed, 180 insertions(+), 67 deletions(-) diff --git a/pylot/core/util/dataprocessing.py b/pylot/core/util/dataprocessing.py index cd8cd004..ee74a960 100644 --- a/pylot/core/util/dataprocessing.py +++ b/pylot/core/util/dataprocessing.py @@ -12,6 +12,186 @@ from pylot.core.util.utils import key_for_set_value, find_in_list, \ remove_underscores, gen_Pool +class Metadata(object): + def __init__(self, inventory=None): + self.inventories = [] + if os.path.isdir(inventory): + self.add_inventory(inventory) + if os.path.isfile(inventory): + self.add_inventory_file(inventory) + self.seed_ids = {} + self.inventory_files = {} + + + def add_inventory(self, path_to_inventory): + # add paths to list of inventories + assert (os.path.isdir(path_to_inventory)), '{} is no directory'.format(path_to_inventory) + if not path_to_inventory in self.inventories: + self.inventories.append(path_to_inventory) + + + def add_inventory_file(self, path_to_inventory_file): + assert (os.path.isfile(path_to_inventory_file)), '{} is no directory'.format(path_to_inventory_file) + self.add_inventory(os.path.split(path_to_inventory_file)[0]) + if not path_to_inventory_file in self.inventory_files.keys(): + self.read_single_file(path_to_inventory_file) + + + def remove_inventory(self, path_to_inventory): + if not path_to_inventory in self.inventories: + print('Path {} not in inventories list.'.format(path_to_inventory)) + return + self.inventories.remove(path_to_inventory) + + + def get_metadata(self, seed_id): + # get metadata for a specific seed_id, if not already read, try to read from inventories + if not seed_id in self.seed_ids.keys(): + self._read_inventory_data(seed_id) + # if seed id is not found read all inventories and try to find it there + if not seed_id in self.seed_ids.keys(): + print('No data found for seed id {}. Trying to find it in all known inventories...'.format(seed_id)) + self.read_all() + for inv_fname, metadata in self.inventory_files.items(): + # use get_coordinates to check for seed_id + if metadata['data'].get_coordinates(seed_id): + self.seed_ids[seed_id] = inv_fname + return metadata + print('Could not find metadata for station {}'.format(seed_id)) + return None + fname = self.seed_ids[seed_id] + return self.inventory_files[fname] + + + def read_all(self): + for inventory in self.inventories: + for inv_fname in os.listdir(inventory): + inv_fname = os.path.join(inventory, inv_fname) + if not self.read_single_file(inv_fname): + continue + + + def read_single_file(self, inv_fname): + if not inv_fname in self.inventory_files.keys(): + pass + else: + if not self.inventory_files[inv_fname]: + pass + else: + return + try: + invtype, robj = self._read_metadata_file(inv_fname) + if robj == None: + return + except Exception as e: + print('Could not read file {}'.format(inv_fname)) + return + self.inventory_files[inv_fname] = {'invtype': invtype, + 'data': robj} + return True + + + def get_coordinates(self, seed_id): + metadata = self.get_metadata(seed_id) + return metadata['data'].get_coordinates(seed_id) + + + def get_paz(self, seed_id, time=None): + metadata = self.get_metadata(seed_id) + if metadata['invtype'] in ['dless', 'dseed']: + return metadata['data'].get_paz(seed_id) + elif metadata['invtype'] in ['resp', 'xml']: + if not time: + print('Time needed to extract metadata from station inventory.') + return None + resp = metadata['data'].get_response(seed_id, time) + return resp.get_paz(seed_id) + + + def _read_inventory_data(self, seed_id=None): + for inventory in self.inventories: + if self._read_metadata_iterator(path_to_inventory=inventory, station_seed_id=seed_id): + return + + + def _read_metadata_iterator(self, path_to_inventory, station_seed_id): + ''' + search for metadata for a specific station iteratively + ''' + station, network, location, channel = station_seed_id.split('.') + fnames = glob.glob(os.path.join(path_to_inventory, '*' + station_seed_id + '*')) + if not fnames: + # search for station name in filename + fnames = glob.glob(os.path.join(path_to_inventory, '*' + station + '*')) + if not fnames: + # search for network name in filename + fnames = glob.glob(os.path.join(path_to_inventory, '*' + network + '*')) + if not fnames: + print('Could not find filenames matching station name, network name or seed id') + return + for fname in fnames: + if fname in self.inventory_files.keys(): + if self.inventory_files[fname]: + # file already read + continue + invtype, robj = self._read_metadata_file(os.path.join(path_to_inventory, fname)) + try: + robj.get_coordinates(station_seed_id) + self.inventory_files[fname] = {'invtype': invtype, + 'data': robj} + if station_seed_id in self.seed_ids.keys(): + print('WARNING: Overwriting metadata for station {}'.format(station_seed_id)) + self.seed_ids[station_seed_id] = fname + return True + except Exception as e: + continue + print('Could not find metadata for station_seed_id {} in path {}'.format(station_seed_id, path_to_inventory)) + + + def _read_metadata_file(self, path_to_inventory_filename): + ''' + function reading metadata files (either dataless seed, xml or resp) + :param path_to_inventory_filename: + :return: file type/ending, inventory object (Parser or Inventory) + ''' + # functions used to read metadata for different file endings (or file types) + read_functions = {'dless': self._read_dless, + 'dseed': self._read_dless, + 'xml': self._read_inventory_file, + 'resp': self._read_inventory_file} + file_ending = path_to_inventory_filename.split('.')[-1] + if file_ending in read_functions.keys(): + robj, exc = read_functions[file_ending](path_to_inventory_filename) + if exc is not None: + raise exc + return file_ending, robj + # in case file endings did not match the above keys, try and error + for file_type in ['dless', 'xml']: + robj, exc = read_functions[file_type](path_to_inventory_filename) + if exc is None: + return file_type, robj + return None, None + + + def _read_dless(self, path_to_inventory): + exc = None + try: + parser = Parser(path_to_inventory) + except Exception as exc: + parser = None + return parser, exc + + + def _read_inventory_file(self, path_to_inventory): + exc = None + try: + inv = read_inventory(path_to_inventory) + except Exception as exc: + inv = None + return inv, exc + + + def time_from_header(header): """ Function takes in the second line from a .gse file and takes out the date and time from that line. @@ -222,73 +402,6 @@ def read_metadata(path_to_inventory): # return metadata_objects -def read_metadata_iterator(path_to_inventory, station_seed_id): - ''' - # search for metadata for a specific station iteratively - ''' - station, network, location, channel = station_seed_id.split('.') - fnames = glob.glob(os.path.join(path_to_inventory, '*' + station_seed_id + '*')) - if not fnames: - # search for station name in filename - fnames = glob.glob(os.path.join(path_to_inventory, '*' + station + '*')) - if not fnames: - # search for network name in filename - fnames = glob.glob(os.path.join(path_to_inventory, '*' + network + '*')) - if not fnames: - print('Could not find filenames matching station name, network name or seed id') - return - for fname in fnames: - invtype, robj = read_metadata_file(os.path.join(path_to_inventory, fname)) - try: - robj.get_coordinates(station_seed_id) - return invtype, robj - except Exception as e: - continue - print('Could not find metadata for station_seed_id {} in path {}'.format(station_seed_id, path_to_inventory)) - - - -def read_metadata_file(path_to_inventory_filename): - ''' - function reading metadata files (either dataless seed, xml or resp) - :param path_to_inventory_filename: - :return: file type/ending, inventory object (Parser or Inventory) - ''' - # functions used to read metadata for different file endings (or file types) - read_functions = {'dless': _read_dless, - 'dseed': _read_dless, - 'xml': _read_inventory_file, - 'resp': _read_inventory_file} - file_ending = path_to_inventory_filename.split('.')[-1] - if file_ending in read_functions.keys(): - robj, exc = read_functions[file_ending](path_to_inventory_filename) - if exc is not None: - raise exc - return file_ending, robj - # in case file endings did not match the above keys, try and error - for file_type in ['dless', 'xml']: - robj, exc = read_functions[file_type](path_to_inventory_filename) - if exc is None: - return file_type, robj - - -def _read_dless(path_to_inventory): - exc = None - try: - parser = Parser(path_to_inventory) - except Exception as exc: - parser = None - return parser, exc - - -def _read_inventory_file(path_to_inventory): - exc = None - try: - inv = read_inventory(path_to_inventory) - except Exception as exc: - inv = None - return inv, exc - def restitute_trace(input_tuple): tr, invtype, inobj, unit, force = input_tuple From 5870843a033591436f27b4a1ca629d7526028b90 Mon Sep 17 00:00:00 2001 From: Marcel Date: Thu, 28 Jun 2018 10:31:48 +0200 Subject: [PATCH 059/169] [bugfix] event_datapath not set if not obspyDMT --- autoPyLoT.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/autoPyLoT.py b/autoPyLoT.py index bf482d1f..2d6a1c14 100755 --- a/autoPyLoT.py +++ b/autoPyLoT.py @@ -229,8 +229,7 @@ def autoPyLoT(input_dict=None, parameter=None, inputfile=None, fnames=None, even glocflag = locflag for eventpath in events: evID = os.path.split(eventpath)[-1] - if wfpath_extension: - event_datapath = os.path.join(eventpath, wfpath_extension) + event_datapath = os.path.join(eventpath, wfpath_extension) fext = '.xml' filename = os.path.join(eventpath, 'PyLoT_' + evID + fext) try: From 4cb3f72ba81fdfa301a29d2a2af892aefc635687 Mon Sep 17 00:00:00 2001 From: Marcel Date: Thu, 28 Jun 2018 15:22:40 +0200 Subject: [PATCH 060/169] [bugfixes] location/magnitude w ludger --- PyLoT.py | 44 ++++++-------------------------- autoPyLoT.py | 8 +++--- pylot/core/analysis/magnitude.py | 9 +++++-- pylot/core/util/widgets.py | 1 - 4 files changed, 18 insertions(+), 44 deletions(-) diff --git a/PyLoT.py b/PyLoT.py index 86199243..379c2f85 100755 --- a/PyLoT.py +++ b/PyLoT.py @@ -2498,7 +2498,6 @@ class MainWindow(QMainWindow): 'iplot': 0, 'fig_dict': None, 'fig_dict_wadatijack': self.fig_dict_wadatijack, - 'locflag': 0, 'savexml': False, 'obspyDMT_wfpath': wfpath} # init pick thread @@ -2756,55 +2755,28 @@ class MainWindow(QMainWindow): """ if not self.okToContinue(): return - settings = QSettings() - # get location tool hook - loctool = settings.value("loc/tool", "nll") + parameter = self._inputs + loctool = 'nll' lt = locateTool[loctool] # get working directory - locroot = settings.value("{0}/rootPath".format(loctool), None) + locroot = parameter['nllocroot'] if locroot is None: self.PyLoTprefs() self.locate_event() - infile = settings.value("{0}/inputFile".format(loctool), None) + ctrfile = parameter['ctrfile'] - if not infile: - caption = 'Select {0} input file'.format(loctool) - filt = "Supported file formats" \ - " (*.in *.ini *.conf *.cfg)" - ans = QFileDialog().getOpenFileName(self, caption=caption, - filter=filt, dir=locroot) - if ans[0]: - infile = ans[0] - else: - QMessageBox.information(self, - self.tr('No infile selected'), - self.tr('Inputfile necessary for localization.')) - return - settings.setValue("{0}/inputFile".format(loctool), infile) - settings.sync() - if loctool == 'nll': - ttt = settings.value("{0}/travelTimeTables", None) - ok = False - if ttt is None: - while not ok: - text, ok = QInputDialog.getText(self, 'Pattern for travel time tables', - 'Base name of travel time tables', - echo=QLineEdit.Normal, - text="ttime") - ttt = text - - outfile = settings.value("{0}/outputFile".format(loctool), - os.path.split(os.tempnam())[-1]) + ttt = parameter['ttpatter'] + outfile = parameter['outpatter'] eventname = self.get_current_event_name() obsdir = os.path.join(self._inputs['rootpath'], self._inputs['datapath'], self._inputs['database'], eventname) self.saveData(event=self.get_current_event(), directory=obsdir, outformats='.obs') filename = 'PyLoT_' + eventname locpath = os.path.join(locroot, 'loc', filename) phasefile = os.path.join(obsdir, filename + '.obs') - lt.modify_inputs(infile, locroot, filename, phasefile, ttt) + lt.modify_inputs(ctrfile, locroot, filename, phasefile, ttt) try: - lt.locate(infile) + lt.locate(ctrfile) except RuntimeError as e: print(e.message) #finally: diff --git a/autoPyLoT.py b/autoPyLoT.py index 2d6a1c14..a8eebabb 100755 --- a/autoPyLoT.py +++ b/autoPyLoT.py @@ -94,7 +94,6 @@ def autoPyLoT(input_dict=None, parameter=None, inputfile=None, fnames=None, even fig_dict = None fig_dict_wadatijack = None - locflag = 1 if input_dict and isinstance(input_dict, dict): if 'parameter' in input_dict: parameter = input_dict['parameter'] @@ -110,8 +109,6 @@ def autoPyLoT(input_dict=None, parameter=None, inputfile=None, fnames=None, even eventid = input_dict['eventid'] if 'iplot' in input_dict: iplot = input_dict['iplot'] - if 'locflag' in input_dict: - locflag = input_dict['locflag'] if 'savexml' in input_dict: savexml = input_dict['savexml'] if 'obspyDMT_wfpath' in input_dict: @@ -153,7 +150,8 @@ def autoPyLoT(input_dict=None, parameter=None, inputfile=None, fnames=None, even datastructure.setExpandFields(exf) # check if default location routine NLLoc is available - if real_None(parameter['nllocbin']) and locflag: + if real_None(parameter['nllocbin']): + locflag = 1 # get NLLoc-root path nllocroot = parameter.get('nllocroot') # get path to NLLoc executable @@ -178,7 +176,7 @@ def autoPyLoT(input_dict=None, parameter=None, inputfile=None, fnames=None, even print(" !!! ") wfpath_extension = '' - if obspyDMT_wfpath not in [None, False, 'False']: + if obspyDMT_wfpath not in [None, False, 'False', '']: wfpath_extension = obspyDMT_wfpath print('Using obspyDMT structure. There will be no restitution, as pre-processed data are expected.') if wfpath_extension != 'processed': diff --git a/pylot/core/analysis/magnitude.py b/pylot/core/analysis/magnitude.py index 7f813172..08704f7b 100644 --- a/pylot/core/analysis/magnitude.py +++ b/pylot/core/analysis/magnitude.py @@ -122,7 +122,13 @@ class Magnitude(object): def net_magnitude(self, magscaling=None): if self: - if magscaling is not None and str(magscaling) is not '[0.0, 0.0]': + if magscaling == None: + scaling = False + elif magscaling[0] != 0 and magscaling[1] != 0: + scaling = False + else: + scaling = True + if scaling: # scaling necessary print("Scaling network magnitude ...") mag = ope.Magnitude( @@ -141,7 +147,6 @@ class Magnitude(object): station_count=len(self.magnitudes), azimuthal_gap=self.origin_id.get_referred_object().quality.azimuthal_gap) return mag - return None class LocalMagnitude(Magnitude): diff --git a/pylot/core/util/widgets.py b/pylot/core/util/widgets.py index b94998eb..60f64939 100644 --- a/pylot/core/util/widgets.py +++ b/pylot/core/util/widgets.py @@ -3419,7 +3419,6 @@ class TuneAutopicker(QWidget): 'eventid': [self.get_current_event_fp()], 'iplot': 2, 'fig_dict': self.fig_dict, - 'locflag': 0, 'savexml': False, 'obspyDMT_wfpath': wfpath} for key in self.fig_dict.keys(): From f4201c4e2f6ca70c74d6f97d0754f5db563b5a42 Mon Sep 17 00:00:00 2001 From: Marcel Date: Thu, 28 Jun 2018 15:59:13 +0200 Subject: [PATCH 061/169] [bugfix] full path for ctrfile --- PyLoT.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/PyLoT.py b/PyLoT.py index 379c2f85..a11b7374 100755 --- a/PyLoT.py +++ b/PyLoT.py @@ -2764,7 +2764,7 @@ class MainWindow(QMainWindow): self.PyLoTprefs() self.locate_event() - ctrfile = parameter['ctrfile'] + ctrfile = os.path.join(locroot, 'run', parameter['ctrfile']) ttt = parameter['ttpatter'] outfile = parameter['outpatter'] From 9b63c1bb241f3532cce138f8d6b349688d541ed1 Mon Sep 17 00:00:00 2001 From: Marcel Date: Fri, 29 Jun 2018 10:13:58 +0200 Subject: [PATCH 062/169] [bugfix] taupy phases lost on plot refresh --- pylot/core/util/widgets.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/pylot/core/util/widgets.py b/pylot/core/util/widgets.py index 60f64939..1b78a456 100644 --- a/pylot/core/util/widgets.py +++ b/pylot/core/util/widgets.py @@ -1727,7 +1727,7 @@ class PickDlg(QDialog): self.arrivalsText.append(ax.text(time_rel, ylims[0], arrival.name, color='0.5')) def drawArrivalsText(self): - return self.drawArrivals(True) + return self.drawArrivals(textOnly=True) def refreshArrivalsText(self, event=None): self.removeArrivalsText() @@ -2682,6 +2682,7 @@ class PickDlg(QDialog): phase = 'S' filter = True self.plotWFData(phase=phase, filter=filter) + self.drawArrivals() def resetZoom(self): ax = self.multicompfig.axes[0] From 22e5de194e9c41dc8bc33a978c6f7062f21fa8cf Mon Sep 17 00:00:00 2001 From: Marcel Date: Fri, 29 Jun 2018 13:55:42 +0200 Subject: [PATCH 063/169] [bugfix] array map only checking for manual picks --- pylot/core/util/array_map.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pylot/core/util/array_map.py b/pylot/core/util/array_map.py index 91dee54e..de9a3bf3 100644 --- a/pylot/core/util/array_map.py +++ b/pylot/core/util/array_map.py @@ -375,13 +375,13 @@ class Array_map(QtGui.QWidget): self.draw_everything() def draw_everything(self): - if self.picks_dict: + if self.picks_dict or self.autopicks_dict: self.init_picks() if len(self.picks) >= 3: self.init_picksgrid() self.draw_contour_filled() self.scatter_all_stations() - if self.picks_dict: + if self.picks_dict or self.autopicks_dict: self.scatter_picked_stations() self.cbar = self.add_cbar(label='Time relative to first onset ({}) [s]'.format(self._earliest_picktime)) self.comboBox_phase.setEnabled(True) From 2c07dd63b8c378d63962462f33831cc2072f3683 Mon Sep 17 00:00:00 2001 From: Marcel Date: Fri, 29 Jun 2018 14:19:09 +0200 Subject: [PATCH 064/169] [bugfix] save Event before tarting tuneAutopicker (else source information might not be accessible to autoPyLoT) --- pylot/core/util/widgets.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/pylot/core/util/widgets.py b/pylot/core/util/widgets.py index 1b78a456..e9b1a965 100644 --- a/pylot/core/util/widgets.py +++ b/pylot/core/util/widgets.py @@ -3422,6 +3422,8 @@ class TuneAutopicker(QWidget): 'fig_dict': self.fig_dict, 'savexml': False, 'obspyDMT_wfpath': wfpath} + event = self.get_current_event() + self.parent().saveData(event, event.path, '.xml') for key in self.fig_dict.keys(): if not key == 'plot_style': self.fig_dict[key].clear() From d2ba8888d1ba3e96762c3c6be2d7354e0e85508c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ludger=20K=C3=BCperkoch?= Date: Fri, 29 Jun 2018 15:07:26 +0200 Subject: [PATCH 065/169] Reduced maximum number if iterations to two, some effort to avoid error for screen output if no magnitude scaling is applied. --- autoPyLoT.py | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/autoPyLoT.py b/autoPyLoT.py index a8eebabb..6b209f4f 100755 --- a/autoPyLoT.py +++ b/autoPyLoT.py @@ -167,7 +167,7 @@ def autoPyLoT(input_dict=None, parameter=None, inputfile=None, fnames=None, even ttpat = parameter.get('ttpatter') # pattern of NLLoc-output file nllocoutpatter = parameter.get('outpatter') - maxnumit = 3 # maximum number of iterations for re-picking + maxnumit = 2 # maximum number of iterations for re-picking else: locflag = 0 print(" !!! ") @@ -439,8 +439,15 @@ def autoPyLoT(input_dict=None, parameter=None, inputfile=None, fnames=None, even evt = local_mag.updated_event(magscaling) net_ml = local_mag.net_magnitude(magscaling) print("Network local magnitude: %4.1f" % net_ml.mag) - print("Network local magnitude scaled with:") - print("%f * Ml + %f" % (magscaling[0], magscaling[1])) + if magscaling == None: + scaling = False + elif magscaling[0] != 0 and magscaling[1] != 0: + scaling = False + else: + scaling = True + if scaling: + print("Network local magnitude scaled with:") + print("%f * Ml + %f" % (magscaling[0], magscaling[1])) else: print("autoPyLoT: No NLLoc-location file available! Stop iteration!") locflag = 9 From 4896c1e1d8f50a849d1645f9df0de55fe465668e Mon Sep 17 00:00:00 2001 From: Marcel Date: Mon, 2 Jul 2018 13:34:30 +0200 Subject: [PATCH 066/169] [cleanup] removed redundancy --- pylot/core/pick/picker.py | 18 +++++++----------- 1 file changed, 7 insertions(+), 11 deletions(-) diff --git a/pylot/core/pick/picker.py b/pylot/core/pick/picker.py index 5328ca90..bb35ec7a 100644 --- a/pylot/core/pick/picker.py +++ b/pylot/core/pick/picker.py @@ -221,7 +221,7 @@ class AICPicker(AutoPicker): # get noise window inoise = getnoisewin(self.Tcf, self.Pick, self.TSNR[0], self.TSNR[1]) # check, if these are counts or m/s, important for slope estimation! - # this is quick and dirty, better solution? + # this is quick and dirty, better solution? #Todo wtf if max(self.Data[0].data < 1e-3) and max(self.Data[0].data >= 1e-6): self.Data[0].data = self.Data[0].data * 1000000. elif max(self.Data[0].data < 1e-6): @@ -351,18 +351,14 @@ class AICPicker(AutoPicker): ax2.set_ylabel('Counts') ax2.set_yticks([]) ax2.legend(loc=1) - if plt_flag == 1: - fig.show() - try: input() - except SyntaxError: pass - plt.close(fig) else: ax1.set_title(self.Data[0].stats.station) - if plt_flag == 1: - fig.show() - try: input() - except SyntaxError: pass - plt.close(fig) + + if plt_flag == 1: + fig.show() + try: input() + except SyntaxError: pass + plt.close(fig) if self.Pick == None: print('AICPicker: Could not find minimum, picking window too short?') From 854f5b8c7ee8c93f45bef8a4c1130867dcc906a0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ludger=20K=C3=BCperkoch?= Date: Tue, 3 Jul 2018 10:34:43 +0200 Subject: [PATCH 067/169] [Bugfix] No network magnitude available for screen output while tuning --- autoPyLoT.py | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/autoPyLoT.py b/autoPyLoT.py index 6b209f4f..5db95399 100755 --- a/autoPyLoT.py +++ b/autoPyLoT.py @@ -346,7 +346,8 @@ def autoPyLoT(input_dict=None, parameter=None, inputfile=None, fnames=None, even picks[stats]['P'].update(props) evt = moment_mag.updated_event() net_mw = moment_mag.net_magnitude() - print("Network moment magnitude: %4.1f" % net_mw.mag) + if net_mw is not None: + print("Network moment magnitude: %4.1f" % net_mw.mag) # calculate local (Richter) magntiude WAscaling = parameter.get('WAscaling') magscaling = parameter.get('magscaling') @@ -363,8 +364,15 @@ def autoPyLoT(input_dict=None, parameter=None, inputfile=None, fnames=None, even evt = local_mag.updated_event(magscaling) net_ml = local_mag.net_magnitude(magscaling) print("Network local magnitude: %4.1f" % net_ml.mag) - print("Network local magnitude scaled with:") - print("%f * Ml + %f" % (magscaling[0], magscaling[1])) + if magscaling == None: + scaling = False + elif magscaling[0] != 0 and magscaling[1] != 0: + scaling = False + else: + scaling = True + if scaling: + print("Network local magnitude scaled with:") + print("%f * Ml + %f" % (magscaling[0], magscaling[1])) else: print("autoPyLoT: No NLLoc-location file available!") print("No source parameter estimation possible!") @@ -421,7 +429,8 @@ def autoPyLoT(input_dict=None, parameter=None, inputfile=None, fnames=None, even picks[stats]['P'].update(props) evt = moment_mag.updated_event() net_mw = moment_mag.net_magnitude() - print("Network moment magnitude: %4.1f" % net_mw.mag) + if net_mw is not None: + print("Network moment magnitude: %4.1f" % net_mw.mag) # calculate local (Richter) magntiude WAscaling = parameter.get('WAscaling') magscaling = parameter.get('magscaling') From 46d4ad7ea54a6054fd2e901f24164c17ed35526b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ludger=20K=C3=BCperkoch?= Date: Tue, 3 Jul 2018 10:35:09 +0200 Subject: [PATCH 068/169] Some new parameter settings. --- inputs/pylot_local.in | 66 +++++++++++++++++++++---------------------- 1 file changed, 33 insertions(+), 33 deletions(-) diff --git a/inputs/pylot_local.in b/inputs/pylot_local.in index fe019440..ccfeddd4 100644 --- a/inputs/pylot_local.in +++ b/inputs/pylot_local.in @@ -4,19 +4,19 @@ %Parameters are optimized for %extent data sets! %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% #main settings# - #rootpath# %project path - #datapath# %data path - #database# %name of data base - #eventID# %event ID for single event processing (* for all events found in database) - #invdir# %full path to inventory or dataless-seed file +/DATA/Insheim #rootpath# %project path +EVENT_DATA/LOCAL #datapath# %data path +2018.02_Insheim #database# %name of data base +e0006.038.18 #eventID# %event ID for single event processing (* for all events found in database) +/DATA/Insheim/STAT_INFO #invdir# %full path to inventory or dataless-seed file PILOT #datastructure# %choose data structure True #apverbose# %choose 'True' or 'False' for terminal output %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% #NLLoc settings# -None #nllocbin# %path to NLLoc executable -None #nllocroot# %root of NLLoc-processing directory -None #phasefile# %name of autoPyLoT-output phase file for NLLoc -None #ctrfile# %name of autoPyLoT-output control file for NLLoc +/home/ludger/NLLOC #nllocbin# %path to NLLoc executable +/home/ludger/NLLOC/Insheim #nllocroot# %root of NLLoc-processing directory +AUTOPHASES.obs #phasefile# %name of autoPyLoT-output phase file for NLLoc +Insheim_min1d032016_auto.in #ctrfile# %name of autoPyLoT-output control file for NLLoc ttime #ttpatter# %pattern of NLLoc ttimes from grid AUTOLOC_nlloc #outpatter# %pattern of NLLoc-output file %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @@ -27,31 +27,31 @@ AUTOLOC_nlloc #outpatter# %pattern of %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% #settings local magnitude# 1.11 0.0009 -2.0 #WAscaling# %Scaling relation (log(Ao)+Alog(r)+Br+C) of Wood-Anderson amplitude Ao [nm] If zeros are set, original Richter magnitude is calculated! -1.0382 -0.447 #magscaling# %Scaling relation for derived local magnitude [a*Ml+b]. If zeros are set, no scaling of network magnitude is applied! +0.0 0.0 #magscaling# %Scaling relation for derived local magnitude [a*Ml+b]. If zeros are set, no scaling of network magnitude is applied! %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% #filter settings# -1.0 1.0 #minfreq# %Lower filter frequency [P, S] -10.0 10.0 #maxfreq# %Upper filter frequency [P, S] -2 2 #filter_order# %filter order [P, S] +2.0 2.0 #minfreq# %Lower filter frequency [P, S] +30.0 15.0 #maxfreq# %Upper filter frequency [P, S] +3 3 #filter_order# %filter order [P, S] bandpass bandpass #filter_type# %filter type (bandpass, bandstop, lowpass, highpass) [P, S] %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% #common settings picker# local #extent# %extent of array ("local", "regional" or "global") -15.0 #pstart# %start time [s] for calculating CF for P-picking -60.0 #pstop# %end time [s] for calculating CF for P-picking --1.0 #sstart# %start time [s] relative to P-onset for calculating CF for S-picking +7.0 #pstart# %start time [s] for calculating CF for P-picking +16.0 #pstop# %end time [s] for calculating CF for P-picking +-0.5 #sstart# %start time [s] relative to P-onset for calculating CF for S-picking 10.0 #sstop# %end time [s] after P-onset for calculating CF for S-picking -True #use_taup# %use estimated traveltimes from TauPy for calculating windows for CF +False #use_taup# %use estimated traveltimes from TauPy for calculating windows for CF iasp91 #taup_model# %define TauPy model for traveltime estimation -2.0 10.0 #bpz1# %lower/upper corner freq. of first band pass filter Z-comp. [Hz] -2.0 12.0 #bpz2# %lower/upper corner freq. of second band pass filter Z-comp. [Hz] -2.0 8.0 #bph1# %lower/upper corner freq. of first band pass filter H-comp. [Hz] -2.0 10.0 #bph2# %lower/upper corner freq. of second band pass filter z-comp. [Hz] +2.0 20.0 #bpz1# %lower/upper corner freq. of first band pass filter Z-comp. [Hz] +2.0 30.0 #bpz2# %lower/upper corner freq. of second band pass filter Z-comp. [Hz] +2.0 10.0 #bph1# %lower/upper corner freq. of first band pass filter H-comp. [Hz] +2.0 15.0 #bph2# %lower/upper corner freq. of second band pass filter z-comp. [Hz] #special settings for calculating CF# %!!Edit the following only if you know what you are doing!!% #Z-component# HOS #algoP# %choose algorithm for P-onset determination (HOS, ARZ, or AR3) -7.0 #tlta# %for HOS-/AR-AIC-picker, length of LTA window [s] +4.0 #tlta# %for HOS-/AR-AIC-picker, length of LTA window [s] 4 #hosorder# %for HOS-picker, order of Higher Order Statistics 2 #Parorder# %for AR-picker, order of AR process of Z-component 1.2 #tdet1z# %for AR-picker, length of AR determination window [s] for Z-component, 1st pick @@ -59,12 +59,12 @@ HOS #algoP# %choose algo 0.6 #tdet2z# %for AR-picker, length of AR determination window [s] for Z-component, 2nd pick 0.2 #tpred2z# %for AR-picker, length of AR prediction window [s] for Z-component, 2nd pick 0.001 #addnoise# %add noise to seismogram for stable AR prediction -3.0 0.1 0.5 1.0 #tsnrz# %for HOS/AR, window lengths for SNR-and slope estimation [tnoise, tsafetey, tsignal, tslope] [s] +3.0 0.0 1.0 0.5 #tsnrz# %for HOS/AR, window lengths for SNR-and slope estimation [tnoise, tsafetey, tsignal, tslope] [s] 3.0 #pickwinP# %for initial AIC pick, length of P-pick window [s] 6.0 #Precalcwin# %for HOS/AR, window length [s] for recalculation of CF (relative to 1st pick) -0.2 #aictsmooth# %for HOS/AR, take average of samples for smoothing of AIC-function [s] +0.4 #aictsmooth# %for HOS/AR, take average of samples for smoothing of AIC-function [s] 0.1 #tsmoothP# %for HOS/AR, take average of samples for smoothing CF [s] -0.001 #ausP# %for HOS/AR, artificial uplift of samples (aus) of CF (P) +0.4 #ausP# %for HOS/AR, artificial uplift of samples (aus) of CF (P) 1.3 #nfacP# %for HOS/AR, noise factor for noise level determination (P) #H-components# ARH #algoS# %choose algorithm for S-onset determination (ARH or AR3) @@ -75,7 +75,7 @@ ARH #algoS# %choose algo 4 #Sarorder# %for AR-picker, order of AR process of H-components 5.0 #Srecalcwin# %for AR-picker, window length [s] for recalculation of CF (2nd pick) (H) 4.0 #pickwinS# %for initial AIC pick, length of S-pick window [s] -2.0 0.3 1.5 1.0 #tsnrh# %for ARH/AR3, window lengths for SNR-and slope estimation [tnoise, tsafetey, tsignal, tslope] [s] +2.0 0.2 1.5 1.0 #tsnrh# %for ARH/AR3, window lengths for SNR-and slope estimation [tnoise, tsafetey, tsignal, tslope] [s] 1.0 #aictsmoothS# %for AIC-picker, take average of samples for smoothing of AIC-function [s] 0.7 #tsmoothS# %for AR-picker, take average of samples for smoothing CF [s] (S) 0.9 #ausS# %for HOS/AR, artificial uplift of samples (aus) of CF (S) @@ -85,16 +85,16 @@ ARH #algoS# %choose algo 2.0 #minFMSNR# %miniumum required SNR for first-motion determination 0.2 #fmpickwin# %pick window around P onset for calculating zero crossings #quality assessment# -0.02 0.04 0.08 0.16 #timeerrorsP# %discrete time errors [s] corresponding to picking weights [0 1 2 3] for P -0.04 0.08 0.16 0.32 #timeerrorsS# %discrete time errors [s] corresponding to picking weights [0 1 2 3] for S +0.04 0.08 0.16 0.32 #timeerrorsP# %discrete time errors [s] corresponding to picking weights [0 1 2 3] for P +0.05 0.10 0.20 0.40 #timeerrorsS# %discrete time errors [s] corresponding to picking weights [0 1 2 3] for S 0.8 #minAICPslope# %below this slope [counts/s] the initial P pick is rejected 1.1 #minAICPSNR# %below this SNR the initial P pick is rejected 1.0 #minAICSslope# %below this slope [counts/s] the initial S pick is rejected 1.5 #minAICSSNR# %below this SNR the initial S pick is rejected 1.0 #minsiglength# %length of signal part for which amplitudes must exceed noiselevel [s] -1.0 #noisefactor# %noiselevel*noisefactor=threshold -10.0 #minpercent# %required percentage of amplitudes exceeding threshold -1.5 #zfac# %P-amplitude must exceed at least zfac times RMS-S amplitude -6.0 #mdttolerance# %maximum allowed deviation of P picks from median [s] +1.1 #noisefactor# %noiselevel*noisefactor=threshold +50.0 #minpercent# %required percentage of amplitudes exceeding threshold +1.1 #zfac# %P-amplitude must exceed at least zfac times RMS-S amplitude +5.0 #mdttolerance# %maximum allowed deviation of P picks from median [s] 1.0 #wdttolerance# %maximum allowed deviation from Wadati-diagram -5.0 #jackfactor# %pick is removed if the variance of the subgroup with the pick removed is larger than the mean variance of all subgroups times safety factor +2.0 #jackfactor# %pick is removed if the variance of the subgroup with the pick removed is larger than the mean variance of all subgroups times safety factor From b6c682315de670e971afbeb43c446def533137ea Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ludger=20K=C3=BCperkoch?= Date: Tue, 3 Jul 2018 11:34:32 +0200 Subject: [PATCH 069/169] Allow negative saftey gap for slope determination, use only mean of noise window for SNR determination --- pylot/core/pick/picker.py | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/pylot/core/pick/picker.py b/pylot/core/pick/picker.py index 5328ca90..e999648e 100644 --- a/pylot/core/pick/picker.py +++ b/pylot/core/pick/picker.py @@ -240,12 +240,17 @@ class AICPicker(AutoPicker): return # calculate SNR from CF self.SNR = max(abs(self.Data[0].data[isignal])) / \ - max(abs(self.Data[0].data[inoise] - np.mean(self.Data[0].data[inoise]))) + abs(np.mean(self.Data[0].data[inoise])) # calculate slope from CF after initial pick # get slope window tslope = self.TSNR[3] # slope determination window - islope = np.where((self.Tcf <= min([self.Pick + tslope, self.Tcf[-1]])) \ - & (self.Tcf >= self.Pick)) # TODO: put this in a seperate function like getsignalwin + tsafety = self.TSNR[1] # safety gap, AIC is usually a little bit too late + if tsafety >= 0: + islope = np.where((self.Tcf <= min([self.Pick + tslope + tsafety, self.Tcf[-1]])) \ + & (self.Tcf >= self.Pick)) # TODO: put this in a seperate function like getsignalwin + else: + islope = np.where((self.Tcf <= min([self.Pick + tslope, self.Tcf[-1]])) \ + & (self.Tcf >= self.Pick + tsafety)) # TODO: put this in a seperate function like getsignalwin # find maximum within slope determination window # 'cause slope should be calculated up to first local minimum only! try: From 2379dee142c861543da3aaa8edb192f4066ade3b Mon Sep 17 00:00:00 2001 From: Marcel Date: Wed, 4 Jul 2018 10:56:18 +0200 Subject: [PATCH 070/169] [hotfix] metadata could not be read (improve this) --- PyLoT.py | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/PyLoT.py b/PyLoT.py index a11b7374..76238428 100755 --- a/PyLoT.py +++ b/PyLoT.py @@ -3128,20 +3128,18 @@ class MainWindow(QMainWindow): settings.setValue("inventoryFile", self.project.inv_path) fninv = settings.value("inventoryFile", None) - if fninv and ask_default: + if (fninv and ask_default) and not new: ans = QMessageBox.question(self, self.tr("Use default metadata..."), self.tr( "Do you want to use the default value for metadata?\n({})".format(fninv)), QMessageBox.Yes | QMessageBox.No, QMessageBox.Yes) - if ans == QMessageBox.No: - if not set_inv(settings): - return None - elif ans == QMessageBox.Yes: + if ans == QMessageBox.Yes: self.read_metadata_thread(fninv) - if fninv and not ask_default: - self.read_metadata_thread(fninv) + return + set_inv(settings) + def calc_magnitude(self, type='ML'): self.init_metadata() if not self.metadata: From e05909b188b4bcdef83372a06c5296d9f10cff20 Mon Sep 17 00:00:00 2001 From: Marcel Date: Wed, 4 Jul 2018 16:48:14 +0200 Subject: [PATCH 071/169] [minor] textobjects split into single lines before adding to log for convenience --- PyLoT.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/PyLoT.py b/PyLoT.py index 76238428..f8c99424 100755 --- a/PyLoT.py +++ b/PyLoT.py @@ -2339,7 +2339,9 @@ class MainWindow(QMainWindow): self.nextStation = bool(signal) def addListItem(self, text): - self.listWidget.addItem(text) + textlist = text.split('\n') + for text in textlist: + self.listWidget.addItem(text) self.listWidget.scrollToBottom() def init_fig_dict(self): From b0ad99eced4907675b7e7a240949a68c06b9cdf3 Mon Sep 17 00:00:00 2001 From: Marcel Date: Wed, 4 Jul 2018 17:25:11 +0200 Subject: [PATCH 072/169] [minor] improved text output if wf data cannot be read --- pylot/core/io/data.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pylot/core/io/data.py b/pylot/core/io/data.py index e84badea..5e6db468 100644 --- a/pylot/core/io/data.py +++ b/pylot/core/io/data.py @@ -445,7 +445,7 @@ class Data(object): except SacIOError as se: warnmsg += '{0}\n{1}\n'.format(fname, se) if warnmsg: - warnmsg = 'WARNING: unable to read\n' + warnmsg + warnmsg = 'WARNING in appendWFData: unable to read waveform data\n' + warnmsg print(warnmsg) def getWFData(self): From df0f059ff396f2855287cfd41c29dc02d7729587 Mon Sep 17 00:00:00 2001 From: Marcel Date: Thu, 5 Jul 2018 14:37:32 +0200 Subject: [PATCH 073/169] [bugfix] parameters tpred2z and tdet2z were unused --- pylot/core/pick/autopick.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/pylot/core/pick/autopick.py b/pylot/core/pick/autopick.py index baa450e1..76985aed 100644 --- a/pylot/core/pick/autopick.py +++ b/pylot/core/pick/autopick.py @@ -179,6 +179,8 @@ def autopickstation(wfstream, pickparam, verbose=False, nfacP = pickparam.get('nfacP') tpred1z = pickparam.get('tpred1z') tdet1z = pickparam.get('tdet1z') + tpred2z = pickparam.get('tpred2z') + tdet2z = pickparam.get('tdet2z') Parorder = pickparam.get('Parorder') addnoise = pickparam.get('addnoise') Precalcwin = pickparam.get('Precalcwin') @@ -489,7 +491,7 @@ def autopickstation(wfstream, pickparam, verbose=False, elif algoP == 'ARZ': # calculate ARZ-CF using subclass ARZcf of class # CharcteristicFunction - cf2 = ARZcf(z_copy, cuttimes2, tpred1z, Parorder, tdet1z, + cf2 = ARZcf(z_copy, cuttimes2, tpred2z, Parorder, tdet2z, addnoise) # instance of ARZcf ############################################################## # get refined onset time from CF2 using class Picker From 2c588c1c802800dc774114637d889aa41c950c81 Mon Sep 17 00:00:00 2001 From: Marcel Date: Thu, 5 Jul 2018 15:29:09 +0200 Subject: [PATCH 074/169] [change] initial pick now searches for latest local minimum instead of first increase in cf --- pylot/core/pick/picker.py | 30 +++++++++++++++++++----------- 1 file changed, 19 insertions(+), 11 deletions(-) diff --git a/pylot/core/pick/picker.py b/pylot/core/pick/picker.py index 6c02593a..a7064319 100644 --- a/pylot/core/pick/picker.py +++ b/pylot/core/pick/picker.py @@ -23,7 +23,7 @@ import warnings import matplotlib.pyplot as plt import numpy as np -from scipy.signal import argrelmax +from scipy.signal import argrelmax, argrelmin from pylot.core.pick.charfuns import CharacteristicFunction from pylot.core.pick.utils import getnoisewin, getsignalwin @@ -197,10 +197,15 @@ class AICPicker(AutoPicker): # find minimum in AIC-CF front of maximum of HOS/AR-CF lpickwindow = int(round(self.PickWindow / self.dt)) - for i in range(icfmax - 1, max([icfmax - lpickwindow, 2]), -1): - if aicsmooth[i - 1] >= aicsmooth[i]: - self.Pick = self.Tcf[i] - break + tsafety = self.TSNR[1] # safety gap, AIC is usually a little bit too late + left_corner_ind = max([icfmax - lpickwindow, 2]) + right_corner_ind = icfmax + int(tsafety / self.dt) + aic_snip = aicsmooth[left_corner_ind : right_corner_ind] + minima = argrelmin(aic_snip)[0] # 0th entry of tuples for axes + if len(minima) > 0: + pickindex = minima[-1] + left_corner_ind + self.Pick = self.Tcf[pickindex] + # if no minimum could be found: # search in 1st derivative of AIC-CF if self.Pick is None: @@ -215,6 +220,7 @@ class AICPicker(AutoPicker): for i in range(icfmax - 1, max([icfmax - lpickwindow, 2]), -1): if diffcf[i - 1] >= diffcf[i]: self.Pick = self.Tcf[i] + pickindex = i break if self.Pick is not None: @@ -244,7 +250,6 @@ class AICPicker(AutoPicker): # calculate slope from CF after initial pick # get slope window tslope = self.TSNR[3] # slope determination window - tsafety = self.TSNR[1] # safety gap, AIC is usually a little bit too late if tsafety >= 0: islope = np.where((self.Tcf <= min([self.Pick + tslope + tsafety, self.Tcf[-1]])) \ & (self.Tcf >= self.Pick)) # TODO: put this in a seperate function like getsignalwin @@ -263,7 +268,6 @@ class AICPicker(AutoPicker): return try: imaxs, = argrelmax(dataslope) - imaxs.size imax = imaxs[0] except ValueError as e: print(e, 'picker: argrelmax not working!') @@ -280,7 +284,7 @@ class AICPicker(AutoPicker): if self.iplot > 1: if self.fig == None or self.fig == 'None': fig = plt.figure() - plt_flag = 1 + plt_flag = iplot else: fig = self.fig ax = fig.add_subplot(111) @@ -291,7 +295,7 @@ class AICPicker(AutoPicker): ax.set_xlabel('Time [s] since %s' % self.Data[0].stats.starttime) ax.set_yticks([]) ax.set_title(self.Data[0].stats.station) - if plt_flag == 1: + if plt_flag in [1, 2]: fig.show() try: input() except SyntaxError: pass @@ -315,7 +319,7 @@ class AICPicker(AutoPicker): if iplot > 1: if self.fig == None or self.fig == 'None': fig = plt.figure() # self.iplot) - plt_flag = 1 + plt_flag = iplot else: fig = self.fig fig._tight = True @@ -359,11 +363,15 @@ class AICPicker(AutoPicker): else: ax1.set_title(self.Data[0].stats.station) - if plt_flag == 1: + if plt_flag in [1, 2]: fig.show() try: input() except SyntaxError: pass plt.close(fig) + if plt_flag == 3: + stats = self.Data[0].stats + netstlc = '{}.{}.{}'.format(stats.network, stats.station, stats.location) + fig.savefig('aicfig_{}_{}.png'.format(netstlc, stats.channel)) if self.Pick == None: print('AICPicker: Could not find minimum, picking window too short?') From 871fb685a48e4e946a250dc4a04719e3e995785b Mon Sep 17 00:00:00 2001 From: Marcel Date: Thu, 5 Jul 2018 15:30:40 +0200 Subject: [PATCH 075/169] [removed] amplification of cf by empirical values to account for restituted data --- pylot/core/pick/picker.py | 6 ------ 1 file changed, 6 deletions(-) diff --git a/pylot/core/pick/picker.py b/pylot/core/pick/picker.py index a7064319..928785a6 100644 --- a/pylot/core/pick/picker.py +++ b/pylot/core/pick/picker.py @@ -226,12 +226,6 @@ class AICPicker(AutoPicker): if self.Pick is not None: # get noise window inoise = getnoisewin(self.Tcf, self.Pick, self.TSNR[0], self.TSNR[1]) - # check, if these are counts or m/s, important for slope estimation! - # this is quick and dirty, better solution? #Todo wtf - if max(self.Data[0].data < 1e-3) and max(self.Data[0].data >= 1e-6): - self.Data[0].data = self.Data[0].data * 1000000. - elif max(self.Data[0].data < 1e-6): - self.Data[0].data = self.Data[0].data * 1e13 # get signal window isignal = getsignalwin(self.Tcf, self.Pick, self.TSNR[2]) if len(isignal) == 0: From 1f2dd689ba7c6fdc20d843f77dc3390a6e441412 Mon Sep 17 00:00:00 2001 From: Marcel Date: Fri, 6 Jul 2018 10:36:38 +0200 Subject: [PATCH 076/169] [change] slope normalized to maximum y value, TESTING NEEDED --- pylot/core/pick/picker.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/pylot/core/pick/picker.py b/pylot/core/pick/picker.py index 928785a6..57934e44 100644 --- a/pylot/core/pick/picker.py +++ b/pylot/core/pick/picker.py @@ -305,6 +305,8 @@ class AICPicker(AutoPicker): print('AICPicker: Negative slope, bad onset skipped!') else: self.slope = 1 / (len(dataslope) * self.Data[0].stats.delta) * (datafit[-1] - datafit[0]) + # normalize slope to maximum of cf to make it unit independent + self.slope /= self.Data[0].data[icfmax] else: self.SNR = None From d223011f90f5cdd2268bfb304adb7f7481a57dba Mon Sep 17 00:00:00 2001 From: Marcel Date: Fri, 6 Jul 2018 11:03:21 +0200 Subject: [PATCH 077/169] [bugfix] Metadata class raised Exception using obspy get_coordinates --- pylot/core/util/dataprocessing.py | 40 +++++++++++++++++++++++++------ 1 file changed, 33 insertions(+), 7 deletions(-) diff --git a/pylot/core/util/dataprocessing.py b/pylot/core/util/dataprocessing.py index ee74a960..e12e61b7 100644 --- a/pylot/core/util/dataprocessing.py +++ b/pylot/core/util/dataprocessing.py @@ -24,13 +24,25 @@ class Metadata(object): def add_inventory(self, path_to_inventory): - # add paths to list of inventories + ''' + add paths to list of inventories + + :param path_to_inventory: + :return: + ''' assert (os.path.isdir(path_to_inventory)), '{} is no directory'.format(path_to_inventory) if not path_to_inventory in self.inventories: self.inventories.append(path_to_inventory) def add_inventory_file(self, path_to_inventory_file): + ''' + add a single file to inventory files + + :param path_to_inventory_file: + :return: + + ''' assert (os.path.isfile(path_to_inventory_file)), '{} is no directory'.format(path_to_inventory_file) self.add_inventory(os.path.split(path_to_inventory_file)[0]) if not path_to_inventory_file in self.inventory_files.keys(): @@ -38,6 +50,12 @@ class Metadata(object): def remove_inventory(self, path_to_inventory): + ''' + remove a path from inventories list + + :param path_to_inventory: + :return: + ''' if not path_to_inventory in self.inventories: print('Path {} not in inventories list.'.format(path_to_inventory)) return @@ -54,9 +72,12 @@ class Metadata(object): self.read_all() for inv_fname, metadata in self.inventory_files.items(): # use get_coordinates to check for seed_id - if metadata['data'].get_coordinates(seed_id): + try: + metadata['data'].get_coordinates(seed_id) self.seed_ids[seed_id] = inv_fname return metadata + except Exception as e: + continue print('Could not find metadata for station {}'.format(seed_id)) return None fname = self.seed_ids[seed_id] @@ -64,6 +85,10 @@ class Metadata(object): def read_all(self): + ''' + read all metadata files found in all inventories + :return: + ''' for inventory in self.inventories: for inv_fname in os.listdir(inventory): inv_fname = os.path.join(inventory, inv_fname) @@ -93,17 +118,18 @@ class Metadata(object): def get_coordinates(self, seed_id): metadata = self.get_metadata(seed_id) + if not metadata: + return return metadata['data'].get_coordinates(seed_id) - def get_paz(self, seed_id, time=None): + def get_paz(self, seed_id, time): metadata = self.get_metadata(seed_id) + if not metadata: + return if metadata['invtype'] in ['dless', 'dseed']: - return metadata['data'].get_paz(seed_id) + return metadata['data'].get_paz(seed_id, time) elif metadata['invtype'] in ['resp', 'xml']: - if not time: - print('Time needed to extract metadata from station inventory.') - return None resp = metadata['data'].get_response(seed_id, time) return resp.get_paz(seed_id) From 689192b25d46643a2ed0b4b93846be32f27c9760 Mon Sep 17 00:00:00 2001 From: Marcel Date: Fri, 6 Jul 2018 12:22:24 +0200 Subject: [PATCH 078/169] [bugfixes] in Metadata class (not fully tested yet) --- pylot/core/util/dataprocessing.py | 40 +++++++++++++++++++++++++++---- 1 file changed, 35 insertions(+), 5 deletions(-) diff --git a/pylot/core/util/dataprocessing.py b/pylot/core/util/dataprocessing.py index e12e61b7..c0630d76 100644 --- a/pylot/core/util/dataprocessing.py +++ b/pylot/core/util/dataprocessing.py @@ -15,14 +15,34 @@ from pylot.core.util.utils import key_for_set_value, find_in_list, \ class Metadata(object): def __init__(self, inventory=None): self.inventories = [] - if os.path.isdir(inventory): - self.add_inventory(inventory) - if os.path.isfile(inventory): - self.add_inventory_file(inventory) + if inventory: + if os.path.isdir(inventory): + self.add_inventory(inventory) + if os.path.isfile(inventory): + self.add_inventory_file(inventory) + # saves filenames holding metadata for a seed_id self.seed_ids = {} + # saves read metadata objects (Parser/inventory) for a filename self.inventory_files = {} + def __str__(self): + repr = 'PyLoT Metadata object including the following inventories:\n\n' + ntotal = len(self.inventories) + for index, inventory in enumerate(self.inventories): + if index < 2 or (ntotal - index) < 3: + repr += '{}\n'.format(inventory) + if ntotal > 4 and int(ntotal/2) == index: + repr += '...\n' + if ntotal > 4: + repr += '\nTotal of {} inventories. Use Metadata.inventories to see all.'.format(ntotal) + return repr + + + def __repr__(self): + return self.__str__() + + def add_inventory(self, path_to_inventory): ''' add paths to list of inventories @@ -43,12 +63,16 @@ class Metadata(object): :return: ''' - assert (os.path.isfile(path_to_inventory_file)), '{} is no directory'.format(path_to_inventory_file) + assert (os.path.isfile(path_to_inventory_file)), '{} is no file'.format(path_to_inventory_file) self.add_inventory(os.path.split(path_to_inventory_file)[0]) if not path_to_inventory_file in self.inventory_files.keys(): self.read_single_file(path_to_inventory_file) + def remove_all_inventories(self): + self.__init__() + + def remove_inventory(self, path_to_inventory): ''' remove a path from inventories list @@ -60,6 +84,12 @@ class Metadata(object): print('Path {} not in inventories list.'.format(path_to_inventory)) return self.inventories.remove(path_to_inventory) + for filename in self.inventory_files.keys(): + if filename.startswith(path_to_inventory): + del(self.inventory_files[filename]) + for seed_id in self.seed_ids.keys(): + if self.seed_ids[seed_id].startswith(path_to_inventory): + del(self.seed_ids[seed_id]) def get_metadata(self, seed_id): From ccec76b8a1313342a985791329c24366f22cf692 Mon Sep 17 00:00:00 2001 From: Marcel Date: Mon, 9 Jul 2018 11:06:19 +0200 Subject: [PATCH 079/169] [revert] iplot = iplot for wadati/jackknife not showing plots anymore in GUI Note: Are not Wadati and Jackknife figures meant to be shown always? Independent of iplot flag? --- pylot/core/pick/autopick.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pylot/core/pick/autopick.py b/pylot/core/pick/autopick.py index 76985aed..eca89e82 100644 --- a/pylot/core/pick/autopick.py +++ b/pylot/core/pick/autopick.py @@ -100,9 +100,9 @@ def autopickevent(data, param, iplot=0, fig_dict=None, fig_dict_wadatijack=None, # quality control # median check and jackknife on P-onset times - jk_checked_onsets = checkPonsets(all_onsets, mdttolerance, jackfactor, iplot, fig_dict_wadatijack) + jk_checked_onsets = checkPonsets(all_onsets, mdttolerance, jackfactor, 1, fig_dict_wadatijack) # check S-P times (Wadati) - wadationsets = wadaticheck(jk_checked_onsets, wdttolerance, iplot, fig_dict_wadatijack) + wadationsets = wadaticheck(jk_checked_onsets, wdttolerance, 1, fig_dict_wadatijack) return wadationsets From 0474e5fbe99a4465ef6e91b97a3860b8682f0fa2 Mon Sep 17 00:00:00 2001 From: Marcel Date: Mon, 9 Jul 2018 13:32:44 +0200 Subject: [PATCH 080/169] [minor] add progressbar to autopick widget --- pylot/core/util/widgets.py | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/pylot/core/util/widgets.py b/pylot/core/util/widgets.py index e9b1a965..44506cb1 100644 --- a/pylot/core/util/widgets.py +++ b/pylot/core/util/widgets.py @@ -2832,10 +2832,20 @@ class MultiEventWidget(QWidget): self.rb_layout.insertWidget(index, rb) self.rb_layout.setStretch(index, 0) + self.pb = QtGui.QProgressBar() + self.pb.setRange(0, 0) + self.pb.setVisible(False) + + #space holder for progressbar + self._pb_space = QtGui.QWidget() + self.rb_layout.addWidget(self.start_button) - self.rb_layout.addWidget(QtGui.QWidget()) + self.rb_layout.addWidget(self.pb) + self.rb_layout.addWidget(self._pb_space) + self.rb_layout.setStretch(len(self.options) + 1, 1) + self.rb_layout.setStretch(len(self.options) + 2, 1) self.main_layout.insertLayout(0, self.rb_layout) @@ -2866,6 +2876,8 @@ class MultiEventWidget(QWidget): for rb in self.rb_dict.values(): rb.setEnabled(bool) self.start_button.setEnabled(bool) + self.pb.setVisible(not(bool)) + self._pb_space.setVisible(bool) self.eventbox.setEnabled(bool) self.button_clear.setEnabled(bool) From 9c119819a63560f48a62ffb6e4da656c96065d09 Mon Sep 17 00:00:00 2001 From: Marcel Date: Mon, 9 Jul 2018 14:14:59 +0200 Subject: [PATCH 081/169] [bugfix] self.inventory_files initiated too late --- pylot/core/util/dataprocessing.py | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/pylot/core/util/dataprocessing.py b/pylot/core/util/dataprocessing.py index c0630d76..8366d134 100644 --- a/pylot/core/util/dataprocessing.py +++ b/pylot/core/util/dataprocessing.py @@ -15,15 +15,15 @@ from pylot.core.util.utils import key_for_set_value, find_in_list, \ class Metadata(object): def __init__(self, inventory=None): self.inventories = [] + # saves read metadata objects (Parser/inventory) for a filename + self.inventory_files = {} + # saves filenames holding metadata for a seed_id + self.seed_ids = {} if inventory: if os.path.isdir(inventory): self.add_inventory(inventory) if os.path.isfile(inventory): self.add_inventory_file(inventory) - # saves filenames holding metadata for a seed_id - self.seed_ids = {} - # saves read metadata objects (Parser/inventory) for a filename - self.inventory_files = {} def __str__(self): @@ -460,11 +460,16 @@ def read_metadata(path_to_inventory): def restitute_trace(input_tuple): - tr, invtype, inobj, unit, force = input_tuple + tr, metadata, unit, force = input_tuple remove_trace = False seed_id = tr.get_id() + + mdata = metadata.get_metadata(seed_id) + invtype = mdata['invtype'] + inobj = mdata['data'] + # check, whether this trace has already been corrected if 'processing' in tr.stats.keys() \ and np.any(['remove' in p for p in tr.stats.processing]) \ @@ -532,7 +537,7 @@ def restitute_trace(input_tuple): return tr, remove_trace -def restitute_data(data, invtype, inobj, unit='VEL', force=False, ncores=0): +def restitute_data(data, metadata, unit='VEL', force=False, ncores=0): """ takes a data stream and a path_to_inventory and returns the corrected waveform data stream @@ -553,7 +558,7 @@ def restitute_data(data, invtype, inobj, unit='VEL', force=False, ncores=0): # loop over traces input_tuples = [] for tr in data: - input_tuples.append((tr, invtype, inobj, unit, force)) + input_tuples.append((tr, metadata, unit, force)) data.remove(tr) pool = gen_Pool(ncores) From b4516fb2cbad73e0fd118324bb20bf55fc2a9ab9 Mon Sep 17 00:00:00 2001 From: Marcel Date: Tue, 10 Jul 2018 11:01:34 +0200 Subject: [PATCH 082/169] [update] save automatic picks calculated inside GUI in XML files as well --- PyLoT.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/PyLoT.py b/PyLoT.py index f8c99424..82d897c2 100755 --- a/PyLoT.py +++ b/PyLoT.py @@ -1407,7 +1407,7 @@ class MainWindow(QMainWindow): self.get_data().resetPicks() return self.saveData(event, directory, outformats) - fcheck = ['manual', 'origins', 'magnitude'] + fcheck = ['auto', 'manual', 'origins', 'magnitude'] saved_as = str() for outformat in outformats: From c46513a626a46de6beca6fe0010ce3ecbed6f1f5 Mon Sep 17 00:00:00 2001 From: Marcel Date: Tue, 10 Jul 2018 11:13:41 +0200 Subject: [PATCH 083/169] [bugfix] full_range called for each station when drawing picks, largely decreasing plot performance --- PyLoT.py | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/PyLoT.py b/PyLoT.py index f8c99424..fa4940f8 100755 --- a/PyLoT.py +++ b/PyLoT.py @@ -2631,17 +2631,20 @@ class MainWindow(QMainWindow): elif type == 'auto': event.addAutopicks(picksdict['auto']) - def drawPicks(self, station=None, picktype=None): + def drawPicks(self, station=None, picktype=None, stime=None): # if picktype not specified, draw both + if not stime: + stime = self.getStime() + if not picktype: - self.drawPicks(station, 'manual') - self.drawPicks(station, 'auto') + self.drawPicks(station, 'manual', stime) + self.drawPicks(station, 'auto', stime) return # if picks to draw not specified, draw all picks available if not station: for station in self.getPicks(type=picktype): - self.drawPicks(station, picktype=picktype) + self.drawPicks(station, picktype=picktype, stime=stime) return # check for station key in dictionary, else return @@ -2659,7 +2662,6 @@ class MainWindow(QMainWindow): ylims = np.array([-.5, +.5]) + plotID stat_picks = self.getPicks(type=picktype)[station] - stime = self.getStime() for phase in stat_picks: if phase == 'SPt': continue # wadati SP time From 3bc3d07793959dbaab2bc8c2afe78d27d28ecc63 Mon Sep 17 00:00:00 2001 From: Marcel Date: Tue, 10 Jul 2018 11:35:13 +0200 Subject: [PATCH 084/169] [new] first use of Metadata class in autoPyLoT, largely increasing read performance using obspyDMT (single DATALESS-Seed files) --- autoPyLoT.py | 18 +++++++---- pylot/core/pick/autopick.py | 25 ++++++++++----- pylot/core/pick/picker.py | 51 ++++++++++++++++++++++--------- pylot/core/util/dataprocessing.py | 24 ++++++++++----- 4 files changed, 83 insertions(+), 35 deletions(-) diff --git a/autoPyLoT.py b/autoPyLoT.py index 5db95399..cafc4fbf 100755 --- a/autoPyLoT.py +++ b/autoPyLoT.py @@ -22,7 +22,7 @@ from pylot.core.analysis.magnitude import MomentMagnitude, LocalMagnitude from pylot.core.io.data import Data from pylot.core.io.inputs import PylotParameter from pylot.core.pick.autopick import autopickevent, iteratepicker -from pylot.core.util.dataprocessing import restitute_data, read_metadata +from pylot.core.util.dataprocessing import restitute_data, read_metadata, Metadata from pylot.core.util.defaults import SEPARATOR from pylot.core.util.event import Event from pylot.core.util.structure import DATASTRUCTURE @@ -276,7 +276,11 @@ def autoPyLoT(input_dict=None, parameter=None, inputfile=None, fnames=None, even wfdat = check4gaps(wfdat) wfdat = check4doubled(wfdat) wfdat = trim_station_components(wfdat, trim_start=True, trim_end=False) - metadata = read_metadata(parameter.get('invdir')) + if not wfpath_extension: + metadata = Metadata(parameter.get('invdir')) + else: + metadata = Metadata(os.path.join(eventpath, 'resp')) + # metadata = read_metadata(parameter.get('invdir')) # TODO: (idea) read metadata from obspy_dmt database # if not wfpath_extension: # metadata = read_metadata(parameter.get('invdir')) @@ -285,10 +289,10 @@ def autoPyLoT(input_dict=None, parameter=None, inputfile=None, fnames=None, even corr_dat = None if metadata: # rotate stations to ZNE - wfdat = check4rotated(wfdat, metadata) + #wfdat = check4rotated(wfdat, metadata) # MP MP TEMPORARILY DISABLED !!!!!!!!!!! if locflag: print("Restitute data ...") - corr_dat = restitute_data(wfdat.copy(), *metadata, ncores=ncores) + corr_dat = restitute_data(wfdat.copy(), metadata, ncores=ncores) if not corr_dat and locflag: locflag = 2 print('Working on event %s. Stations: %s' % (eventpath, station)) @@ -363,7 +367,8 @@ def autoPyLoT(input_dict=None, parameter=None, inputfile=None, fnames=None, even WAscaling[2])) evt = local_mag.updated_event(magscaling) net_ml = local_mag.net_magnitude(magscaling) - print("Network local magnitude: %4.1f" % net_ml.mag) + if net_ml: + print("Network local magnitude: %4.1f" % net_ml.mag) if magscaling == None: scaling = False elif magscaling[0] != 0 and magscaling[1] != 0: @@ -447,7 +452,8 @@ def autoPyLoT(input_dict=None, parameter=None, inputfile=None, fnames=None, even WAscaling[2])) evt = local_mag.updated_event(magscaling) net_ml = local_mag.net_magnitude(magscaling) - print("Network local magnitude: %4.1f" % net_ml.mag) + if net_ml: + print("Network local magnitude: %4.1f" % net_ml.mag) if magscaling == None: scaling = False elif magscaling[0] != 0 and magscaling[1] != 0: diff --git a/pylot/core/pick/autopick.py b/pylot/core/pick/autopick.py index eca89e82..2fb98e8e 100644 --- a/pylot/core/pick/autopick.py +++ b/pylot/core/pick/autopick.py @@ -88,9 +88,9 @@ def autopickevent(data, param, iplot=0, fig_dict=None, fig_dict_wadatijack=None, print('Autopickstation: Distribute autopicking for {} ' 'stations on {} cores.'.format(len(input_tuples), ncores_str)) - pool = gen_Pool(ncores) - result = pool.map(call_autopickstation, input_tuples) - pool.close() + + result = parallel_picking(input_tuples, ncores) + #result = serial_picking(input_tuples) for pick in result: if pick: @@ -106,6 +106,20 @@ def autopickevent(data, param, iplot=0, fig_dict=None, fig_dict_wadatijack=None, return wadationsets +def serial_picking(input_tuples): + result = [] + for input_tuple in input_tuples: + result.append(call_autopickstation(input_tuple)) + return result + + +def parallel_picking(input_tuples, ncores): + pool = gen_Pool(ncores) + result = pool.imap_unordered(call_autopickstation, input_tuples) + pool.close() + return result + + def call_autopickstation(input_tuple): """ helper function used for multiprocessing @@ -286,13 +300,10 @@ def autopickstation(wfstream, pickparam, verbose=False, Lc = np.inf print('autopickstation: use_taup flag active.') if not metadata: - metadata = [None, None] - if not metadata[1]: print('Warning: Could not use TauPy to estimate onsets as there are no metadata given.') else: station_id = wfstream[0].get_id() - parser = metadata[1] - station_coords = get_source_coords(parser, station_id) + station_coords = metadata.get_coordinates(station_id) if station_coords and origin: source_origin = origin[0] model = TauPyModel(taup_model) diff --git a/pylot/core/pick/picker.py b/pylot/core/pick/picker.py index 57934e44..748dce99 100644 --- a/pylot/core/pick/picker.py +++ b/pylot/core/pick/picker.py @@ -191,9 +191,24 @@ class AICPicker(AutoPicker): # remove offset in AIC function offset = abs(min(aic) - min(aicsmooth)) aicsmooth = aicsmooth - offset + cf = self.Data[0].data # get maximum of HOS/AR-CF as startimg point for searching # minimum in AIC function - icfmax = np.argmax(self.Data[0].data) + icfmax = np.argmax(cf) + + # MP MP testing threshold + thresh_hit = False + thresh_factor = 0.6 + thresh = thresh_factor * cf[icfmax] + for index, sample in enumerate(cf): + if sample >= thresh: + thresh_hit = True + # go on searching for the following maximum + if index > 0 and thresh_hit: + if sample <= cf[index - 1]: + icfmax = index - 1 + break + # MP MP --- # find minimum in AIC-CF front of maximum of HOS/AR-CF lpickwindow = int(round(self.PickWindow / self.dt)) @@ -233,14 +248,14 @@ class AICPicker(AutoPicker): ii = min([isignal[len(isignal) - 1], len(self.Tcf)]) isignal = isignal[0:ii] try: - self.Data[0].data[isignal] + cf[isignal] except IndexError as e: msg = "Time series out of bounds! {}".format(e) print(msg) return # calculate SNR from CF - self.SNR = max(abs(self.Data[0].data[isignal])) / \ - abs(np.mean(self.Data[0].data[inoise])) + self.SNR = max(abs(cf[isignal])) / \ + abs(np.mean(cf[inoise])) # calculate slope from CF after initial pick # get slope window tslope = self.TSNR[3] # slope determination window @@ -253,7 +268,7 @@ class AICPicker(AutoPicker): # find maximum within slope determination window # 'cause slope should be calculated up to first local minimum only! try: - dataslope = self.Data[0].data[islope[0][0:-1]] + dataslope = cf[islope[0][0:-1]] except IndexError: print("Slope Calculation: empty array islope, check signal window") return @@ -282,8 +297,8 @@ class AICPicker(AutoPicker): else: fig = self.fig ax = fig.add_subplot(111) - x = self.Data[0].data - ax.plot(self.Tcf, x / max(x), color=self._linecolor, linewidth=0.7, label='(HOS-/AR-) Data') + cf = cf + ax.plot(self.Tcf, cf / max(cf), color=self._linecolor, linewidth=0.7, label='(HOS-/AR-) Data') ax.plot(self.Tcf, aicsmooth / max(aicsmooth), 'r', label='Smoothed AIC-CF') ax.legend(loc=1) ax.set_xlabel('Time [s] since %s' % self.Data[0].stats.starttime) @@ -296,7 +311,16 @@ class AICPicker(AutoPicker): plt.close(fig) return iislope = islope[0][0:imax+1] - dataslope = self.Data[0].data[iislope] + # MP MP change slope calculation + # get all maxima of aicsmooth + iaicmaxima = argrelmax(aicsmooth)[0] + # get first index of maximum after pickindex (indices saved in iaicmaxima) + aicmax = iaicmaxima[np.where(iaicmaxima > pickindex)[0]] + if len(aicmax) > 0: + iaicmax = aicmax[0] + else: + iaicmax = -1 + dataslope = aicsmooth[pickindex : iaicmax] # calculate slope as polynomal fit of order 1 xslope = np.arange(0, len(dataslope), 1) P = np.polyfit(xslope, dataslope, 1) @@ -306,7 +330,7 @@ class AICPicker(AutoPicker): else: self.slope = 1 / (len(dataslope) * self.Data[0].stats.delta) * (datafit[-1] - datafit[0]) # normalize slope to maximum of cf to make it unit independent - self.slope /= self.Data[0].data[icfmax] + self.slope /= aicsmooth[iaicmax] else: self.SNR = None @@ -320,10 +344,9 @@ class AICPicker(AutoPicker): fig = self.fig fig._tight = True ax1 = fig.add_subplot(211) - x = self.Data[0].data - if len(self.Tcf) > len(self.Data[0].data): # why? LK + if len(self.Tcf) > len(cf): # why? LK self.Tcf = self.Tcf[0:len(self.Tcf)-1] - ax1.plot(self.Tcf, x / max(x), color=self._linecolor, linewidth=0.7, label='(HOS-/AR-) Data') + ax1.plot(self.Tcf, cf / max(cf), color=self._linecolor, linewidth=0.7, label='(HOS-/AR-) Data') ax1.plot(self.Tcf, aicsmooth / max(aicsmooth), 'r', label='Smoothed AIC-CF') if self.Pick is not None: ax1.plot([self.Pick, self.Pick], [-0.1, 0.5], 'b', linewidth=2, label='AIC-Pick') @@ -333,7 +356,7 @@ class AICPicker(AutoPicker): if self.Pick is not None: ax2 = fig.add_subplot(2, 1, 2, sharex=ax1) - ax2.plot(self.Tcf, x, color=self._linecolor, linewidth=0.7, label='Data') + ax2.plot(self.Tcf, aicsmooth, color='r', linewidth=0.7, label='Data') ax1.axvspan(self.Tcf[inoise[0]], self.Tcf[inoise[-1]], color='y', alpha=0.2, lw=0, label='Noise Window') ax1.axvspan(self.Tcf[isignal[0]], self.Tcf[isignal[-1]], color='b', alpha=0.2, lw=0, label='Signal Window') @@ -345,7 +368,7 @@ class AICPicker(AutoPicker): label='Signal Window') ax2.axvspan(self.Tcf[iislope[0]], self.Tcf[iislope[-1]], color='g', alpha=0.2, lw=0, label='Slope Window') - ax2.plot(self.Tcf[iislope], datafit, 'g', linewidth=2, label='Slope') + ax2.plot(self.Tcf[pickindex : iaicmax], datafit, 'g', linewidth=2, label='Slope') # MP MP changed temporarily! if self.slope is not None: ax1.set_title('Station %s, SNR=%7.2f, Slope= %12.2f counts/s' % (self.Data[0].stats.station, diff --git a/pylot/core/util/dataprocessing.py b/pylot/core/util/dataprocessing.py index 8366d134..f98d99a2 100644 --- a/pylot/core/util/dataprocessing.py +++ b/pylot/core/util/dataprocessing.py @@ -100,12 +100,13 @@ class Metadata(object): if not seed_id in self.seed_ids.keys(): print('No data found for seed id {}. Trying to find it in all known inventories...'.format(seed_id)) self.read_all() - for inv_fname, metadata in self.inventory_files.items(): + for inv_fname, metadata_dict in self.inventory_files.items(): # use get_coordinates to check for seed_id try: - metadata['data'].get_coordinates(seed_id) + metadata_dict['data'].get_coordinates(seed_id) self.seed_ids[seed_id] = inv_fname - return metadata + print('Found metadata for station {}!'.format(seed_id)) + return metadata_dict except Exception as e: continue print('Could not find metadata for station {}'.format(seed_id)) @@ -127,6 +128,7 @@ class Metadata(object): def read_single_file(self, inv_fname): + # try to read a single file as Parser/Inventory if it was not already read before if not inv_fname in self.inventory_files.keys(): pass else: @@ -460,6 +462,11 @@ def read_metadata(path_to_inventory): def restitute_trace(input_tuple): + def no_metadata(tr, seed_id): + print('no metadata file found ' + 'for trace {0}'.format(seed_id)) + return tr, True + tr, metadata, unit, force = input_tuple remove_trace = False @@ -467,6 +474,9 @@ def restitute_trace(input_tuple): seed_id = tr.get_id() mdata = metadata.get_metadata(seed_id) + if not mdata: + return no_metadata(tr, seed_id) + invtype = mdata['invtype'] inobj = mdata['data'] @@ -481,8 +491,7 @@ def restitute_trace(input_tuple): if invtype == 'resp': fresp = find_in_list(inobj, seed_id) if not fresp: - raise IOError('no response file found ' - 'for trace {0}'.format(seed_id)) + return no_metadata(tr, seed_id) fname = fresp seedresp = dict(filename=fname, date=stime, @@ -505,8 +514,7 @@ def restitute_trace(input_tuple): finv = invlist[0] inventory = read_inventory(finv, format='STATIONXML') elif invtype == None: - print("No restitution possible, as there are no station-meta data available!") - return tr, True + return no_metadata(tr, seed_id) else: remove_trace = True # apply restitution to data @@ -562,7 +570,7 @@ def restitute_data(data, metadata, unit='VEL', force=False, ncores=0): data.remove(tr) pool = gen_Pool(ncores) - result = pool.map(restitute_trace, input_tuples) + result = pool.imap_unordered(restitute_trace, input_tuples) pool.close() for tr, remove_trace in result: From 1de1dc71f8f604990cf5a82f7128ad03f99d420d Mon Sep 17 00:00:00 2001 From: Marcel Date: Tue, 10 Jul 2018 11:47:45 +0200 Subject: [PATCH 085/169] [bugfix] reinstated ludgers changes, added bugfix for GUI --- pylot/core/pick/autopick.py | 4 ++-- pylot/core/pick/utils.py | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/pylot/core/pick/autopick.py b/pylot/core/pick/autopick.py index eca89e82..76985aed 100644 --- a/pylot/core/pick/autopick.py +++ b/pylot/core/pick/autopick.py @@ -100,9 +100,9 @@ def autopickevent(data, param, iplot=0, fig_dict=None, fig_dict_wadatijack=None, # quality control # median check and jackknife on P-onset times - jk_checked_onsets = checkPonsets(all_onsets, mdttolerance, jackfactor, 1, fig_dict_wadatijack) + jk_checked_onsets = checkPonsets(all_onsets, mdttolerance, jackfactor, iplot, fig_dict_wadatijack) # check S-P times (Wadati) - wadationsets = wadaticheck(jk_checked_onsets, wdttolerance, 1, fig_dict_wadatijack) + wadationsets = wadaticheck(jk_checked_onsets, wdttolerance, iplot, fig_dict_wadatijack) return wadationsets diff --git a/pylot/core/pick/utils.py b/pylot/core/pick/utils.py index 803524c3..96878c4d 100644 --- a/pylot/core/pick/utils.py +++ b/pylot/core/pick/utils.py @@ -684,7 +684,7 @@ def wadaticheck(pickdic, dttolerance, iplot=0, fig_dict=None): wfitflag = 1 # plot results - if iplot > 0: + if iplot > 0 or fig_dict: if fig_dict: fig = fig_dict['wadati'] linecolor = fig_dict['plot_style']['linecolor']['rgba_mpl'] @@ -926,7 +926,7 @@ def checkPonsets(pickdic, dttolerance, jackfactor=5, iplot=0, fig_dict=None): checkedonsets = pickdic - if iplot > 0: + if iplot > 0 or fig_dict: if fig_dict: fig = fig_dict['jackknife'] plt_flag = 0 From 6ab2609e8cf14c22768e2f34f272ea7ac899f22d Mon Sep 17 00:00:00 2001 From: Marcel Date: Tue, 10 Jul 2018 13:35:24 +0200 Subject: [PATCH 086/169] [bugfix] default filename given for nlloc in default_parameters --- pylot/core/io/default_parameters.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pylot/core/io/default_parameters.py b/pylot/core/io/default_parameters.py index 18137435..78057056 100644 --- a/pylot/core/io/default_parameters.py +++ b/pylot/core/io/default_parameters.py @@ -63,7 +63,7 @@ defaults = {'rootpath': {'type': str, 'ctrfile': {'type': str, 'tooltip': 'name of autoPyLoT-output control file for NLLoc', - 'value': 'Insheim_min1d2015_auto.in', + 'value': '', 'namestring': 'Control filename'}, 'ttpatter': {'type': str, From e7284cba41f03bc4abb1028dbaa37c9b8612431a Mon Sep 17 00:00:00 2001 From: Marcel Date: Tue, 10 Jul 2018 13:36:52 +0200 Subject: [PATCH 087/169] [bugfix] dictionary containing params not initiated in __init__ --- pylot/core/io/inputs.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/pylot/core/io/inputs.py b/pylot/core/io/inputs.py index 82152e44..7f449ed9 100644 --- a/pylot/core/io/inputs.py +++ b/pylot/core/io/inputs.py @@ -48,6 +48,7 @@ class PylotParameter(object): self.__init_default_paras() self.__init_subsettings() self.__filename = fnin + self.__parameter = {} self._verbosity = verbosity self._parFileCont = {} # io from parsed arguments alternatively @@ -273,8 +274,8 @@ class PylotParameter(object): :rtype: None """ defaults = self.get_defaults() - for param in defaults: - self.setParamKV(param, defaults[param]['value']) + for param_name, param in defaults.items(): + self.setParamKV(param_name, param['value']) def from_file(self, fnin=None): """ From 8d3bd88be90bb86e2a5a201847055ad0cc59c380 Mon Sep 17 00:00:00 2001 From: Marcel Date: Tue, 10 Jul 2018 13:54:49 +0200 Subject: [PATCH 088/169] [minor] gitignore update --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 78b6b4e7..29d71484 100644 --- a/.gitignore +++ b/.gitignore @@ -2,3 +2,4 @@ *~ pylot/RELEASE-VERSION *.idea +autopylot.sh* From 5f6f986e3e4fc696e4efffed12d6bfdd32c869f5 Mon Sep 17 00:00:00 2001 From: Marcel Date: Tue, 10 Jul 2018 13:56:17 +0200 Subject: [PATCH 089/169] [update] removed read of pylot.in on start!!! Now using default params from now on all input files should be saved in directory different to ~/.pylot --- PyLoT.py | 31 +++++++++++++++++-------------- 1 file changed, 17 insertions(+), 14 deletions(-) diff --git a/PyLoT.py b/PyLoT.py index 675f8c14..9d3ac38f 100755 --- a/PyLoT.py +++ b/PyLoT.py @@ -110,21 +110,8 @@ class MainWindow(QMainWindow): def __init__(self, parent=None, infile=None): super(MainWindow, self).__init__(parent) - # check for default pylot.in-file - if not infile: - infile = os.path.join(os.path.expanduser('~'), '.pylot', 'pylot.in') - print('Using default input file {}'.format(infile)) - if os.path.isfile(infile) == False: - infile = QFileDialog().getOpenFileName(caption='Choose PyLoT-input file') + self.init_config_files(infile) - if not os.path.exists(infile[0]): - QMessageBox.warning(self, "PyLoT Warning", - "No PyLoT-input file declared!") - sys.exit(0) - self.infile = infile[0] - else: - self.infile = infile - self._inputs = PylotParameter(infile) self._props = None self.dirty = False @@ -208,6 +195,22 @@ class MainWindow(QMainWindow): self.loc = False + + def init_config_files(self, infile): + pylot_config_dir = os.path.join(os.path.expanduser('~'), '.pylot') + if not os.path.exists(pylot_config_dir): + os.mkdir(pylot_config_dir) + + self._inputs = PylotParameter(infile) + if not infile: + self._inputs.reset_defaults() + # check for default pylot.in-file + infile = os.path.join(pylot_config_dir, '.pylot.in') + print('Using default input file {}'.format(infile)) + self._inputs.export2File(infile) + self.infile = infile + + def setupUi(self): try: self.startTime = min( From b870b5378af1c651e392319adeb1e313671868fe Mon Sep 17 00:00:00 2001 From: Marcel Date: Tue, 10 Jul 2018 14:20:31 +0200 Subject: [PATCH 090/169] [bugfix] setting Datastructure to obspydmt or None caused crash and corrupted QSettings --- pylot/core/io/data.py | 16 ++++++++++++++++ pylot/core/util/structure.py | 4 ++-- 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/pylot/core/io/data.py b/pylot/core/io/data.py index 5e6db468..176f76ac 100644 --- a/pylot/core/io/data.py +++ b/pylot/core/io/data.py @@ -733,6 +733,22 @@ class PilotDataStructure(GenericDataStructure): self.setExpandFields(['root', 'database']) +class ObspyDMTdataStructure(GenericDataStructure): + """ + Object containing the data access information for the old PILOT data + structure. + """ + + def __init__(self, **fields): + if not fields: + fields = {'database': '', + 'root': ''} + + GenericDataStructure.__init__(self, **fields) + + self.setExpandFields(['root', 'database']) + + class SeiscompDataStructure(GenericDataStructure): """ Dictionary containing the data access information for an SDS data archive: diff --git a/pylot/core/util/structure.py b/pylot/core/util/structure.py index f556eb7c..dd6cffd9 100644 --- a/pylot/core/util/structure.py +++ b/pylot/core/util/structure.py @@ -6,7 +6,7 @@ Created on Wed Jan 26 17:47:25 2015 @author: sebastianw """ -from pylot.core.io.data import SeiscompDataStructure, PilotDataStructure +from pylot.core.io.data import SeiscompDataStructure, PilotDataStructure, ObspyDMTdataStructure DATASTRUCTURE = {'PILOT': PilotDataStructure, 'SeisComP': SeiscompDataStructure, - 'obspyDMT': None, None: None} + 'obspyDMT': ObspyDMTdataStructure, None: PilotDataStructure} From 51f2ded063e91006bad0d2d96a99d380a725a1d7 Mon Sep 17 00:00:00 2001 From: Darius Arnold Date: Tue, 10 Jul 2018 17:07:46 +0200 Subject: [PATCH 091/169] [add] basic unittests for Metadata class --- .../metadata1/DATALESS.BW.WETR..HHE | 1 + .../metadata1/DATALESS.BW.WETR..HHN | 1 + .../metadata1/DATALESS.BW.WETR..HHZ | 1 + .../metadata2/DATALESS.GR.GRA1..HHE | 1 + .../metadata2/DATALESS.GR.GRA1..HHN | 1 + .../metadata2/DATALESS.GR.GRA1..HHZ | 1 + .../metadata2/DATALESS.GR.GRA2..HHE | 1 + .../metadata2/DATALESS.GR.GRA2..HHN | 1 + .../metadata2/DATALESS.GR.GRA2..HHZ | 1 + tests/test_Metadata/test_Metadata.py | 104 ++++++++++++++++++ 10 files changed, 113 insertions(+) create mode 100644 tests/test_Metadata/metadata1/DATALESS.BW.WETR..HHE create mode 100644 tests/test_Metadata/metadata1/DATALESS.BW.WETR..HHN create mode 100644 tests/test_Metadata/metadata1/DATALESS.BW.WETR..HHZ create mode 100644 tests/test_Metadata/metadata2/DATALESS.GR.GRA1..HHE create mode 100644 tests/test_Metadata/metadata2/DATALESS.GR.GRA1..HHN create mode 100644 tests/test_Metadata/metadata2/DATALESS.GR.GRA1..HHZ create mode 100644 tests/test_Metadata/metadata2/DATALESS.GR.GRA2..HHE create mode 100644 tests/test_Metadata/metadata2/DATALESS.GR.GRA2..HHN create mode 100644 tests/test_Metadata/metadata2/DATALESS.GR.GRA2..HHZ create mode 100644 tests/test_Metadata/test_Metadata.py diff --git a/tests/test_Metadata/metadata1/DATALESS.BW.WETR..HHE b/tests/test_Metadata/metadata1/DATALESS.BW.WETR..HHE new file mode 100644 index 00000000..426318fc --- /dev/null +++ b/tests/test_Metadata/metadata1/DATALESS.BW.WETR..HHE @@ -0,0 +1 @@ +000001V 010 65 2.3122012,213,12:05:00.0000~~2018,144,14:13:39.9981~GFZ~~011 21 1WETR 3 000002A 030 237Steim2 Integer Compression Format~ 1 5014F1 P4 W4 D C2 R1 P8 W4 D C2~P0 W4 N15 S2,0,1~T0 X W4~T1 Y4 W1 D C2~T2 W4 I D2~K0 X D30~K1 N0 D30 C2~K2 Y2 D15 C2~K3 Y3 D10 C2~T3 W4 I D2~K0 Y5 D6 C2~K1 Y6 D5 C2~K2 X D2 Y7 D4 C2~K3 X D30~033 21 1BayernNetz~033 16 2LE-3D~034 44 1M/S~Velocity in Meters per Second~034 18 2V~Volts~034 32 3COUNTS~Digital Counts~043 264 1RSSENSOR201509030717001~A 1 2 1.00000E+00 1.00000E+00 2 0.00000E+00 0.00000E+00 0.00000E-00 0.00000E-00 0.00000E+00 0.00000E+00 0.00000E-00 0.00000E-00 2-2.22100E-01 2.22100E-01 0.00000E-00 0.00000E-00-2.22100E-01-2.22100E-01 0.00000E-00 0.00000E-00044 51 3RLDATALOGGER201509030717~D 2 3 0 0047 78 4DLDATALOGGER201509030717~1.0000E+02 1 0 0.0000E+00 0.0000E+00048 57 2GSWETR2012213HEYYYY~ 1.00000E+03 1.00000E-01 0048 58 5GLWETR2012213HHEXXXX~ 1.67772E+06 0.00000E+00 0 000003S 050 109WETR 49.145020 12.875710 607.0 Wettzell, Bavaria, BW-Net~ 13210102012,213,12:05:00.0000~~NBW052 127 HHE 0 2~ 1 0 49.145020 12.875710 607.0 0.0 90.0 0.0 1121.0000E+021.0000E+00 TG~2012,213,12:05:00.0000~~N060 37 2 1 2 1 2 2 3 3 4 5058 35 0 1.67770E+09 1.00000E-01 0 \ No newline at end of file diff --git a/tests/test_Metadata/metadata1/DATALESS.BW.WETR..HHN b/tests/test_Metadata/metadata1/DATALESS.BW.WETR..HHN new file mode 100644 index 00000000..cb0d5be9 --- /dev/null +++ b/tests/test_Metadata/metadata1/DATALESS.BW.WETR..HHN @@ -0,0 +1 @@ +000001V 010 65 2.3122012,213,12:05:00.0000~~2018,144,14:13:40.4553~GFZ~~011 21 1WETR 3 000002A 030 237Steim2 Integer Compression Format~ 1 5014F1 P4 W4 D C2 R1 P8 W4 D C2~P0 W4 N15 S2,0,1~T0 X W4~T1 Y4 W1 D C2~T2 W4 I D2~K0 X D30~K1 N0 D30 C2~K2 Y2 D15 C2~K3 Y3 D10 C2~T3 W4 I D2~K0 Y5 D6 C2~K1 Y6 D5 C2~K2 X D2 Y7 D4 C2~K3 X D30~033 21 1BayernNetz~033 16 2LE-3D~034 44 1M/S~Velocity in Meters per Second~034 18 2V~Volts~034 32 3COUNTS~Digital Counts~043 264 1RSSENSOR201509030717001~A 1 2 1.00000E+00 1.00000E+00 2 0.00000E+00 0.00000E+00 0.00000E-00 0.00000E-00 0.00000E+00 0.00000E+00 0.00000E-00 0.00000E-00 2-2.22100E-01 2.22100E-01 0.00000E-00 0.00000E-00-2.22100E-01-2.22100E-01 0.00000E-00 0.00000E-00044 51 3RLDATALOGGER201509030717~D 2 3 0 0047 78 4DLDATALOGGER201509030717~1.0000E+02 1 0 0.0000E+00 0.0000E+00048 57 2GSWETR2012213HNYYYY~ 1.00000E+03 1.00000E-01 0048 58 5GLWETR2012213HHNXXXX~ 1.67772E+06 0.00000E+00 0 000003S 050 109WETR 49.145020 12.875710 607.0 Wettzell, Bavaria, BW-Net~ 13210102012,213,12:05:00.0000~~NBW052 127 HHN 0 2~ 1 0 49.145020 12.875710 607.0 0.0 0.0 0.0 1121.0000E+021.0000E+00 TG~2012,213,12:05:00.0000~~N060 37 2 1 2 1 2 2 3 3 4 5058 35 0 1.67770E+09 1.00000E-01 0 \ No newline at end of file diff --git a/tests/test_Metadata/metadata1/DATALESS.BW.WETR..HHZ b/tests/test_Metadata/metadata1/DATALESS.BW.WETR..HHZ new file mode 100644 index 00000000..59200ce2 --- /dev/null +++ b/tests/test_Metadata/metadata1/DATALESS.BW.WETR..HHZ @@ -0,0 +1 @@ +000001V 010 65 2.3122012,213,12:05:00.0000~~2018,144,14:13:39.5005~GFZ~~011 21 1WETR 3 000002A 030 237Steim2 Integer Compression Format~ 1 5014F1 P4 W4 D C2 R1 P8 W4 D C2~P0 W4 N15 S2,0,1~T0 X W4~T1 Y4 W1 D C2~T2 W4 I D2~K0 X D30~K1 N0 D30 C2~K2 Y2 D15 C2~K3 Y3 D10 C2~T3 W4 I D2~K0 Y5 D6 C2~K1 Y6 D5 C2~K2 X D2 Y7 D4 C2~K3 X D30~033 21 1BayernNetz~033 16 2LE-3D~034 44 1M/S~Velocity in Meters per Second~034 18 2V~Volts~034 32 3COUNTS~Digital Counts~043 264 1RSSENSOR201509030717001~A 1 2 1.00000E+00 1.00000E+00 2 0.00000E+00 0.00000E+00 0.00000E-00 0.00000E-00 0.00000E+00 0.00000E+00 0.00000E-00 0.00000E-00 2-2.22100E-01 2.22100E-01 0.00000E-00 0.00000E-00-2.22100E-01-2.22100E-01 0.00000E-00 0.00000E-00044 51 3RLDATALOGGER201509030717~D 2 3 0 0047 78 4DLDATALOGGER201509030717~1.0000E+02 1 0 0.0000E+00 0.0000E+00048 57 2GSWETR2012213HZYYYY~ 1.00000E+03 1.00000E-01 0048 58 5GLWETR2012213HHZXXXX~ 1.67772E+06 0.00000E+00 0 000003S 050 109WETR 49.145020 12.875710 607.0 Wettzell, Bavaria, BW-Net~ 13210102012,213,12:05:00.0000~~NBW052 127 HHZ 0 2~ 1 0 49.145020 12.875710 607.0 0.0 0.0-90.0 1121.0000E+021.0000E+00 TG~2012,213,12:05:00.0000~~N060 37 2 1 2 1 2 2 3 3 4 5058 35 0 1.67770E+09 1.00000E-01 0 \ No newline at end of file diff --git a/tests/test_Metadata/metadata2/DATALESS.GR.GRA1..HHE b/tests/test_Metadata/metadata2/DATALESS.GR.GRA1..HHE new file mode 100644 index 00000000..b562b239 --- /dev/null +++ b/tests/test_Metadata/metadata2/DATALESS.GR.GRA1..HHE @@ -0,0 +1 @@ +000001V 010 65 2.3122007,262,00:00:00.0000~~2018,144,14:14:34.7940~GFZ~~011 21 1GRA1 3 000002A 030 237Steim2 Integer Compression Format~ 1 5014F1 P4 W4 D C2 R1 P8 W4 D C2~P0 W4 N15 S2,0,1~T0 X W4~T1 Y4 W1 D C2~T2 W4 I D2~K0 X D30~K1 N0 D30 C2~K2 Y2 D15 C2~K3 Y3 D10 C2~T3 W4 I D2~K0 Y5 D6 C2~K1 Y6 D5 C2~K2 X D2 Y7 D4 C2~K3 X D30~033 56 1German Regional Seismic Network, BGR Hannover~033 15 2STS2~034 44 1M/S~Velocity in Meters per Second~034 18 2V~Volts~034 32 3COUNTS~Digital Counts~043 264 1RSSENSOR201207231411139~A 1 2 1.00000E+00 1.00000E+00 2 0.00000E+00 0.00000E+00 0.00000E-00 0.00000E-00 0.00000E+00 0.00000E+00 0.00000E-00 0.00000E-00 2-3.67429E-02 3.67540E-02 0.00000E-00 0.00000E-00-3.67429E-02-3.67540E-02 0.00000E-00 0.00000E-00044 51 3RLDATALOGGER201207231411~D 2 3 0 0047 78 4DLDATALOGGER201207231411~1.0000E+02 1 0 0.0000E+00 0.0000E+00048 57 2GSGRGRA1HHE2007262S~ 9.44020E+08 1.00000E+00 0048 54 5GLSZGRFDUMMYXXXX~ 1.00000E+00 0.00000E+00 0 000003S 050 117GRA1 49.691888 11.221720 499.5 Graefenberg Array Station Haidhof~ 13210101976,048,00:00:00.0000~~NGR052 125 HHE 0 2~ 1 0 49.691888 11.221720 499.5 0.0 90.0 0.0 1121.0000E+021.0000E-02 ~2007,262,00:00:00.0000~~N060 37 2 1 2 1 2 2 3 3 4 5058 35 0 9.44020E+08 1.00000E+00 0 \ No newline at end of file diff --git a/tests/test_Metadata/metadata2/DATALESS.GR.GRA1..HHN b/tests/test_Metadata/metadata2/DATALESS.GR.GRA1..HHN new file mode 100644 index 00000000..8a1259a4 --- /dev/null +++ b/tests/test_Metadata/metadata2/DATALESS.GR.GRA1..HHN @@ -0,0 +1 @@ +000001V 010 65 2.3122007,262,00:00:00.0000~~2018,144,14:14:35.2579~GFZ~~011 21 1GRA1 3 000002A 030 237Steim2 Integer Compression Format~ 1 5014F1 P4 W4 D C2 R1 P8 W4 D C2~P0 W4 N15 S2,0,1~T0 X W4~T1 Y4 W1 D C2~T2 W4 I D2~K0 X D30~K1 N0 D30 C2~K2 Y2 D15 C2~K3 Y3 D10 C2~T3 W4 I D2~K0 Y5 D6 C2~K1 Y6 D5 C2~K2 X D2 Y7 D4 C2~K3 X D30~033 56 1German Regional Seismic Network, BGR Hannover~033 15 2STS2~034 44 1M/S~Velocity in Meters per Second~034 18 2V~Volts~034 32 3COUNTS~Digital Counts~043 264 1RSSENSOR201207231411139~A 1 2 1.00000E+00 1.00000E+00 2 0.00000E+00 0.00000E+00 0.00000E-00 0.00000E-00 0.00000E+00 0.00000E+00 0.00000E-00 0.00000E-00 2-3.67429E-02 3.67540E-02 0.00000E-00 0.00000E-00-3.67429E-02-3.67540E-02 0.00000E-00 0.00000E-00044 51 3RLDATALOGGER201207231411~D 2 3 0 0047 78 4DLDATALOGGER201207231411~1.0000E+02 1 0 0.0000E+00 0.0000E+00048 57 2GSGRGRA1HHN2007262S~ 9.44020E+08 1.00000E+00 0048 54 5GLSZGRFDUMMYXXXX~ 1.00000E+00 0.00000E+00 0 000003S 050 117GRA1 49.691888 11.221720 499.5 Graefenberg Array Station Haidhof~ 13210101976,048,00:00:00.0000~~NGR052 125 HHN 0 2~ 1 0 49.691888 11.221720 499.5 0.0 0.0 0.0 1121.0000E+021.0000E-02 ~2007,262,00:00:00.0000~~N060 37 2 1 2 1 2 2 3 3 4 5058 35 0 9.44020E+08 1.00000E+00 0 \ No newline at end of file diff --git a/tests/test_Metadata/metadata2/DATALESS.GR.GRA1..HHZ b/tests/test_Metadata/metadata2/DATALESS.GR.GRA1..HHZ new file mode 100644 index 00000000..9ddaa477 --- /dev/null +++ b/tests/test_Metadata/metadata2/DATALESS.GR.GRA1..HHZ @@ -0,0 +1 @@ +000001V 010 65 2.3122007,262,00:00:00.0000~~2018,144,14:14:35.6913~GFZ~~011 21 1GRA1 3 000002A 030 237Steim2 Integer Compression Format~ 1 5014F1 P4 W4 D C2 R1 P8 W4 D C2~P0 W4 N15 S2,0,1~T0 X W4~T1 Y4 W1 D C2~T2 W4 I D2~K0 X D30~K1 N0 D30 C2~K2 Y2 D15 C2~K3 Y3 D10 C2~T3 W4 I D2~K0 Y5 D6 C2~K1 Y6 D5 C2~K2 X D2 Y7 D4 C2~K3 X D30~033 56 1German Regional Seismic Network, BGR Hannover~033 15 2STS2~034 44 1M/S~Velocity in Meters per Second~034 18 2V~Volts~034 32 3COUNTS~Digital Counts~043 264 1RSSENSOR201207231411139~A 1 2 1.00000E+00 1.00000E+00 2 0.00000E+00 0.00000E+00 0.00000E-00 0.00000E-00 0.00000E+00 0.00000E+00 0.00000E-00 0.00000E-00 2-3.67429E-02 3.67540E-02 0.00000E-00 0.00000E-00-3.67429E-02-3.67540E-02 0.00000E-00 0.00000E-00044 51 3RLDATALOGGER201207231411~D 2 3 0 0047 78 4DLDATALOGGER201207231411~1.0000E+02 1 0 0.0000E+00 0.0000E+00048 57 2GSGRGRA1HHZ2007262S~ 9.44020E+08 1.00000E+00 0048 54 5GLSZGRFDUMMYXXXX~ 1.00000E+00 0.00000E+00 0 000003S 050 117GRA1 49.691888 11.221720 499.5 Graefenberg Array Station Haidhof~ 13210101976,048,00:00:00.0000~~NGR052 125 HHZ 0 2~ 1 0 49.691888 11.221720 499.5 0.0 0.0-90.0 1121.0000E+021.0000E-02 ~2007,262,00:00:00.0000~~N060 37 2 1 2 1 2 2 3 3 4 5058 35 0 9.44020E+08 1.00000E+00 0 \ No newline at end of file diff --git a/tests/test_Metadata/metadata2/DATALESS.GR.GRA2..HHE b/tests/test_Metadata/metadata2/DATALESS.GR.GRA2..HHE new file mode 100644 index 00000000..9cddf024 --- /dev/null +++ b/tests/test_Metadata/metadata2/DATALESS.GR.GRA2..HHE @@ -0,0 +1 @@ +000001V 010 65 2.3122007,242,00:00:00.0000~~2018,144,14:14:36.1800~GFZ~~011 21 1GRA2 3 000002A 030 237Steim2 Integer Compression Format~ 1 5014F1 P4 W4 D C2 R1 P8 W4 D C2~P0 W4 N15 S2,0,1~T0 X W4~T1 Y4 W1 D C2~T2 W4 I D2~K0 X D30~K1 N0 D30 C2~K2 Y2 D15 C2~K3 Y3 D10 C2~T3 W4 I D2~K0 Y5 D6 C2~K1 Y6 D5 C2~K2 X D2 Y7 D4 C2~K3 X D30~033 56 1German Regional Seismic Network, BGR Hannover~033 15 2STS2~034 44 1M/S~Velocity in Meters per Second~034 18 2V~Volts~034 32 3COUNTS~Digital Counts~043 264 1RSSENSOR201207231411139~A 1 2 1.00000E+00 1.00000E+00 2 0.00000E+00 0.00000E+00 0.00000E-00 0.00000E-00 0.00000E+00 0.00000E+00 0.00000E-00 0.00000E-00 2-3.67429E-02 3.67540E-02 0.00000E-00 0.00000E-00-3.67429E-02-3.67540E-02 0.00000E-00 0.00000E-00044 51 3RLDATALOGGER201207231411~D 2 3 0 0047 78 4DLDATALOGGER201207231411~1.0000E+02 1 0 0.0000E+00 0.0000E+00048 57 2GSGRGRA2HHE2007242S~ 9.44020E+08 1.00000E+00 0048 54 5GLSZGRFDUMMYXXXX~ 1.00000E+00 0.00000E+00 0 000003S 050 120GRA2 49.655208 11.359444 512.0 Graefenberg Array Station Wildenfels~ 13210101976,048,00:00:00.0000~~NGR052 125 HHE 0 2~ 1 0 49.655208 11.359444 512.0 0.0 90.0 0.0 1121.0000E+021.0000E-02 ~2007,242,00:00:00.0000~~N060 37 2 1 2 1 2 2 3 3 4 5058 35 0 9.44020E+08 1.00000E+00 0 \ No newline at end of file diff --git a/tests/test_Metadata/metadata2/DATALESS.GR.GRA2..HHN b/tests/test_Metadata/metadata2/DATALESS.GR.GRA2..HHN new file mode 100644 index 00000000..64b7d929 --- /dev/null +++ b/tests/test_Metadata/metadata2/DATALESS.GR.GRA2..HHN @@ -0,0 +1 @@ +000001V 010 65 2.3122007,242,00:00:00.0000~~2018,144,14:14:38.5280~GFZ~~011 21 1GRA2 3 000002A 030 237Steim2 Integer Compression Format~ 1 5014F1 P4 W4 D C2 R1 P8 W4 D C2~P0 W4 N15 S2,0,1~T0 X W4~T1 Y4 W1 D C2~T2 W4 I D2~K0 X D30~K1 N0 D30 C2~K2 Y2 D15 C2~K3 Y3 D10 C2~T3 W4 I D2~K0 Y5 D6 C2~K1 Y6 D5 C2~K2 X D2 Y7 D4 C2~K3 X D30~033 56 1German Regional Seismic Network, BGR Hannover~033 15 2STS2~034 44 1M/S~Velocity in Meters per Second~034 18 2V~Volts~034 32 3COUNTS~Digital Counts~043 264 1RSSENSOR201207231411139~A 1 2 1.00000E+00 1.00000E+00 2 0.00000E+00 0.00000E+00 0.00000E-00 0.00000E-00 0.00000E+00 0.00000E+00 0.00000E-00 0.00000E-00 2-3.67429E-02 3.67540E-02 0.00000E-00 0.00000E-00-3.67429E-02-3.67540E-02 0.00000E-00 0.00000E-00044 51 3RLDATALOGGER201207231411~D 2 3 0 0047 78 4DLDATALOGGER201207231411~1.0000E+02 1 0 0.0000E+00 0.0000E+00048 57 2GSGRGRA2HHN2007242S~ 9.44020E+08 1.00000E+00 0048 54 5GLSZGRFDUMMYXXXX~ 1.00000E+00 0.00000E+00 0 000003S 050 120GRA2 49.655208 11.359444 512.0 Graefenberg Array Station Wildenfels~ 13210101976,048,00:00:00.0000~~NGR052 125 HHN 0 2~ 1 0 49.655208 11.359444 512.0 0.0 0.0 0.0 1121.0000E+021.0000E-02 ~2007,242,00:00:00.0000~~N060 37 2 1 2 1 2 2 3 3 4 5058 35 0 9.44020E+08 1.00000E+00 0 \ No newline at end of file diff --git a/tests/test_Metadata/metadata2/DATALESS.GR.GRA2..HHZ b/tests/test_Metadata/metadata2/DATALESS.GR.GRA2..HHZ new file mode 100644 index 00000000..669afa69 --- /dev/null +++ b/tests/test_Metadata/metadata2/DATALESS.GR.GRA2..HHZ @@ -0,0 +1 @@ +000001V 010 65 2.3122007,242,00:00:00.0000~~2018,144,14:14:39.0145~GFZ~~011 21 1GRA2 3 000002A 030 237Steim2 Integer Compression Format~ 1 5014F1 P4 W4 D C2 R1 P8 W4 D C2~P0 W4 N15 S2,0,1~T0 X W4~T1 Y4 W1 D C2~T2 W4 I D2~K0 X D30~K1 N0 D30 C2~K2 Y2 D15 C2~K3 Y3 D10 C2~T3 W4 I D2~K0 Y5 D6 C2~K1 Y6 D5 C2~K2 X D2 Y7 D4 C2~K3 X D30~033 56 1German Regional Seismic Network, BGR Hannover~033 15 2STS2~034 44 1M/S~Velocity in Meters per Second~034 18 2V~Volts~034 32 3COUNTS~Digital Counts~043 264 1RSSENSOR201207231411139~A 1 2 1.00000E+00 1.00000E+00 2 0.00000E+00 0.00000E+00 0.00000E-00 0.00000E-00 0.00000E+00 0.00000E+00 0.00000E-00 0.00000E-00 2-3.67429E-02 3.67540E-02 0.00000E-00 0.00000E-00-3.67429E-02-3.67540E-02 0.00000E-00 0.00000E-00044 51 3RLDATALOGGER201207231411~D 2 3 0 0047 78 4DLDATALOGGER201207231411~1.0000E+02 1 0 0.0000E+00 0.0000E+00048 57 2GSGRGRA2HHZ2007242S~ 9.44020E+08 1.00000E+00 0048 54 5GLSZGRFDUMMYXXXX~ 1.00000E+00 0.00000E+00 0 000003S 050 120GRA2 49.655208 11.359444 512.0 Graefenberg Array Station Wildenfels~ 13210101976,048,00:00:00.0000~~NGR052 125 HHZ 0 2~ 1 0 49.655208 11.359444 512.0 0.0 0.0-90.0 1121.0000E+021.0000E-02 ~2007,242,00:00:00.0000~~N060 37 2 1 2 1 2 2 3 3 4 5058 35 0 9.44020E+08 1.00000E+00 0 \ No newline at end of file diff --git a/tests/test_Metadata/test_Metadata.py b/tests/test_Metadata/test_Metadata.py new file mode 100644 index 00000000..244adbe2 --- /dev/null +++ b/tests/test_Metadata/test_Metadata.py @@ -0,0 +1,104 @@ +import unittest +import os + +from pylot.core.util.dataprocessing import Metadata + +class TestMetadata(unittest.TestCase): + + def setUp(self): + self.station_id = 'BW.WETR..HH' + metadata_folder = 'metadata1' + self.m = Metadata(metadata_folder) + + def test_get_coordinates_sucess(self): + expected = {'Z': {u'elevation': 607.0, u'longitude': 12.87571, u'local_depth': 0.0, u'azimuth': 0.0, u'latitude': 49.14502, u'dip': -90.0}, + 'E': {u'azimuth': 90.0, u'dip': 0.0, u'elevation': 607.0, u'latitude': 49.14502, u'local_depth': 0.0, u'longitude': 12.87571}, + 'N': {u'azimuth': 0.0, u'dip': 0.0, u'elevation': 607.0, u'latitude': 49.14502, u'local_depth': 0.0, u'longitude': 12.87571} + } + result = {} + for channel in ('Z', 'N', 'E'): + coords = self.m.get_coordinates(self.station_id+channel) + result[channel] = coords + self.assertDictEqual(result[channel], expected[channel]) + +class TestMetadataAdding(unittest.TestCase): + """Tests if adding files and directories to a metadata object works.""" + + def setUp(self): + self.station_id = 'BW.WETR..HH' + self.metadata_folders = ('metadata1', 'metadata2') + self.m = Metadata() + + def test_add_inventory_folder(self): + """Test if add_inventory adds the folder to the list of inventories""" + self.m.add_inventory(self.metadata_folders[0]) + # adding an inventory folder should append it to the list of inventories + self.assertDictEqual({}, self.m.inventory_files) + self.assertDictEqual({}, self.m.seed_ids) + self.assertEqual([self.metadata_folders[0]], self.m.inventories) + + def test_add_inventory_file(self): + """Test if add_inventory_file adds the folder containing the file to the list of inventories and + if the files is added to inventory_files""" + fpath = os.path.join(self.metadata_folders[0], 'DATALESS.BW.WETR..HHZ') + self.m.add_inventory_file(fpath) + # adding an inventory file should append its folder to the list of inventories and the file to the + self.assertEqual(['metadata1/DATALESS.BW.WETR..HHZ'], self.m.inventory_files.keys()) # does the filename exist in inventory files? + self.assertEqual(['data', 'invtype'], self.m.inventory_files['metadata1/DATALESS.BW.WETR..HHZ'].keys()) # is the required information attacht to the filename? + self.assertDictEqual({}, self.m.seed_ids) + self.assertEqual([self.metadata_folders[0]], self.m.inventories) + + def test_add_inventory_invalid_path(self): + """Test if adding an inventory that is not an existing directory fails with an exception""" + with self.assertRaises(Exception): + self.m.add_inventory('InvalidDirName') + self.assertEqual([], self.m.inventories) # inventory list should still be empty + + def test_add_inventory_file_invalid_path(self): + """Test if adding a inventory file with an invalid path fails with an exception""" + with self.assertRaises(Exception): + self.m.add_inventory_file('/invalid/file/name') + self.assertEqual([], self.m.inventories) # inventory list should still be empty + + +class TestMetadataRemoval(unittest.TestCase): + """Tests if removing files and directories to a metadata object works.""" + + def setUp(self): + self.station_id = 'BW.WETR..HH' + self.metadata_folders = ('metadata1', 'metadata2') + self.m = Metadata() + + def test_remove_all_inventories(self): + """Test if function remove_inventory cleans the Metadata object """ + # add multiple inventories + for folder in self.metadata_folders: + self.m.add_inventory(folder) + self.m.remove_all_inventories() + self.isEmpty(self.m) + + def test_remove_inventory(self): + """Test if remove_inventory removes single inventories""" + # add multiple inventories + for folder in self.metadata_folders: + self.m.add_inventory(folder) + self.m.remove_inventory(self.metadata_folders[0]) + self.assertNotIn(self.metadata_folders[0], self.m.inventories) + self.m.remove_inventory(self.metadata_folders[1]) + self.assertNotIn(self.metadata_folders[1], self.m.inventories) + self.isEmpty(self.m) + + def test_remove_inventory_not_in_inventory_list(self): + """Test if remove_inventory does not modify the metadata instance if the given inventory to remove does not + exist in the instance.""" + # add multiple inventories + self.m.add_inventory(self.metadata_folders[0]) + self.m.remove_inventory('metadata_not_existing') + self.assertIn(self.metadata_folders[0], self.m.inventories) + + def isEmpty(self, metadata): + """Asserts if the given metadata object is empty""" + self.assertDictEqual({}, metadata.inventory_files) + self.assertDictEqual({}, metadata.seed_ids) + self.assertEqual([], metadata.inventories) + From 0dc4d648269dd92d569eeb253f320a27b3e8f752 Mon Sep 17 00:00:00 2001 From: Darius Arnold Date: Tue, 10 Jul 2018 20:22:25 +0200 Subject: [PATCH 092/169] Rewrite check4rotated function to work with new Metadata class --- pylot/core/util/utils.py | 125 +++++++++++++-------------------------- 1 file changed, 41 insertions(+), 84 deletions(-) diff --git a/pylot/core/util/utils.py b/pylot/core/util/utils.py index a973f622..d5883153 100644 --- a/pylot/core/util/utils.py +++ b/pylot/core/util/utils.py @@ -926,7 +926,10 @@ def get_stations(data): def check4rotated(data, metadata=None, verbosity=1): """ - + Check all traces in data. If a trace is not in ZNE rotation (last symbol of channel code is numeric) and the trace + is in the metadata with azimuth and dip, rotate it to classical ZNE orientation. + Rotating the traces requires them to be of the same length, so, all traces will be trimmed to a common length as a + side effect. :param data: stream object containing seismic traces :type data: `~obspy.core.stream.Stream` :param metadata: tuple containing metadata type string and metadata parser object @@ -943,100 +946,54 @@ def check4rotated(data, metadata=None, verbosity=1): Azimut and dip are fetched from metadata. To be rotated, traces of a station have to be cut to the same length. Returns unrotated traces of no metadata is provided - :param wfstream: stream containing seismic traces + :param wfstream: stream containing seismic traces of a station :type wfstream: `~obspy.core.stream.Stream` :param metadata: tuple containing metadata type string and metadata parser object :type metadata: (str, `~obspy.io.xseed.parser.Parser`) :return: stream object with traditionally oriented traces (ZNE) :rtype: `~obspy.core.stream.Stream` """ - try: - # indexing fails if metadata is None - metadata[0] - except TypeError: - if verbosity: - msg = 'Warning: could not rotate traces since no metadata was given\nset Inventory file!' - print(msg) - return wfstream - if metadata[0] is None: - # sometimes metadata is (None, (None,)) - if verbosity: - msg = 'Warning: could not rotate traces since no metadata was given\nCheck inventory directory!' - print(msg) - return wfstream - else: - parser = metadata[1] - - def get_dip_azimut(parser, trace_id): - """ - Gets azimuth and dip by trace id out of the metadata parser - :param parser: metadata parser object - :type parser: `~obspy.io.xseed.parser.Parser` - :param trace_id: eg. 'BW.RJOB..EHZ', - :type trace_id: str - :return: tuple containing dip and azimuth of the trace corresponding to trace_id - :rtype: (float, float) - """ - dip = None - azimut = None - try: - blockettes = parser._select(trace_id) - except SEEDParserException as e: - print(e) - raise ValueError - for blockette_ in blockettes: - if blockette_.id != 52: - continue - dip = blockette_.dip - azimut = blockette_.azimuth - break - if (dip is None or azimut is None) or (dip == 0 and azimut == 0): - error_msg = 'Dip and azimuth not available for trace_id {}'.format(trace_id) - raise ValueError(error_msg) - return dip, azimut + # check if any traces in this station need to be rotated trace_ids = [trace.id for trace in wfstream] - for trace_id in trace_ids: - orientation = trace_id[-1] # last letter if trace id is orientation code, ZNE or 123 - if orientation.isnumeric(): - # misaligned channels have a number as orientation - azimuts = [] - dips = [] - for trace_id in trace_ids: - try: - dip, azimut = get_dip_azimut(parser, trace_id) - except ValueError as e: - print(e) - print('Failed to rotate station {}, no azimuth or dip available in metadata'.format(trace_id)) - return wfstream - azimuts.append(azimut) - dips.append(dip) - # to rotate all traces must have same length - wfstream = trim_station_components(wfstream, trim_start=True, trim_end=True) - z, n, e = rotate2zne(wfstream[0], azimuts[0], dips[0], - wfstream[1], azimuts[1], dips[1], - wfstream[2], azimuts[2], dips[2]) - print('check4rotated: rotated station {} to ZNE'.format(trace_id)) - z_index = dips.index(min(dips)) # get z-trace index (dip is measured from 0 to -90) - wfstream[z_index].data = z - wfstream[z_index].stats.channel = wfstream[z_index].stats.channel[0:-1] + 'Z' - del trace_ids[z_index] - for trace_id in trace_ids: - dip, az = get_dip_azimut(parser, trace_id) - trace = wfstream.select(id=trace_id)[0] - if az > 315 and az <= 45 or az > 135 and az <= 225: - trace.data = n - trace.stats.channel = trace.stats.channel[0:-1] + 'N' - elif az > 45 and az <= 135 or az > 225 and az <= 315: - trace.data = e - trace.stats.channel = trace.stats.channel[0:-1] + 'E' - break - else: - continue + orientations = [trace_id[-1] for trace_id in trace_ids] + rotation_required = [orientation.isnumeric() for orientation in orientations] + if any(rotation_required): + try: + azimuts = [metadata.get_coordinates(tr_id)['azimuth'] for tr_id in trace_ids] + dips = [metadata.get_coordinates(tr_id)['dip'] for tr_id in trace_ids] + except (KeyError, TypeError) as e: + print('Failed to rotate trace {}, no azimuth or dip available in metadata'.format(trace_id)) + return wfstream + # to rotate all traces must have same length, so trim them + wfstream = trim_station_components(wfstream, trim_start=True, trim_end=True) + z, n, e = rotate2zne(wfstream[0], azimuts[0], dips[0], + wfstream[1], azimuts[1], dips[1], + wfstream[2], azimuts[2], dips[2]) + print('check4rotated: rotated trace {} to ZNE'.format(trace_id)) + # replace old data with rotated data, change the channel code to ZNE + z_index = dips.index(min(dips)) # get z-trace index, z has minimum dip of -90 (dip is measured from 0 to -90, with -90 being vertical) + wfstream[z_index].data = z + wfstream[z_index].stats.channel = wfstream[z_index].stats.channel[0:-1] + 'Z' + del trace_ids[z_index] + for trace_id in trace_ids: + coordinates = metadata.get_coordinates(trace_id) + dip, az = coordinates['dip'], coordinates['azimuth'] + trace = wfstream.select(id=trace_id)[0] + if az > 315 or az <= 45 or az > 135 and az <= 225: + trace.data = n + trace.stats.channel = trace.stats.channel[0:-1] + 'N' + elif az > 45 and az <= 135 or az > 225 and az <= 315: + trace.data = e + trace.stats.channel = trace.stats.channel[0:-1] + 'E' return wfstream + if metadata is None: + if verbosity: + msg = 'Warning: could not rotate traces since no metadata was given\nset Inventory file!' + print(msg) + return data stations = get_stations(data) - for station in stations: # loop through all stations and rotate data if neccessary wf_station = data.select(station=station) rotate_components(wf_station, metadata) From 82ac08157c081e2219d9e31a28d14f246c9d0a06 Mon Sep 17 00:00:00 2001 From: Darius Arnold Date: Tue, 10 Jul 2018 21:41:07 +0200 Subject: [PATCH 093/169] =?UTF-8?q?[bugfix]=20azimuth=20<45=C2=B0=20was=20?= =?UTF-8?q?misattributed=20as=20E=20instead=20of=20N=20trace=20in=20check4?= =?UTF-8?q?rotated?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pylot/core/util/utils.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pylot/core/util/utils.py b/pylot/core/util/utils.py index a973f622..06388a0d 100644 --- a/pylot/core/util/utils.py +++ b/pylot/core/util/utils.py @@ -1024,7 +1024,7 @@ def check4rotated(data, metadata=None, verbosity=1): for trace_id in trace_ids: dip, az = get_dip_azimut(parser, trace_id) trace = wfstream.select(id=trace_id)[0] - if az > 315 and az <= 45 or az > 135 and az <= 225: + if az > 315 or az <= 45 or az > 135 and az <= 225: trace.data = n trace.stats.channel = trace.stats.channel[0:-1] + 'N' elif az > 45 and az <= 135 or az > 225 and az <= 315: From 91959367d43508f4503b745f89e9b4f22cd64d6f Mon Sep 17 00:00:00 2001 From: Marcel Date: Wed, 11 Jul 2018 09:41:58 +0200 Subject: [PATCH 094/169] [minor] set DATASTRUCTURE correctly --- PyLoT.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/PyLoT.py b/PyLoT.py index 9d3ac38f..8fa43a6f 100755 --- a/PyLoT.py +++ b/PyLoT.py @@ -1061,9 +1061,12 @@ class MainWindow(QMainWindow): eventlist = ed.selectedFiles() basepath = eventlist[0].split(os.path.basename(eventlist[0]))[0] if check_obspydmt_structure(basepath): - print('Recognized obspyDMT structure in selected files.') + print('Recognized obspyDMT structure in selected files. Settings Datastructure to ObspyDMT') + self.dataStructure = DATASTRUCTURE['obspyDMT']() eventlist = check_all_obspy(eventlist) else: + print('Settings Datastructure to PILOT') + self.dataStructure = DATASTRUCTURE['PILOT']() eventlist = check_all_pylot(eventlist) if not eventlist: print('No events found! Expected structure for event folders: [eEVID.DOY.YR],\n' From a0fcf03c1eb0ce22560bfa0c8b9610b1ec70e715 Mon Sep 17 00:00:00 2001 From: Marcel Date: Wed, 11 Jul 2018 09:42:28 +0200 Subject: [PATCH 095/169] [update] add try/except to autopickstation call --- pylot/core/pick/autopick.py | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/pylot/core/pick/autopick.py b/pylot/core/pick/autopick.py index 76985aed..c68afcc0 100644 --- a/pylot/core/pick/autopick.py +++ b/pylot/core/pick/autopick.py @@ -93,7 +93,9 @@ def autopickevent(data, param, iplot=0, fig_dict=None, fig_dict_wadatijack=None, pool.close() for pick in result: - if pick: + if type(pick) == BaseException: + print(pick) + elif pick: station = pick['station'] pick.pop('station') all_onsets[station] = pick @@ -116,7 +118,10 @@ def call_autopickstation(input_tuple): """ wfstream, pickparam, verbose, metadata, origin = input_tuple # multiprocessing not possible with interactive plotting - return autopickstation(wfstream, pickparam, verbose, iplot=0, metadata=metadata, origin=origin) + try: + return autopickstation(wfstream, pickparam, verbose, iplot=0, metadata=metadata, origin=origin) + except Exception as e: + return e def get_source_coords(parser, station_id): From c3e8b2c03dd6f1735e34d684efca67ccb43fff97 Mon Sep 17 00:00:00 2001 From: Marcel Date: Wed, 11 Jul 2018 14:01:47 +0200 Subject: [PATCH 096/169] /metadata_class: Auto stash before merge of "feature/metadata_class" and "develop" --- autopylot.sh | 1 + pylot/core/pick/autopick.py | 30 +++++++++++++++++++++--------- 2 files changed, 22 insertions(+), 9 deletions(-) create mode 100644 autopylot.sh diff --git a/autopylot.sh b/autopylot.sh new file mode 100644 index 00000000..727e8c93 --- /dev/null +++ b/autopylot.sh @@ -0,0 +1 @@ +python ./autoPyLoT.py -i /home/marcel/.pylot/pylot_global.in -dmt processed -c 80 diff --git a/pylot/core/pick/autopick.py b/pylot/core/pick/autopick.py index c68afcc0..e2928b59 100644 --- a/pylot/core/pick/autopick.py +++ b/pylot/core/pick/autopick.py @@ -92,13 +92,25 @@ def autopickevent(data, param, iplot=0, fig_dict=None, fig_dict_wadatijack=None, result = pool.map(call_autopickstation, input_tuples) pool.close() - for pick in result: - if type(pick) == BaseException: - print(pick) - elif pick: - station = pick['station'] - pick.pop('station') - all_onsets[station] = pick + if ncores == 1: + results = serial_picking(input_tuples) + else: + results = parallel_picking(input_tuples, ncores) + + + for result, wfstream in results: + if type(result) == dict: + station = result['station'] + result.pop('station') + all_onsets[station] = result + else: + if result == None: + result = 'Picker exited unexpectedly.' + if len(wfstream) > 0: + station = wfstream[0].stats.station + else: + station = None + print('Could not pick a station: {}\nReason: {}'.format(station, result)) # quality control # median check and jackknife on P-onset times @@ -119,9 +131,9 @@ def call_autopickstation(input_tuple): wfstream, pickparam, verbose, metadata, origin = input_tuple # multiprocessing not possible with interactive plotting try: - return autopickstation(wfstream, pickparam, verbose, iplot=0, metadata=metadata, origin=origin) + return autopickstation(wfstream, pickparam, verbose, iplot=0, metadata=metadata, origin=origin), wfstream except Exception as e: - return e + return e, wfstream def get_source_coords(parser, station_id): From 27ea20fa47724ab163c87b85ae14e6b8cd7d161c Mon Sep 17 00:00:00 2001 From: Marcel Date: Thu, 12 Jul 2018 09:40:57 +0200 Subject: [PATCH 097/169] [bugfix] NLLoc: take nlloc bin explicitly from PylotParameter and not (randomly) from default pylot.in file!! --- autoPyLoT.py | 4 ++-- pylot/core/loc/nll.py | 7 ++----- pylot/core/util/utils.py | 15 ++++----------- 3 files changed, 8 insertions(+), 18 deletions(-) diff --git a/autoPyLoT.py b/autoPyLoT.py index 5db95399..fc1489ce 100755 --- a/autoPyLoT.py +++ b/autoPyLoT.py @@ -314,7 +314,7 @@ def autoPyLoT(input_dict=None, parameter=None, inputfile=None, fnames=None, even ttpat) # locate the event - nll.locate(ctrfile, inputfile) + nll.locate(ctrfile, parameter) # !iterative picking if traces remained unpicked or occupied with bad picks! # get theoretical onset times for picks with weights >= 4 @@ -402,7 +402,7 @@ def autoPyLoT(input_dict=None, parameter=None, inputfile=None, fnames=None, even # remove actual NLLoc-location file to keep only the last os.remove(nllocfile) # locate the event - nll.locate(ctrfile, inputfile) + nll.locate(ctrfile, parameter) print("autoPyLoT: Iteration No. %d finished." % nlloccounter) # get updated NLLoc-location file nllocfile = max(glob.glob(locsearch), key=os.path.getctime) diff --git a/pylot/core/loc/nll.py b/pylot/core/loc/nll.py index 4788894a..94986ed1 100644 --- a/pylot/core/loc/nll.py +++ b/pylot/core/loc/nll.py @@ -73,17 +73,14 @@ def modify_inputs(ctrfn, root, nllocoutn, phasefn, tttn): nllfile.close() -def locate(fnin, infile=None): +def locate(fnin, parameter=None): """ takes an external program name and tries to run it :param fnin: external program name :return: None """ - if infile is None: - exe_path = which('NLLoc') - else: - exe_path = which('NLLoc', infile) + exe_path = which('NLLoc', parameter) if exe_path is None: raise NLLocError('NonLinLoc executable not found; check your ' 'environment variables') diff --git a/pylot/core/util/utils.py b/pylot/core/util/utils.py index 06388a0d..2ff9e5e9 100644 --- a/pylot/core/util/utils.py +++ b/pylot/core/util/utils.py @@ -1094,7 +1094,7 @@ def runProgram(cmd, parameter=None): subprocess.check_output('{} | tee /dev/stderr'.format(cmd), shell=True) -def which(program, infile=None): +def which(program, parameter): """ takes a program name and returns the full path to the executable or None modified after: http://stackoverflow.com/questions/377017/test-if-executable-exists-in-python @@ -1109,16 +1109,9 @@ def which(program, infile=None): for key in settings.allKeys(): if 'binPath' in key: os.environ['PATH'] += ':{0}'.format(settings.value(key)) - if infile is None: - # use default parameter-file name - bpath = os.path.join(os.path.expanduser('~'), '.pylot', 'pylot.in') - else: - bpath = os.path.join(os.path.expanduser('~'), '.pylot', infile) - - if os.path.exists(bpath): - nllocpath = ":" + PylotParameter(bpath).get('nllocbin') - os.environ['PATH'] += nllocpath - except ImportError as e: + nllocpath = ":" + parameter.get('nllocbin') + os.environ['PATH'] += nllocpath + except Exception as e: print(e.message) def is_exe(fpath): From 6c162fc94a51dd62a791f808b900124b0996fd8a Mon Sep 17 00:00:00 2001 From: Marcel Date: Tue, 10 Jul 2018 11:35:13 +0200 Subject: [PATCH 098/169] [new] first use of Metadata class in autoPyLoT, largely increasing read performance using obspyDMT (single DATALESS-Seed files) --- autoPyLoT.py | 18 +++++++---- pylot/core/pick/autopick.py | 25 ++++++++++----- pylot/core/pick/picker.py | 51 ++++++++++++++++++++++--------- pylot/core/util/dataprocessing.py | 24 ++++++++++----- 4 files changed, 83 insertions(+), 35 deletions(-) diff --git a/autoPyLoT.py b/autoPyLoT.py index fc1489ce..bb90abc2 100755 --- a/autoPyLoT.py +++ b/autoPyLoT.py @@ -22,7 +22,7 @@ from pylot.core.analysis.magnitude import MomentMagnitude, LocalMagnitude from pylot.core.io.data import Data from pylot.core.io.inputs import PylotParameter from pylot.core.pick.autopick import autopickevent, iteratepicker -from pylot.core.util.dataprocessing import restitute_data, read_metadata +from pylot.core.util.dataprocessing import restitute_data, read_metadata, Metadata from pylot.core.util.defaults import SEPARATOR from pylot.core.util.event import Event from pylot.core.util.structure import DATASTRUCTURE @@ -276,7 +276,11 @@ def autoPyLoT(input_dict=None, parameter=None, inputfile=None, fnames=None, even wfdat = check4gaps(wfdat) wfdat = check4doubled(wfdat) wfdat = trim_station_components(wfdat, trim_start=True, trim_end=False) - metadata = read_metadata(parameter.get('invdir')) + if not wfpath_extension: + metadata = Metadata(parameter.get('invdir')) + else: + metadata = Metadata(os.path.join(eventpath, 'resp')) + # metadata = read_metadata(parameter.get('invdir')) # TODO: (idea) read metadata from obspy_dmt database # if not wfpath_extension: # metadata = read_metadata(parameter.get('invdir')) @@ -285,10 +289,10 @@ def autoPyLoT(input_dict=None, parameter=None, inputfile=None, fnames=None, even corr_dat = None if metadata: # rotate stations to ZNE - wfdat = check4rotated(wfdat, metadata) + #wfdat = check4rotated(wfdat, metadata) # MP MP TEMPORARILY DISABLED !!!!!!!!!!! if locflag: print("Restitute data ...") - corr_dat = restitute_data(wfdat.copy(), *metadata, ncores=ncores) + corr_dat = restitute_data(wfdat.copy(), metadata, ncores=ncores) if not corr_dat and locflag: locflag = 2 print('Working on event %s. Stations: %s' % (eventpath, station)) @@ -363,7 +367,8 @@ def autoPyLoT(input_dict=None, parameter=None, inputfile=None, fnames=None, even WAscaling[2])) evt = local_mag.updated_event(magscaling) net_ml = local_mag.net_magnitude(magscaling) - print("Network local magnitude: %4.1f" % net_ml.mag) + if net_ml: + print("Network local magnitude: %4.1f" % net_ml.mag) if magscaling == None: scaling = False elif magscaling[0] != 0 and magscaling[1] != 0: @@ -447,7 +452,8 @@ def autoPyLoT(input_dict=None, parameter=None, inputfile=None, fnames=None, even WAscaling[2])) evt = local_mag.updated_event(magscaling) net_ml = local_mag.net_magnitude(magscaling) - print("Network local magnitude: %4.1f" % net_ml.mag) + if net_ml: + print("Network local magnitude: %4.1f" % net_ml.mag) if magscaling == None: scaling = False elif magscaling[0] != 0 and magscaling[1] != 0: diff --git a/pylot/core/pick/autopick.py b/pylot/core/pick/autopick.py index e2928b59..ec6d3760 100644 --- a/pylot/core/pick/autopick.py +++ b/pylot/core/pick/autopick.py @@ -88,9 +88,9 @@ def autopickevent(data, param, iplot=0, fig_dict=None, fig_dict_wadatijack=None, print('Autopickstation: Distribute autopicking for {} ' 'stations on {} cores.'.format(len(input_tuples), ncores_str)) - pool = gen_Pool(ncores) - result = pool.map(call_autopickstation, input_tuples) - pool.close() + + result = parallel_picking(input_tuples, ncores) + #result = serial_picking(input_tuples) if ncores == 1: results = serial_picking(input_tuples) @@ -120,6 +120,20 @@ def autopickevent(data, param, iplot=0, fig_dict=None, fig_dict_wadatijack=None, return wadationsets +def serial_picking(input_tuples): + result = [] + for input_tuple in input_tuples: + result.append(call_autopickstation(input_tuple)) + return result + + +def parallel_picking(input_tuples, ncores): + pool = gen_Pool(ncores) + result = pool.imap_unordered(call_autopickstation, input_tuples) + pool.close() + return result + + def call_autopickstation(input_tuple): """ helper function used for multiprocessing @@ -303,13 +317,10 @@ def autopickstation(wfstream, pickparam, verbose=False, Lc = np.inf print('autopickstation: use_taup flag active.') if not metadata: - metadata = [None, None] - if not metadata[1]: print('Warning: Could not use TauPy to estimate onsets as there are no metadata given.') else: station_id = wfstream[0].get_id() - parser = metadata[1] - station_coords = get_source_coords(parser, station_id) + station_coords = metadata.get_coordinates(station_id) if station_coords and origin: source_origin = origin[0] model = TauPyModel(taup_model) diff --git a/pylot/core/pick/picker.py b/pylot/core/pick/picker.py index 57934e44..748dce99 100644 --- a/pylot/core/pick/picker.py +++ b/pylot/core/pick/picker.py @@ -191,9 +191,24 @@ class AICPicker(AutoPicker): # remove offset in AIC function offset = abs(min(aic) - min(aicsmooth)) aicsmooth = aicsmooth - offset + cf = self.Data[0].data # get maximum of HOS/AR-CF as startimg point for searching # minimum in AIC function - icfmax = np.argmax(self.Data[0].data) + icfmax = np.argmax(cf) + + # MP MP testing threshold + thresh_hit = False + thresh_factor = 0.6 + thresh = thresh_factor * cf[icfmax] + for index, sample in enumerate(cf): + if sample >= thresh: + thresh_hit = True + # go on searching for the following maximum + if index > 0 and thresh_hit: + if sample <= cf[index - 1]: + icfmax = index - 1 + break + # MP MP --- # find minimum in AIC-CF front of maximum of HOS/AR-CF lpickwindow = int(round(self.PickWindow / self.dt)) @@ -233,14 +248,14 @@ class AICPicker(AutoPicker): ii = min([isignal[len(isignal) - 1], len(self.Tcf)]) isignal = isignal[0:ii] try: - self.Data[0].data[isignal] + cf[isignal] except IndexError as e: msg = "Time series out of bounds! {}".format(e) print(msg) return # calculate SNR from CF - self.SNR = max(abs(self.Data[0].data[isignal])) / \ - abs(np.mean(self.Data[0].data[inoise])) + self.SNR = max(abs(cf[isignal])) / \ + abs(np.mean(cf[inoise])) # calculate slope from CF after initial pick # get slope window tslope = self.TSNR[3] # slope determination window @@ -253,7 +268,7 @@ class AICPicker(AutoPicker): # find maximum within slope determination window # 'cause slope should be calculated up to first local minimum only! try: - dataslope = self.Data[0].data[islope[0][0:-1]] + dataslope = cf[islope[0][0:-1]] except IndexError: print("Slope Calculation: empty array islope, check signal window") return @@ -282,8 +297,8 @@ class AICPicker(AutoPicker): else: fig = self.fig ax = fig.add_subplot(111) - x = self.Data[0].data - ax.plot(self.Tcf, x / max(x), color=self._linecolor, linewidth=0.7, label='(HOS-/AR-) Data') + cf = cf + ax.plot(self.Tcf, cf / max(cf), color=self._linecolor, linewidth=0.7, label='(HOS-/AR-) Data') ax.plot(self.Tcf, aicsmooth / max(aicsmooth), 'r', label='Smoothed AIC-CF') ax.legend(loc=1) ax.set_xlabel('Time [s] since %s' % self.Data[0].stats.starttime) @@ -296,7 +311,16 @@ class AICPicker(AutoPicker): plt.close(fig) return iislope = islope[0][0:imax+1] - dataslope = self.Data[0].data[iislope] + # MP MP change slope calculation + # get all maxima of aicsmooth + iaicmaxima = argrelmax(aicsmooth)[0] + # get first index of maximum after pickindex (indices saved in iaicmaxima) + aicmax = iaicmaxima[np.where(iaicmaxima > pickindex)[0]] + if len(aicmax) > 0: + iaicmax = aicmax[0] + else: + iaicmax = -1 + dataslope = aicsmooth[pickindex : iaicmax] # calculate slope as polynomal fit of order 1 xslope = np.arange(0, len(dataslope), 1) P = np.polyfit(xslope, dataslope, 1) @@ -306,7 +330,7 @@ class AICPicker(AutoPicker): else: self.slope = 1 / (len(dataslope) * self.Data[0].stats.delta) * (datafit[-1] - datafit[0]) # normalize slope to maximum of cf to make it unit independent - self.slope /= self.Data[0].data[icfmax] + self.slope /= aicsmooth[iaicmax] else: self.SNR = None @@ -320,10 +344,9 @@ class AICPicker(AutoPicker): fig = self.fig fig._tight = True ax1 = fig.add_subplot(211) - x = self.Data[0].data - if len(self.Tcf) > len(self.Data[0].data): # why? LK + if len(self.Tcf) > len(cf): # why? LK self.Tcf = self.Tcf[0:len(self.Tcf)-1] - ax1.plot(self.Tcf, x / max(x), color=self._linecolor, linewidth=0.7, label='(HOS-/AR-) Data') + ax1.plot(self.Tcf, cf / max(cf), color=self._linecolor, linewidth=0.7, label='(HOS-/AR-) Data') ax1.plot(self.Tcf, aicsmooth / max(aicsmooth), 'r', label='Smoothed AIC-CF') if self.Pick is not None: ax1.plot([self.Pick, self.Pick], [-0.1, 0.5], 'b', linewidth=2, label='AIC-Pick') @@ -333,7 +356,7 @@ class AICPicker(AutoPicker): if self.Pick is not None: ax2 = fig.add_subplot(2, 1, 2, sharex=ax1) - ax2.plot(self.Tcf, x, color=self._linecolor, linewidth=0.7, label='Data') + ax2.plot(self.Tcf, aicsmooth, color='r', linewidth=0.7, label='Data') ax1.axvspan(self.Tcf[inoise[0]], self.Tcf[inoise[-1]], color='y', alpha=0.2, lw=0, label='Noise Window') ax1.axvspan(self.Tcf[isignal[0]], self.Tcf[isignal[-1]], color='b', alpha=0.2, lw=0, label='Signal Window') @@ -345,7 +368,7 @@ class AICPicker(AutoPicker): label='Signal Window') ax2.axvspan(self.Tcf[iislope[0]], self.Tcf[iislope[-1]], color='g', alpha=0.2, lw=0, label='Slope Window') - ax2.plot(self.Tcf[iislope], datafit, 'g', linewidth=2, label='Slope') + ax2.plot(self.Tcf[pickindex : iaicmax], datafit, 'g', linewidth=2, label='Slope') # MP MP changed temporarily! if self.slope is not None: ax1.set_title('Station %s, SNR=%7.2f, Slope= %12.2f counts/s' % (self.Data[0].stats.station, diff --git a/pylot/core/util/dataprocessing.py b/pylot/core/util/dataprocessing.py index 8366d134..f98d99a2 100644 --- a/pylot/core/util/dataprocessing.py +++ b/pylot/core/util/dataprocessing.py @@ -100,12 +100,13 @@ class Metadata(object): if not seed_id in self.seed_ids.keys(): print('No data found for seed id {}. Trying to find it in all known inventories...'.format(seed_id)) self.read_all() - for inv_fname, metadata in self.inventory_files.items(): + for inv_fname, metadata_dict in self.inventory_files.items(): # use get_coordinates to check for seed_id try: - metadata['data'].get_coordinates(seed_id) + metadata_dict['data'].get_coordinates(seed_id) self.seed_ids[seed_id] = inv_fname - return metadata + print('Found metadata for station {}!'.format(seed_id)) + return metadata_dict except Exception as e: continue print('Could not find metadata for station {}'.format(seed_id)) @@ -127,6 +128,7 @@ class Metadata(object): def read_single_file(self, inv_fname): + # try to read a single file as Parser/Inventory if it was not already read before if not inv_fname in self.inventory_files.keys(): pass else: @@ -460,6 +462,11 @@ def read_metadata(path_to_inventory): def restitute_trace(input_tuple): + def no_metadata(tr, seed_id): + print('no metadata file found ' + 'for trace {0}'.format(seed_id)) + return tr, True + tr, metadata, unit, force = input_tuple remove_trace = False @@ -467,6 +474,9 @@ def restitute_trace(input_tuple): seed_id = tr.get_id() mdata = metadata.get_metadata(seed_id) + if not mdata: + return no_metadata(tr, seed_id) + invtype = mdata['invtype'] inobj = mdata['data'] @@ -481,8 +491,7 @@ def restitute_trace(input_tuple): if invtype == 'resp': fresp = find_in_list(inobj, seed_id) if not fresp: - raise IOError('no response file found ' - 'for trace {0}'.format(seed_id)) + return no_metadata(tr, seed_id) fname = fresp seedresp = dict(filename=fname, date=stime, @@ -505,8 +514,7 @@ def restitute_trace(input_tuple): finv = invlist[0] inventory = read_inventory(finv, format='STATIONXML') elif invtype == None: - print("No restitution possible, as there are no station-meta data available!") - return tr, True + return no_metadata(tr, seed_id) else: remove_trace = True # apply restitution to data @@ -562,7 +570,7 @@ def restitute_data(data, metadata, unit='VEL', force=False, ncores=0): data.remove(tr) pool = gen_Pool(ncores) - result = pool.map(restitute_trace, input_tuples) + result = pool.imap_unordered(restitute_trace, input_tuples) pool.close() for tr, remove_trace in result: From 869ede96a911cc927fa4044db23493c8afe61143 Mon Sep 17 00:00:00 2001 From: Darius Arnold Date: Tue, 10 Jul 2018 20:22:25 +0200 Subject: [PATCH 099/169] Rewrite check4rotated function to work with new Metadata class --- pylot/core/util/utils.py | 125 +++++++++++++-------------------------- 1 file changed, 41 insertions(+), 84 deletions(-) diff --git a/pylot/core/util/utils.py b/pylot/core/util/utils.py index 2ff9e5e9..a4269c83 100644 --- a/pylot/core/util/utils.py +++ b/pylot/core/util/utils.py @@ -926,7 +926,10 @@ def get_stations(data): def check4rotated(data, metadata=None, verbosity=1): """ - + Check all traces in data. If a trace is not in ZNE rotation (last symbol of channel code is numeric) and the trace + is in the metadata with azimuth and dip, rotate it to classical ZNE orientation. + Rotating the traces requires them to be of the same length, so, all traces will be trimmed to a common length as a + side effect. :param data: stream object containing seismic traces :type data: `~obspy.core.stream.Stream` :param metadata: tuple containing metadata type string and metadata parser object @@ -943,100 +946,54 @@ def check4rotated(data, metadata=None, verbosity=1): Azimut and dip are fetched from metadata. To be rotated, traces of a station have to be cut to the same length. Returns unrotated traces of no metadata is provided - :param wfstream: stream containing seismic traces + :param wfstream: stream containing seismic traces of a station :type wfstream: `~obspy.core.stream.Stream` :param metadata: tuple containing metadata type string and metadata parser object :type metadata: (str, `~obspy.io.xseed.parser.Parser`) :return: stream object with traditionally oriented traces (ZNE) :rtype: `~obspy.core.stream.Stream` """ - try: - # indexing fails if metadata is None - metadata[0] - except TypeError: - if verbosity: - msg = 'Warning: could not rotate traces since no metadata was given\nset Inventory file!' - print(msg) - return wfstream - if metadata[0] is None: - # sometimes metadata is (None, (None,)) - if verbosity: - msg = 'Warning: could not rotate traces since no metadata was given\nCheck inventory directory!' - print(msg) - return wfstream - else: - parser = metadata[1] - - def get_dip_azimut(parser, trace_id): - """ - Gets azimuth and dip by trace id out of the metadata parser - :param parser: metadata parser object - :type parser: `~obspy.io.xseed.parser.Parser` - :param trace_id: eg. 'BW.RJOB..EHZ', - :type trace_id: str - :return: tuple containing dip and azimuth of the trace corresponding to trace_id - :rtype: (float, float) - """ - dip = None - azimut = None - try: - blockettes = parser._select(trace_id) - except SEEDParserException as e: - print(e) - raise ValueError - for blockette_ in blockettes: - if blockette_.id != 52: - continue - dip = blockette_.dip - azimut = blockette_.azimuth - break - if (dip is None or azimut is None) or (dip == 0 and azimut == 0): - error_msg = 'Dip and azimuth not available for trace_id {}'.format(trace_id) - raise ValueError(error_msg) - return dip, azimut + # check if any traces in this station need to be rotated trace_ids = [trace.id for trace in wfstream] - for trace_id in trace_ids: - orientation = trace_id[-1] # last letter if trace id is orientation code, ZNE or 123 - if orientation.isnumeric(): - # misaligned channels have a number as orientation - azimuts = [] - dips = [] - for trace_id in trace_ids: - try: - dip, azimut = get_dip_azimut(parser, trace_id) - except ValueError as e: - print(e) - print('Failed to rotate station {}, no azimuth or dip available in metadata'.format(trace_id)) - return wfstream - azimuts.append(azimut) - dips.append(dip) - # to rotate all traces must have same length - wfstream = trim_station_components(wfstream, trim_start=True, trim_end=True) - z, n, e = rotate2zne(wfstream[0], azimuts[0], dips[0], - wfstream[1], azimuts[1], dips[1], - wfstream[2], azimuts[2], dips[2]) - print('check4rotated: rotated station {} to ZNE'.format(trace_id)) - z_index = dips.index(min(dips)) # get z-trace index (dip is measured from 0 to -90) - wfstream[z_index].data = z - wfstream[z_index].stats.channel = wfstream[z_index].stats.channel[0:-1] + 'Z' - del trace_ids[z_index] - for trace_id in trace_ids: - dip, az = get_dip_azimut(parser, trace_id) - trace = wfstream.select(id=trace_id)[0] - if az > 315 or az <= 45 or az > 135 and az <= 225: - trace.data = n - trace.stats.channel = trace.stats.channel[0:-1] + 'N' - elif az > 45 and az <= 135 or az > 225 and az <= 315: - trace.data = e - trace.stats.channel = trace.stats.channel[0:-1] + 'E' - break - else: - continue + orientations = [trace_id[-1] for trace_id in trace_ids] + rotation_required = [orientation.isnumeric() for orientation in orientations] + if any(rotation_required): + try: + azimuts = [metadata.get_coordinates(tr_id)['azimuth'] for tr_id in trace_ids] + dips = [metadata.get_coordinates(tr_id)['dip'] for tr_id in trace_ids] + except (KeyError, TypeError) as e: + print('Failed to rotate trace {}, no azimuth or dip available in metadata'.format(trace_id)) + return wfstream + # to rotate all traces must have same length, so trim them + wfstream = trim_station_components(wfstream, trim_start=True, trim_end=True) + z, n, e = rotate2zne(wfstream[0], azimuts[0], dips[0], + wfstream[1], azimuts[1], dips[1], + wfstream[2], azimuts[2], dips[2]) + print('check4rotated: rotated trace {} to ZNE'.format(trace_id)) + # replace old data with rotated data, change the channel code to ZNE + z_index = dips.index(min(dips)) # get z-trace index, z has minimum dip of -90 (dip is measured from 0 to -90, with -90 being vertical) + wfstream[z_index].data = z + wfstream[z_index].stats.channel = wfstream[z_index].stats.channel[0:-1] + 'Z' + del trace_ids[z_index] + for trace_id in trace_ids: + coordinates = metadata.get_coordinates(trace_id) + dip, az = coordinates['dip'], coordinates['azimuth'] + trace = wfstream.select(id=trace_id)[0] + if az > 315 or az <= 45 or az > 135 and az <= 225: + trace.data = n + trace.stats.channel = trace.stats.channel[0:-1] + 'N' + elif az > 45 and az <= 135 or az > 225 and az <= 315: + trace.data = e + trace.stats.channel = trace.stats.channel[0:-1] + 'E' return wfstream + if metadata is None: + if verbosity: + msg = 'Warning: could not rotate traces since no metadata was given\nset Inventory file!' + print(msg) + return data stations = get_stations(data) - for station in stations: # loop through all stations and rotate data if neccessary wf_station = data.select(station=station) rotate_components(wf_station, metadata) From 704a45f8453e2e324d7555d56a56a3d993e91e4e Mon Sep 17 00:00:00 2001 From: Marcel Date: Thu, 12 Jul 2018 09:33:52 +0200 Subject: [PATCH 100/169] [minor] changes/testing threshfactor --- PyLoT.py | 3 ++- pylot/core/pick/picker.py | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/PyLoT.py b/PyLoT.py index 8fa43a6f..fdb41991 100755 --- a/PyLoT.py +++ b/PyLoT.py @@ -339,7 +339,7 @@ class MainWindow(QMainWindow): "Ctrl+A", openEventsIcon, "Load event data automatically " - "for for all events.") + "for all events.") self.openEventsAutoAction.setEnabled(False) self.openEventsAutoAction.setData(None) @@ -900,6 +900,7 @@ class MainWindow(QMainWindow): return if self.get_current_event().pylot_picks: self.refreshEvents() + self.fill_eventbox() self.setDirty(True) def load_data(self, fname=None, loc=False, draw=True, event=None, overwrite=False): diff --git a/pylot/core/pick/picker.py b/pylot/core/pick/picker.py index 748dce99..952c47db 100644 --- a/pylot/core/pick/picker.py +++ b/pylot/core/pick/picker.py @@ -198,7 +198,7 @@ class AICPicker(AutoPicker): # MP MP testing threshold thresh_hit = False - thresh_factor = 0.6 + thresh_factor = 0.7 thresh = thresh_factor * cf[icfmax] for index, sample in enumerate(cf): if sample >= thresh: From 3bd5243f2a27f405726feb247ae1f713a3482216 Mon Sep 17 00:00:00 2001 From: Marcel Date: Thu, 12 Jul 2018 10:04:35 +0200 Subject: [PATCH 101/169] [minor] typo --- pylot/core/pick/autopick.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pylot/core/pick/autopick.py b/pylot/core/pick/autopick.py index ec6d3760..b11c3662 100644 --- a/pylot/core/pick/autopick.py +++ b/pylot/core/pick/autopick.py @@ -594,7 +594,7 @@ def autopickstation(wfstream, pickparam, verbose=False, SNRPdB, FM) print(msg) - msg = 'autopickstation: Refind P-Pick: {} s | P-Error: {} s'.format(zdat[0].stats.starttime \ + msg = 'autopickstation: Refined P-Pick: {} s | P-Error: {} s'.format(zdat[0].stats.starttime \ + mpickP, Perror) print(msg) Sflag = 1 From 1d571a004609dace9932a234d7078226561a5691 Mon Sep 17 00:00:00 2001 From: Marcel Date: Thu, 12 Jul 2018 11:27:20 +0200 Subject: [PATCH 102/169] [add] Metadata class now requires time for get_metadata and get_coordinates as well --- pylot/core/util/dataprocessing.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/pylot/core/util/dataprocessing.py b/pylot/core/util/dataprocessing.py index f98d99a2..3796fdda 100644 --- a/pylot/core/util/dataprocessing.py +++ b/pylot/core/util/dataprocessing.py @@ -92,7 +92,7 @@ class Metadata(object): del(self.seed_ids[seed_id]) - def get_metadata(self, seed_id): + def get_metadata(self, seed_id, time): # get metadata for a specific seed_id, if not already read, try to read from inventories if not seed_id in self.seed_ids.keys(): self._read_inventory_data(seed_id) @@ -103,7 +103,7 @@ class Metadata(object): for inv_fname, metadata_dict in self.inventory_files.items(): # use get_coordinates to check for seed_id try: - metadata_dict['data'].get_coordinates(seed_id) + metadata_dict['data'].get_coordinates(seed_id, time) self.seed_ids[seed_id] = inv_fname print('Found metadata for station {}!'.format(seed_id)) return metadata_dict @@ -148,11 +148,11 @@ class Metadata(object): return True - def get_coordinates(self, seed_id): - metadata = self.get_metadata(seed_id) + def get_coordinates(self, seed_id, time): + metadata = self.get_metadata(seed_id, time) if not metadata: return - return metadata['data'].get_coordinates(seed_id) + return metadata['data'].get_coordinates(seed_id, time) def get_paz(self, seed_id, time): From 84ed0b900fe4875d38bf9dd74f512b3897b73d95 Mon Sep 17 00:00:00 2001 From: Marcel Date: Thu, 12 Jul 2018 11:28:43 +0200 Subject: [PATCH 103/169] [update] unit test for Metadata class --- tests/test_Metadata/test_Metadata.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/tests/test_Metadata/test_Metadata.py b/tests/test_Metadata/test_Metadata.py index 244adbe2..3d8b770e 100644 --- a/tests/test_Metadata/test_Metadata.py +++ b/tests/test_Metadata/test_Metadata.py @@ -1,12 +1,14 @@ import unittest import os +from obspy import UTCDateTime from pylot.core.util.dataprocessing import Metadata class TestMetadata(unittest.TestCase): def setUp(self): self.station_id = 'BW.WETR..HH' + self.time = UTCDateTime('2012-08-01') metadata_folder = 'metadata1' self.m = Metadata(metadata_folder) @@ -17,7 +19,7 @@ class TestMetadata(unittest.TestCase): } result = {} for channel in ('Z', 'N', 'E'): - coords = self.m.get_coordinates(self.station_id+channel) + coords = self.m.get_coordinates(self.station_id+channel, time=self.time) result[channel] = coords self.assertDictEqual(result[channel], expected[channel]) From 1d215c181c90793a01465a4ff719495b77758f61 Mon Sep 17 00:00:00 2001 From: Marcel Date: Thu, 12 Jul 2018 11:43:15 +0200 Subject: [PATCH 104/169] [update] time optional for get_metadata/get_coordinates, if not time is specified use current UTCDateTime --- pylot/core/util/dataprocessing.py | 26 +++++++++++++++----------- tests/test_Metadata/test_Metadata.py | 12 ++++++++++++ 2 files changed, 27 insertions(+), 11 deletions(-) diff --git a/pylot/core/util/dataprocessing.py b/pylot/core/util/dataprocessing.py index 3796fdda..e6093435 100644 --- a/pylot/core/util/dataprocessing.py +++ b/pylot/core/util/dataprocessing.py @@ -92,7 +92,10 @@ class Metadata(object): del(self.seed_ids[seed_id]) - def get_metadata(self, seed_id, time): + def get_metadata(self, seed_id, time=None): + # try most recent data if no time is specified + if not time: + time = UTCDateTime() # get metadata for a specific seed_id, if not already read, try to read from inventories if not seed_id in self.seed_ids.keys(): self._read_inventory_data(seed_id) @@ -128,14 +131,12 @@ class Metadata(object): def read_single_file(self, inv_fname): - # try to read a single file as Parser/Inventory if it was not already read before - if not inv_fname in self.inventory_files.keys(): - pass - else: - if not self.inventory_files[inv_fname]: - pass - else: - return + # try to read a single file as Parser/Inventory + + # return if it was read already + if self.inventory_files.get(inv_fname, None): + return + try: invtype, robj = self._read_metadata_file(inv_fname) if robj == None: @@ -148,7 +149,10 @@ class Metadata(object): return True - def get_coordinates(self, seed_id, time): + def get_coordinates(self, seed_id, time=None): + # try most recent data if no time is specified + if not time: + time = UTCDateTime() metadata = self.get_metadata(seed_id, time) if not metadata: return @@ -473,7 +477,7 @@ def restitute_trace(input_tuple): seed_id = tr.get_id() - mdata = metadata.get_metadata(seed_id) + mdata = metadata.get_metadata(seed_id, time=tr.stats.starttime) if not mdata: return no_metadata(tr, seed_id) diff --git a/tests/test_Metadata/test_Metadata.py b/tests/test_Metadata/test_Metadata.py index 3d8b770e..271bf4a9 100644 --- a/tests/test_Metadata/test_Metadata.py +++ b/tests/test_Metadata/test_Metadata.py @@ -23,6 +23,18 @@ class TestMetadata(unittest.TestCase): result[channel] = coords self.assertDictEqual(result[channel], expected[channel]) + def test_get_coordinates_sucess_no_time(self): + expected = {'Z': {u'elevation': 607.0, u'longitude': 12.87571, u'local_depth': 0.0, u'azimuth': 0.0, u'latitude': 49.14502, u'dip': -90.0}, + 'E': {u'azimuth': 90.0, u'dip': 0.0, u'elevation': 607.0, u'latitude': 49.14502, u'local_depth': 0.0, u'longitude': 12.87571}, + 'N': {u'azimuth': 0.0, u'dip': 0.0, u'elevation': 607.0, u'latitude': 49.14502, u'local_depth': 0.0, u'longitude': 12.87571} + } + result = {} + for channel in ('Z', 'N', 'E'): + coords = self.m.get_coordinates(self.station_id+channel) + result[channel] = coords + self.assertDictEqual(result[channel], expected[channel]) + + class TestMetadataAdding(unittest.TestCase): """Tests if adding files and directories to a metadata object works.""" From 9a5624c9510605bcd32e8d08a39e796270bcba1e Mon Sep 17 00:00:00 2001 From: Marcel Date: Thu, 12 Jul 2018 14:09:25 +0200 Subject: [PATCH 105/169] [change] return values of autopickstation --- pylot/core/pick/autopick.py | 29 +++++++++++++---------------- 1 file changed, 13 insertions(+), 16 deletions(-) diff --git a/pylot/core/pick/autopick.py b/pylot/core/pick/autopick.py index b11c3662..c4e7753f 100644 --- a/pylot/core/pick/autopick.py +++ b/pylot/core/pick/autopick.py @@ -76,7 +76,7 @@ def autopickevent(data, param, iplot=0, fig_dict=None, fig_dict_wadatijack=None, if iplot > 0: all_onsets[station] = autopickstation(topick, param, verbose=apverbose, iplot=iplot, fig_dict=fig_dict, - metadata=metadata, origin=origin) + metadata=metadata, origin=origin)[0] if iplot > 0: print('iPlot Flag active: NO MULTIPROCESSING possible.') @@ -98,18 +98,12 @@ def autopickevent(data, param, iplot=0, fig_dict=None, fig_dict_wadatijack=None, results = parallel_picking(input_tuples, ncores) - for result, wfstream in results: + for result, station in results: if type(result) == dict: - station = result['station'] - result.pop('station') all_onsets[station] = result else: if result == None: result = 'Picker exited unexpectedly.' - if len(wfstream) > 0: - station = wfstream[0].stats.station - else: - station = None print('Could not pick a station: {}\nReason: {}'.format(station, result)) # quality control @@ -145,9 +139,9 @@ def call_autopickstation(input_tuple): wfstream, pickparam, verbose, metadata, origin = input_tuple # multiprocessing not possible with interactive plotting try: - return autopickstation(wfstream, pickparam, verbose, iplot=0, metadata=metadata, origin=origin), wfstream + return autopickstation(wfstream, pickparam, verbose, iplot=0, metadata=metadata, origin=origin) except Exception as e: - return e, wfstream + return e, wfstream[0].stats.station def get_source_coords(parser, station_id): @@ -289,9 +283,12 @@ def autopickstation(wfstream, pickparam, verbose=False, if len(ndat) == 0: # check for other components ndat = wfstream.select(component="1") + picks = {} + station = zdat[0].stats.station + if not zdat: print('No z-component found for station {}. STOP'.format(wfstream[0].stats.station)) - return + return picks, station if algoP == 'HOS' or algoP == 'ARZ' and zdat is not None: msg = '##################################################\nautopickstation:' \ @@ -360,7 +357,7 @@ def autopickstation(wfstream, pickparam, verbose=False, Lwf = zdat[0].stats.endtime - zdat[0].stats.starttime if not Lwf > 0: print('autopickstation: empty trace! Return!') - return + return picks, station Ldiff = Lwf - abs(Lc) if Ldiff <= 0 or pstop <= pstart or pstop - pstart <= thosmw: @@ -1123,7 +1120,7 @@ def autopickstation(wfstream, pickparam, verbose=False, elif ndat: hdat = ndat[0] else: - return + return picks, station if lpickS is not None and lpickS == mpickS: lpickS += hdat.stats.delta @@ -1153,8 +1150,8 @@ def autopickstation(wfstream, pickparam, verbose=False, spick = dict(channel=ccode, network=ncode, lpp=lpickS, epp=epickS, mpp=mpickS, spe=Serror, snr=SNRS, snrdb=SNRSdB, weight=Sweight, fm=None, picker=picker, Ao=Ao) # merge picks into returning dictionary - picks = dict(P=ppick, S=spick, station=zdat[0].stats.station) - return picks + picks = dict(P=ppick, S=spick) + return picks, station def iteratepicker(wf, NLLocfile, picks, badpicks, pickparameter, fig_dict=None): @@ -1239,7 +1236,7 @@ def iteratepicker(wf, NLLocfile, picks, badpicks, pickparameter, fig_dict=None): print("zfac: %f => %f" % (zfac_old, pickparameter.get('zfac'))) # repick station - newpicks = autopickstation(wf2pick, pickparameter, fig_dict=fig_dict) + newpicks, _ = autopickstation(wf2pick, pickparameter, fig_dict=fig_dict) # replace old dictionary with new one picks[badpicks[i][0]] = newpicks From d360d9db928deac322739cf4d742f2d764a90f2c Mon Sep 17 00:00:00 2001 From: Marcel Date: Thu, 12 Jul 2018 14:13:34 +0200 Subject: [PATCH 106/169] [bugfix] raise Exception if no Z-component is found for Magnitude calculation --- pylot/core/analysis/magnitude.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/pylot/core/analysis/magnitude.py b/pylot/core/analysis/magnitude.py index 08704f7b..cd1fe257 100644 --- a/pylot/core/analysis/magnitude.py +++ b/pylot/core/analysis/magnitude.py @@ -510,6 +510,9 @@ def calcsourcespec(wfstream, onset, vp, delta, azimuth, incidence, zdat = select_for_phase(wfstream, "P") + if len(zdat) == 0: + raise IOError('No vertical component found in stream:\n{}'.format(wfstream)) + dt = zdat[0].stats.delta freq = zdat[0].stats.sampling_rate From 319343499b7516dd8ed2a35bb80713957cb3b499 Mon Sep 17 00:00:00 2001 From: Marcel Date: Thu, 12 Jul 2018 14:14:22 +0200 Subject: [PATCH 107/169] [bugfix] parallel picking called accidently --- pylot/core/pick/autopick.py | 4 ---- 1 file changed, 4 deletions(-) diff --git a/pylot/core/pick/autopick.py b/pylot/core/pick/autopick.py index c4e7753f..464a4763 100644 --- a/pylot/core/pick/autopick.py +++ b/pylot/core/pick/autopick.py @@ -88,10 +88,6 @@ def autopickevent(data, param, iplot=0, fig_dict=None, fig_dict_wadatijack=None, print('Autopickstation: Distribute autopicking for {} ' 'stations on {} cores.'.format(len(input_tuples), ncores_str)) - - result = parallel_picking(input_tuples, ncores) - #result = serial_picking(input_tuples) - if ncores == 1: results = serial_picking(input_tuples) else: From 9f1672d7930eafc23f546e318aae53e2d8452296 Mon Sep 17 00:00:00 2001 From: Marcel Date: Thu, 12 Jul 2018 14:17:06 +0200 Subject: [PATCH 108/169] [hotfix] something went wrong trying to merge/rebase develop --- pylot/core/pick/autopick.py | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/pylot/core/pick/autopick.py b/pylot/core/pick/autopick.py index e2928b59..75756e9a 100644 --- a/pylot/core/pick/autopick.py +++ b/pylot/core/pick/autopick.py @@ -89,15 +89,9 @@ def autopickevent(data, param, iplot=0, fig_dict=None, fig_dict_wadatijack=None, 'stations on {} cores.'.format(len(input_tuples), ncores_str)) pool = gen_Pool(ncores) - result = pool.map(call_autopickstation, input_tuples) + results = pool.map(call_autopickstation, input_tuples) pool.close() - if ncores == 1: - results = serial_picking(input_tuples) - else: - results = parallel_picking(input_tuples, ncores) - - for result, wfstream in results: if type(result) == dict: station = result['station'] From 3b52b7a28f022785d80396ddd40a5414ed9efec0 Mon Sep 17 00:00:00 2001 From: Marcel Date: Thu, 12 Jul 2018 15:56:34 +0200 Subject: [PATCH 109/169] [bugfix] fixed some bugs resulting from restructuring of serial/parallel picking --- autoPyLoT.py | 6 +++--- pylot/core/pick/autopick.py | 24 +++++++++++------------- pylot/core/util/utils.py | 8 ++++++-- 3 files changed, 20 insertions(+), 18 deletions(-) diff --git a/autoPyLoT.py b/autoPyLoT.py index bb90abc2..f253d420 100755 --- a/autoPyLoT.py +++ b/autoPyLoT.py @@ -53,7 +53,7 @@ def autoPyLoT(input_dict=None, parameter=None, inputfile=None, fnames=None, even :type savepath: str :param savexml: export results in XML file if True :type savexml: bool - :param station: list of station names or 'all' to pick all stations + :param station: choose specific station name or 'all' to pick all stations :type station: str :param iplot: logical variable for plotting: 0=none, 1=partial, 2=all :type iplot: int @@ -149,8 +149,8 @@ def autoPyLoT(input_dict=None, parameter=None, inputfile=None, fnames=None, even datastructure.modifyFields(**dsfields) datastructure.setExpandFields(exf) - # check if default location routine NLLoc is available - if real_None(parameter['nllocbin']): + # check if default location routine NLLoc is available and all stations are used + if real_None(parameter['nllocbin']) and station=='all': locflag = 1 # get NLLoc-root path nllocroot = parameter.get('nllocroot') diff --git a/pylot/core/pick/autopick.py b/pylot/core/pick/autopick.py index 464a4763..6da10085 100644 --- a/pylot/core/pick/autopick.py +++ b/pylot/core/pick/autopick.py @@ -70,21 +70,14 @@ def autopickevent(data, param, iplot=0, fig_dict=None, fig_dict_wadatijack=None, for station in stations: topick = data.select(station=station) - - if iplot is None or iplot == 'None' or iplot == 0: - input_tuples.append((topick, param, apverbose, metadata, origin)) - if iplot > 0: - all_onsets[station] = autopickstation(topick, param, verbose=apverbose, - iplot=iplot, fig_dict=fig_dict, - metadata=metadata, origin=origin)[0] + input_tuples.append((topick, param, apverbose, iplot, fig_dict, metadata, origin)) if iplot > 0: print('iPlot Flag active: NO MULTIPROCESSING possible.') - return all_onsets + ncores = 1 - # rename str for ncores in case ncores == 0 (use all cores) + # rename ncores for string representation in case ncores == 0 (use all cores) ncores_str = ncores if ncores != 0 else 'all available' - print('Autopickstation: Distribute autopicking for {} ' 'stations on {} cores.'.format(len(input_tuples), ncores_str)) @@ -93,7 +86,6 @@ def autopickevent(data, param, iplot=0, fig_dict=None, fig_dict_wadatijack=None, else: results = parallel_picking(input_tuples, ncores) - for result, station in results: if type(result) == dict: all_onsets[station] = result @@ -102,6 +94,10 @@ def autopickevent(data, param, iplot=0, fig_dict=None, fig_dict_wadatijack=None, result = 'Picker exited unexpectedly.' print('Could not pick a station: {}\nReason: {}'.format(station, result)) + # no Wadati/JK for single station (also valid for tuning mode) + if len(stations) == 1: + return all_onsets + # quality control # median check and jackknife on P-onset times jk_checked_onsets = checkPonsets(all_onsets, mdttolerance, jackfactor, iplot, fig_dict_wadatijack) @@ -132,10 +128,12 @@ def call_autopickstation(input_tuple): :return: dictionary containing P pick, S pick and station name :rtype: dict """ - wfstream, pickparam, verbose, metadata, origin = input_tuple + wfstream, pickparam, verbose, iplot, fig_dict, metadata, origin = input_tuple + if fig_dict: + print('Running in interactive mode') # multiprocessing not possible with interactive plotting try: - return autopickstation(wfstream, pickparam, verbose, iplot=0, metadata=metadata, origin=origin) + return autopickstation(wfstream, pickparam, verbose, fig_dict=fig_dict, iplot=iplot, metadata=metadata, origin=origin) except Exception as e: return e, wfstream[0].stats.station diff --git a/pylot/core/util/utils.py b/pylot/core/util/utils.py index a4269c83..80ef5d84 100644 --- a/pylot/core/util/utils.py +++ b/pylot/core/util/utils.py @@ -118,8 +118,12 @@ def gen_Pool(ncores=0): """ import multiprocessing - if ncores == 0: - ncores = multiprocessing.cpu_count() + ncores_max = multiprocessing.cpu_count() + + if ncores == 0 or ncores > ncores_max: + ncores = ncores_max + if ncores > ncores_max: + print('Reduced number of requested CPU slots to available number: {}'.format(ncores)) print('gen_Pool: Generated multiprocessing Pool with {} cores\n'.format(ncores)) From 10aa0360bc71faa5fad3998410b88cae981f3189 Mon Sep 17 00:00:00 2001 From: Darius Arnold Date: Fri, 13 Jul 2018 21:33:27 +0200 Subject: [PATCH 110/169] [Add] Utility class to hide prints during testing Provides with HidePrints context manager and @HidePrints.hide decorator --- tests/__init__.py | 27 ++++++++++++++++++++++++ tests/utils.py | 52 +++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 79 insertions(+) create mode 100644 tests/__init__.py create mode 100644 tests/utils.py diff --git a/tests/__init__.py b/tests/__init__.py new file mode 100644 index 00000000..e0981d72 --- /dev/null +++ b/tests/__init__.py @@ -0,0 +1,27 @@ +# -*- coding: utf-8 -*- +# -------------------------------------------------------- +# Purpose: Convience imports for PyLoT +# +''' +================================================ +PyLoT - the Python picking and Localization Tool +================================================ + +This python library contains a graphical user interfaces for picking +seismic phases. This software needs ObsPy (http://github.com/obspy/obspy/wiki) +and the Qt4 libraries to be installed first. + +PILOT has been developed in Mathworks' MatLab. In order to distribute +PILOT without facing portability problems, it has been decided to re- +develop the software package in Python. The great work of the ObsPy +group allows easy handling of a bunch of seismic data and PyLoT will +benefit a lot compared to the former MatLab version. + +The development of PyLoT is part of the joint research project MAGS2. + +:copyright: + The PyLoT Development Team +:license: + GNU Lesser General Public License, Version 3 + (http://www.gnu.org/copyleft/lesser.html) +''' diff --git a/tests/utils.py b/tests/utils.py new file mode 100644 index 00000000..9c154e63 --- /dev/null +++ b/tests/utils.py @@ -0,0 +1,52 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + +"""Utilities/helpers for testing""" + +import sys +import os + + +class HidePrints: + """ + Context manager that hides all standard output within its body. + The optional hide_prints argument can be used to quickly enable printing during debugging of tests. + + + Use (This will result in all console output of noisy_function to be suppressed): + from tests.utils import HidePrints + with HidePrints(): + noise_function() + """ + + @staticmethod + def hide(func, *args, **kwargs): + """Decorator that hides all prints of the decorated function. + + Use: + from tests.utils import HidePrints + @HidePrints.hide + def noise() + print("NOISE") + """ + + def silencer(*args, **kwargs): + with HidePrints(): + func(*args, **kwargs) + return silencer + + def __init__(self, hide_prints=True): + """Create object with hide_prints=False to disable print hiding""" + self.hide = hide_prints + + def __enter__(self): + """Redirect stdout to /dev/null, save old stdout""" + if self.hide: + self._original_stdout = sys.stdout + devnull = open(os.devnull, "w") + sys.stdout = devnull + + def __exit__(self, exc_type, exc_val, exc_tb): + """Reinstate old stdout""" + if self.hide: + sys.stdout = self._original_stdout \ No newline at end of file From 6ae5a213d1966ca200c31f9cc59321ecd5a630c0 Mon Sep 17 00:00:00 2001 From: Darius Arnold Date: Fri, 13 Jul 2018 23:10:47 +0200 Subject: [PATCH 111/169] [update] Metadata docstrings improved --- pylot/core/util/dataprocessing.py | 100 +++++++++++++++++++----------- 1 file changed, 64 insertions(+), 36 deletions(-) diff --git a/pylot/core/util/dataprocessing.py b/pylot/core/util/dataprocessing.py index e6093435..491cfa37 100644 --- a/pylot/core/util/dataprocessing.py +++ b/pylot/core/util/dataprocessing.py @@ -13,11 +13,13 @@ from pylot.core.util.utils import key_for_set_value, find_in_list, \ class Metadata(object): + def __init__(self, inventory=None): self.inventories = [] # saves read metadata objects (Parser/inventory) for a filename self.inventory_files = {} # saves filenames holding metadata for a seed_id + # seed id as key, path to file as value self.seed_ids = {} if inventory: if os.path.isdir(inventory): @@ -25,7 +27,6 @@ class Metadata(object): if os.path.isfile(inventory): self.add_inventory_file(inventory) - def __str__(self): repr = 'PyLoT Metadata object including the following inventories:\n\n' ntotal = len(self.inventories) @@ -38,48 +39,40 @@ class Metadata(object): repr += '\nTotal of {} inventories. Use Metadata.inventories to see all.'.format(ntotal) return repr - def __repr__(self): return self.__str__() - def add_inventory(self, path_to_inventory): - ''' - add paths to list of inventories - - :param path_to_inventory: - :return: - ''' + """ + Add path to list of inventories. + :param path_to_inventory: Path to a folder + :type path_to_inventory: str + :return: None + """ assert (os.path.isdir(path_to_inventory)), '{} is no directory'.format(path_to_inventory) if not path_to_inventory in self.inventories: self.inventories.append(path_to_inventory) - def add_inventory_file(self, path_to_inventory_file): - ''' - add a single file to inventory files - - :param path_to_inventory_file: - :return: - - ''' + """ + Add the folder in which the file exists to the list of inventories. + :param path_to_inventory_file: full path including filename + :type path_to_inventory_file: str + :return: None + """ assert (os.path.isfile(path_to_inventory_file)), '{} is no file'.format(path_to_inventory_file) self.add_inventory(os.path.split(path_to_inventory_file)[0]) if not path_to_inventory_file in self.inventory_files.keys(): self.read_single_file(path_to_inventory_file) - def remove_all_inventories(self): self.__init__() - def remove_inventory(self, path_to_inventory): - ''' - remove a path from inventories list - - :param path_to_inventory: - :return: - ''' + """ + Remove a path from inventories list. If path is not in inventories list, do nothing. + :param path_to_inventory: Path to a folder + """ if not path_to_inventory in self.inventories: print('Path {} not in inventories list.'.format(path_to_inventory)) return @@ -93,6 +86,19 @@ class Metadata(object): def get_metadata(self, seed_id, time=None): + """ + Get metadata for seed id at time. When time is not specified, metadata for current time is fetched. + :param seed_id: Seed id such as BW.WETR..HHZ (Network.Station.Location.Channel) + :type seed_id: str + :param time: Time for which the metadata should be returned + :type time: UTCDateTime + :return: Dictionary with keys data and invtype. + data is a obspy.io.xseed.parser.Parser or an obspy.core.inventory.inventory.Inventory depending on the metadata + file. + invtype is a string denoting of which type the value of the data key is. It can take the values 'dless', + 'dseed', 'xml', 'resp', according to the filetype of the metadata. + :rtype: dict + """ # try most recent data if no time is specified if not time: time = UTCDateTime() @@ -119,10 +125,9 @@ class Metadata(object): def read_all(self): - ''' - read all metadata files found in all inventories - :return: - ''' + """ + Read all metadata files found in all inventories + """ for inventory in self.inventories: for inv_fname in os.listdir(inventory): inv_fname = os.path.join(inventory, inv_fname) @@ -131,8 +136,12 @@ class Metadata(object): def read_single_file(self, inv_fname): - # try to read a single file as Parser/Inventory - + """ + Try to read a single file as Parser/Inventory and add its dictionary to inventory files if reading sudceeded. + :param inv_fname: path/filename of inventory file + :type inv_fname: str + :rtype: None + """ # return if it was read already if self.inventory_files.get(inv_fname, None): return @@ -150,6 +159,15 @@ class Metadata(object): def get_coordinates(self, seed_id, time=None): + """ + Get coordinates of given seed id. + :param seed_id: Seed id such as BW.WETR..HHZ (Network.Station.Location.Channel) + :type seed_id: str + :param time: Used when a station has data available at multiple time intervals + :type time: UTCDateTime + :return: dict containing position information of the station + :rtype: dict + """ # try most recent data if no time is specified if not time: time = UTCDateTime() @@ -160,6 +178,14 @@ class Metadata(object): def get_paz(self, seed_id, time): + """ + + :param seed_id: Seed id such as BW.WETR..HHZ (Network.Station.Location.Channel) + :type seed_id: str + :param time: Used when a station has data available at multiple time intervals + :type time: UTCDateTime + :rtype: dict + """ metadata = self.get_metadata(seed_id) if not metadata: return @@ -177,10 +203,11 @@ class Metadata(object): def _read_metadata_iterator(self, path_to_inventory, station_seed_id): - ''' - search for metadata for a specific station iteratively - ''' + """ + Search for metadata for a specific station iteratively. + """ station, network, location, channel = station_seed_id.split('.') + # seach for station seed id in filenames in invetory fnames = glob.glob(os.path.join(path_to_inventory, '*' + station_seed_id + '*')) if not fnames: # search for station name in filename @@ -211,11 +238,12 @@ class Metadata(object): def _read_metadata_file(self, path_to_inventory_filename): - ''' + """ function reading metadata files (either dataless seed, xml or resp) :param path_to_inventory_filename: :return: file type/ending, inventory object (Parser or Inventory) - ''' + :rtype: (str, obspy.io.xseed.Parser or obspy.core.inventory.inventory.Inventory) + """ # functions used to read metadata for different file endings (or file types) read_functions = {'dless': self._read_dless, 'dseed': self._read_dless, From f5c1fea159dc64d1f1f401b6e0494c87934db820 Mon Sep 17 00:00:00 2001 From: Darius Arnold Date: Fri, 13 Jul 2018 23:25:11 +0200 Subject: [PATCH 112/169] [Change] use HidePrints to clean output of test results --- tests/test_Metadata/test_Metadata.py | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/tests/test_Metadata/test_Metadata.py b/tests/test_Metadata/test_Metadata.py index 271bf4a9..9a091894 100644 --- a/tests/test_Metadata/test_Metadata.py +++ b/tests/test_Metadata/test_Metadata.py @@ -3,6 +3,7 @@ import os from obspy import UTCDateTime from pylot.core.util.dataprocessing import Metadata +from tests.utils import HidePrints class TestMetadata(unittest.TestCase): @@ -19,7 +20,8 @@ class TestMetadata(unittest.TestCase): } result = {} for channel in ('Z', 'N', 'E'): - coords = self.m.get_coordinates(self.station_id+channel, time=self.time) + with HidePrints(): + coords = self.m.get_coordinates(self.station_id+channel, time=self.time) result[channel] = coords self.assertDictEqual(result[channel], expected[channel]) @@ -30,7 +32,8 @@ class TestMetadata(unittest.TestCase): } result = {} for channel in ('Z', 'N', 'E'): - coords = self.m.get_coordinates(self.station_id+channel) + with HidePrints(): + coords = self.m.get_coordinates(self.station_id+channel) result[channel] = coords self.assertDictEqual(result[channel], expected[channel]) @@ -107,7 +110,8 @@ class TestMetadataRemoval(unittest.TestCase): exist in the instance.""" # add multiple inventories self.m.add_inventory(self.metadata_folders[0]) - self.m.remove_inventory('metadata_not_existing') + with HidePrints(): + self.m.remove_inventory('metadata_not_existing') self.assertIn(self.metadata_folders[0], self.m.inventories) def isEmpty(self, metadata): From 7734650d2e1bb3442390ca39e31b5f8691394cda Mon Sep 17 00:00:00 2001 From: Darius Arnold Date: Tue, 17 Jul 2018 10:34:42 +0200 Subject: [PATCH 113/169] Move the metadata files used ofr testing into own folder --- tests/test_Metadata/test_Metadata.py | 12 +++++++----- .../metadata1/DATALESS.BW.WETR..HHE | 0 .../metadata1/DATALESS.BW.WETR..HHN | 0 .../metadata1/DATALESS.BW.WETR..HHZ | 0 .../metadata2/DATALESS.GR.GRA1..HHE | 0 .../metadata2/DATALESS.GR.GRA1..HHN | 0 .../metadata2/DATALESS.GR.GRA1..HHZ | 0 .../metadata2/DATALESS.GR.GRA2..HHE | 0 .../metadata2/DATALESS.GR.GRA2..HHN | 0 .../metadata2/DATALESS.GR.GRA2..HHZ | 0 .../dless_multiple_instruments/MAGS2_KB_TMO07.dless | 1 + .../dless_multiple_times/MAGS2_LE_ROTT.dless | 1 + 12 files changed, 9 insertions(+), 5 deletions(-) rename tests/test_Metadata/{ => test_data/dless_multiple_files}/metadata1/DATALESS.BW.WETR..HHE (100%) rename tests/test_Metadata/{ => test_data/dless_multiple_files}/metadata1/DATALESS.BW.WETR..HHN (100%) rename tests/test_Metadata/{ => test_data/dless_multiple_files}/metadata1/DATALESS.BW.WETR..HHZ (100%) rename tests/test_Metadata/{ => test_data/dless_multiple_files}/metadata2/DATALESS.GR.GRA1..HHE (100%) rename tests/test_Metadata/{ => test_data/dless_multiple_files}/metadata2/DATALESS.GR.GRA1..HHN (100%) rename tests/test_Metadata/{ => test_data/dless_multiple_files}/metadata2/DATALESS.GR.GRA1..HHZ (100%) rename tests/test_Metadata/{ => test_data/dless_multiple_files}/metadata2/DATALESS.GR.GRA2..HHE (100%) rename tests/test_Metadata/{ => test_data/dless_multiple_files}/metadata2/DATALESS.GR.GRA2..HHN (100%) rename tests/test_Metadata/{ => test_data/dless_multiple_files}/metadata2/DATALESS.GR.GRA2..HHZ (100%) create mode 100644 tests/test_Metadata/test_data/dless_multiple_instruments/MAGS2_KB_TMO07.dless create mode 100644 tests/test_Metadata/test_data/dless_multiple_times/MAGS2_LE_ROTT.dless diff --git a/tests/test_Metadata/test_Metadata.py b/tests/test_Metadata/test_Metadata.py index 9a091894..8cb4a08f 100644 --- a/tests/test_Metadata/test_Metadata.py +++ b/tests/test_Metadata/test_Metadata.py @@ -10,7 +10,7 @@ class TestMetadata(unittest.TestCase): def setUp(self): self.station_id = 'BW.WETR..HH' self.time = UTCDateTime('2012-08-01') - metadata_folder = 'metadata1' + metadata_folder = os.path.join('test_data', 'dless_multiple_files', 'metadata1') self.m = Metadata(metadata_folder) def test_get_coordinates_sucess(self): @@ -43,7 +43,8 @@ class TestMetadataAdding(unittest.TestCase): def setUp(self): self.station_id = 'BW.WETR..HH' - self.metadata_folders = ('metadata1', 'metadata2') + self.metadata_folders = (os.path.join('test_data', 'dless_multiple_files', 'metadata1'), + os.path.join('test_data', 'dless_multiple_files', 'metadata2')) self.m = Metadata() def test_add_inventory_folder(self): @@ -60,8 +61,8 @@ class TestMetadataAdding(unittest.TestCase): fpath = os.path.join(self.metadata_folders[0], 'DATALESS.BW.WETR..HHZ') self.m.add_inventory_file(fpath) # adding an inventory file should append its folder to the list of inventories and the file to the - self.assertEqual(['metadata1/DATALESS.BW.WETR..HHZ'], self.m.inventory_files.keys()) # does the filename exist in inventory files? - self.assertEqual(['data', 'invtype'], self.m.inventory_files['metadata1/DATALESS.BW.WETR..HHZ'].keys()) # is the required information attacht to the filename? + self.assertEqual([os.path.join(self.metadata_folders[0], 'DATALESS.BW.WETR..HHZ')], self.m.inventory_files.keys()) # does the filename exist in inventory files? + self.assertEqual(['data', 'invtype'], self.m.inventory_files[os.path.join(self.metadata_folders[0], 'DATALESS.BW.WETR..HHZ')].keys()) # is the required information attacht to the filename? self.assertDictEqual({}, self.m.seed_ids) self.assertEqual([self.metadata_folders[0]], self.m.inventories) @@ -83,7 +84,8 @@ class TestMetadataRemoval(unittest.TestCase): def setUp(self): self.station_id = 'BW.WETR..HH' - self.metadata_folders = ('metadata1', 'metadata2') + self.metadata_folders = (os.path.join('test_data', 'dless_multiple_files', 'metadata1'), + os.path.join('test_data', 'dless_multiple_files', 'metadata2')) self.m = Metadata() def test_remove_all_inventories(self): diff --git a/tests/test_Metadata/metadata1/DATALESS.BW.WETR..HHE b/tests/test_Metadata/test_data/dless_multiple_files/metadata1/DATALESS.BW.WETR..HHE similarity index 100% rename from tests/test_Metadata/metadata1/DATALESS.BW.WETR..HHE rename to tests/test_Metadata/test_data/dless_multiple_files/metadata1/DATALESS.BW.WETR..HHE diff --git a/tests/test_Metadata/metadata1/DATALESS.BW.WETR..HHN b/tests/test_Metadata/test_data/dless_multiple_files/metadata1/DATALESS.BW.WETR..HHN similarity index 100% rename from tests/test_Metadata/metadata1/DATALESS.BW.WETR..HHN rename to tests/test_Metadata/test_data/dless_multiple_files/metadata1/DATALESS.BW.WETR..HHN diff --git a/tests/test_Metadata/metadata1/DATALESS.BW.WETR..HHZ b/tests/test_Metadata/test_data/dless_multiple_files/metadata1/DATALESS.BW.WETR..HHZ similarity index 100% rename from tests/test_Metadata/metadata1/DATALESS.BW.WETR..HHZ rename to tests/test_Metadata/test_data/dless_multiple_files/metadata1/DATALESS.BW.WETR..HHZ diff --git a/tests/test_Metadata/metadata2/DATALESS.GR.GRA1..HHE b/tests/test_Metadata/test_data/dless_multiple_files/metadata2/DATALESS.GR.GRA1..HHE similarity index 100% rename from tests/test_Metadata/metadata2/DATALESS.GR.GRA1..HHE rename to tests/test_Metadata/test_data/dless_multiple_files/metadata2/DATALESS.GR.GRA1..HHE diff --git a/tests/test_Metadata/metadata2/DATALESS.GR.GRA1..HHN b/tests/test_Metadata/test_data/dless_multiple_files/metadata2/DATALESS.GR.GRA1..HHN similarity index 100% rename from tests/test_Metadata/metadata2/DATALESS.GR.GRA1..HHN rename to tests/test_Metadata/test_data/dless_multiple_files/metadata2/DATALESS.GR.GRA1..HHN diff --git a/tests/test_Metadata/metadata2/DATALESS.GR.GRA1..HHZ b/tests/test_Metadata/test_data/dless_multiple_files/metadata2/DATALESS.GR.GRA1..HHZ similarity index 100% rename from tests/test_Metadata/metadata2/DATALESS.GR.GRA1..HHZ rename to tests/test_Metadata/test_data/dless_multiple_files/metadata2/DATALESS.GR.GRA1..HHZ diff --git a/tests/test_Metadata/metadata2/DATALESS.GR.GRA2..HHE b/tests/test_Metadata/test_data/dless_multiple_files/metadata2/DATALESS.GR.GRA2..HHE similarity index 100% rename from tests/test_Metadata/metadata2/DATALESS.GR.GRA2..HHE rename to tests/test_Metadata/test_data/dless_multiple_files/metadata2/DATALESS.GR.GRA2..HHE diff --git a/tests/test_Metadata/metadata2/DATALESS.GR.GRA2..HHN b/tests/test_Metadata/test_data/dless_multiple_files/metadata2/DATALESS.GR.GRA2..HHN similarity index 100% rename from tests/test_Metadata/metadata2/DATALESS.GR.GRA2..HHN rename to tests/test_Metadata/test_data/dless_multiple_files/metadata2/DATALESS.GR.GRA2..HHN diff --git a/tests/test_Metadata/metadata2/DATALESS.GR.GRA2..HHZ b/tests/test_Metadata/test_data/dless_multiple_files/metadata2/DATALESS.GR.GRA2..HHZ similarity index 100% rename from tests/test_Metadata/metadata2/DATALESS.GR.GRA2..HHZ rename to tests/test_Metadata/test_data/dless_multiple_files/metadata2/DATALESS.GR.GRA2..HHZ diff --git a/tests/test_Metadata/test_data/dless_multiple_instruments/MAGS2_KB_TMO07.dless b/tests/test_Metadata/test_data/dless_multiple_instruments/MAGS2_KB_TMO07.dless new file mode 100644 index 00000000..5b6e0938 --- /dev/null +++ b/tests/test_Metadata/test_data/dless_multiple_instruments/MAGS2_KB_TMO07.dless @@ -0,0 +1 @@ +000001V 010008402.4121950,001,00:00:00.0000~2500,001,00:00:00.0000~2018,194,18:47:19.0000~~~0110021001TMO07000003 000002A 0300237Steim2 Integer Compression Format~000105014F1 P4 W4 D C2 R1 P8 W4 D C2~P0 W4 N15 S2,0,1~T0 X W4~T1 Y4 W1 D C2~T2 W4 I D2~K0 X D30~K1 N0 D30 C2~K2 Y2 D15 C2~K3 Y3 D10 C2~T3 W4 I D2~K0 Y5 D6 C2~K1 Y6 D5 C2~K2 X D2 Y7 D4 C2~K3 X D30~0330021001KB network~0330034002Streckeisen KABBA-STS-2~0330033003Lennartz KABBA-LE-3D/5~0330033004Lennartz KABBA-LE-3D/1~0340044001M/S~Velocity in Meters per Second~0340020002A~Amperes~0340018003V~Volts~0340032004COUNTS~Digital Counts~ 000003S 0500097TMO07+49.020590+008.367240+0129.00000000Karlsruhe GPI~0013210102004,341,12:55:00.0000~~NKB052014900BHE0000002~001002+49.020590+008.367240+0129.0000.0090.0+00.00001125.0000E+010.0000E+000000GC~2004,341,12:55:00.0000~2005,108,15:21:00.0000~N0530862A01001003+3.47380E+17+2.00000E+00006+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00-1.51500E+01+0.00000E+00+0.00000E+00+0.00000E+00-1.76600E+02+0.00000E+00+0.00000E+00+0.00000E+00-4.63100E+02+4.30500E+02+0.00000E+00+0.00000E+00-4.63100E+02+4.30500E+02+0.00000E+00+0.00000E+00011-3.70000E-02+3.70000E-02+0.00000E+00+0.00000E+00-3.70000E-02-3.70000E-02+0.00000E+00+0.00000E+00-1.56400E+01+0.00000E+00+0.00000E+00+0.00000E+00-9.73400E+01-4.00700E+02+0.00000E+00+0.00000E+00-9.73400E+01+4.00700E+02+0.00000E+00+0.00000E+00-2.55100E+02+0.00000E+00+0.00000E+00+0.00000E+00-3.74800E+02+0.00000E+00+0.00000E+00+0.00000E+00-5.20300E+02+0.00000E+00+0.00000E+00+0.00000E+00-1.05300E+04+1.00500E+04+0.00000E+00+0.00000E+00-1.05300E+04-1.00500E+04+0.00000E+00+0.00000E+00-1.33000E+04+0.00000E+00+0.00000E+00+0.00000E+00058003501+1.50000E+03+2.00000E+00000540024D02003004000000000570051025.0000E+010000100000+0.0000E+00+0.0000E+00058003502+1.00000E+06+0.00000E+0000058003500+1.50000E+09+2.00000E+0000052014900BHN0000002~001002+49.020590+008.367240+0129.0000.0000.0+00.00001125.0000E+010.0000E+000000GC~2004,341,12:55:00.0000~2005,108,15:21:00.0000~N0530862A01001003+3.47380E+17+2.00000E+00006+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00-1.51500E+01+0.00000E+00+0.00000E+00+0.00000E+00-1.76600E+02+0.00000E+00+0.00000E+00+0.00000E+00-4.63100E+02+4.30500E+02+0.00000E+00+0.00000E+00-4.63100E+02+4.30500E+02+0.00000E+00+0.00000E+00011-3.70000E-02+3.70000E-02+0.00000E+00+0.00000E+00-3.70000E-02-3.70000E-02+0.00000E+00+0.00000E+00-1.56400E+01+0.00000E+00+0.00000E+00+0.00000E+00-9.73400E+01-4.00700E+02+0.00000E+00+0.00000E+00-9.73400E+01+4.00700E+02+0.00000E+00+0.00000E+00-2.55100E+02+0.00000E+00+0.00000E+00+0.00000E+00-3.74800E+02+0.00000E+00+0.00000E+00+0.00000E+00-5.20300E+02+0.00000E+00+0.00000E+00+0.00000E+00-1.05300E+04+1.00500E+04+0.00000E+00+0.00000E+00-1.05300E+04-1.00500E+04+0.00000E+00+0.00000E+00-1.33000E+04+0.00000E+00+0.00000E+00+0.00000E+00058003501+1.50000E+03+2.00000E+00000540024D02003004000000000570051025.0000E+010000100000+0.0000E+00+0.0000E+00058003502+1.00000E+06+0.00000E+0000058003500+1.50000E+09+2.00000E+0000052014900BHZ0000002~001002+49.020590+008.367240+0129.0000.0000.0-90.00001125.0000E+010.0000E+000000GC~2004,341,12:55:00.0000~2005,108,15:21:00.0000~N0530862A01001003+3.47380E+17+2.00000E+00006+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00-1.51500E+01+0.00000E+00+0.00000E+00+0.00000E+00-1.76600E+02+0.00000E+00+0.00000E+00+0.00000E+00-4.63100E+02+4.30500E+02+0.00000E+00+0.00000E+00-4.63100E+02+4.30500E+02+0.00000E+00+0.00000E+00011-3.70000E-02+3.70000E-02+0.00000E+00+0.00000E+00-3.70000E-02-3.70000E-02+0.00000E+00+0.00000E+00-1.56400E+01+0.00000E+00+0.00000E+00+0.00000E+00-9.73400E+01-4.00700E+02+0.00000E+00+0.00000E+00-9.73400E+01+4.00700E+02+0.00000E+00+0.00000E+00-2.55100E+02+0.00000E+00+0.00000E+00+0.00000E+00-3.74800E+02+0.00000E+00+0.00000E+00+0.00000E+00-5.20300E+02+0.00000E+00+0.00000E+00+0.00000E+00-1.05300E+04+1.00500E+04+0.00000E+00+0.00000E+00-1.05300E+04-1.00500E+04+0.00000E+00+0.00000E+00-1.33000E+04+0.00000E+00+0.00000E+00+0.00000E+00058003501+1.50000E+03+2.00000E+00000540024D02003004000000000570051025.0000E+010000100000+0.0000E+00+0.0000E+00058003502+1.00000E+06+0.00000E+0000058003500+1.50000E+09+2.00000E+0000052014900BHE0000002~001002+49.020590+008.367240+0129.0000.0090.0+00.00001125.0000E+010.0000E+000000GC~2005,108,15:22:00.0000~2006,199,10:00:00.0000~N0530862A01001003+3.47380E+17+2.00000E+00006+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00-1.51500E+01+0.00000E+00+0.00000E+00+0.00000E+00-1.76600E+02+0.00000E+00+0.00000E+00+0.00000E+00-4.63100E+02+4.30500E+02+0.00000E+000004S*00+0.00000E+00-4.63100E+02+4.30500E+02+0.00000E+00+0.00000E+00011-3.70000E-02+3.70000E-02+0.00000E+00+0.00000E+00-3.70000E-02-3.70000E-02+0.00000E+00+0.00000E+00-1.56400E+01+0.00000E+00+0.00000E+00+0.00000E+00-9.73400E+01-4.00700E+02+0.00000E+00+0.00000E+00-9.73400E+01+4.00700E+02+0.00000E+00+0.00000E+00-2.55100E+02+0.00000E+00+0.00000E+00+0.00000E+00-3.74800E+02+0.00000E+00+0.00000E+00+0.00000E+00-5.20300E+02+0.00000E+00+0.00000E+00+0.00000E+00-1.05300E+04+1.00500E+04+0.00000E+00+0.00000E+00-1.05300E+04-1.00500E+04+0.00000E+00+0.00000E+00-1.33000E+04+0.00000E+00+0.00000E+00+0.00000E+00058003501+1.50000E+03+2.00000E+00000540024D02003004000000000570051025.0000E+010000100000+0.0000E+00+0.0000E+00058003502+1.00000E+06+0.00000E+0000058003500+1.50000E+09+2.00000E+0000052014900BHN0000002~001002+49.020590+008.367240+0129.0000.0000.0+00.00001125.0000E+010.0000E+000000GC~2005,108,15:22:00.0000~2006,199,10:00:00.0000~N0530862A01001003+3.47380E+17+2.00000E+00006+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00-1.51500E+01+0.00000E+00+0.00000E+00+0.00000E+00-1.76600E+02+0.00000E+00+0.00000E+00+0.00000E+00-4.63100E+02+4.30500E+02+0.00000E+00+0.00000E+00-4.63100E+02+4.30500E+02+0.00000E+00+0.00000E+00011-3.70000E-02+3.70000E-02+0.00000E+00+0.00000E+00-3.70000E-02-3.70000E-02+0.00000E+00+0.00000E+00-1.56400E+01+0.00000E+00+0.00000E+00+0.00000E+00-9.73400E+01-4.00700E+02+0.00000E+00+0.00000E+00-9.73400E+01+4.00700E+02+0.00000E+00+0.00000E+00-2.55100E+02+0.00000E+00+0.00000E+00+0.00000E+00-3.74800E+02+0.00000E+00+0.00000E+00+0.00000E+00-5.20300E+02+0.00000E+00+0.00000E+00+0.00000E+00-1.05300E+04+1.00500E+04+0.00000E+00+0.00000E+00-1.05300E+04-1.00500E+04+0.00000E+00+0.00000E+00-1.33000E+04+0.00000E+00+0.00000E+00+0.00000E+00058003501+1.50000E+03+2.00000E+00000540024D02003004000000000570051025.0000E+010000100000+0.0000E+00+0.0000E+00058003502+1.00000E+06+0.00000E+0000058003500+1.50000E+09+2.00000E+0000052014900BHZ0000002~001002+49.020590+008.367240+0129.0000.0000.0-90.00001125.0000E+010.0000E+000000GC~2005,108,15:22:00.0000~2006,199,10:00:00.0000~N0530862A01001003+3.47380E+17+2.00000E+00006+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00-1.51500E+01+0.00000E+00+0.00000E+00+0.00000E+00-1.76600E+02+0.00000E+00+0.00000E+00+0.00000E+00-4.63100E+02+4.30500E+02+0.00000E+00+0.00000E+00-4.63100E+02+4.30500E+02+0.00000E+00+0.00000E+00011-3.70000E-02+3.70000E-02+0.00000E+00+0.00000E+00-3.70000E-02-3.70000E-02+0.00000E+00+0.00000E+00-1.56400E+01+0.00000E+00+0.00000E+00+0.00000E+00-9.73400E+01-4.00700E+02+0.00000E+00+0.00000E+00-9.73400E+01+4.00700E+02+0.00000E+00+0.00000E+00-2.55100E+02+0.00000E+00+0.00000E+00+0.00000E+00-3.74800E+02+0.00000E+00+0.00000E+00+0.00000E+00-5.20300E+02+0.00000E+00+0.00000E+00+0.00000E+00-1.05300E+04+1.00500E+04+0.00000E+00+0.00000E+00-1.05300E+04-1.00500E+04+0.00000E+00+0.00000E+00-1.33000E+04+0.00000E+00+0.00000E+00+0.00000E+00058003501+1.50000E+03+2.00000E+00000540024D02003004000000000570051025.0000E+010000100000+0.0000E+00+0.0000E+00058003502+1.00000E+06+0.00000E+0000058003500+1.50000E+09+2.00000E+0000052014900BHE0000003~001002+49.020590+008.367240+0129.0000.0090.0+00.00001125.0000E+010.0000E+000000GC~2006,283,08:45:00.0000~2006,318,11:30:00.0000~N0530334A01001003+1.00000E+00+2.00000E+00003+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00003-8.88000E-01+8.88000E-01+0.00000E+00+0.00000E+00-8.88000E-01-8.88000E-01+0.00000E+00+0.00000E+00-2.20000E-01+0.00000E+00+0.00000E+00+0.00000E+00058003501+4.00000E+02+2.00000E+00000540024D02003004000000000570051025.0000E+010000100000+0.0000E+00+0.0000E+00058003502+1.00000E+06+0.00000E+0000058003500+4.00000E+08+2.00000E+0000052014900BHN0000003~001002+49.020590+008.367240+0129.0000.0000.0+00.00001125.0000E+010.0000E+000000GC~2006,283,08:45:00.0000~2006,318,11:30:00.0000~N0530334A01001003+1.00000E+00+2.00000E+00003+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+0.000000005S*00E+00+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00003-8.88000E-01+8.88000E-01+0.00000E+00+0.00000E+00-8.88000E-01-8.88000E-01+0.00000E+00+0.00000E+00-2.20000E-01+0.00000E+00+0.00000E+00+0.00000E+00058003501+4.00000E+02+2.00000E+00000540024D02003004000000000570051025.0000E+010000100000+0.0000E+00+0.0000E+00058003502+1.00000E+06+0.00000E+0000058003500+4.00000E+08+2.00000E+0000052014900BHZ0000003~001002+49.020590+008.367240+0129.0000.0000.0-90.00001125.0000E+010.0000E+000000GC~2006,283,08:45:00.0000~2006,318,11:30:00.0000~N0530334A01001003+1.00000E+00+2.00000E+00003+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00003-8.88000E-01+8.88000E-01+0.00000E+00+0.00000E+00-8.88000E-01-8.88000E-01+0.00000E+00+0.00000E+00-2.20000E-01+0.00000E+00+0.00000E+00+0.00000E+00058003501+4.00000E+02+2.00000E+00000540024D02003004000000000570051025.0000E+010000100000+0.0000E+00+0.0000E+00058003502+1.00000E+06+0.00000E+0000058003500+4.00000E+08+2.00000E+0000052014900BHE0000003~001002+49.020590+008.367240+0129.0000.0090.0+00.00001125.0000E+010.0000E+000000GC~2006,328,11:07:00.0000~2007,012,07:30:00.0000~N0530334A01001003+1.00000E+00+2.00000E+00003+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00003-8.88000E-01+8.88000E-01+0.00000E+00+0.00000E+00-8.88000E-01-8.88000E-01+0.00000E+00+0.00000E+00-2.20000E-01+0.00000E+00+0.00000E+00+0.00000E+00058003501+4.00000E+02+2.00000E+00000540024D02003004000000000570051025.0000E+010000100000+0.0000E+00+0.0000E+00058003502+1.00000E+06+0.00000E+0000058003500+4.00000E+08+2.00000E+0000052014900BHN0000003~001002+49.020590+008.367240+0129.0000.0000.0+00.00001125.0000E+010.0000E+000000GC~2006,328,11:07:00.0000~2007,012,07:30:00.0000~N0530334A01001003+1.00000E+00+2.00000E+00003+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00003-8.88000E-01+8.88000E-01+0.00000E+00+0.00000E+00-8.88000E-01-8.88000E-01+0.00000E+00+0.00000E+00-2.20000E-01+0.00000E+00+0.00000E+00+0.00000E+00058003501+4.00000E+02+2.00000E+00000540024D02003004000000000570051025.0000E+010000100000+0.0000E+00+0.0000E+00058003502+1.00000E+06+0.00000E+0000058003500+4.00000E+08+2.00000E+0000052014900BHZ0000003~001002+49.020590+008.367240+0129.0000.0000.0-90.00001125.0000E+010.0000E+000000GC~2006,328,11:07:00.0000~2007,012,07:30:00.0000~N0530334A01001003+1.00000E+00+2.00000E+00003+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00003-8.88000E-01+8.88000E-01+0.00000E+00+0.00000E+00-8.88000E-01-8.88000E-01+0.00000E+00+0.00000E+00-2.20000E-01+0.00000E+00+0.00000E+00+0.00000E+00058003501+4.00000E+02+2.00000E+00000540024D02003004000000000570051025.0000E+010000100000+0.0000E+00+0.0000E+00058003502+1.00000E+06+0.00000E+0000058003500+4.00000E+08+2.00000E+0000052014900HHE0000003~001002+49.020590+008.367240+0129.0000.0090.0+00.00001121.0000E+020.0000E+000000GC~2007,012,12:03:00.0000~2007,018,10:43:00.0000~N0530334A01001003+1.00000E+00+2.00000E+00003+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00003-8.88000E-01+8.88000E-01+0.00000E+00+0.00000E+00-8.88000E-01-8.88000E-01+0.00000E+00+0.00000E+00-2.20000E-01+0.00000E+00+0.00000E+00+0.00000E+00058003501+4.00000E+02+2.00000E+00000540024D02003004000000000570051021.0000E+020000100000+0.0000E+00+0.0000E+00058003502+1.00000E+06+0.00000E+0000058003500+4.00000E+08+2.00000E+0000052014900HHN0000003~001002+49.020590+008.367240+0129.0000.0000.0+00.00001121.0000E+020.0000E+000000GC~2007,012,12:03:00.0000~2007,018,10:43:00.0000~N0530334A01001003+1.00000E+00+2.00000E+00003+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00003-8.88000E-01+8.88000E-01+0.00000E+00+0.00000006S*000E+00-8.88000E-01-8.88000E-01+0.00000E+00+0.00000E+00-2.20000E-01+0.00000E+00+0.00000E+00+0.00000E+00058003501+4.00000E+02+2.00000E+00000540024D02003004000000000570051021.0000E+020000100000+0.0000E+00+0.0000E+00058003502+1.00000E+06+0.00000E+0000058003500+4.00000E+08+2.00000E+0000052014900HHZ0000003~001002+49.020590+008.367240+0129.0000.0000.0-90.00001121.0000E+020.0000E+000000GC~2007,012,12:03:00.0000~2007,018,10:43:00.0000~N0530334A01001003+1.00000E+00+2.00000E+00003+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00003-8.88000E-01+8.88000E-01+0.00000E+00+0.00000E+00-8.88000E-01-8.88000E-01+0.00000E+00+0.00000E+00-2.20000E-01+0.00000E+00+0.00000E+00+0.00000E+00058003501+4.00000E+02+2.00000E+00000540024D02003004000000000570051021.0000E+020000100000+0.0000E+00+0.0000E+00058003502+1.00000E+06+0.00000E+0000058003500+4.00000E+08+2.00000E+0000052014900BHE0000003~001002+49.020590+008.367240+0129.0000.0090.0+00.00001125.0000E+010.0000E+000000GC~2007,018,10:44:00.0000~2007,074,10:00:00.0000~N0530334A01001003+1.00000E+00+2.00000E+00003+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00003-8.88000E-01+8.88000E-01+0.00000E+00+0.00000E+00-8.88000E-01-8.88000E-01+0.00000E+00+0.00000E+00-2.20000E-01+0.00000E+00+0.00000E+00+0.00000E+00058003501+4.00000E+02+2.00000E+00000540024D02003004000000000570051025.0000E+010000100000+0.0000E+00+0.0000E+00058003502+1.00000E+06+0.00000E+0000058003500+4.00000E+08+2.00000E+0000052014900BHN0000003~001002+49.020590+008.367240+0129.0000.0000.0+00.00001125.0000E+010.0000E+000000GC~2007,018,10:44:00.0000~2007,074,10:00:00.0000~N0530334A01001003+1.00000E+00+2.00000E+00003+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00003-8.88000E-01+8.88000E-01+0.00000E+00+0.00000E+00-8.88000E-01-8.88000E-01+0.00000E+00+0.00000E+00-2.20000E-01+0.00000E+00+0.00000E+00+0.00000E+00058003501+4.00000E+02+2.00000E+00000540024D02003004000000000570051025.0000E+010000100000+0.0000E+00+0.0000E+00058003502+1.00000E+06+0.00000E+0000058003500+4.00000E+08+2.00000E+0000052014900BHZ0000003~001002+49.020590+008.367240+0129.0000.0000.0-90.00001125.0000E+010.0000E+000000GC~2007,018,10:44:00.0000~2007,074,10:00:00.0000~N0530334A01001003+1.00000E+00+2.00000E+00003+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00003-8.88000E-01+8.88000E-01+0.00000E+00+0.00000E+00-8.88000E-01-8.88000E-01+0.00000E+00+0.00000E+00-2.20000E-01+0.00000E+00+0.00000E+00+0.00000E+00058003501+4.00000E+02+2.00000E+00000540024D02003004000000000570051025.0000E+010000100000+0.0000E+00+0.0000E+00058003502+1.00000E+06+0.00000E+0000058003500+4.00000E+08+2.00000E+0000052014900HHE0000003~001002+49.020590+008.367240+0129.0000.0090.0+00.00001121.0000E+020.0000E+000000GC~2007,283,12:50:00.0000~2007,298,12:11:00.0000~N0530334A01001003+1.00000E+00+2.00000E+00003+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00003-8.88000E-01+8.88000E-01+0.00000E+00+0.00000E+00-8.88000E-01-8.88000E-01+0.00000E+00+0.00000E+00-2.20000E-01+0.00000E+00+0.00000E+00+0.00000E+00058003501+4.00000E+02+2.00000E+00000540024D02003004000000000570051021.0000E+020000100000+0.0000E+00+0.0000E+00058003502+1.00000E+06+0.00000E+0000058003500+4.00000E+08+2.00000E+0000052014900HHN0000003~001002+49.020590+008.367240+0129.0000.0000.0+00.00001121.0000E+020.0000E+000000GC~2007,283,12:50:00.0000~2007,298,12:11:00.0000~N0530334A01001003+1.00000E+00+2.00000E+00003+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00003-8.88000E-01+8.88000E-01+0.00000E+00+0.00000E+00-8.88000E-01-8.88000E-01+0.00000E+00+0.00000E+00-2.20000E-01+0.00000E+00+0.00000E+00+0.00000E+000580035000007S*01+4.00000E+02+2.00000E+00000540024D02003004000000000570051021.0000E+020000100000+0.0000E+00+0.0000E+00058003502+1.00000E+06+0.00000E+0000058003500+4.00000E+08+2.00000E+0000052014900HHZ0000003~001002+49.020590+008.367240+0129.0000.0000.0-90.00001121.0000E+020.0000E+000000GC~2007,283,12:50:00.0000~2007,298,12:11:00.0000~N0530334A01001003+1.00000E+00+2.00000E+00003+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00003-8.88000E-01+8.88000E-01+0.00000E+00+0.00000E+00-8.88000E-01-8.88000E-01+0.00000E+00+0.00000E+00-2.20000E-01+0.00000E+00+0.00000E+00+0.00000E+00058003501+4.00000E+02+2.00000E+00000540024D02003004000000000570051021.0000E+020000100000+0.0000E+00+0.0000E+00058003502+1.00000E+06+0.00000E+0000058003500+4.00000E+08+2.00000E+0000052014900BHE0000003~001002+49.020590+008.367240+0129.0000.0090.0+00.00001125.0000E+010.0000E+000000GC~2007,298,12:13:00.0000~2007,325,14:36:00.0000~N0530334A01001003+1.00000E+00+2.00000E+00003+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00003-8.88000E-01+8.88000E-01+0.00000E+00+0.00000E+00-8.88000E-01-8.88000E-01+0.00000E+00+0.00000E+00-2.20000E-01+0.00000E+00+0.00000E+00+0.00000E+00058003501+4.00000E+02+2.00000E+00000540024D02003004000000000570051025.0000E+010000100000+0.0000E+00+0.0000E+00058003502+1.00000E+06+0.00000E+0000058003500+4.00000E+08+2.00000E+0000052014900BHN0000003~001002+49.020590+008.367240+0129.0000.0000.0+00.00001125.0000E+010.0000E+000000GC~2007,298,12:13:00.0000~2007,325,14:36:00.0000~N0530334A01001003+1.00000E+00+2.00000E+00003+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00003-8.88000E-01+8.88000E-01+0.00000E+00+0.00000E+00-8.88000E-01-8.88000E-01+0.00000E+00+0.00000E+00-2.20000E-01+0.00000E+00+0.00000E+00+0.00000E+00058003501+4.00000E+02+2.00000E+00000540024D02003004000000000570051025.0000E+010000100000+0.0000E+00+0.0000E+00058003502+1.00000E+06+0.00000E+0000058003500+4.00000E+08+2.00000E+0000052014900BHZ0000003~001002+49.020590+008.367240+0129.0000.0000.0-90.00001125.0000E+010.0000E+000000GC~2007,298,12:13:00.0000~2007,325,14:36:00.0000~N0530334A01001003+1.00000E+00+2.00000E+00003+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00003-8.88000E-01+8.88000E-01+0.00000E+00+0.00000E+00-8.88000E-01-8.88000E-01+0.00000E+00+0.00000E+00-2.20000E-01+0.00000E+00+0.00000E+00+0.00000E+00058003501+4.00000E+02+2.00000E+00000540024D02003004000000000570051025.0000E+010000100000+0.0000E+00+0.0000E+00058003502+1.00000E+06+0.00000E+0000058003500+4.00000E+08+2.00000E+0000052014900BHE0000003~001002+49.020590+008.367240+0129.0000.0090.0+00.00001125.0000E+010.0000E+000000GC~2007,325,14:37:00.0000~2008,017,07:53:00.0000~N0530334A01001003+1.00000E+00+2.00000E+00003+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00003-8.88000E-01+8.88000E-01+0.00000E+00+0.00000E+00-8.88000E-01-8.88000E-01+0.00000E+00+0.00000E+00-2.20000E-01+0.00000E+00+0.00000E+00+0.00000E+00058003501+4.00000E+02+2.00000E+00000540024D02003004000000000570051025.0000E+010000100000+0.0000E+00+0.0000E+00058003502+1.00000E+06+0.00000E+0000058003500+4.00000E+08+2.00000E+0000052014900BHN0000003~001002+49.020590+008.367240+0129.0000.0000.0+00.00001125.0000E+010.0000E+000000GC~2007,325,14:37:00.0000~2008,017,07:53:00.0000~N0530334A01001003+1.00000E+00+2.00000E+00003+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00003-8.88000E-01+8.88000E-01+0.00000E+00+0.00000E+00-8.88000E-01-8.88000E-01+0.00000E+00+0.00000E+00-2.20000E-01+0.00000E+00+0.00000E+00+0.00000E+00058003501+4.00000E+02+2.00000E+00000540024D02003004000000000570051025.0000E+010000100000+0.0000E+00+0.0000E+000580035000008S*02+1.00000E+06+0.00000E+0000058003500+4.00000E+08+2.00000E+0000052014900BHZ0000003~001002+49.020590+008.367240+0129.0000.0000.0-90.00001125.0000E+010.0000E+000000GC~2007,325,14:37:00.0000~2008,017,07:53:00.0000~N0530334A01001003+1.00000E+00+2.00000E+00003+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00003-8.88000E-01+8.88000E-01+0.00000E+00+0.00000E+00-8.88000E-01-8.88000E-01+0.00000E+00+0.00000E+00-2.20000E-01+0.00000E+00+0.00000E+00+0.00000E+00058003501+4.00000E+02+2.00000E+00000540024D02003004000000000570051025.0000E+010000100000+0.0000E+00+0.0000E+00058003502+1.00000E+06+0.00000E+0000058003500+4.00000E+08+2.00000E+0000052014900HHE0000002~001002+49.020590+008.367240+0129.0000.0090.0+00.00001121.0000E+020.0000E+000000GC~2008,193,09:51:00.0000~2008,340,10:00:00.0000~N0530862A01001003+3.47380E+17+2.00000E+00006+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00-1.51500E+01+0.00000E+00+0.00000E+00+0.00000E+00-1.76600E+02+0.00000E+00+0.00000E+00+0.00000E+00-4.63100E+02+4.30500E+02+0.00000E+00+0.00000E+00-4.63100E+02+4.30500E+02+0.00000E+00+0.00000E+00011-3.70000E-02+3.70000E-02+0.00000E+00+0.00000E+00-3.70000E-02-3.70000E-02+0.00000E+00+0.00000E+00-1.56400E+01+0.00000E+00+0.00000E+00+0.00000E+00-9.73400E+01-4.00700E+02+0.00000E+00+0.00000E+00-9.73400E+01+4.00700E+02+0.00000E+00+0.00000E+00-2.55100E+02+0.00000E+00+0.00000E+00+0.00000E+00-3.74800E+02+0.00000E+00+0.00000E+00+0.00000E+00-5.20300E+02+0.00000E+00+0.00000E+00+0.00000E+00-1.05300E+04+1.00500E+04+0.00000E+00+0.00000E+00-1.05300E+04-1.00500E+04+0.00000E+00+0.00000E+00-1.33000E+04+0.00000E+00+0.00000E+00+0.00000E+00058003501+1.50000E+03+2.00000E+00000540024D02003004000000000570051021.0000E+020000100000+0.0000E+00+0.0000E+00058003502+1.00000E+06+0.00000E+0000058003500+1.50000E+09+2.00000E+0000052014900HHN0000002~001002+49.020590+008.367240+0129.0000.0000.0+00.00001121.0000E+020.0000E+000000GC~2008,193,09:51:00.0000~2008,340,10:00:00.0000~N0530862A01001003+3.47380E+17+2.00000E+00006+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00-1.51500E+01+0.00000E+00+0.00000E+00+0.00000E+00-1.76600E+02+0.00000E+00+0.00000E+00+0.00000E+00-4.63100E+02+4.30500E+02+0.00000E+00+0.00000E+00-4.63100E+02+4.30500E+02+0.00000E+00+0.00000E+00011-3.70000E-02+3.70000E-02+0.00000E+00+0.00000E+00-3.70000E-02-3.70000E-02+0.00000E+00+0.00000E+00-1.56400E+01+0.00000E+00+0.00000E+00+0.00000E+00-9.73400E+01-4.00700E+02+0.00000E+00+0.00000E+00-9.73400E+01+4.00700E+02+0.00000E+00+0.00000E+00-2.55100E+02+0.00000E+00+0.00000E+00+0.00000E+00-3.74800E+02+0.00000E+00+0.00000E+00+0.00000E+00-5.20300E+02+0.00000E+00+0.00000E+00+0.00000E+00-1.05300E+04+1.00500E+04+0.00000E+00+0.00000E+00-1.05300E+04-1.00500E+04+0.00000E+00+0.00000E+00-1.33000E+04+0.00000E+00+0.00000E+00+0.00000E+00058003501+1.50000E+03+2.00000E+00000540024D02003004000000000570051021.0000E+020000100000+0.0000E+00+0.0000E+00058003502+1.00000E+06+0.00000E+0000058003500+1.50000E+09+2.00000E+0000052014900HHZ0000002~001002+49.020590+008.367240+0129.0000.0000.0-90.00001121.0000E+020.0000E+000000GC~2008,193,09:51:00.0000~2008,340,10:00:00.0000~N0530862A01001003+3.47380E+17+2.00000E+00006+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00-1.51500E+01+0.00000E+00+0.00000E+00+0.00000E+00-1.76600E+02+0.00000E+00+0.00000E+00+0.00000E+00-4.63100E+02+4.30500E+02+0.00000E+00+0.00000E+00-4.63100E+02+4.30500E+02+0.00000E+00+0.00000E+00011-3.70000E-02+3.70000E-02+0.00000E+00+0.00000E+00-3.70000E-02-3.70000E-02+0.00000E+00+0.00000E+00-1.56400E+01+0.00000E+00+0.00000E+00+0.00000E+00-9.73400E+01-4.00700E+02+0.00000E+00+0.00000E+00-9.73400E+01+4.00700E+02+0.00000E+00+0.00000E+00-2.55100E+02+0.00000E+00+0.00000E+00+0.00000E+00-3.74800E+02+0.00000E+00+0.00000E+00+0.00000E+00-5.20300E+02+0.00000E+00+0.00000E+00+0.00000E+00-1.05300E+04+1.00500E+04+0.00000E+00+0.00000E+00-1.05300E+04-1.00500E+04+0.00000E+00+0.00000E+00-1.33000E+04+0.00000009S*000E+00+0.00000E+00+0.00000E+00058003501+1.50000E+03+2.00000E+00000540024D02003004000000000570051021.0000E+020000100000+0.0000E+00+0.0000E+00058003502+1.00000E+06+0.00000E+0000058003500+1.50000E+09+2.00000E+0000052014900HHE0000002~001002+49.020590+008.367240+0129.0000.0090.0+00.00001121.0000E+020.0000E+000000GC~2009,132,11:19:00.0000~2010,046,14:00:00.0000~N0530862A01001003+3.47380E+17+2.00000E+00006+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00-1.51500E+01+0.00000E+00+0.00000E+00+0.00000E+00-1.76600E+02+0.00000E+00+0.00000E+00+0.00000E+00-4.63100E+02+4.30500E+02+0.00000E+00+0.00000E+00-4.63100E+02+4.30500E+02+0.00000E+00+0.00000E+00011-3.70000E-02+3.70000E-02+0.00000E+00+0.00000E+00-3.70000E-02-3.70000E-02+0.00000E+00+0.00000E+00-1.56400E+01+0.00000E+00+0.00000E+00+0.00000E+00-9.73400E+01-4.00700E+02+0.00000E+00+0.00000E+00-9.73400E+01+4.00700E+02+0.00000E+00+0.00000E+00-2.55100E+02+0.00000E+00+0.00000E+00+0.00000E+00-3.74800E+02+0.00000E+00+0.00000E+00+0.00000E+00-5.20300E+02+0.00000E+00+0.00000E+00+0.00000E+00-1.05300E+04+1.00500E+04+0.00000E+00+0.00000E+00-1.05300E+04-1.00500E+04+0.00000E+00+0.00000E+00-1.33000E+04+0.00000E+00+0.00000E+00+0.00000E+00058003501+1.50000E+03+2.00000E+00000540024D02003004000000000570051021.0000E+020000100000+0.0000E+00+0.0000E+00058003502+1.00000E+06+0.00000E+0000058003500+1.50000E+09+2.00000E+0000052014900HHN0000002~001002+49.020590+008.367240+0129.0000.0000.0+00.00001121.0000E+020.0000E+000000GC~2009,132,11:19:00.0000~2010,046,14:00:00.0000~N0530862A01001003+3.47380E+17+2.00000E+00006+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00-1.51500E+01+0.00000E+00+0.00000E+00+0.00000E+00-1.76600E+02+0.00000E+00+0.00000E+00+0.00000E+00-4.63100E+02+4.30500E+02+0.00000E+00+0.00000E+00-4.63100E+02+4.30500E+02+0.00000E+00+0.00000E+00011-3.70000E-02+3.70000E-02+0.00000E+00+0.00000E+00-3.70000E-02-3.70000E-02+0.00000E+00+0.00000E+00-1.56400E+01+0.00000E+00+0.00000E+00+0.00000E+00-9.73400E+01-4.00700E+02+0.00000E+00+0.00000E+00-9.73400E+01+4.00700E+02+0.00000E+00+0.00000E+00-2.55100E+02+0.00000E+00+0.00000E+00+0.00000E+00-3.74800E+02+0.00000E+00+0.00000E+00+0.00000E+00-5.20300E+02+0.00000E+00+0.00000E+00+0.00000E+00-1.05300E+04+1.00500E+04+0.00000E+00+0.00000E+00-1.05300E+04-1.00500E+04+0.00000E+00+0.00000E+00-1.33000E+04+0.00000E+00+0.00000E+00+0.00000E+00058003501+1.50000E+03+2.00000E+00000540024D02003004000000000570051021.0000E+020000100000+0.0000E+00+0.0000E+00058003502+1.00000E+06+0.00000E+0000058003500+1.50000E+09+2.00000E+0000052014900HHZ0000002~001002+49.020590+008.367240+0129.0000.0000.0-90.00001121.0000E+020.0000E+000000GC~2009,132,11:19:00.0000~2010,046,14:00:00.0000~N0530862A01001003+3.47380E+17+2.00000E+00006+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00-1.51500E+01+0.00000E+00+0.00000E+00+0.00000E+00-1.76600E+02+0.00000E+00+0.00000E+00+0.00000E+00-4.63100E+02+4.30500E+02+0.00000E+00+0.00000E+00-4.63100E+02+4.30500E+02+0.00000E+00+0.00000E+00011-3.70000E-02+3.70000E-02+0.00000E+00+0.00000E+00-3.70000E-02-3.70000E-02+0.00000E+00+0.00000E+00-1.56400E+01+0.00000E+00+0.00000E+00+0.00000E+00-9.73400E+01-4.00700E+02+0.00000E+00+0.00000E+00-9.73400E+01+4.00700E+02+0.00000E+00+0.00000E+00-2.55100E+02+0.00000E+00+0.00000E+00+0.00000E+00-3.74800E+02+0.00000E+00+0.00000E+00+0.00000E+00-5.20300E+02+0.00000E+00+0.00000E+00+0.00000E+00-1.05300E+04+1.00500E+04+0.00000E+00+0.00000E+00-1.05300E+04-1.00500E+04+0.00000E+00+0.00000E+00-1.33000E+04+0.00000E+00+0.00000E+00+0.00000E+00058003501+1.50000E+03+2.00000E+00000540024D02003004000000000570051021.0000E+020000100000+0.0000E+00+0.0000E+00058003502+1.00000E+06+0.00000E+0000058003500+1.50000E+09+2.00000E+0000052014900HHE0000002~001002+49.020590+008.367240+0129.0000.0090.0+00.00001121.0000E+020.0000E+000000GC~2010,046,14:28:00.0000~2010,097,07:26:00.0000~N0530862A01001003+3.47380E+17+2.00000E+00006+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00-1.51500E+01+0.0000010S*0000E+00+0.00000E+00+0.00000E+00-1.76600E+02+0.00000E+00+0.00000E+00+0.00000E+00-4.63100E+02+4.30500E+02+0.00000E+00+0.00000E+00-4.63100E+02+4.30500E+02+0.00000E+00+0.00000E+00011-3.70000E-02+3.70000E-02+0.00000E+00+0.00000E+00-3.70000E-02-3.70000E-02+0.00000E+00+0.00000E+00-1.56400E+01+0.00000E+00+0.00000E+00+0.00000E+00-9.73400E+01-4.00700E+02+0.00000E+00+0.00000E+00-9.73400E+01+4.00700E+02+0.00000E+00+0.00000E+00-2.55100E+02+0.00000E+00+0.00000E+00+0.00000E+00-3.74800E+02+0.00000E+00+0.00000E+00+0.00000E+00-5.20300E+02+0.00000E+00+0.00000E+00+0.00000E+00-1.05300E+04+1.00500E+04+0.00000E+00+0.00000E+00-1.05300E+04-1.00500E+04+0.00000E+00+0.00000E+00-1.33000E+04+0.00000E+00+0.00000E+00+0.00000E+00058003501+1.50000E+03+2.00000E+00000540024D02003004000000000570051021.0000E+020000100000+0.0000E+00+0.0000E+00058003502+1.00000E+06+0.00000E+0000058003500+1.50000E+09+2.00000E+0000052014900HHN0000002~001002+49.020590+008.367240+0129.0000.0000.0+00.00001121.0000E+020.0000E+000000GC~2010,046,14:28:00.0000~2010,097,07:26:00.0000~N0530862A01001003+3.47380E+17+2.00000E+00006+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00-1.51500E+01+0.00000E+00+0.00000E+00+0.00000E+00-1.76600E+02+0.00000E+00+0.00000E+00+0.00000E+00-4.63100E+02+4.30500E+02+0.00000E+00+0.00000E+00-4.63100E+02+4.30500E+02+0.00000E+00+0.00000E+00011-3.70000E-02+3.70000E-02+0.00000E+00+0.00000E+00-3.70000E-02-3.70000E-02+0.00000E+00+0.00000E+00-1.56400E+01+0.00000E+00+0.00000E+00+0.00000E+00-9.73400E+01-4.00700E+02+0.00000E+00+0.00000E+00-9.73400E+01+4.00700E+02+0.00000E+00+0.00000E+00-2.55100E+02+0.00000E+00+0.00000E+00+0.00000E+00-3.74800E+02+0.00000E+00+0.00000E+00+0.00000E+00-5.20300E+02+0.00000E+00+0.00000E+00+0.00000E+00-1.05300E+04+1.00500E+04+0.00000E+00+0.00000E+00-1.05300E+04-1.00500E+04+0.00000E+00+0.00000E+00-1.33000E+04+0.00000E+00+0.00000E+00+0.00000E+00058003501+1.50000E+03+2.00000E+00000540024D02003004000000000570051021.0000E+020000100000+0.0000E+00+0.0000E+00058003502+1.00000E+06+0.00000E+0000058003500+1.50000E+09+2.00000E+0000052014900HHZ0000002~001002+49.020590+008.367240+0129.0000.0000.0-90.00001121.0000E+020.0000E+000000GC~2010,046,14:28:00.0000~2010,097,07:26:00.0000~N0530862A01001003+3.47380E+17+2.00000E+00006+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00-1.51500E+01+0.00000E+00+0.00000E+00+0.00000E+00-1.76600E+02+0.00000E+00+0.00000E+00+0.00000E+00-4.63100E+02+4.30500E+02+0.00000E+00+0.00000E+00-4.63100E+02+4.30500E+02+0.00000E+00+0.00000E+00011-3.70000E-02+3.70000E-02+0.00000E+00+0.00000E+00-3.70000E-02-3.70000E-02+0.00000E+00+0.00000E+00-1.56400E+01+0.00000E+00+0.00000E+00+0.00000E+00-9.73400E+01-4.00700E+02+0.00000E+00+0.00000E+00-9.73400E+01+4.00700E+02+0.00000E+00+0.00000E+00-2.55100E+02+0.00000E+00+0.00000E+00+0.00000E+00-3.74800E+02+0.00000E+00+0.00000E+00+0.00000E+00-5.20300E+02+0.00000E+00+0.00000E+00+0.00000E+00-1.05300E+04+1.00500E+04+0.00000E+00+0.00000E+00-1.05300E+04-1.00500E+04+0.00000E+00+0.00000E+00-1.33000E+04+0.00000E+00+0.00000E+00+0.00000E+00058003501+1.50000E+03+2.00000E+00000540024D02003004000000000570051021.0000E+020000100000+0.0000E+00+0.0000E+00058003502+1.00000E+06+0.00000E+0000058003500+1.50000E+09+2.00000E+0000052014900HHE0000004~001002+49.020590+008.367240+0129.0000.0090.0+00.00001121.0000E+020.0000E+000000GC~2010,097,07:30:00.0000~2010,215,16:00:00.0000~N0530334A01001003+1.00000E+00+5.00000E+00003+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00003-4.44000E+00+4.44000E+00+0.00000E+00+0.00000E+00-4.44000E+00-4.44000E+00+0.00000E+00+0.00000E+00-1.08300E+00+0.00000E+00+0.00000E+00+0.00000E+00058003501+4.00000E+02+5.00000E+00000540024D02003004000000000570051021.0000E+020000100000+0.0000E+00+0.0000E+00058003502+1.00000E+06+0.00000E+0000058003500+4.00000E+08+5.00000E+0000052014900HHN0000004~001002+49.020590+008.367240+0129.0000.0000.0+00.00001121.0000E+020.0000E+000000GC~2010,097,07:30:00.0000~2010,215,16:00:00.0000~N0530334000011S*A01001003+1.00000E+00+5.00000E+00003+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00003-4.44000E+00+4.44000E+00+0.00000E+00+0.00000E+00-4.44000E+00-4.44000E+00+0.00000E+00+0.00000E+00-1.08300E+00+0.00000E+00+0.00000E+00+0.00000E+00058003501+4.00000E+02+5.00000E+00000540024D02003004000000000570051021.0000E+020000100000+0.0000E+00+0.0000E+00058003502+1.00000E+06+0.00000E+0000058003500+4.00000E+08+5.00000E+0000052014900HHZ0000004~001002+49.020590+008.367240+0129.0000.0000.0-90.00001121.0000E+020.0000E+000000GC~2010,097,07:30:00.0000~2010,215,16:00:00.0000~N0530334A01001003+1.00000E+00+5.00000E+00003+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00003-4.44000E+00+4.44000E+00+0.00000E+00+0.00000E+00-4.44000E+00-4.44000E+00+0.00000E+00+0.00000E+00-1.08300E+00+0.00000E+00+0.00000E+00+0.00000E+00058003501+4.00000E+02+5.00000E+00000540024D02003004000000000570051021.0000E+020000100000+0.0000E+00+0.0000E+00058003502+1.00000E+06+0.00000E+0000058003500+4.00000E+08+5.00000E+0000052014900HHE0000002~001002+49.020590+008.367240+0129.0000.0090.0+00.00001122.0000E+020.0000E+000000GC~2010,217,09:29:00.0000~2010,354,13:30:00.0000~N0530862A01001003+3.47380E+17+2.00000E+00006+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00-1.51500E+01+0.00000E+00+0.00000E+00+0.00000E+00-1.76600E+02+0.00000E+00+0.00000E+00+0.00000E+00-4.63100E+02+4.30500E+02+0.00000E+00+0.00000E+00-4.63100E+02+4.30500E+02+0.00000E+00+0.00000E+00011-3.70000E-02+3.70000E-02+0.00000E+00+0.00000E+00-3.70000E-02-3.70000E-02+0.00000E+00+0.00000E+00-1.56400E+01+0.00000E+00+0.00000E+00+0.00000E+00-9.73400E+01-4.00700E+02+0.00000E+00+0.00000E+00-9.73400E+01+4.00700E+02+0.00000E+00+0.00000E+00-2.55100E+02+0.00000E+00+0.00000E+00+0.00000E+00-3.74800E+02+0.00000E+00+0.00000E+00+0.00000E+00-5.20300E+02+0.00000E+00+0.00000E+00+0.00000E+00-1.05300E+04+1.00500E+04+0.00000E+00+0.00000E+00-1.05300E+04-1.00500E+04+0.00000E+00+0.00000E+00-1.33000E+04+0.00000E+00+0.00000E+00+0.00000E+00058003501+1.50000E+03+2.00000E+00000540024D02003004000000000570051022.0000E+020000100000+0.0000E+00+0.0000E+00058003502+1.00000E+06+0.00000E+0000058003500+1.50000E+09+2.00000E+0000052014900HHN0000002~001002+49.020590+008.367240+0129.0000.0000.0+00.00001122.0000E+020.0000E+000000GC~2010,217,09:29:00.0000~2010,354,13:30:00.0000~N0530862A01001003+3.47380E+17+2.00000E+00006+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00-1.51500E+01+0.00000E+00+0.00000E+00+0.00000E+00-1.76600E+02+0.00000E+00+0.00000E+00+0.00000E+00-4.63100E+02+4.30500E+02+0.00000E+00+0.00000E+00-4.63100E+02+4.30500E+02+0.00000E+00+0.00000E+00011-3.70000E-02+3.70000E-02+0.00000E+00+0.00000E+00-3.70000E-02-3.70000E-02+0.00000E+00+0.00000E+00-1.56400E+01+0.00000E+00+0.00000E+00+0.00000E+00-9.73400E+01-4.00700E+02+0.00000E+00+0.00000E+00-9.73400E+01+4.00700E+02+0.00000E+00+0.00000E+00-2.55100E+02+0.00000E+00+0.00000E+00+0.00000E+00-3.74800E+02+0.00000E+00+0.00000E+00+0.00000E+00-5.20300E+02+0.00000E+00+0.00000E+00+0.00000E+00-1.05300E+04+1.00500E+04+0.00000E+00+0.00000E+00-1.05300E+04-1.00500E+04+0.00000E+00+0.00000E+00-1.33000E+04+0.00000E+00+0.00000E+00+0.00000E+00058003501+1.50000E+03+2.00000E+00000540024D02003004000000000570051022.0000E+020000100000+0.0000E+00+0.0000E+00058003502+1.00000E+06+0.00000E+0000058003500+1.50000E+09+2.00000E+0000052014900HHZ0000002~001002+49.020590+008.367240+0129.0000.0000.0-90.00001122.0000E+020.0000E+000000GC~2010,217,09:29:00.0000~2010,354,13:30:00.0000~N0530862A01001003+3.47380E+17+2.00000E+00006+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00-1.51500E+01+0.00000E+00+0.00000E+00+0.00000E+00-1.76600E+02+0.00000E+00+0.00000E+00+0.00000E+00-4.63100E+02+4.30500E+02+0.00000E+00+0.00000E+00-4.63100E+02+4.30500E+02+0.00000E+00+0.00000E+00011-3.70000E-02+3.70000E-02+0.00000E+00+0.00000E+00-3.70000012S*000E-02-3.70000E-02+0.00000E+00+0.00000E+00-1.56400E+01+0.00000E+00+0.00000E+00+0.00000E+00-9.73400E+01-4.00700E+02+0.00000E+00+0.00000E+00-9.73400E+01+4.00700E+02+0.00000E+00+0.00000E+00-2.55100E+02+0.00000E+00+0.00000E+00+0.00000E+00-3.74800E+02+0.00000E+00+0.00000E+00+0.00000E+00-5.20300E+02+0.00000E+00+0.00000E+00+0.00000E+00-1.05300E+04+1.00500E+04+0.00000E+00+0.00000E+00-1.05300E+04-1.00500E+04+0.00000E+00+0.00000E+00-1.33000E+04+0.00000E+00+0.00000E+00+0.00000E+00058003501+1.50000E+03+2.00000E+00000540024D02003004000000000570051022.0000E+020000100000+0.0000E+00+0.0000E+00058003502+1.00000E+06+0.00000E+0000058003500+1.50000E+09+2.00000E+0000052014900HHE0000002~001002+49.020590+008.367240+0129.0000.0090.0+00.00001121.0000E+020.0000E+000000GC~2010,354,14:32:00.0000~2010,356,09:58:00.0000~N0530862A01001003+3.47380E+17+2.00000E+00006+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00-1.51500E+01+0.00000E+00+0.00000E+00+0.00000E+00-1.76600E+02+0.00000E+00+0.00000E+00+0.00000E+00-4.63100E+02+4.30500E+02+0.00000E+00+0.00000E+00-4.63100E+02+4.30500E+02+0.00000E+00+0.00000E+00011-3.70000E-02+3.70000E-02+0.00000E+00+0.00000E+00-3.70000E-02-3.70000E-02+0.00000E+00+0.00000E+00-1.56400E+01+0.00000E+00+0.00000E+00+0.00000E+00-9.73400E+01-4.00700E+02+0.00000E+00+0.00000E+00-9.73400E+01+4.00700E+02+0.00000E+00+0.00000E+00-2.55100E+02+0.00000E+00+0.00000E+00+0.00000E+00-3.74800E+02+0.00000E+00+0.00000E+00+0.00000E+00-5.20300E+02+0.00000E+00+0.00000E+00+0.00000E+00-1.05300E+04+1.00500E+04+0.00000E+00+0.00000E+00-1.05300E+04-1.00500E+04+0.00000E+00+0.00000E+00-1.33000E+04+0.00000E+00+0.00000E+00+0.00000E+00058003501+1.50000E+03+2.00000E+00000540024D02003004000000000570051021.0000E+020000100000+0.0000E+00+0.0000E+00058003502+1.00000E+06+0.00000E+0000058003500+1.50000E+09+2.00000E+0000052014900HHN0000002~001002+49.020590+008.367240+0129.0000.0000.0+00.00001121.0000E+020.0000E+000000GC~2010,354,14:32:00.0000~2010,356,09:58:00.0000~N0530862A01001003+3.47380E+17+2.00000E+00006+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00-1.51500E+01+0.00000E+00+0.00000E+00+0.00000E+00-1.76600E+02+0.00000E+00+0.00000E+00+0.00000E+00-4.63100E+02+4.30500E+02+0.00000E+00+0.00000E+00-4.63100E+02+4.30500E+02+0.00000E+00+0.00000E+00011-3.70000E-02+3.70000E-02+0.00000E+00+0.00000E+00-3.70000E-02-3.70000E-02+0.00000E+00+0.00000E+00-1.56400E+01+0.00000E+00+0.00000E+00+0.00000E+00-9.73400E+01-4.00700E+02+0.00000E+00+0.00000E+00-9.73400E+01+4.00700E+02+0.00000E+00+0.00000E+00-2.55100E+02+0.00000E+00+0.00000E+00+0.00000E+00-3.74800E+02+0.00000E+00+0.00000E+00+0.00000E+00-5.20300E+02+0.00000E+00+0.00000E+00+0.00000E+00-1.05300E+04+1.00500E+04+0.00000E+00+0.00000E+00-1.05300E+04-1.00500E+04+0.00000E+00+0.00000E+00-1.33000E+04+0.00000E+00+0.00000E+00+0.00000E+00058003501+1.50000E+03+2.00000E+00000540024D02003004000000000570051021.0000E+020000100000+0.0000E+00+0.0000E+00058003502+1.00000E+06+0.00000E+0000058003500+1.50000E+09+2.00000E+0000052014900HHZ0000002~001002+49.020590+008.367240+0129.0000.0000.0-90.00001121.0000E+020.0000E+000000GC~2010,354,14:32:00.0000~2010,356,09:58:00.0000~N0530862A01001003+3.47380E+17+2.00000E+00006+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00-1.51500E+01+0.00000E+00+0.00000E+00+0.00000E+00-1.76600E+02+0.00000E+00+0.00000E+00+0.00000E+00-4.63100E+02+4.30500E+02+0.00000E+00+0.00000E+00-4.63100E+02+4.30500E+02+0.00000E+00+0.00000E+00011-3.70000E-02+3.70000E-02+0.00000E+00+0.00000E+00-3.70000E-02-3.70000E-02+0.00000E+00+0.00000E+00-1.56400E+01+0.00000E+00+0.00000E+00+0.00000E+00-9.73400E+01-4.00700E+02+0.00000E+00+0.00000E+00-9.73400E+01+4.00700E+02+0.00000E+00+0.00000E+00-2.55100E+02+0.00000E+00+0.00000E+00+0.00000E+00-3.74800E+02+0.00000E+00+0.00000E+00+0.00000E+00-5.20300E+02+0.00000E+00+0.00000E+00+0.00000E+00-1.05300E+04+1.00500E+04+0.00000E+00+0.00000E+00-1.05300E+04-1.00500E+04+0.00000E+00+0.00000E+00-1.33000E+04+0.00000E+00+0.00000E+00+0.00000E+00058003501+1.50000E+03+2.00000E+0000 000013S 0540024D02003004000000000570051021.0000E+020000100000+0.0000E+00+0.0000E+00058003502+1.00000E+06+0.00000E+0000058003500+1.50000E+09+2.00000E+0000052014900HHE0000002~001002+49.020590+008.367240+0129.0000.0090.0+00.00001122.0000E+020.0000E+000000GC~2010,356,09:59:00.0000~2011,092,17:30:00.0000~N0530862A01001003+3.47380E+17+2.00000E+00006+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00-1.51500E+01+0.00000E+00+0.00000E+00+0.00000E+00-1.76600E+02+0.00000E+00+0.00000E+00+0.00000E+00-4.63100E+02+4.30500E+02+0.00000E+00+0.00000E+00-4.63100E+02+4.30500E+02+0.00000E+00+0.00000E+00011-3.70000E-02+3.70000E-02+0.00000E+00+0.00000E+00-3.70000E-02-3.70000E-02+0.00000E+00+0.00000E+00-1.56400E+01+0.00000E+00+0.00000E+00+0.00000E+00-9.73400E+01-4.00700E+02+0.00000E+00+0.00000E+00-9.73400E+01+4.00700E+02+0.00000E+00+0.00000E+00-2.55100E+02+0.00000E+00+0.00000E+00+0.00000E+00-3.74800E+02+0.00000E+00+0.00000E+00+0.00000E+00-5.20300E+02+0.00000E+00+0.00000E+00+0.00000E+00-1.05300E+04+1.00500E+04+0.00000E+00+0.00000E+00-1.05300E+04-1.00500E+04+0.00000E+00+0.00000E+00-1.33000E+04+0.00000E+00+0.00000E+00+0.00000E+00058003501+1.50000E+03+2.00000E+00000540024D02003004000000000570051022.0000E+020000100000+0.0000E+00+0.0000E+00058003502+1.00000E+06+0.00000E+0000058003500+1.50000E+09+2.00000E+0000052014900HHN0000002~001002+49.020590+008.367240+0129.0000.0000.0+00.00001122.0000E+020.0000E+000000GC~2010,356,09:59:00.0000~2011,092,17:30:00.0000~N0530862A01001003+3.47380E+17+2.00000E+00006+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00-1.51500E+01+0.00000E+00+0.00000E+00+0.00000E+00-1.76600E+02+0.00000E+00+0.00000E+00+0.00000E+00-4.63100E+02+4.30500E+02+0.00000E+00+0.00000E+00-4.63100E+02+4.30500E+02+0.00000E+00+0.00000E+00011-3.70000E-02+3.70000E-02+0.00000E+00+0.00000E+00-3.70000E-02-3.70000E-02+0.00000E+00+0.00000E+00-1.56400E+01+0.00000E+00+0.00000E+00+0.00000E+00-9.73400E+01-4.00700E+02+0.00000E+00+0.00000E+00-9.73400E+01+4.00700E+02+0.00000E+00+0.00000E+00-2.55100E+02+0.00000E+00+0.00000E+00+0.00000E+00-3.74800E+02+0.00000E+00+0.00000E+00+0.00000E+00-5.20300E+02+0.00000E+00+0.00000E+00+0.00000E+00-1.05300E+04+1.00500E+04+0.00000E+00+0.00000E+00-1.05300E+04-1.00500E+04+0.00000E+00+0.00000E+00-1.33000E+04+0.00000E+00+0.00000E+00+0.00000E+00058003501+1.50000E+03+2.00000E+00000540024D02003004000000000570051022.0000E+020000100000+0.0000E+00+0.0000E+00058003502+1.00000E+06+0.00000E+0000058003500+1.50000E+09+2.00000E+0000052014900HHZ0000002~001002+49.020590+008.367240+0129.0000.0000.0-90.00001122.0000E+020.0000E+000000GC~2010,356,09:59:00.0000~2011,092,17:30:00.0000~N0530862A01001003+3.47380E+17+2.00000E+00006+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00-1.51500E+01+0.00000E+00+0.00000E+00+0.00000E+00-1.76600E+02+0.00000E+00+0.00000E+00+0.00000E+00-4.63100E+02+4.30500E+02+0.00000E+00+0.00000E+00-4.63100E+02+4.30500E+02+0.00000E+00+0.00000E+00011-3.70000E-02+3.70000E-02+0.00000E+00+0.00000E+00-3.70000E-02-3.70000E-02+0.00000E+00+0.00000E+00-1.56400E+01+0.00000E+00+0.00000E+00+0.00000E+00-9.73400E+01-4.00700E+02+0.00000E+00+0.00000E+00-9.73400E+01+4.00700E+02+0.00000E+00+0.00000E+00-2.55100E+02+0.00000E+00+0.00000E+00+0.00000E+00-3.74800E+02+0.00000E+00+0.00000E+00+0.00000E+00-5.20300E+02+0.00000E+00+0.00000E+00+0.00000E+00-1.05300E+04+1.00500E+04+0.00000E+00+0.00000E+00-1.05300E+04-1.00500E+04+0.00000E+00+0.00000E+00-1.33000E+04+0.00000E+00+0.00000E+00+0.00000E+00058003501+1.50000E+03+2.00000E+00000540024D02003004000000000570051022.0000E+020000100000+0.0000E+00+0.0000E+00058003502+1.00000E+06+0.00000E+0000058003500+1.50000E+09+2.00000E+0000052014900HHE0000002~001002+49.020590+008.367240+0129.0000.0090.0+00.00001122.0000E+020.0000E+000000GC~2011,105,10:19:00.0000~2012,128,09:35:00.0000~N0530862A01001003+3.47380E+17+2.00000E+00006+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00-1.51500E+01+0.00000E+00+0.00000E+00+0.00000E+00-1.76600E+02+0.00000E+00+0.00000E+000014S*00+0.00000E+00-4.63100E+02+4.30500E+02+0.00000E+00+0.00000E+00-4.63100E+02+4.30500E+02+0.00000E+00+0.00000E+00011-3.70000E-02+3.70000E-02+0.00000E+00+0.00000E+00-3.70000E-02-3.70000E-02+0.00000E+00+0.00000E+00-1.56400E+01+0.00000E+00+0.00000E+00+0.00000E+00-9.73400E+01-4.00700E+02+0.00000E+00+0.00000E+00-9.73400E+01+4.00700E+02+0.00000E+00+0.00000E+00-2.55100E+02+0.00000E+00+0.00000E+00+0.00000E+00-3.74800E+02+0.00000E+00+0.00000E+00+0.00000E+00-5.20300E+02+0.00000E+00+0.00000E+00+0.00000E+00-1.05300E+04+1.00500E+04+0.00000E+00+0.00000E+00-1.05300E+04-1.00500E+04+0.00000E+00+0.00000E+00-1.33000E+04+0.00000E+00+0.00000E+00+0.00000E+00058003501+1.50000E+03+2.00000E+00000540024D02003004000000000570051022.0000E+020000100000+0.0000E+00+0.0000E+00058003502+1.00000E+06+0.00000E+0000058003500+1.50000E+09+2.00000E+0000052014900HHN0000002~001002+49.020590+008.367240+0129.0000.0000.0+00.00001122.0000E+020.0000E+000000GC~2011,105,10:19:00.0000~2012,128,09:35:00.0000~N0530862A01001003+3.47380E+17+2.00000E+00006+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00-1.51500E+01+0.00000E+00+0.00000E+00+0.00000E+00-1.76600E+02+0.00000E+00+0.00000E+00+0.00000E+00-4.63100E+02+4.30500E+02+0.00000E+00+0.00000E+00-4.63100E+02+4.30500E+02+0.00000E+00+0.00000E+00011-3.70000E-02+3.70000E-02+0.00000E+00+0.00000E+00-3.70000E-02-3.70000E-02+0.00000E+00+0.00000E+00-1.56400E+01+0.00000E+00+0.00000E+00+0.00000E+00-9.73400E+01-4.00700E+02+0.00000E+00+0.00000E+00-9.73400E+01+4.00700E+02+0.00000E+00+0.00000E+00-2.55100E+02+0.00000E+00+0.00000E+00+0.00000E+00-3.74800E+02+0.00000E+00+0.00000E+00+0.00000E+00-5.20300E+02+0.00000E+00+0.00000E+00+0.00000E+00-1.05300E+04+1.00500E+04+0.00000E+00+0.00000E+00-1.05300E+04-1.00500E+04+0.00000E+00+0.00000E+00-1.33000E+04+0.00000E+00+0.00000E+00+0.00000E+00058003501+1.50000E+03+2.00000E+00000540024D02003004000000000570051022.0000E+020000100000+0.0000E+00+0.0000E+00058003502+1.00000E+06+0.00000E+0000058003500+1.50000E+09+2.00000E+0000052014900HHZ0000002~001002+49.020590+008.367240+0129.0000.0000.0-90.00001122.0000E+020.0000E+000000GC~2011,105,10:19:00.0000~2012,128,09:35:00.0000~N0530862A01001003+3.47380E+17+2.00000E+00006+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00-1.51500E+01+0.00000E+00+0.00000E+00+0.00000E+00-1.76600E+02+0.00000E+00+0.00000E+00+0.00000E+00-4.63100E+02+4.30500E+02+0.00000E+00+0.00000E+00-4.63100E+02+4.30500E+02+0.00000E+00+0.00000E+00011-3.70000E-02+3.70000E-02+0.00000E+00+0.00000E+00-3.70000E-02-3.70000E-02+0.00000E+00+0.00000E+00-1.56400E+01+0.00000E+00+0.00000E+00+0.00000E+00-9.73400E+01-4.00700E+02+0.00000E+00+0.00000E+00-9.73400E+01+4.00700E+02+0.00000E+00+0.00000E+00-2.55100E+02+0.00000E+00+0.00000E+00+0.00000E+00-3.74800E+02+0.00000E+00+0.00000E+00+0.00000E+00-5.20300E+02+0.00000E+00+0.00000E+00+0.00000E+00-1.05300E+04+1.00500E+04+0.00000E+00+0.00000E+00-1.05300E+04-1.00500E+04+0.00000E+00+0.00000E+00-1.33000E+04+0.00000E+00+0.00000E+00+0.00000E+00058003501+1.50000E+03+2.00000E+00000540024D02003004000000000570051022.0000E+020000100000+0.0000E+00+0.0000E+00058003502+1.00000E+06+0.00000E+0000058003500+1.50000E+09+2.00000E+0000052012700HHE0000002~001002+49.020590+008.367240+0129.0000.0090.0+00.00001122.0000E+020.0000E+000000GC~2012,128,09:36:00.0000~~N0530862A01001003+3.47380E+17+2.00000E+00006+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00-1.51500E+01+0.00000E+00+0.00000E+00+0.00000E+00-1.76600E+02+0.00000E+00+0.00000E+00+0.00000E+00-4.63100E+02+4.30500E+02+0.00000E+00+0.00000E+00-4.63100E+02+4.30500E+02+0.00000E+00+0.00000E+00011-3.70000E-02+3.70000E-02+0.00000E+00+0.00000E+00-3.70000E-02-3.70000E-02+0.00000E+00+0.00000E+00-1.56400E+01+0.00000E+00+0.00000E+00+0.00000E+00-9.73400E+01-4.00700E+02+0.00000E+00+0.00000E+00-9.73400E+01+4.00700E+02+0.00000E+00+0.00000E+00-2.55100E+02+0.00000E+00+0.00000E+00+0.00000E+00-3.74800E+02+0.00000E+00+0.00000E+00+0.00000E+00-5.20300E+02+0.00000E+00+0.00000E+00+0.00000E+00-1.05300E+04+1.00500E+04+0.00000E+00+0.0000015S*0000E+00-1.05300E+04-1.00500E+04+0.00000E+00+0.00000E+00-1.33000E+04+0.00000E+00+0.00000E+00+0.00000E+00058003501+1.50000E+03+2.00000E+00000540024D02003004000000000570051022.0000E+020000100000+0.0000E+00+0.0000E+00058003502+1.00000E+06+0.00000E+0000058003500+1.50000E+09+2.00000E+0000052012700HHN0000002~001002+49.020590+008.367240+0129.0000.0000.0+00.00001122.0000E+020.0000E+000000GC~2012,128,09:36:00.0000~~N0530862A01001003+3.47380E+17+2.00000E+00006+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00-1.51500E+01+0.00000E+00+0.00000E+00+0.00000E+00-1.76600E+02+0.00000E+00+0.00000E+00+0.00000E+00-4.63100E+02+4.30500E+02+0.00000E+00+0.00000E+00-4.63100E+02+4.30500E+02+0.00000E+00+0.00000E+00011-3.70000E-02+3.70000E-02+0.00000E+00+0.00000E+00-3.70000E-02-3.70000E-02+0.00000E+00+0.00000E+00-1.56400E+01+0.00000E+00+0.00000E+00+0.00000E+00-9.73400E+01-4.00700E+02+0.00000E+00+0.00000E+00-9.73400E+01+4.00700E+02+0.00000E+00+0.00000E+00-2.55100E+02+0.00000E+00+0.00000E+00+0.00000E+00-3.74800E+02+0.00000E+00+0.00000E+00+0.00000E+00-5.20300E+02+0.00000E+00+0.00000E+00+0.00000E+00-1.05300E+04+1.00500E+04+0.00000E+00+0.00000E+00-1.05300E+04-1.00500E+04+0.00000E+00+0.00000E+00-1.33000E+04+0.00000E+00+0.00000E+00+0.00000E+00058003501+1.50000E+03+2.00000E+00000540024D02003004000000000570051022.0000E+020000100000+0.0000E+00+0.0000E+00058003502+1.00000E+06+0.00000E+0000058003500+1.50000E+09+2.00000E+0000052012700HHZ0000002~001002+49.020590+008.367240+0129.0000.0000.0-90.00001122.0000E+020.0000E+000000GC~2012,128,09:36:00.0000~~N0530862A01001003+3.47380E+17+2.00000E+00006+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00-1.51500E+01+0.00000E+00+0.00000E+00+0.00000E+00-1.76600E+02+0.00000E+00+0.00000E+00+0.00000E+00-4.63100E+02+4.30500E+02+0.00000E+00+0.00000E+00-4.63100E+02+4.30500E+02+0.00000E+00+0.00000E+00011-3.70000E-02+3.70000E-02+0.00000E+00+0.00000E+00-3.70000E-02-3.70000E-02+0.00000E+00+0.00000E+00-1.56400E+01+0.00000E+00+0.00000E+00+0.00000E+00-9.73400E+01-4.00700E+02+0.00000E+00+0.00000E+00-9.73400E+01+4.00700E+02+0.00000E+00+0.00000E+00-2.55100E+02+0.00000E+00+0.00000E+00+0.00000E+00-3.74800E+02+0.00000E+00+0.00000E+00+0.00000E+00-5.20300E+02+0.00000E+00+0.00000E+00+0.00000E+00-1.05300E+04+1.00500E+04+0.00000E+00+0.00000E+00-1.05300E+04-1.00500E+04+0.00000E+00+0.00000E+00-1.33000E+04+0.00000E+00+0.00000E+00+0.00000E+00058003501+1.50000E+03+2.00000E+00000540024D02003004000000000570051022.0000E+020000100000+0.0000E+00+0.0000E+00058003502+1.00000E+06+0.00000E+0000058003500+1.50000E+09+2.00000E+0000 000016 \ No newline at end of file diff --git a/tests/test_Metadata/test_data/dless_multiple_times/MAGS2_LE_ROTT.dless b/tests/test_Metadata/test_data/dless_multiple_times/MAGS2_LE_ROTT.dless new file mode 100644 index 00000000..1d5849d3 --- /dev/null +++ b/tests/test_Metadata/test_data/dless_multiple_times/MAGS2_LE_ROTT.dless @@ -0,0 +1 @@ +000001V 010008402.4121950,001,00:00:00.0000~2500,001,00:00:00.0000~2018,194,18:08:41.0000~~~0110021001ROTT 000003 000002A 0300146Steim-1 Integer Compression Format~000105006F1 P4 W4 D C2 R1 P8 W4 D C2~P0 W4 N15 S2,0,1~T0 X W4~T1 Y4 W7 D C2~T2 Y2 W2 D C2~T3 N0 W4 D C2~0330047001Landeserdbebendienst Rheinland-Pfalz~0330061002LE-3D/BH, 1 s, 400 V/m/s-EDR-209, Low (default) ga~0330051003Titan 4g-EDR-209, Very Low gain, 200 sps~0340044001M/S~Velocity in Meters Per Second~0340020002A~Amperes~0340032003COUNTS~Digital Counts~0340062004M/S**2~Acceleration in Meters Per Second Per Second~ 000003S 0500128ROTT +49.129100+008.148700+0128.00006000Rottmuehle Steinweiler~0013210102014,325,12:00:00.0000~2015,078,13:00:00.0000~NLE0520149 EHE0000002~001002+49.129100+008.148700-0177.0305.0000.0+00.00001122.0000E+022.0000E-020000TG~2014,325,12:00:00.0000~2015,078,13:00:00.0000~N0530334A01001003+1.00000E+00+5.00000E+00003+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00003-4.44400E+00+4.44400E+00+0.00000E+00+0.00000E+00-4.44400E+00-4.44400E+00+0.00000E+00+0.00000E+00-1.08300E+00+0.00000E+00+0.00000E+00+0.00000E+00058003501+4.00000E+02+5.00000E+0000058003502+2.50000E+00+5.00000E-02000540048D030030040001+1.00000E+00+0.00000E+0000000570051031.9200E+050000100000+0.0000E+00+0.0000E+00058003503+4.00000E+05+5.00000E-02000541152D040040040047+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+3.81470E-06+0.00000E+00+2.28882E-05+0.00000E+00+8.01086E-05+0.00000E+00+2.13623E-04+0.00000E+00+4.80652E-04+0.00000E+00+9.61304E-04+0.00000E+00+1.76239E-03+0.00000E+00+3.02124E-03+0.00000E+00+4.88663E-03+0.00000E+00+7.49969E-03+0.00000E+00+1.09749E-02+0.00000E+00+1.53809E-02+0.00000E+00+2.07214E-02+0.00000E+00+2.69165E-02+0.00000E+00+3.37830E-02+0.00000E+00+4.10156E-02+0.00000E+00+4.82254E-02+0.00000E+00+5.49774E-02+0.00000E+00+6.08292E-02+0.00000E+00+6.53687E-02+0.00000E+00+6.82526E-02+0.00000E+00+6.92444E-02+0.00000E+00+6.82526E-02+0.00000E+00+6.53687E-02+0.00000E+00+6.08292E-02+0.00000E+00+5.49774E-02+0.00000E+00+4.82254E-02+0.00000E+00+4.10156E-02+0.00000E+00+3.37830E-02+0.00000E+00+2.69165E-02+0.00000E+00+2.07214E-02+0.00000E+00+1.53809E-02+0.00000E+00+1.09749E-02+0.00000E+00+7.49969E-03+0.00000E+00+4.88663E-03+0.00000E+00+3.02124E-03+0.00000E+00+1.76239E-03+0.00000E+00+9.61304E-04+0.00000E+00+4.80652E-04+0.00000E+00+2.13623E-04+0.00000E+00+8.01086E-05+0.00000E+00+2.28882E-05+0.00000E+00+3.81470E-06+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+0000000570051041.9200E+050000800000+1.1979E-04+1.1979E-04058003504+1.00000E+00+5.00000E-02000541776D050040040073+7.86395E-07+0.00000E+00+2.15223E-06+0.00000E+00+4.09013E-06+0.00000E+00+6.42053E-06+0.00000E+00+7.61300E-06+0.00000E+00+4.52134E-06+0.00000E+00-8.38839E-06+0.00000E+00-4.00745E-05+0.00000E+00-1.08702E-04+0.00000E+00-2.31570E-04+0.00000E+00-4.32673E-04+0.00000E+00-7.41861E-04+0.00000E+00-1.18635E-03+0.00000E+00-1.78887E-03+0.00000E+00-2.56156E-03+0.00000E+00-3.49756E-03+0.00000E+00-4.54784E-03+0.00000E+00-5.64473E-03+0.00000E+00-6.67437E-03+0.00000E+00-7.46932E-03+0.00000E+00-7.83206E-03+0.00000E+00-7.53472E-03+0.00000E+00-6.33480E-03+0.00000E+00-3.99943E-03+0.00000E+00-3.60688E-04+0.00000E+00+4.71408E-03+0.00000E+00+1.12572E-02+0.00000E+00+1.91611E-02+0.00000E+00+2.82115E-02+0.00000E+00+3.80655E-02+0.00000E+00+4.82646E-02+0.00000E+00+5.82654E-02+0.00000E+00+6.75164E-02+0.00000E+00+7.54318E-02+0.00000E+00+8.14859E-02+0.00000E+00+8.52972E-02+0.00000E+00+8.65986E-02+0.00000E+00+8.52972E-02+0.00000E+00+8.14859E-02+0.00000E+00+7.54318E-02+0.00000E+00+6.75164E-02+0.00000E+00+5.82654E-02+0.00000E+00+4.82646E-02+0.00000E+00+3.80655E-02+0.00000E+00+2.82115E-02+0.00000E+00+1.91611E-02+0.00000E+00+1.12572E-02+0.00000E+00+4.71408E-03+0.00000E+00-3.60688E-04+0.00000E+00-3.99943E-03+0.00000E+00-6.33480E-03+0.00000E+00-7.53472E-03+0.00000E+00-7.83206E-03+0.00000E+00-7.46932E-03+0.00000E+00-6.67437E-03+0.00000E+00-5.64473E-03+0.00000E+00-4.54784E-03+0.00000E+00-3.49756E-03+0.00000E+00-2.56156E-03+0.00000E+00-1.78887E-03+0.00000E+00-1.18635E-03+0.00000E+00-7.41861E-04+0.00000E+00-4.32673E-04+0.00000E+00-2.31570E-04+0.00000E+00-1.08702E-04+0.00000E+00-4.00745E-05+0.00000E+00-8.38839E-06+0.00000E+00+4.52134E-06+0.00000E+00+7.61300E-06+0.00000E+00+6.42053E-06+0.00000E+00+4.09013E-06+0.00000E+00+2.15223E-06+0.00000E+00+7.86395E-07+0.00000E+0000000570051052.4000E+040000800000+1.5000E-03+1.5000E-03058003505+1.00000E+00+5.00000E-02000544320D060040040179+1.65488E-07+0.00000E+00+7.48132E-07+0.00000E+00+1.76664E-06+0.00000E+00+1.62612E-06+0.00000E+00-5.16640E-06+0.00000E+00-3.00692E-05+0.00000E+00-8.97376E000004S*-05+0.00000E+00-1.99571E-04+0.00000E+00-3.61172E-04+0.00000E+00-5.48500E-04+0.00000E+00-7.02688E-04+0.00000E+00-7.45976E-04+0.00000E+00-6.17072E-04+0.00000E+00-3.15191E-04+0.00000E+00+7.38188E-05+0.00000E+00+3.95725E-04+0.00000E+00+4.96800E-04+0.00000E+00+3.15263E-04+0.00000E+00-5.96548E-05+0.00000E+00-4.11872E-04+0.00000E+00-5.12780E-04+0.00000E+00-2.69536E-04+0.00000E+00+1.89248E-04+0.00000E+00+5.66172E-04+0.00000E+00+5.78372E-04+0.00000E+00+1.64727E-04+0.00000E+00-4.31664E-04+0.00000E+00-7.92432E-04+0.00000E+00-6.08316E-04+0.00000E+00+6.76780E-05+0.00000E+00+7.98316E-04+0.00000E+00+1.03172E-03+0.00000E+00+5.07504E-04+0.00000E+00-4.91744E-04+0.00000E+00-1.26810E-03+0.00000E+00-1.18261E-03+0.00000E+00-1.64670E-04+0.00000E+00+1.13876E-03+0.00000E+00+1.75363E-03+0.00000E+00+1.09177E-03+0.00000E+00-5.24120E-04+0.00000E+00-1.97068E-03+0.00000E+00-2.08536E-03+0.00000E+00-5.79052E-04+0.00000E+00+1.60144E-03+0.00000E+00+2.83576E-03+0.00000E+00+2.01276E-03+0.00000E+00-5.13156E-04+0.00000E+00-2.98815E-03+0.00000E+00-3.44765E-03+0.00000E+00-1.24599E-03+0.00000E+00+2.24272E-03+0.00000E+00+4.43120E-03+0.00000E+00+3.40590E-03+0.00000E+00-4.57304E-04+0.00000E+00-4.47584E-03+0.00000E+00-5.47828E-03+0.00000E+00-2.26220E-03+0.00000E+00+3.18035E-03+0.00000E+00+6.81616E-03+0.00000E+00+5.50776E-03+0.00000E+00-3.65328E-04+0.00000E+00-6.73316E-03+0.00000E+00-8.58052E-03+0.00000E+00-3.81782E-03+0.00000E+00+4.65228E-03+0.00000E+00+1.05646E-02+0.00000E+00+8.82560E-03+0.00000E+00-2.56374E-04+0.00000E+00-1.04496E-02+0.00000E+00-1.37224E-02+0.00000E+00-6.39512E-03+0.00000E+00+7.26512E-03+0.00000E+00+1.72312E-02+0.00000E+00+1.48181E-02+0.00000E+00-1.54011E-04+0.00000E+00-1.77680E-02+0.00000E+00-2.41384E-02+0.00000E+00-1.17549E-02+0.00000E+00+1.32733E-02+0.00000E+00+3.32147E-02+0.00000E+00+3.01309E-02+0.00000E+00-8.13468E-05+0.00000E+00-4.08284E-02+0.00000E+00-6.13256E-02+0.00000E+00-3.42109E-02+0.00000E+00+4.58968E-02+0.00000E+00+1.54886E-01+0.00000E+00+2.48713E-01+0.00000E+00+2.85658E-01+0.00000E+00+2.48713E-01+0.00000E+00+1.54886E-01+0.00000E+00+4.58968E-02+0.00000E+00-3.42109E-02+0.00000E+00-6.13256E-02+0.00000E+00-4.08284E-02+0.00000E+00-8.13468E-05+0.00000E+00+3.01309E-02+0.00000E+00+3.32147E-02+0.00000E+00+1.32733E-02+0.00000E+00-1.17549E-02+0.00000E+00-2.41384E-02+0.00000E+00-1.77680E-02+0.00000E+00-1.54011E-04+0.00000E+00+1.48181E-02+0.00000E+00+1.72312E-02+0.00000E+00+7.26512E-03+0.00000E+00-6.39512E-03+0.00000E+00-1.37224E-02+0.00000E+00-1.04496E-02+0.00000E+00-2.56374E-04+0.00000E+00+8.82560E-03+0.00000E+00+1.05646E-02+0.00000E+00+4.65228E-03+0.00000E+00-3.81782E-03+0.00000E+00-8.58052E-03+0.00000E+00-6.73316E-03+0.00000E+00-3.65328E-04+0.00000E+00+5.50776E-03+0.00000E+00+6.81616E-03+0.00000E+00+3.18035E-03+0.00000E+00-2.26220E-03+0.00000E+00-5.47828E-03+0.00000E+00-4.47584E-03+0.00000E+00-4.57304E-04+0.00000E+00+3.40590E-03+0.00000E+00+4.43120E-03+0.00000E+00+2.24272E-03+0.00000E+00-1.24599E-03+0.00000E+00-3.44765E-03+0.00000E+00-2.98815E-03+0.00000E+00-5.13156E-04+0.00000E+00+2.01276E-03+0.00000E+00+2.83576E-03+0.00000E+00+1.60144E-03+0.00000E+00-5.79052E-04+0.00000E+00-2.08536E-03+0.00000E+00-1.97068E-03+0.00000E+00-5.24120E-04+0.00000E+00+1.09177E-03+0.00000E+00+1.75363E-03+0.00000E+00+1.13876E-03+0.00000E+00-1.64670E-04+0.00000E+00-1.18261E-03+0.00000E+00-1.26810E-03+0.00000E+00-4.91744E-04+0.00000E+00+5.07504E-04+0.00000E+00+1.03172E-03+0.00000E+00+7.98316E-04+0.00000E+00+6.76780E-05+0.00000E+00-6.08316E-04+0.00000E+00-7.92432E-04+0.00000E+00-4.31664E-04+0.00000E+00+1.64727E-04+0.00000E+00+5.78372E-04+0.00000E+00+5.66172E-04+0.00000E+00+1.89248E-04+0.00000E+00-2.69536E-04+0.00000E+00-5.12780E-04+0.00000E+00-4.11872E-04+0.00000E+00-5.96548E-05+0.00000E+00+3.15263E-04+0.00000E+00+4.96800E-04+0.00000E+00+3.95725E-04+0.00000E+00+7.38188E-05+0.00000E+00-3.15191E-04+0.00000E+00-6.17072E-04+0.00000E+00-7.45976E-04+0.00000E+00-7.02688E-04+0.00000E+00-5.48500E-04+0.00000E+00-3.61172E-04+0.00000E+00-1.99571E-04+0.00000E+00-8.97376E-05+0.00000E+00-3.00692E-05+0.00000E+00-5.16640E-06+0.00000E+00+1.62612E-06+0.00000E+00+1.76664E-06+0.00000005S*000E+00+7.48132E-07+0.00000E+00+1.65488E-07+0.00000E+0000000570051063.0000E+030000300000+2.9667E-02+2.9667E-02058003506+1.00000E+00+5.00000E-02000547680D070040040319+7.72762E-09+0.00000E+00+4.52378E-09+0.00000E+00-5.32080E-08+0.00000E+00-2.80036E-07+0.00000E+00-9.08544E-07+0.00000E+00-2.34472E-06+0.00000E+00-5.21464E-06+0.00000E+00-1.03793E-05+0.00000E+00-1.88893E-05+0.00000E+00-3.18550E-05+0.00000E+00-5.02182E-05+0.00000E+00-7.44366E-05+0.00000E+00-1.04124E-04+0.00000E+00-1.37722E-04+0.00000E+00-1.72307E-04+0.00000E+00-2.03638E-04+0.00000E+00-2.26532E-04+0.00000E+00-2.35600E-04+0.00000E+00-2.26268E-04+0.00000E+00-1.95955E-04+0.00000E+00-1.45142E-04+0.00000E+00-7.80380E-05+0.00000E+00-2.59160E-06+0.00000E+00+7.03544E-05+0.00000E+00+1.28752E-04+0.00000E+00+1.61671E-04+0.00000E+00+1.61835E-04+0.00000E+00+1.27774E-04+0.00000E+00+6.50032E-05+0.00000E+00-1.42499E-05+0.00000E+00-9.29802E-05+0.00000E+00-1.52783E-04+0.00000E+00-1.78068E-04+0.00000E+00-1.60164E-04+0.00000E+00-1.00242E-04+0.00000E+00-1.01214E-05+0.00000E+00+8.95560E-05+0.00000E+00+1.73672E-04+0.00000E+00+2.18690E-04+0.00000E+00+2.09036E-04+0.00000E+00+1.42114E-04+0.00000E+00+3.04418E-05+0.00000E+00-1.00068E-04+0.00000E+00-2.15680E-04+0.00000E+00-2.83208E-04+0.00000E+00-2.79208E-04+0.00000E+00-1.97535E-04+0.00000E+00-5.29412E-05+0.00000E+00+1.20744E-04+0.00000E+00+2.78002E-04+0.00000E+00+3.73138E-04+0.00000E+00+3.73118E-04+0.00000E+00+2.68272E-04+0.00000E+00+7.75194E-05+0.00000E+00-1.53942E-04+0.00000E+00-3.64712E-04+0.00000E+00-4.92968E-04+0.00000E+00-4.94058E-04+0.00000E+00-3.55056E-04+0.00000E+00-1.01725E-04+0.00000E+00+2.04904E-04+0.00000E+00+4.82464E-04+0.00000E+00+6.48778E-04+0.00000E+00+6.45532E-04+0.00000E+00+4.57442E-04+0.00000E+00+1.20911E-04+0.00000E+00-2.81414E-04+0.00000E+00-6.40040E-04+0.00000E+00-8.47708E-04+0.00000E+00-8.30656E-04+0.00000E+00-5.73180E-04+0.00000E+00-1.27650E-04+0.00000E+00+3.94310E-04+0.00000E+00+8.48744E-04+0.00000E+00+1.09821E-03+0.00000E+00+1.05234E-03+0.00000E+00+6.98398E-04+0.00000E+00+1.11999E-04+0.00000E+00-5.57036E-04+0.00000E+00-1.12174E-03+0.00000E+00-1.40922E-03+0.00000E+00-1.31236E-03+0.00000E+00-8.26764E-04+0.00000E+00-6.09068E-05+0.00000E+00+7.85842E-04+0.00000E+00+1.47374E-03+0.00000E+00+1.78935E-03+0.00000E+00+1.61011E-03+0.00000E+00+9.47830E-04+0.00000E+00-4.36276E-05+0.00000E+00-1.10163E-03+0.00000E+00-1.92275E-03+0.00000E+00-2.24826E-03+0.00000E+00-1.94359E-03+0.00000E+00-1.04776E-03+0.00000E+00+2.24088E-04+0.00000E+00+1.52962E-03+0.00000E+00+2.48958E-03+0.00000E+00+2.79606E-03+0.00000E+00+2.30850E-03+0.00000E+00+1.10801E-03+0.00000E+00-5.08938E-04+0.00000E+00-2.10070E-03+0.00000E+00-3.19878E-03+0.00000E+00-3.44326E-03+0.00000E+00-2.69684E-03+0.00000E+00-1.10249E-03+0.00000E+00+9.36892E-04+0.00000E+00+2.85672E-03+0.00000E+00+4.08406E-03+0.00000E+00+4.20524E-03+0.00000E+00+3.09968E-03+0.00000E+00+9.97970E-04+0.00000E+00-1.55873E-03+0.00000E+00-3.85362E-03+0.00000E+00-5.19124E-03+0.00000E+00-5.10336E-03+0.00000E+00-3.50440E-03+0.00000E+00-7.46438E-04+0.00000E+00+2.44968E-03+0.00000E+00+5.17690E-03+0.00000E+00+6.59364E-03+0.00000E+00+6.17604E-03+0.00000E+00+3.89756E-03+0.00000E+00+2.77256E-04+0.00000E+00-3.72784E-03+0.00000E+00-6.96714E-03+0.00000E+00-8.41784E-03+0.00000E+00-7.49572E-03+0.00000E+00-4.26426E-03+0.00000E+00+5.27466E-04+0.00000E+00+5.60328E-03+0.00000E+00+9.48592E-03+0.00000E+00+1.09107E-02+0.00000E+00+9.21506E-03+0.00000E+00+4.58962E-03+0.00000E+00-1.89363E-03+0.00000E+00-8.50506E-03+0.00000E+00-1.32925E-02+0.00000E+00-1.46243E-02+0.00000E+00-1.16967E-02+0.00000E+00-4.85962E-03+0.00000E+00+4.34870E-03+0.00000E+00+1.34983E-02+0.00000E+00+1.98472E-02+0.00000E+00+2.10770E-02+0.00000E+00+1.60019E-02+0.00000E+00+5.06204E-03+0.00000E+00-9.55078E-03+0.00000E+00-2.42030E-02+0.00000E+00-3.45266E-02+0.00000E+00-3.63864E-02+0.00000E+00-2.68872E-02+0.00000E+00-5.18748E-03+0.00000E+00+2.70918E-02+0.00000E+00+6.59838E-02+0.00000E+00+1.05820E-01+0.00000E+00+1.40281E-01+0.00000E+00+1.63636E-01+0.00000E+00+1.71897E-01+0.00000E+00+1.63636E-01+0.00000E+00+1.40281E-01+0.00000E+00+1.05820E-01+0.00000E+00+6.59838E-0000006S*2+0.00000E+00+2.70918E-02+0.00000E+00-5.18748E-03+0.00000E+00-2.68872E-02+0.00000E+00-3.63864E-02+0.00000E+00-3.45266E-02+0.00000E+00-2.42030E-02+0.00000E+00-9.55078E-03+0.00000E+00+5.06204E-03+0.00000E+00+1.60019E-02+0.00000E+00+2.10770E-02+0.00000E+00+1.98472E-02+0.00000E+00+1.34983E-02+0.00000E+00+4.34870E-03+0.00000E+00-4.85962E-03+0.00000E+00-1.16967E-02+0.00000E+00-1.46243E-02+0.00000E+00-1.32925E-02+0.00000E+00-8.50506E-03+0.00000E+00-1.89363E-03+0.00000E+00+4.58962E-03+0.00000E+00+9.21506E-03+0.00000E+00+1.09107E-02+0.00000E+00+9.48592E-03+0.00000E+00+5.60328E-03+0.00000E+00+5.27466E-04+0.00000E+00-4.26426E-03+0.00000E+00-7.49572E-03+0.00000E+00-8.41784E-03+0.00000E+00-6.96714E-03+0.00000E+00-3.72784E-03+0.00000E+00+2.77256E-04+0.00000E+00+3.89756E-03+0.00000E+00+6.17604E-03+0.00000E+00+6.59364E-03+0.00000E+00+5.17690E-03+0.00000E+00+2.44968E-03+0.00000E+00-7.46438E-04+0.00000E+00-3.50440E-03+0.00000E+00-5.10336E-03+0.00000E+00-5.19124E-03+0.00000E+00-3.85362E-03+0.00000E+00-1.55873E-03+0.00000E+00+9.97970E-04+0.00000E+00+3.09968E-03+0.00000E+00+4.20524E-03+0.00000E+00+4.08406E-03+0.00000E+00+2.85672E-03+0.00000E+00+9.36892E-04+0.00000E+00-1.10249E-03+0.00000E+00-2.69684E-03+0.00000E+00-3.44326E-03+0.00000E+00-3.19878E-03+0.00000E+00-2.10070E-03+0.00000E+00-5.08938E-04+0.00000E+00+1.10801E-03+0.00000E+00+2.30850E-03+0.00000E+00+2.79606E-03+0.00000E+00+2.48958E-03+0.00000E+00+1.52962E-03+0.00000E+00+2.24088E-04+0.00000E+00-1.04776E-03+0.00000E+00-1.94359E-03+0.00000E+00-2.24826E-03+0.00000E+00-1.92275E-03+0.00000E+00-1.10163E-03+0.00000E+00-4.36276E-05+0.00000E+00+9.47830E-04+0.00000E+00+1.61011E-03+0.00000E+00+1.78935E-03+0.00000E+00+1.47374E-03+0.00000E+00+7.85842E-04+0.00000E+00-6.09068E-05+0.00000E+00-8.26764E-04+0.00000E+00-1.31236E-03+0.00000E+00-1.40922E-03+0.00000E+00-1.12174E-03+0.00000E+00-5.57036E-04+0.00000E+00+1.11999E-04+0.00000E+00+6.98398E-04+0.00000E+00+1.05234E-03+0.00000E+00+1.09821E-03+0.00000E+00+8.48744E-04+0.00000E+00+3.94310E-04+0.00000E+00-1.27650E-04+0.00000E+00-5.73180E-04+0.00000E+00-8.30656E-04+0.00000E+00-8.47708E-04+0.00000E+00-6.40040E-04+0.00000E+00-2.81414E-04+0.00000E+00+1.20911E-04+0.00000E+00+4.57442E-04+0.00000E+00+6.45532E-04+0.00000E+00+6.48778E-04+0.00000E+00+4.82464E-04+0.00000E+00+2.04904E-04+0.00000E+00-1.01725E-04+0.00000E+00-3.55056E-04+0.00000E+00-4.94058E-04+0.00000E+00-4.92968E-04+0.00000E+00-3.64712E-04+0.00000E+00-1.53942E-04+0.00000E+00+7.75194E-05+0.00000E+00+2.68272E-04+0.00000E+00+3.73118E-04+0.00000E+00+3.73138E-04+0.00000E+00+2.78002E-04+0.00000E+00+1.20744E-04+0.00000E+00-5.29412E-05+0.00000E+00-1.97535E-04+0.00000E+00-2.79208E-04+0.00000E+00-2.83208E-04+0.00000E+00-2.15680E-04+0.00000E+00-1.00068E-04+0.00000E+00+3.04418E-05+0.00000E+00+1.42114E-04+0.00000E+00+2.09036E-04+0.00000E+00+2.18690E-04+0.00000E+00+1.73672E-04+0.00000E+00+8.95560E-05+0.00000E+00-1.01214E-05+0.00000E+00-1.00242E-04+0.00000E+00-1.60164E-04+0.00000E+00-1.78068E-04+0.00000E+00-1.52783E-04+0.00000E+00-9.29802E-05+0.00000E+00-1.42499E-05+0.00000E+00+6.50032E-05+0.00000E+00+1.27774E-04+0.00000E+00+1.61835E-04+0.00000E+00+1.61671E-04+0.00000E+00+1.28752E-04+0.00000E+00+7.03544E-05+0.00000E+00-2.59160E-06+0.00000E+00-7.80380E-05+0.00000E+00-1.45142E-04+0.00000E+00-1.95955E-04+0.00000E+00-2.26268E-04+0.00000E+00-2.35600E-04+0.00000E+00-2.26532E-04+0.00000E+00-2.03638E-04+0.00000E+00-1.72307E-04+0.00000E+00-1.37722E-04+0.00000E+00-1.04124E-04+0.00000E+00-7.44366E-05+0.00000E+00-5.02182E-05+0.00000E+00-3.18550E-05+0.00000E+00-1.88893E-05+0.00000E+00-1.03793E-05+0.00000E+00-5.21464E-06+0.00000E+00-2.34472E-06+0.00000E+00-9.08544E-07+0.00000E+00-2.80036E-07+0.00000E+00-5.32080E-08+0.00000E+00+4.52378E-09+0.00000E+00+7.72762E-09+0.00000E+0000000570051071.0000E+030000500000+1.5900E-01+1.5900E-01058003507+1.00000E+00+5.00000E-0200058003500+2.78845E+05+5.00000E-02000520149 EHN0000002~001002+49.129100+008.148700-0177.0305.0000.0+00.00001122.0000E+022.0000E-020000TG~2014,325,12:00:00.0000~2015,078,13:00:00.0000~N0530334A01001003+1.00000E+00+5.00000E+00003+0.00000E+00+0.00000E+00+0.00000E+00+0000007S*.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00003-4.44400E+00+4.44400E+00+0.00000E+00+0.00000E+00-4.44400E+00-4.44400E+00+0.00000E+00+0.00000E+00-1.08300E+00+0.00000E+00+0.00000E+00+0.00000E+00058003501+4.00000E+02+5.00000E+0000058003502+2.50000E+00+5.00000E-02000540048D030030040001+1.00000E+00+0.00000E+0000000570051031.9200E+050000100000+0.0000E+00+0.0000E+00058003503+4.00000E+05+5.00000E-02000541152D040040040047+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+3.81470E-06+0.00000E+00+2.28882E-05+0.00000E+00+8.01086E-05+0.00000E+00+2.13623E-04+0.00000E+00+4.80652E-04+0.00000E+00+9.61304E-04+0.00000E+00+1.76239E-03+0.00000E+00+3.02124E-03+0.00000E+00+4.88663E-03+0.00000E+00+7.49969E-03+0.00000E+00+1.09749E-02+0.00000E+00+1.53809E-02+0.00000E+00+2.07214E-02+0.00000E+00+2.69165E-02+0.00000E+00+3.37830E-02+0.00000E+00+4.10156E-02+0.00000E+00+4.82254E-02+0.00000E+00+5.49774E-02+0.00000E+00+6.08292E-02+0.00000E+00+6.53687E-02+0.00000E+00+6.82526E-02+0.00000E+00+6.92444E-02+0.00000E+00+6.82526E-02+0.00000E+00+6.53687E-02+0.00000E+00+6.08292E-02+0.00000E+00+5.49774E-02+0.00000E+00+4.82254E-02+0.00000E+00+4.10156E-02+0.00000E+00+3.37830E-02+0.00000E+00+2.69165E-02+0.00000E+00+2.07214E-02+0.00000E+00+1.53809E-02+0.00000E+00+1.09749E-02+0.00000E+00+7.49969E-03+0.00000E+00+4.88663E-03+0.00000E+00+3.02124E-03+0.00000E+00+1.76239E-03+0.00000E+00+9.61304E-04+0.00000E+00+4.80652E-04+0.00000E+00+2.13623E-04+0.00000E+00+8.01086E-05+0.00000E+00+2.28882E-05+0.00000E+00+3.81470E-06+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+0000000570051041.9200E+050000800000+1.1979E-04+1.1979E-04058003504+1.00000E+00+5.00000E-02000541776D050040040073+7.86395E-07+0.00000E+00+2.15223E-06+0.00000E+00+4.09013E-06+0.00000E+00+6.42053E-06+0.00000E+00+7.61300E-06+0.00000E+00+4.52134E-06+0.00000E+00-8.38839E-06+0.00000E+00-4.00745E-05+0.00000E+00-1.08702E-04+0.00000E+00-2.31570E-04+0.00000E+00-4.32673E-04+0.00000E+00-7.41861E-04+0.00000E+00-1.18635E-03+0.00000E+00-1.78887E-03+0.00000E+00-2.56156E-03+0.00000E+00-3.49756E-03+0.00000E+00-4.54784E-03+0.00000E+00-5.64473E-03+0.00000E+00-6.67437E-03+0.00000E+00-7.46932E-03+0.00000E+00-7.83206E-03+0.00000E+00-7.53472E-03+0.00000E+00-6.33480E-03+0.00000E+00-3.99943E-03+0.00000E+00-3.60688E-04+0.00000E+00+4.71408E-03+0.00000E+00+1.12572E-02+0.00000E+00+1.91611E-02+0.00000E+00+2.82115E-02+0.00000E+00+3.80655E-02+0.00000E+00+4.82646E-02+0.00000E+00+5.82654E-02+0.00000E+00+6.75164E-02+0.00000E+00+7.54318E-02+0.00000E+00+8.14859E-02+0.00000E+00+8.52972E-02+0.00000E+00+8.65986E-02+0.00000E+00+8.52972E-02+0.00000E+00+8.14859E-02+0.00000E+00+7.54318E-02+0.00000E+00+6.75164E-02+0.00000E+00+5.82654E-02+0.00000E+00+4.82646E-02+0.00000E+00+3.80655E-02+0.00000E+00+2.82115E-02+0.00000E+00+1.91611E-02+0.00000E+00+1.12572E-02+0.00000E+00+4.71408E-03+0.00000E+00-3.60688E-04+0.00000E+00-3.99943E-03+0.00000E+00-6.33480E-03+0.00000E+00-7.53472E-03+0.00000E+00-7.83206E-03+0.00000E+00-7.46932E-03+0.00000E+00-6.67437E-03+0.00000E+00-5.64473E-03+0.00000E+00-4.54784E-03+0.00000E+00-3.49756E-03+0.00000E+00-2.56156E-03+0.00000E+00-1.78887E-03+0.00000E+00-1.18635E-03+0.00000E+00-7.41861E-04+0.00000E+00-4.32673E-04+0.00000E+00-2.31570E-04+0.00000E+00-1.08702E-04+0.00000E+00-4.00745E-05+0.00000E+00-8.38839E-06+0.00000E+00+4.52134E-06+0.00000E+00+7.61300E-06+0.00000E+00+6.42053E-06+0.00000E+00+4.09013E-06+0.00000E+00+2.15223E-06+0.00000E+00+7.86395E-07+0.00000E+0000000570051052.4000E+040000800000+1.5000E-03+1.5000E-03058003505+1.00000E+00+5.00000E-02000544320D060040040179+1.65488E-07+0.00000E+00+7.48132E-07+0.00000E+00+1.76664E-06+0.00000E+00+1.62612E-06+0.00000E+00-5.16640E-06+0.00000E+00-3.00692E-05+0.00000E+00-8.97376E-05+0.00000E+00-1.99571E-04+0.00000E+00-3.61172E-04+0.00000E+00-5.48500E-04+0.00000E+00-7.02688E-04+0.00000E+00-7.45976E-04+0.00000E+00-6.17072E-04+0.00000E+00-3.15191E-04+0.00000E+00+7.38188E-05+0.00000E+00+3.95725E-04+0.00000E+00+4.96800E-04+0.00000E+00+3.15263E-04+0.00000E+00-5.96548E-05+0.00000E+00-4.11872E-04+0.00000E+00-5.12780E-04+0.00000E+00-2.6953000008S*6E-04+0.00000E+00+1.89248E-04+0.00000E+00+5.66172E-04+0.00000E+00+5.78372E-04+0.00000E+00+1.64727E-04+0.00000E+00-4.31664E-04+0.00000E+00-7.92432E-04+0.00000E+00-6.08316E-04+0.00000E+00+6.76780E-05+0.00000E+00+7.98316E-04+0.00000E+00+1.03172E-03+0.00000E+00+5.07504E-04+0.00000E+00-4.91744E-04+0.00000E+00-1.26810E-03+0.00000E+00-1.18261E-03+0.00000E+00-1.64670E-04+0.00000E+00+1.13876E-03+0.00000E+00+1.75363E-03+0.00000E+00+1.09177E-03+0.00000E+00-5.24120E-04+0.00000E+00-1.97068E-03+0.00000E+00-2.08536E-03+0.00000E+00-5.79052E-04+0.00000E+00+1.60144E-03+0.00000E+00+2.83576E-03+0.00000E+00+2.01276E-03+0.00000E+00-5.13156E-04+0.00000E+00-2.98815E-03+0.00000E+00-3.44765E-03+0.00000E+00-1.24599E-03+0.00000E+00+2.24272E-03+0.00000E+00+4.43120E-03+0.00000E+00+3.40590E-03+0.00000E+00-4.57304E-04+0.00000E+00-4.47584E-03+0.00000E+00-5.47828E-03+0.00000E+00-2.26220E-03+0.00000E+00+3.18035E-03+0.00000E+00+6.81616E-03+0.00000E+00+5.50776E-03+0.00000E+00-3.65328E-04+0.00000E+00-6.73316E-03+0.00000E+00-8.58052E-03+0.00000E+00-3.81782E-03+0.00000E+00+4.65228E-03+0.00000E+00+1.05646E-02+0.00000E+00+8.82560E-03+0.00000E+00-2.56374E-04+0.00000E+00-1.04496E-02+0.00000E+00-1.37224E-02+0.00000E+00-6.39512E-03+0.00000E+00+7.26512E-03+0.00000E+00+1.72312E-02+0.00000E+00+1.48181E-02+0.00000E+00-1.54011E-04+0.00000E+00-1.77680E-02+0.00000E+00-2.41384E-02+0.00000E+00-1.17549E-02+0.00000E+00+1.32733E-02+0.00000E+00+3.32147E-02+0.00000E+00+3.01309E-02+0.00000E+00-8.13468E-05+0.00000E+00-4.08284E-02+0.00000E+00-6.13256E-02+0.00000E+00-3.42109E-02+0.00000E+00+4.58968E-02+0.00000E+00+1.54886E-01+0.00000E+00+2.48713E-01+0.00000E+00+2.85658E-01+0.00000E+00+2.48713E-01+0.00000E+00+1.54886E-01+0.00000E+00+4.58968E-02+0.00000E+00-3.42109E-02+0.00000E+00-6.13256E-02+0.00000E+00-4.08284E-02+0.00000E+00-8.13468E-05+0.00000E+00+3.01309E-02+0.00000E+00+3.32147E-02+0.00000E+00+1.32733E-02+0.00000E+00-1.17549E-02+0.00000E+00-2.41384E-02+0.00000E+00-1.77680E-02+0.00000E+00-1.54011E-04+0.00000E+00+1.48181E-02+0.00000E+00+1.72312E-02+0.00000E+00+7.26512E-03+0.00000E+00-6.39512E-03+0.00000E+00-1.37224E-02+0.00000E+00-1.04496E-02+0.00000E+00-2.56374E-04+0.00000E+00+8.82560E-03+0.00000E+00+1.05646E-02+0.00000E+00+4.65228E-03+0.00000E+00-3.81782E-03+0.00000E+00-8.58052E-03+0.00000E+00-6.73316E-03+0.00000E+00-3.65328E-04+0.00000E+00+5.50776E-03+0.00000E+00+6.81616E-03+0.00000E+00+3.18035E-03+0.00000E+00-2.26220E-03+0.00000E+00-5.47828E-03+0.00000E+00-4.47584E-03+0.00000E+00-4.57304E-04+0.00000E+00+3.40590E-03+0.00000E+00+4.43120E-03+0.00000E+00+2.24272E-03+0.00000E+00-1.24599E-03+0.00000E+00-3.44765E-03+0.00000E+00-2.98815E-03+0.00000E+00-5.13156E-04+0.00000E+00+2.01276E-03+0.00000E+00+2.83576E-03+0.00000E+00+1.60144E-03+0.00000E+00-5.79052E-04+0.00000E+00-2.08536E-03+0.00000E+00-1.97068E-03+0.00000E+00-5.24120E-04+0.00000E+00+1.09177E-03+0.00000E+00+1.75363E-03+0.00000E+00+1.13876E-03+0.00000E+00-1.64670E-04+0.00000E+00-1.18261E-03+0.00000E+00-1.26810E-03+0.00000E+00-4.91744E-04+0.00000E+00+5.07504E-04+0.00000E+00+1.03172E-03+0.00000E+00+7.98316E-04+0.00000E+00+6.76780E-05+0.00000E+00-6.08316E-04+0.00000E+00-7.92432E-04+0.00000E+00-4.31664E-04+0.00000E+00+1.64727E-04+0.00000E+00+5.78372E-04+0.00000E+00+5.66172E-04+0.00000E+00+1.89248E-04+0.00000E+00-2.69536E-04+0.00000E+00-5.12780E-04+0.00000E+00-4.11872E-04+0.00000E+00-5.96548E-05+0.00000E+00+3.15263E-04+0.00000E+00+4.96800E-04+0.00000E+00+3.95725E-04+0.00000E+00+7.38188E-05+0.00000E+00-3.15191E-04+0.00000E+00-6.17072E-04+0.00000E+00-7.45976E-04+0.00000E+00-7.02688E-04+0.00000E+00-5.48500E-04+0.00000E+00-3.61172E-04+0.00000E+00-1.99571E-04+0.00000E+00-8.97376E-05+0.00000E+00-3.00692E-05+0.00000E+00-5.16640E-06+0.00000E+00+1.62612E-06+0.00000E+00+1.76664E-06+0.00000E+00+7.48132E-07+0.00000E+00+1.65488E-07+0.00000E+0000000570051063.0000E+030000300000+2.9667E-02+2.9667E-02058003506+1.00000E+00+5.00000E-02000547680D070040040319+7.72762E-09+0.00000E+00+4.52378E-09+0.00000E+00-5.32080E-08+0.00000E+00-2.80036E-07+0.00000E+00-9.08544E-07+0.00000E+00-2.34472E-06+0.00000E+00-5.21464E-06+0.00000E+00-1.03793E-05+0.00000E+00-000009S*1.88893E-05+0.00000E+00-3.18550E-05+0.00000E+00-5.02182E-05+0.00000E+00-7.44366E-05+0.00000E+00-1.04124E-04+0.00000E+00-1.37722E-04+0.00000E+00-1.72307E-04+0.00000E+00-2.03638E-04+0.00000E+00-2.26532E-04+0.00000E+00-2.35600E-04+0.00000E+00-2.26268E-04+0.00000E+00-1.95955E-04+0.00000E+00-1.45142E-04+0.00000E+00-7.80380E-05+0.00000E+00-2.59160E-06+0.00000E+00+7.03544E-05+0.00000E+00+1.28752E-04+0.00000E+00+1.61671E-04+0.00000E+00+1.61835E-04+0.00000E+00+1.27774E-04+0.00000E+00+6.50032E-05+0.00000E+00-1.42499E-05+0.00000E+00-9.29802E-05+0.00000E+00-1.52783E-04+0.00000E+00-1.78068E-04+0.00000E+00-1.60164E-04+0.00000E+00-1.00242E-04+0.00000E+00-1.01214E-05+0.00000E+00+8.95560E-05+0.00000E+00+1.73672E-04+0.00000E+00+2.18690E-04+0.00000E+00+2.09036E-04+0.00000E+00+1.42114E-04+0.00000E+00+3.04418E-05+0.00000E+00-1.00068E-04+0.00000E+00-2.15680E-04+0.00000E+00-2.83208E-04+0.00000E+00-2.79208E-04+0.00000E+00-1.97535E-04+0.00000E+00-5.29412E-05+0.00000E+00+1.20744E-04+0.00000E+00+2.78002E-04+0.00000E+00+3.73138E-04+0.00000E+00+3.73118E-04+0.00000E+00+2.68272E-04+0.00000E+00+7.75194E-05+0.00000E+00-1.53942E-04+0.00000E+00-3.64712E-04+0.00000E+00-4.92968E-04+0.00000E+00-4.94058E-04+0.00000E+00-3.55056E-04+0.00000E+00-1.01725E-04+0.00000E+00+2.04904E-04+0.00000E+00+4.82464E-04+0.00000E+00+6.48778E-04+0.00000E+00+6.45532E-04+0.00000E+00+4.57442E-04+0.00000E+00+1.20911E-04+0.00000E+00-2.81414E-04+0.00000E+00-6.40040E-04+0.00000E+00-8.47708E-04+0.00000E+00-8.30656E-04+0.00000E+00-5.73180E-04+0.00000E+00-1.27650E-04+0.00000E+00+3.94310E-04+0.00000E+00+8.48744E-04+0.00000E+00+1.09821E-03+0.00000E+00+1.05234E-03+0.00000E+00+6.98398E-04+0.00000E+00+1.11999E-04+0.00000E+00-5.57036E-04+0.00000E+00-1.12174E-03+0.00000E+00-1.40922E-03+0.00000E+00-1.31236E-03+0.00000E+00-8.26764E-04+0.00000E+00-6.09068E-05+0.00000E+00+7.85842E-04+0.00000E+00+1.47374E-03+0.00000E+00+1.78935E-03+0.00000E+00+1.61011E-03+0.00000E+00+9.47830E-04+0.00000E+00-4.36276E-05+0.00000E+00-1.10163E-03+0.00000E+00-1.92275E-03+0.00000E+00-2.24826E-03+0.00000E+00-1.94359E-03+0.00000E+00-1.04776E-03+0.00000E+00+2.24088E-04+0.00000E+00+1.52962E-03+0.00000E+00+2.48958E-03+0.00000E+00+2.79606E-03+0.00000E+00+2.30850E-03+0.00000E+00+1.10801E-03+0.00000E+00-5.08938E-04+0.00000E+00-2.10070E-03+0.00000E+00-3.19878E-03+0.00000E+00-3.44326E-03+0.00000E+00-2.69684E-03+0.00000E+00-1.10249E-03+0.00000E+00+9.36892E-04+0.00000E+00+2.85672E-03+0.00000E+00+4.08406E-03+0.00000E+00+4.20524E-03+0.00000E+00+3.09968E-03+0.00000E+00+9.97970E-04+0.00000E+00-1.55873E-03+0.00000E+00-3.85362E-03+0.00000E+00-5.19124E-03+0.00000E+00-5.10336E-03+0.00000E+00-3.50440E-03+0.00000E+00-7.46438E-04+0.00000E+00+2.44968E-03+0.00000E+00+5.17690E-03+0.00000E+00+6.59364E-03+0.00000E+00+6.17604E-03+0.00000E+00+3.89756E-03+0.00000E+00+2.77256E-04+0.00000E+00-3.72784E-03+0.00000E+00-6.96714E-03+0.00000E+00-8.41784E-03+0.00000E+00-7.49572E-03+0.00000E+00-4.26426E-03+0.00000E+00+5.27466E-04+0.00000E+00+5.60328E-03+0.00000E+00+9.48592E-03+0.00000E+00+1.09107E-02+0.00000E+00+9.21506E-03+0.00000E+00+4.58962E-03+0.00000E+00-1.89363E-03+0.00000E+00-8.50506E-03+0.00000E+00-1.32925E-02+0.00000E+00-1.46243E-02+0.00000E+00-1.16967E-02+0.00000E+00-4.85962E-03+0.00000E+00+4.34870E-03+0.00000E+00+1.34983E-02+0.00000E+00+1.98472E-02+0.00000E+00+2.10770E-02+0.00000E+00+1.60019E-02+0.00000E+00+5.06204E-03+0.00000E+00-9.55078E-03+0.00000E+00-2.42030E-02+0.00000E+00-3.45266E-02+0.00000E+00-3.63864E-02+0.00000E+00-2.68872E-02+0.00000E+00-5.18748E-03+0.00000E+00+2.70918E-02+0.00000E+00+6.59838E-02+0.00000E+00+1.05820E-01+0.00000E+00+1.40281E-01+0.00000E+00+1.63636E-01+0.00000E+00+1.71897E-01+0.00000E+00+1.63636E-01+0.00000E+00+1.40281E-01+0.00000E+00+1.05820E-01+0.00000E+00+6.59838E-02+0.00000E+00+2.70918E-02+0.00000E+00-5.18748E-03+0.00000E+00-2.68872E-02+0.00000E+00-3.63864E-02+0.00000E+00-3.45266E-02+0.00000E+00-2.42030E-02+0.00000E+00-9.55078E-03+0.00000E+00+5.06204E-03+0.00000E+00+1.60019E-02+0.00000E+00+2.10770E-02+0.00000E+00+1.98472E-02+0.00000E+00+1.34983E-02+0.00000E+00+4.34870E-03+0.00000E+00-4.85962E-03+0.00000E+00-1.16967E000010S*-02+0.00000E+00-1.46243E-02+0.00000E+00-1.32925E-02+0.00000E+00-8.50506E-03+0.00000E+00-1.89363E-03+0.00000E+00+4.58962E-03+0.00000E+00+9.21506E-03+0.00000E+00+1.09107E-02+0.00000E+00+9.48592E-03+0.00000E+00+5.60328E-03+0.00000E+00+5.27466E-04+0.00000E+00-4.26426E-03+0.00000E+00-7.49572E-03+0.00000E+00-8.41784E-03+0.00000E+00-6.96714E-03+0.00000E+00-3.72784E-03+0.00000E+00+2.77256E-04+0.00000E+00+3.89756E-03+0.00000E+00+6.17604E-03+0.00000E+00+6.59364E-03+0.00000E+00+5.17690E-03+0.00000E+00+2.44968E-03+0.00000E+00-7.46438E-04+0.00000E+00-3.50440E-03+0.00000E+00-5.10336E-03+0.00000E+00-5.19124E-03+0.00000E+00-3.85362E-03+0.00000E+00-1.55873E-03+0.00000E+00+9.97970E-04+0.00000E+00+3.09968E-03+0.00000E+00+4.20524E-03+0.00000E+00+4.08406E-03+0.00000E+00+2.85672E-03+0.00000E+00+9.36892E-04+0.00000E+00-1.10249E-03+0.00000E+00-2.69684E-03+0.00000E+00-3.44326E-03+0.00000E+00-3.19878E-03+0.00000E+00-2.10070E-03+0.00000E+00-5.08938E-04+0.00000E+00+1.10801E-03+0.00000E+00+2.30850E-03+0.00000E+00+2.79606E-03+0.00000E+00+2.48958E-03+0.00000E+00+1.52962E-03+0.00000E+00+2.24088E-04+0.00000E+00-1.04776E-03+0.00000E+00-1.94359E-03+0.00000E+00-2.24826E-03+0.00000E+00-1.92275E-03+0.00000E+00-1.10163E-03+0.00000E+00-4.36276E-05+0.00000E+00+9.47830E-04+0.00000E+00+1.61011E-03+0.00000E+00+1.78935E-03+0.00000E+00+1.47374E-03+0.00000E+00+7.85842E-04+0.00000E+00-6.09068E-05+0.00000E+00-8.26764E-04+0.00000E+00-1.31236E-03+0.00000E+00-1.40922E-03+0.00000E+00-1.12174E-03+0.00000E+00-5.57036E-04+0.00000E+00+1.11999E-04+0.00000E+00+6.98398E-04+0.00000E+00+1.05234E-03+0.00000E+00+1.09821E-03+0.00000E+00+8.48744E-04+0.00000E+00+3.94310E-04+0.00000E+00-1.27650E-04+0.00000E+00-5.73180E-04+0.00000E+00-8.30656E-04+0.00000E+00-8.47708E-04+0.00000E+00-6.40040E-04+0.00000E+00-2.81414E-04+0.00000E+00+1.20911E-04+0.00000E+00+4.57442E-04+0.00000E+00+6.45532E-04+0.00000E+00+6.48778E-04+0.00000E+00+4.82464E-04+0.00000E+00+2.04904E-04+0.00000E+00-1.01725E-04+0.00000E+00-3.55056E-04+0.00000E+00-4.94058E-04+0.00000E+00-4.92968E-04+0.00000E+00-3.64712E-04+0.00000E+00-1.53942E-04+0.00000E+00+7.75194E-05+0.00000E+00+2.68272E-04+0.00000E+00+3.73118E-04+0.00000E+00+3.73138E-04+0.00000E+00+2.78002E-04+0.00000E+00+1.20744E-04+0.00000E+00-5.29412E-05+0.00000E+00-1.97535E-04+0.00000E+00-2.79208E-04+0.00000E+00-2.83208E-04+0.00000E+00-2.15680E-04+0.00000E+00-1.00068E-04+0.00000E+00+3.04418E-05+0.00000E+00+1.42114E-04+0.00000E+00+2.09036E-04+0.00000E+00+2.18690E-04+0.00000E+00+1.73672E-04+0.00000E+00+8.95560E-05+0.00000E+00-1.01214E-05+0.00000E+00-1.00242E-04+0.00000E+00-1.60164E-04+0.00000E+00-1.78068E-04+0.00000E+00-1.52783E-04+0.00000E+00-9.29802E-05+0.00000E+00-1.42499E-05+0.00000E+00+6.50032E-05+0.00000E+00+1.27774E-04+0.00000E+00+1.61835E-04+0.00000E+00+1.61671E-04+0.00000E+00+1.28752E-04+0.00000E+00+7.03544E-05+0.00000E+00-2.59160E-06+0.00000E+00-7.80380E-05+0.00000E+00-1.45142E-04+0.00000E+00-1.95955E-04+0.00000E+00-2.26268E-04+0.00000E+00-2.35600E-04+0.00000E+00-2.26532E-04+0.00000E+00-2.03638E-04+0.00000E+00-1.72307E-04+0.00000E+00-1.37722E-04+0.00000E+00-1.04124E-04+0.00000E+00-7.44366E-05+0.00000E+00-5.02182E-05+0.00000E+00-3.18550E-05+0.00000E+00-1.88893E-05+0.00000E+00-1.03793E-05+0.00000E+00-5.21464E-06+0.00000E+00-2.34472E-06+0.00000E+00-9.08544E-07+0.00000E+00-2.80036E-07+0.00000E+00-5.32080E-08+0.00000E+00+4.52378E-09+0.00000E+00+7.72762E-09+0.00000E+0000000570051071.0000E+030000500000+1.5900E-01+1.5900E-01058003507+1.00000E+00+5.00000E-0200058003500+2.78845E+05+5.00000E-02000520149 EHZ0000002~001002+49.129100+008.148700-0177.0305.0000.0-90.00001122.0000E+022.0000E-020000TG~2014,325,12:00:00.0000~2015,078,13:00:00.0000~N0530334A01001003+1.00000E+00+5.00000E+00003+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00003-4.44400E+00+4.44400E+00+0.00000E+00+0.00000E+00-4.44400E+00-4.44400E+00+0.00000E+00+0.00000E+00-1.08300E+00+0.00000E+00+0.00000E+00+0.00000E+00058003501+4.00000E+02+5.00000E+0000058003502+2.50000E+00+5.00000E-02000540048D030030040001+1.00000E+00+0.000011S*00000E+0000000570051031.9200E+050000100000+0.0000E+00+0.0000E+00058003503+4.00000E+05+5.00000E-02000541152D040040040047+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+3.81470E-06+0.00000E+00+2.28882E-05+0.00000E+00+8.01086E-05+0.00000E+00+2.13623E-04+0.00000E+00+4.80652E-04+0.00000E+00+9.61304E-04+0.00000E+00+1.76239E-03+0.00000E+00+3.02124E-03+0.00000E+00+4.88663E-03+0.00000E+00+7.49969E-03+0.00000E+00+1.09749E-02+0.00000E+00+1.53809E-02+0.00000E+00+2.07214E-02+0.00000E+00+2.69165E-02+0.00000E+00+3.37830E-02+0.00000E+00+4.10156E-02+0.00000E+00+4.82254E-02+0.00000E+00+5.49774E-02+0.00000E+00+6.08292E-02+0.00000E+00+6.53687E-02+0.00000E+00+6.82526E-02+0.00000E+00+6.92444E-02+0.00000E+00+6.82526E-02+0.00000E+00+6.53687E-02+0.00000E+00+6.08292E-02+0.00000E+00+5.49774E-02+0.00000E+00+4.82254E-02+0.00000E+00+4.10156E-02+0.00000E+00+3.37830E-02+0.00000E+00+2.69165E-02+0.00000E+00+2.07214E-02+0.00000E+00+1.53809E-02+0.00000E+00+1.09749E-02+0.00000E+00+7.49969E-03+0.00000E+00+4.88663E-03+0.00000E+00+3.02124E-03+0.00000E+00+1.76239E-03+0.00000E+00+9.61304E-04+0.00000E+00+4.80652E-04+0.00000E+00+2.13623E-04+0.00000E+00+8.01086E-05+0.00000E+00+2.28882E-05+0.00000E+00+3.81470E-06+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+0000000570051041.9200E+050000800000+1.1979E-04+1.1979E-04058003504+1.00000E+00+5.00000E-02000541776D050040040073+7.86395E-07+0.00000E+00+2.15223E-06+0.00000E+00+4.09013E-06+0.00000E+00+6.42053E-06+0.00000E+00+7.61300E-06+0.00000E+00+4.52134E-06+0.00000E+00-8.38839E-06+0.00000E+00-4.00745E-05+0.00000E+00-1.08702E-04+0.00000E+00-2.31570E-04+0.00000E+00-4.32673E-04+0.00000E+00-7.41861E-04+0.00000E+00-1.18635E-03+0.00000E+00-1.78887E-03+0.00000E+00-2.56156E-03+0.00000E+00-3.49756E-03+0.00000E+00-4.54784E-03+0.00000E+00-5.64473E-03+0.00000E+00-6.67437E-03+0.00000E+00-7.46932E-03+0.00000E+00-7.83206E-03+0.00000E+00-7.53472E-03+0.00000E+00-6.33480E-03+0.00000E+00-3.99943E-03+0.00000E+00-3.60688E-04+0.00000E+00+4.71408E-03+0.00000E+00+1.12572E-02+0.00000E+00+1.91611E-02+0.00000E+00+2.82115E-02+0.00000E+00+3.80655E-02+0.00000E+00+4.82646E-02+0.00000E+00+5.82654E-02+0.00000E+00+6.75164E-02+0.00000E+00+7.54318E-02+0.00000E+00+8.14859E-02+0.00000E+00+8.52972E-02+0.00000E+00+8.65986E-02+0.00000E+00+8.52972E-02+0.00000E+00+8.14859E-02+0.00000E+00+7.54318E-02+0.00000E+00+6.75164E-02+0.00000E+00+5.82654E-02+0.00000E+00+4.82646E-02+0.00000E+00+3.80655E-02+0.00000E+00+2.82115E-02+0.00000E+00+1.91611E-02+0.00000E+00+1.12572E-02+0.00000E+00+4.71408E-03+0.00000E+00-3.60688E-04+0.00000E+00-3.99943E-03+0.00000E+00-6.33480E-03+0.00000E+00-7.53472E-03+0.00000E+00-7.83206E-03+0.00000E+00-7.46932E-03+0.00000E+00-6.67437E-03+0.00000E+00-5.64473E-03+0.00000E+00-4.54784E-03+0.00000E+00-3.49756E-03+0.00000E+00-2.56156E-03+0.00000E+00-1.78887E-03+0.00000E+00-1.18635E-03+0.00000E+00-7.41861E-04+0.00000E+00-4.32673E-04+0.00000E+00-2.31570E-04+0.00000E+00-1.08702E-04+0.00000E+00-4.00745E-05+0.00000E+00-8.38839E-06+0.00000E+00+4.52134E-06+0.00000E+00+7.61300E-06+0.00000E+00+6.42053E-06+0.00000E+00+4.09013E-06+0.00000E+00+2.15223E-06+0.00000E+00+7.86395E-07+0.00000E+0000000570051052.4000E+040000800000+1.5000E-03+1.5000E-03058003505+1.00000E+00+5.00000E-02000544320D060040040179+1.65488E-07+0.00000E+00+7.48132E-07+0.00000E+00+1.76664E-06+0.00000E+00+1.62612E-06+0.00000E+00-5.16640E-06+0.00000E+00-3.00692E-05+0.00000E+00-8.97376E-05+0.00000E+00-1.99571E-04+0.00000E+00-3.61172E-04+0.00000E+00-5.48500E-04+0.00000E+00-7.02688E-04+0.00000E+00-7.45976E-04+0.00000E+00-6.17072E-04+0.00000E+00-3.15191E-04+0.00000E+00+7.38188E-05+0.00000E+00+3.95725E-04+0.00000E+00+4.96800E-04+0.00000E+00+3.15263E-04+0.00000E+00-5.96548E-05+0.00000E+00-4.11872E-04+0.00000E+00-5.12780E-04+0.00000E+00-2.69536E-04+0.00000E+00+1.89248E-04+0.00000E+00+5.66172E-04+0.00000E+00+5.78372E-04+0.00000E+00+1.64727E-04+0.00000E+00-4.31664E-04+0.00000E+00-7.92432E-04+0.00000E+00-6.08316E-04+0.00000E+00+6.76780E-05+0.00000E+00+7.98316E-04+0.00000E+00+1.03172E-03+0.00000E+00+5.07504E-04+0.00000E+00-4.91744E-04+0.00000E+00-1.26810E-03+0.00000E+00-1.18261E-03+0.00000E+00-1.64000012S*670E-04+0.00000E+00+1.13876E-03+0.00000E+00+1.75363E-03+0.00000E+00+1.09177E-03+0.00000E+00-5.24120E-04+0.00000E+00-1.97068E-03+0.00000E+00-2.08536E-03+0.00000E+00-5.79052E-04+0.00000E+00+1.60144E-03+0.00000E+00+2.83576E-03+0.00000E+00+2.01276E-03+0.00000E+00-5.13156E-04+0.00000E+00-2.98815E-03+0.00000E+00-3.44765E-03+0.00000E+00-1.24599E-03+0.00000E+00+2.24272E-03+0.00000E+00+4.43120E-03+0.00000E+00+3.40590E-03+0.00000E+00-4.57304E-04+0.00000E+00-4.47584E-03+0.00000E+00-5.47828E-03+0.00000E+00-2.26220E-03+0.00000E+00+3.18035E-03+0.00000E+00+6.81616E-03+0.00000E+00+5.50776E-03+0.00000E+00-3.65328E-04+0.00000E+00-6.73316E-03+0.00000E+00-8.58052E-03+0.00000E+00-3.81782E-03+0.00000E+00+4.65228E-03+0.00000E+00+1.05646E-02+0.00000E+00+8.82560E-03+0.00000E+00-2.56374E-04+0.00000E+00-1.04496E-02+0.00000E+00-1.37224E-02+0.00000E+00-6.39512E-03+0.00000E+00+7.26512E-03+0.00000E+00+1.72312E-02+0.00000E+00+1.48181E-02+0.00000E+00-1.54011E-04+0.00000E+00-1.77680E-02+0.00000E+00-2.41384E-02+0.00000E+00-1.17549E-02+0.00000E+00+1.32733E-02+0.00000E+00+3.32147E-02+0.00000E+00+3.01309E-02+0.00000E+00-8.13468E-05+0.00000E+00-4.08284E-02+0.00000E+00-6.13256E-02+0.00000E+00-3.42109E-02+0.00000E+00+4.58968E-02+0.00000E+00+1.54886E-01+0.00000E+00+2.48713E-01+0.00000E+00+2.85658E-01+0.00000E+00+2.48713E-01+0.00000E+00+1.54886E-01+0.00000E+00+4.58968E-02+0.00000E+00-3.42109E-02+0.00000E+00-6.13256E-02+0.00000E+00-4.08284E-02+0.00000E+00-8.13468E-05+0.00000E+00+3.01309E-02+0.00000E+00+3.32147E-02+0.00000E+00+1.32733E-02+0.00000E+00-1.17549E-02+0.00000E+00-2.41384E-02+0.00000E+00-1.77680E-02+0.00000E+00-1.54011E-04+0.00000E+00+1.48181E-02+0.00000E+00+1.72312E-02+0.00000E+00+7.26512E-03+0.00000E+00-6.39512E-03+0.00000E+00-1.37224E-02+0.00000E+00-1.04496E-02+0.00000E+00-2.56374E-04+0.00000E+00+8.82560E-03+0.00000E+00+1.05646E-02+0.00000E+00+4.65228E-03+0.00000E+00-3.81782E-03+0.00000E+00-8.58052E-03+0.00000E+00-6.73316E-03+0.00000E+00-3.65328E-04+0.00000E+00+5.50776E-03+0.00000E+00+6.81616E-03+0.00000E+00+3.18035E-03+0.00000E+00-2.26220E-03+0.00000E+00-5.47828E-03+0.00000E+00-4.47584E-03+0.00000E+00-4.57304E-04+0.00000E+00+3.40590E-03+0.00000E+00+4.43120E-03+0.00000E+00+2.24272E-03+0.00000E+00-1.24599E-03+0.00000E+00-3.44765E-03+0.00000E+00-2.98815E-03+0.00000E+00-5.13156E-04+0.00000E+00+2.01276E-03+0.00000E+00+2.83576E-03+0.00000E+00+1.60144E-03+0.00000E+00-5.79052E-04+0.00000E+00-2.08536E-03+0.00000E+00-1.97068E-03+0.00000E+00-5.24120E-04+0.00000E+00+1.09177E-03+0.00000E+00+1.75363E-03+0.00000E+00+1.13876E-03+0.00000E+00-1.64670E-04+0.00000E+00-1.18261E-03+0.00000E+00-1.26810E-03+0.00000E+00-4.91744E-04+0.00000E+00+5.07504E-04+0.00000E+00+1.03172E-03+0.00000E+00+7.98316E-04+0.00000E+00+6.76780E-05+0.00000E+00-6.08316E-04+0.00000E+00-7.92432E-04+0.00000E+00-4.31664E-04+0.00000E+00+1.64727E-04+0.00000E+00+5.78372E-04+0.00000E+00+5.66172E-04+0.00000E+00+1.89248E-04+0.00000E+00-2.69536E-04+0.00000E+00-5.12780E-04+0.00000E+00-4.11872E-04+0.00000E+00-5.96548E-05+0.00000E+00+3.15263E-04+0.00000E+00+4.96800E-04+0.00000E+00+3.95725E-04+0.00000E+00+7.38188E-05+0.00000E+00-3.15191E-04+0.00000E+00-6.17072E-04+0.00000E+00-7.45976E-04+0.00000E+00-7.02688E-04+0.00000E+00-5.48500E-04+0.00000E+00-3.61172E-04+0.00000E+00-1.99571E-04+0.00000E+00-8.97376E-05+0.00000E+00-3.00692E-05+0.00000E+00-5.16640E-06+0.00000E+00+1.62612E-06+0.00000E+00+1.76664E-06+0.00000E+00+7.48132E-07+0.00000E+00+1.65488E-07+0.00000E+0000000570051063.0000E+030000300000+2.9667E-02+2.9667E-02058003506+1.00000E+00+5.00000E-02000547680D070040040319+7.72762E-09+0.00000E+00+4.52378E-09+0.00000E+00-5.32080E-08+0.00000E+00-2.80036E-07+0.00000E+00-9.08544E-07+0.00000E+00-2.34472E-06+0.00000E+00-5.21464E-06+0.00000E+00-1.03793E-05+0.00000E+00-1.88893E-05+0.00000E+00-3.18550E-05+0.00000E+00-5.02182E-05+0.00000E+00-7.44366E-05+0.00000E+00-1.04124E-04+0.00000E+00-1.37722E-04+0.00000E+00-1.72307E-04+0.00000E+00-2.03638E-04+0.00000E+00-2.26532E-04+0.00000E+00-2.35600E-04+0.00000E+00-2.26268E-04+0.00000E+00-1.95955E-04+0.00000E+00-1.45142E-04+0.00000E+00-7.80380E-05+0.00000E+00-2.59160E-06+0.00000E+0000013S*0+7.03544E-05+0.00000E+00+1.28752E-04+0.00000E+00+1.61671E-04+0.00000E+00+1.61835E-04+0.00000E+00+1.27774E-04+0.00000E+00+6.50032E-05+0.00000E+00-1.42499E-05+0.00000E+00-9.29802E-05+0.00000E+00-1.52783E-04+0.00000E+00-1.78068E-04+0.00000E+00-1.60164E-04+0.00000E+00-1.00242E-04+0.00000E+00-1.01214E-05+0.00000E+00+8.95560E-05+0.00000E+00+1.73672E-04+0.00000E+00+2.18690E-04+0.00000E+00+2.09036E-04+0.00000E+00+1.42114E-04+0.00000E+00+3.04418E-05+0.00000E+00-1.00068E-04+0.00000E+00-2.15680E-04+0.00000E+00-2.83208E-04+0.00000E+00-2.79208E-04+0.00000E+00-1.97535E-04+0.00000E+00-5.29412E-05+0.00000E+00+1.20744E-04+0.00000E+00+2.78002E-04+0.00000E+00+3.73138E-04+0.00000E+00+3.73118E-04+0.00000E+00+2.68272E-04+0.00000E+00+7.75194E-05+0.00000E+00-1.53942E-04+0.00000E+00-3.64712E-04+0.00000E+00-4.92968E-04+0.00000E+00-4.94058E-04+0.00000E+00-3.55056E-04+0.00000E+00-1.01725E-04+0.00000E+00+2.04904E-04+0.00000E+00+4.82464E-04+0.00000E+00+6.48778E-04+0.00000E+00+6.45532E-04+0.00000E+00+4.57442E-04+0.00000E+00+1.20911E-04+0.00000E+00-2.81414E-04+0.00000E+00-6.40040E-04+0.00000E+00-8.47708E-04+0.00000E+00-8.30656E-04+0.00000E+00-5.73180E-04+0.00000E+00-1.27650E-04+0.00000E+00+3.94310E-04+0.00000E+00+8.48744E-04+0.00000E+00+1.09821E-03+0.00000E+00+1.05234E-03+0.00000E+00+6.98398E-04+0.00000E+00+1.11999E-04+0.00000E+00-5.57036E-04+0.00000E+00-1.12174E-03+0.00000E+00-1.40922E-03+0.00000E+00-1.31236E-03+0.00000E+00-8.26764E-04+0.00000E+00-6.09068E-05+0.00000E+00+7.85842E-04+0.00000E+00+1.47374E-03+0.00000E+00+1.78935E-03+0.00000E+00+1.61011E-03+0.00000E+00+9.47830E-04+0.00000E+00-4.36276E-05+0.00000E+00-1.10163E-03+0.00000E+00-1.92275E-03+0.00000E+00-2.24826E-03+0.00000E+00-1.94359E-03+0.00000E+00-1.04776E-03+0.00000E+00+2.24088E-04+0.00000E+00+1.52962E-03+0.00000E+00+2.48958E-03+0.00000E+00+2.79606E-03+0.00000E+00+2.30850E-03+0.00000E+00+1.10801E-03+0.00000E+00-5.08938E-04+0.00000E+00-2.10070E-03+0.00000E+00-3.19878E-03+0.00000E+00-3.44326E-03+0.00000E+00-2.69684E-03+0.00000E+00-1.10249E-03+0.00000E+00+9.36892E-04+0.00000E+00+2.85672E-03+0.00000E+00+4.08406E-03+0.00000E+00+4.20524E-03+0.00000E+00+3.09968E-03+0.00000E+00+9.97970E-04+0.00000E+00-1.55873E-03+0.00000E+00-3.85362E-03+0.00000E+00-5.19124E-03+0.00000E+00-5.10336E-03+0.00000E+00-3.50440E-03+0.00000E+00-7.46438E-04+0.00000E+00+2.44968E-03+0.00000E+00+5.17690E-03+0.00000E+00+6.59364E-03+0.00000E+00+6.17604E-03+0.00000E+00+3.89756E-03+0.00000E+00+2.77256E-04+0.00000E+00-3.72784E-03+0.00000E+00-6.96714E-03+0.00000E+00-8.41784E-03+0.00000E+00-7.49572E-03+0.00000E+00-4.26426E-03+0.00000E+00+5.27466E-04+0.00000E+00+5.60328E-03+0.00000E+00+9.48592E-03+0.00000E+00+1.09107E-02+0.00000E+00+9.21506E-03+0.00000E+00+4.58962E-03+0.00000E+00-1.89363E-03+0.00000E+00-8.50506E-03+0.00000E+00-1.32925E-02+0.00000E+00-1.46243E-02+0.00000E+00-1.16967E-02+0.00000E+00-4.85962E-03+0.00000E+00+4.34870E-03+0.00000E+00+1.34983E-02+0.00000E+00+1.98472E-02+0.00000E+00+2.10770E-02+0.00000E+00+1.60019E-02+0.00000E+00+5.06204E-03+0.00000E+00-9.55078E-03+0.00000E+00-2.42030E-02+0.00000E+00-3.45266E-02+0.00000E+00-3.63864E-02+0.00000E+00-2.68872E-02+0.00000E+00-5.18748E-03+0.00000E+00+2.70918E-02+0.00000E+00+6.59838E-02+0.00000E+00+1.05820E-01+0.00000E+00+1.40281E-01+0.00000E+00+1.63636E-01+0.00000E+00+1.71897E-01+0.00000E+00+1.63636E-01+0.00000E+00+1.40281E-01+0.00000E+00+1.05820E-01+0.00000E+00+6.59838E-02+0.00000E+00+2.70918E-02+0.00000E+00-5.18748E-03+0.00000E+00-2.68872E-02+0.00000E+00-3.63864E-02+0.00000E+00-3.45266E-02+0.00000E+00-2.42030E-02+0.00000E+00-9.55078E-03+0.00000E+00+5.06204E-03+0.00000E+00+1.60019E-02+0.00000E+00+2.10770E-02+0.00000E+00+1.98472E-02+0.00000E+00+1.34983E-02+0.00000E+00+4.34870E-03+0.00000E+00-4.85962E-03+0.00000E+00-1.16967E-02+0.00000E+00-1.46243E-02+0.00000E+00-1.32925E-02+0.00000E+00-8.50506E-03+0.00000E+00-1.89363E-03+0.00000E+00+4.58962E-03+0.00000E+00+9.21506E-03+0.00000E+00+1.09107E-02+0.00000E+00+9.48592E-03+0.00000E+00+5.60328E-03+0.00000E+00+5.27466E-04+0.00000E+00-4.26426E-03+0.00000E+00-7.49572E-03+0.00000E+00-8.41784E-03+0.00000E+00-6.96714E-03+0.00000E+00-3.7278000014S*4E-03+0.00000E+00+2.77256E-04+0.00000E+00+3.89756E-03+0.00000E+00+6.17604E-03+0.00000E+00+6.59364E-03+0.00000E+00+5.17690E-03+0.00000E+00+2.44968E-03+0.00000E+00-7.46438E-04+0.00000E+00-3.50440E-03+0.00000E+00-5.10336E-03+0.00000E+00-5.19124E-03+0.00000E+00-3.85362E-03+0.00000E+00-1.55873E-03+0.00000E+00+9.97970E-04+0.00000E+00+3.09968E-03+0.00000E+00+4.20524E-03+0.00000E+00+4.08406E-03+0.00000E+00+2.85672E-03+0.00000E+00+9.36892E-04+0.00000E+00-1.10249E-03+0.00000E+00-2.69684E-03+0.00000E+00-3.44326E-03+0.00000E+00-3.19878E-03+0.00000E+00-2.10070E-03+0.00000E+00-5.08938E-04+0.00000E+00+1.10801E-03+0.00000E+00+2.30850E-03+0.00000E+00+2.79606E-03+0.00000E+00+2.48958E-03+0.00000E+00+1.52962E-03+0.00000E+00+2.24088E-04+0.00000E+00-1.04776E-03+0.00000E+00-1.94359E-03+0.00000E+00-2.24826E-03+0.00000E+00-1.92275E-03+0.00000E+00-1.10163E-03+0.00000E+00-4.36276E-05+0.00000E+00+9.47830E-04+0.00000E+00+1.61011E-03+0.00000E+00+1.78935E-03+0.00000E+00+1.47374E-03+0.00000E+00+7.85842E-04+0.00000E+00-6.09068E-05+0.00000E+00-8.26764E-04+0.00000E+00-1.31236E-03+0.00000E+00-1.40922E-03+0.00000E+00-1.12174E-03+0.00000E+00-5.57036E-04+0.00000E+00+1.11999E-04+0.00000E+00+6.98398E-04+0.00000E+00+1.05234E-03+0.00000E+00+1.09821E-03+0.00000E+00+8.48744E-04+0.00000E+00+3.94310E-04+0.00000E+00-1.27650E-04+0.00000E+00-5.73180E-04+0.00000E+00-8.30656E-04+0.00000E+00-8.47708E-04+0.00000E+00-6.40040E-04+0.00000E+00-2.81414E-04+0.00000E+00+1.20911E-04+0.00000E+00+4.57442E-04+0.00000E+00+6.45532E-04+0.00000E+00+6.48778E-04+0.00000E+00+4.82464E-04+0.00000E+00+2.04904E-04+0.00000E+00-1.01725E-04+0.00000E+00-3.55056E-04+0.00000E+00-4.94058E-04+0.00000E+00-4.92968E-04+0.00000E+00-3.64712E-04+0.00000E+00-1.53942E-04+0.00000E+00+7.75194E-05+0.00000E+00+2.68272E-04+0.00000E+00+3.73118E-04+0.00000E+00+3.73138E-04+0.00000E+00+2.78002E-04+0.00000E+00+1.20744E-04+0.00000E+00-5.29412E-05+0.00000E+00-1.97535E-04+0.00000E+00-2.79208E-04+0.00000E+00-2.83208E-04+0.00000E+00-2.15680E-04+0.00000E+00-1.00068E-04+0.00000E+00+3.04418E-05+0.00000E+00+1.42114E-04+0.00000E+00+2.09036E-04+0.00000E+00+2.18690E-04+0.00000E+00+1.73672E-04+0.00000E+00+8.95560E-05+0.00000E+00-1.01214E-05+0.00000E+00-1.00242E-04+0.00000E+00-1.60164E-04+0.00000E+00-1.78068E-04+0.00000E+00-1.52783E-04+0.00000E+00-9.29802E-05+0.00000E+00-1.42499E-05+0.00000E+00+6.50032E-05+0.00000E+00+1.27774E-04+0.00000E+00+1.61835E-04+0.00000E+00+1.61671E-04+0.00000E+00+1.28752E-04+0.00000E+00+7.03544E-05+0.00000E+00-2.59160E-06+0.00000E+00-7.80380E-05+0.00000E+00-1.45142E-04+0.00000E+00-1.95955E-04+0.00000E+00-2.26268E-04+0.00000E+00-2.35600E-04+0.00000E+00-2.26532E-04+0.00000E+00-2.03638E-04+0.00000E+00-1.72307E-04+0.00000E+00-1.37722E-04+0.00000E+00-1.04124E-04+0.00000E+00-7.44366E-05+0.00000E+00-5.02182E-05+0.00000E+00-3.18550E-05+0.00000E+00-1.88893E-05+0.00000E+00-1.03793E-05+0.00000E+00-5.21464E-06+0.00000E+00-2.34472E-06+0.00000E+00-9.08544E-07+0.00000E+00-2.80036E-07+0.00000E+00-5.32080E-08+0.00000E+00+4.52378E-09+0.00000E+00+7.72762E-09+0.00000E+0000000570051071.0000E+030000500000+1.5900E-01+1.5900E-01058003507+1.00000E+00+5.00000E-0200058003500+2.78845E+05+5.00000E-02000520149 HNE0000003~004002+49.129100+008.148700+0128.0000.0090.0+00.00001122.0000E+022.0000E-020000TG~2015,008,10:45:00.0000~2015,078,13:00:00.0000~N0530382A01004003+1.00770E+18+1.00000E+00001-5.15000E+02+0.00000E+00+0.00000E+00+0.00000E+00006-9.77000E+02+3.28000E+02+0.00000E+00+0.00000E+00-9.77000E+02-3.28000E+02+0.00000E+00+0.00000E+00-1.48600E+03+2.51200E+03+0.00000E+00+0.00000E+00-1.48600E+03-2.51200E+03+0.00000E+00+0.00000E+00-5.73600E+03+4.94600E+03+0.00000E+00+0.00000E+00-5.73600E+03-4.94600E+03+0.00000E+00+0.00000E+00058003501+5.10000E-01+1.00000E+0000058003502+1.00000E+00+5.00000E-02000540048D030030040001+1.00000E+00+0.00000E+0000000570051031.9200E+050000100000+0.0000E+00+0.0000E+00058003503+4.00000E+05+5.00000E-02000541152D040040040047+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+3.81470E-06+0.00000E+00+2.28882E-05+0.00000E+00+8.01086E-05+0.00000E+00+2.13623E-04+0.00000E+00+4.80652E-04+0.00000E+00+9.61304E-04+0.00000E+0000015S*0+1.76239E-03+0.00000E+00+3.02124E-03+0.00000E+00+4.88663E-03+0.00000E+00+7.49969E-03+0.00000E+00+1.09749E-02+0.00000E+00+1.53809E-02+0.00000E+00+2.07214E-02+0.00000E+00+2.69165E-02+0.00000E+00+3.37830E-02+0.00000E+00+4.10156E-02+0.00000E+00+4.82254E-02+0.00000E+00+5.49774E-02+0.00000E+00+6.08292E-02+0.00000E+00+6.53687E-02+0.00000E+00+6.82526E-02+0.00000E+00+6.92444E-02+0.00000E+00+6.82526E-02+0.00000E+00+6.53687E-02+0.00000E+00+6.08292E-02+0.00000E+00+5.49774E-02+0.00000E+00+4.82254E-02+0.00000E+00+4.10156E-02+0.00000E+00+3.37830E-02+0.00000E+00+2.69165E-02+0.00000E+00+2.07214E-02+0.00000E+00+1.53809E-02+0.00000E+00+1.09749E-02+0.00000E+00+7.49969E-03+0.00000E+00+4.88663E-03+0.00000E+00+3.02124E-03+0.00000E+00+1.76239E-03+0.00000E+00+9.61304E-04+0.00000E+00+4.80652E-04+0.00000E+00+2.13623E-04+0.00000E+00+8.01086E-05+0.00000E+00+2.28882E-05+0.00000E+00+3.81470E-06+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+0000000570051041.9200E+050000800000+1.1979E-04+1.1979E-04058003504+1.00000E+00+5.00000E-02000541776D050040040073+7.86395E-07+0.00000E+00+2.15223E-06+0.00000E+00+4.09013E-06+0.00000E+00+6.42053E-06+0.00000E+00+7.61300E-06+0.00000E+00+4.52134E-06+0.00000E+00-8.38839E-06+0.00000E+00-4.00745E-05+0.00000E+00-1.08702E-04+0.00000E+00-2.31570E-04+0.00000E+00-4.32673E-04+0.00000E+00-7.41861E-04+0.00000E+00-1.18635E-03+0.00000E+00-1.78887E-03+0.00000E+00-2.56156E-03+0.00000E+00-3.49756E-03+0.00000E+00-4.54784E-03+0.00000E+00-5.64473E-03+0.00000E+00-6.67437E-03+0.00000E+00-7.46932E-03+0.00000E+00-7.83206E-03+0.00000E+00-7.53472E-03+0.00000E+00-6.33480E-03+0.00000E+00-3.99943E-03+0.00000E+00-3.60688E-04+0.00000E+00+4.71408E-03+0.00000E+00+1.12572E-02+0.00000E+00+1.91611E-02+0.00000E+00+2.82115E-02+0.00000E+00+3.80655E-02+0.00000E+00+4.82646E-02+0.00000E+00+5.82654E-02+0.00000E+00+6.75164E-02+0.00000E+00+7.54318E-02+0.00000E+00+8.14859E-02+0.00000E+00+8.52972E-02+0.00000E+00+8.65986E-02+0.00000E+00+8.52972E-02+0.00000E+00+8.14859E-02+0.00000E+00+7.54318E-02+0.00000E+00+6.75164E-02+0.00000E+00+5.82654E-02+0.00000E+00+4.82646E-02+0.00000E+00+3.80655E-02+0.00000E+00+2.82115E-02+0.00000E+00+1.91611E-02+0.00000E+00+1.12572E-02+0.00000E+00+4.71408E-03+0.00000E+00-3.60688E-04+0.00000E+00-3.99943E-03+0.00000E+00-6.33480E-03+0.00000E+00-7.53472E-03+0.00000E+00-7.83206E-03+0.00000E+00-7.46932E-03+0.00000E+00-6.67437E-03+0.00000E+00-5.64473E-03+0.00000E+00-4.54784E-03+0.00000E+00-3.49756E-03+0.00000E+00-2.56156E-03+0.00000E+00-1.78887E-03+0.00000E+00-1.18635E-03+0.00000E+00-7.41861E-04+0.00000E+00-4.32673E-04+0.00000E+00-2.31570E-04+0.00000E+00-1.08702E-04+0.00000E+00-4.00745E-05+0.00000E+00-8.38839E-06+0.00000E+00+4.52134E-06+0.00000E+00+7.61300E-06+0.00000E+00+6.42053E-06+0.00000E+00+4.09013E-06+0.00000E+00+2.15223E-06+0.00000E+00+7.86395E-07+0.00000E+0000000570051052.4000E+040000800000+1.5000E-03+1.5000E-03058003505+1.00000E+00+5.00000E-02000544320D060040040179+1.65488E-07+0.00000E+00+7.48132E-07+0.00000E+00+1.76664E-06+0.00000E+00+1.62612E-06+0.00000E+00-5.16640E-06+0.00000E+00-3.00692E-05+0.00000E+00-8.97376E-05+0.00000E+00-1.99571E-04+0.00000E+00-3.61172E-04+0.00000E+00-5.48500E-04+0.00000E+00-7.02688E-04+0.00000E+00-7.45976E-04+0.00000E+00-6.17072E-04+0.00000E+00-3.15191E-04+0.00000E+00+7.38188E-05+0.00000E+00+3.95725E-04+0.00000E+00+4.96800E-04+0.00000E+00+3.15263E-04+0.00000E+00-5.96548E-05+0.00000E+00-4.11872E-04+0.00000E+00-5.12780E-04+0.00000E+00-2.69536E-04+0.00000E+00+1.89248E-04+0.00000E+00+5.66172E-04+0.00000E+00+5.78372E-04+0.00000E+00+1.64727E-04+0.00000E+00-4.31664E-04+0.00000E+00-7.92432E-04+0.00000E+00-6.08316E-04+0.00000E+00+6.76780E-05+0.00000E+00+7.98316E-04+0.00000E+00+1.03172E-03+0.00000E+00+5.07504E-04+0.00000E+00-4.91744E-04+0.00000E+00-1.26810E-03+0.00000E+00-1.18261E-03+0.00000E+00-1.64670E-04+0.00000E+00+1.13876E-03+0.00000E+00+1.75363E-03+0.00000E+00+1.09177E-03+0.00000E+00-5.24120E-04+0.00000E+00-1.97068E-03+0.00000E+00-2.08536E-03+0.00000E+00-5.79052E-04+0.00000E+00+1.60144E-03+0.00000E+00+2.83576E-03+0.00000E+00+2.01276E-03+0.00000E+00-5.13156E-04+0.00000E+00-2.98815E-03+0.00000E+00-3.000016S*44765E-03+0.00000E+00-1.24599E-03+0.00000E+00+2.24272E-03+0.00000E+00+4.43120E-03+0.00000E+00+3.40590E-03+0.00000E+00-4.57304E-04+0.00000E+00-4.47584E-03+0.00000E+00-5.47828E-03+0.00000E+00-2.26220E-03+0.00000E+00+3.18035E-03+0.00000E+00+6.81616E-03+0.00000E+00+5.50776E-03+0.00000E+00-3.65328E-04+0.00000E+00-6.73316E-03+0.00000E+00-8.58052E-03+0.00000E+00-3.81782E-03+0.00000E+00+4.65228E-03+0.00000E+00+1.05646E-02+0.00000E+00+8.82560E-03+0.00000E+00-2.56374E-04+0.00000E+00-1.04496E-02+0.00000E+00-1.37224E-02+0.00000E+00-6.39512E-03+0.00000E+00+7.26512E-03+0.00000E+00+1.72312E-02+0.00000E+00+1.48181E-02+0.00000E+00-1.54011E-04+0.00000E+00-1.77680E-02+0.00000E+00-2.41384E-02+0.00000E+00-1.17549E-02+0.00000E+00+1.32733E-02+0.00000E+00+3.32147E-02+0.00000E+00+3.01309E-02+0.00000E+00-8.13468E-05+0.00000E+00-4.08284E-02+0.00000E+00-6.13256E-02+0.00000E+00-3.42109E-02+0.00000E+00+4.58968E-02+0.00000E+00+1.54886E-01+0.00000E+00+2.48713E-01+0.00000E+00+2.85658E-01+0.00000E+00+2.48713E-01+0.00000E+00+1.54886E-01+0.00000E+00+4.58968E-02+0.00000E+00-3.42109E-02+0.00000E+00-6.13256E-02+0.00000E+00-4.08284E-02+0.00000E+00-8.13468E-05+0.00000E+00+3.01309E-02+0.00000E+00+3.32147E-02+0.00000E+00+1.32733E-02+0.00000E+00-1.17549E-02+0.00000E+00-2.41384E-02+0.00000E+00-1.77680E-02+0.00000E+00-1.54011E-04+0.00000E+00+1.48181E-02+0.00000E+00+1.72312E-02+0.00000E+00+7.26512E-03+0.00000E+00-6.39512E-03+0.00000E+00-1.37224E-02+0.00000E+00-1.04496E-02+0.00000E+00-2.56374E-04+0.00000E+00+8.82560E-03+0.00000E+00+1.05646E-02+0.00000E+00+4.65228E-03+0.00000E+00-3.81782E-03+0.00000E+00-8.58052E-03+0.00000E+00-6.73316E-03+0.00000E+00-3.65328E-04+0.00000E+00+5.50776E-03+0.00000E+00+6.81616E-03+0.00000E+00+3.18035E-03+0.00000E+00-2.26220E-03+0.00000E+00-5.47828E-03+0.00000E+00-4.47584E-03+0.00000E+00-4.57304E-04+0.00000E+00+3.40590E-03+0.00000E+00+4.43120E-03+0.00000E+00+2.24272E-03+0.00000E+00-1.24599E-03+0.00000E+00-3.44765E-03+0.00000E+00-2.98815E-03+0.00000E+00-5.13156E-04+0.00000E+00+2.01276E-03+0.00000E+00+2.83576E-03+0.00000E+00+1.60144E-03+0.00000E+00-5.79052E-04+0.00000E+00-2.08536E-03+0.00000E+00-1.97068E-03+0.00000E+00-5.24120E-04+0.00000E+00+1.09177E-03+0.00000E+00+1.75363E-03+0.00000E+00+1.13876E-03+0.00000E+00-1.64670E-04+0.00000E+00-1.18261E-03+0.00000E+00-1.26810E-03+0.00000E+00-4.91744E-04+0.00000E+00+5.07504E-04+0.00000E+00+1.03172E-03+0.00000E+00+7.98316E-04+0.00000E+00+6.76780E-05+0.00000E+00-6.08316E-04+0.00000E+00-7.92432E-04+0.00000E+00-4.31664E-04+0.00000E+00+1.64727E-04+0.00000E+00+5.78372E-04+0.00000E+00+5.66172E-04+0.00000E+00+1.89248E-04+0.00000E+00-2.69536E-04+0.00000E+00-5.12780E-04+0.00000E+00-4.11872E-04+0.00000E+00-5.96548E-05+0.00000E+00+3.15263E-04+0.00000E+00+4.96800E-04+0.00000E+00+3.95725E-04+0.00000E+00+7.38188E-05+0.00000E+00-3.15191E-04+0.00000E+00-6.17072E-04+0.00000E+00-7.45976E-04+0.00000E+00-7.02688E-04+0.00000E+00-5.48500E-04+0.00000E+00-3.61172E-04+0.00000E+00-1.99571E-04+0.00000E+00-8.97376E-05+0.00000E+00-3.00692E-05+0.00000E+00-5.16640E-06+0.00000E+00+1.62612E-06+0.00000E+00+1.76664E-06+0.00000E+00+7.48132E-07+0.00000E+00+1.65488E-07+0.00000E+0000000570051063.0000E+030000300000+2.9667E-02+2.9667E-02058003506+1.00000E+00+5.00000E-02000547680D070040040319+7.72762E-09+0.00000E+00+4.52378E-09+0.00000E+00-5.32080E-08+0.00000E+00-2.80036E-07+0.00000E+00-9.08544E-07+0.00000E+00-2.34472E-06+0.00000E+00-5.21464E-06+0.00000E+00-1.03793E-05+0.00000E+00-1.88893E-05+0.00000E+00-3.18550E-05+0.00000E+00-5.02182E-05+0.00000E+00-7.44366E-05+0.00000E+00-1.04124E-04+0.00000E+00-1.37722E-04+0.00000E+00-1.72307E-04+0.00000E+00-2.03638E-04+0.00000E+00-2.26532E-04+0.00000E+00-2.35600E-04+0.00000E+00-2.26268E-04+0.00000E+00-1.95955E-04+0.00000E+00-1.45142E-04+0.00000E+00-7.80380E-05+0.00000E+00-2.59160E-06+0.00000E+00+7.03544E-05+0.00000E+00+1.28752E-04+0.00000E+00+1.61671E-04+0.00000E+00+1.61835E-04+0.00000E+00+1.27774E-04+0.00000E+00+6.50032E-05+0.00000E+00-1.42499E-05+0.00000E+00-9.29802E-05+0.00000E+00-1.52783E-04+0.00000E+00-1.78068E-04+0.00000E+00-1.60164E-04+0.00000E+00-1.00242E-04+0.00000E+00-1.01214E-05+0.00000E000017S*+00+8.95560E-05+0.00000E+00+1.73672E-04+0.00000E+00+2.18690E-04+0.00000E+00+2.09036E-04+0.00000E+00+1.42114E-04+0.00000E+00+3.04418E-05+0.00000E+00-1.00068E-04+0.00000E+00-2.15680E-04+0.00000E+00-2.83208E-04+0.00000E+00-2.79208E-04+0.00000E+00-1.97535E-04+0.00000E+00-5.29412E-05+0.00000E+00+1.20744E-04+0.00000E+00+2.78002E-04+0.00000E+00+3.73138E-04+0.00000E+00+3.73118E-04+0.00000E+00+2.68272E-04+0.00000E+00+7.75194E-05+0.00000E+00-1.53942E-04+0.00000E+00-3.64712E-04+0.00000E+00-4.92968E-04+0.00000E+00-4.94058E-04+0.00000E+00-3.55056E-04+0.00000E+00-1.01725E-04+0.00000E+00+2.04904E-04+0.00000E+00+4.82464E-04+0.00000E+00+6.48778E-04+0.00000E+00+6.45532E-04+0.00000E+00+4.57442E-04+0.00000E+00+1.20911E-04+0.00000E+00-2.81414E-04+0.00000E+00-6.40040E-04+0.00000E+00-8.47708E-04+0.00000E+00-8.30656E-04+0.00000E+00-5.73180E-04+0.00000E+00-1.27650E-04+0.00000E+00+3.94310E-04+0.00000E+00+8.48744E-04+0.00000E+00+1.09821E-03+0.00000E+00+1.05234E-03+0.00000E+00+6.98398E-04+0.00000E+00+1.11999E-04+0.00000E+00-5.57036E-04+0.00000E+00-1.12174E-03+0.00000E+00-1.40922E-03+0.00000E+00-1.31236E-03+0.00000E+00-8.26764E-04+0.00000E+00-6.09068E-05+0.00000E+00+7.85842E-04+0.00000E+00+1.47374E-03+0.00000E+00+1.78935E-03+0.00000E+00+1.61011E-03+0.00000E+00+9.47830E-04+0.00000E+00-4.36276E-05+0.00000E+00-1.10163E-03+0.00000E+00-1.92275E-03+0.00000E+00-2.24826E-03+0.00000E+00-1.94359E-03+0.00000E+00-1.04776E-03+0.00000E+00+2.24088E-04+0.00000E+00+1.52962E-03+0.00000E+00+2.48958E-03+0.00000E+00+2.79606E-03+0.00000E+00+2.30850E-03+0.00000E+00+1.10801E-03+0.00000E+00-5.08938E-04+0.00000E+00-2.10070E-03+0.00000E+00-3.19878E-03+0.00000E+00-3.44326E-03+0.00000E+00-2.69684E-03+0.00000E+00-1.10249E-03+0.00000E+00+9.36892E-04+0.00000E+00+2.85672E-03+0.00000E+00+4.08406E-03+0.00000E+00+4.20524E-03+0.00000E+00+3.09968E-03+0.00000E+00+9.97970E-04+0.00000E+00-1.55873E-03+0.00000E+00-3.85362E-03+0.00000E+00-5.19124E-03+0.00000E+00-5.10336E-03+0.00000E+00-3.50440E-03+0.00000E+00-7.46438E-04+0.00000E+00+2.44968E-03+0.00000E+00+5.17690E-03+0.00000E+00+6.59364E-03+0.00000E+00+6.17604E-03+0.00000E+00+3.89756E-03+0.00000E+00+2.77256E-04+0.00000E+00-3.72784E-03+0.00000E+00-6.96714E-03+0.00000E+00-8.41784E-03+0.00000E+00-7.49572E-03+0.00000E+00-4.26426E-03+0.00000E+00+5.27466E-04+0.00000E+00+5.60328E-03+0.00000E+00+9.48592E-03+0.00000E+00+1.09107E-02+0.00000E+00+9.21506E-03+0.00000E+00+4.58962E-03+0.00000E+00-1.89363E-03+0.00000E+00-8.50506E-03+0.00000E+00-1.32925E-02+0.00000E+00-1.46243E-02+0.00000E+00-1.16967E-02+0.00000E+00-4.85962E-03+0.00000E+00+4.34870E-03+0.00000E+00+1.34983E-02+0.00000E+00+1.98472E-02+0.00000E+00+2.10770E-02+0.00000E+00+1.60019E-02+0.00000E+00+5.06204E-03+0.00000E+00-9.55078E-03+0.00000E+00-2.42030E-02+0.00000E+00-3.45266E-02+0.00000E+00-3.63864E-02+0.00000E+00-2.68872E-02+0.00000E+00-5.18748E-03+0.00000E+00+2.70918E-02+0.00000E+00+6.59838E-02+0.00000E+00+1.05820E-01+0.00000E+00+1.40281E-01+0.00000E+00+1.63636E-01+0.00000E+00+1.71897E-01+0.00000E+00+1.63636E-01+0.00000E+00+1.40281E-01+0.00000E+00+1.05820E-01+0.00000E+00+6.59838E-02+0.00000E+00+2.70918E-02+0.00000E+00-5.18748E-03+0.00000E+00-2.68872E-02+0.00000E+00-3.63864E-02+0.00000E+00-3.45266E-02+0.00000E+00-2.42030E-02+0.00000E+00-9.55078E-03+0.00000E+00+5.06204E-03+0.00000E+00+1.60019E-02+0.00000E+00+2.10770E-02+0.00000E+00+1.98472E-02+0.00000E+00+1.34983E-02+0.00000E+00+4.34870E-03+0.00000E+00-4.85962E-03+0.00000E+00-1.16967E-02+0.00000E+00-1.46243E-02+0.00000E+00-1.32925E-02+0.00000E+00-8.50506E-03+0.00000E+00-1.89363E-03+0.00000E+00+4.58962E-03+0.00000E+00+9.21506E-03+0.00000E+00+1.09107E-02+0.00000E+00+9.48592E-03+0.00000E+00+5.60328E-03+0.00000E+00+5.27466E-04+0.00000E+00-4.26426E-03+0.00000E+00-7.49572E-03+0.00000E+00-8.41784E-03+0.00000E+00-6.96714E-03+0.00000E+00-3.72784E-03+0.00000E+00+2.77256E-04+0.00000E+00+3.89756E-03+0.00000E+00+6.17604E-03+0.00000E+00+6.59364E-03+0.00000E+00+5.17690E-03+0.00000E+00+2.44968E-03+0.00000E+00-7.46438E-04+0.00000E+00-3.50440E-03+0.00000E+00-5.10336E-03+0.00000E+00-5.19124E-03+0.00000E+00-3.85362E-03+0.00000E+00-1.55873E-03+0.00000E+00+9.97000018S*970E-04+0.00000E+00+3.09968E-03+0.00000E+00+4.20524E-03+0.00000E+00+4.08406E-03+0.00000E+00+2.85672E-03+0.00000E+00+9.36892E-04+0.00000E+00-1.10249E-03+0.00000E+00-2.69684E-03+0.00000E+00-3.44326E-03+0.00000E+00-3.19878E-03+0.00000E+00-2.10070E-03+0.00000E+00-5.08938E-04+0.00000E+00+1.10801E-03+0.00000E+00+2.30850E-03+0.00000E+00+2.79606E-03+0.00000E+00+2.48958E-03+0.00000E+00+1.52962E-03+0.00000E+00+2.24088E-04+0.00000E+00-1.04776E-03+0.00000E+00-1.94359E-03+0.00000E+00-2.24826E-03+0.00000E+00-1.92275E-03+0.00000E+00-1.10163E-03+0.00000E+00-4.36276E-05+0.00000E+00+9.47830E-04+0.00000E+00+1.61011E-03+0.00000E+00+1.78935E-03+0.00000E+00+1.47374E-03+0.00000E+00+7.85842E-04+0.00000E+00-6.09068E-05+0.00000E+00-8.26764E-04+0.00000E+00-1.31236E-03+0.00000E+00-1.40922E-03+0.00000E+00-1.12174E-03+0.00000E+00-5.57036E-04+0.00000E+00+1.11999E-04+0.00000E+00+6.98398E-04+0.00000E+00+1.05234E-03+0.00000E+00+1.09821E-03+0.00000E+00+8.48744E-04+0.00000E+00+3.94310E-04+0.00000E+00-1.27650E-04+0.00000E+00-5.73180E-04+0.00000E+00-8.30656E-04+0.00000E+00-8.47708E-04+0.00000E+00-6.40040E-04+0.00000E+00-2.81414E-04+0.00000E+00+1.20911E-04+0.00000E+00+4.57442E-04+0.00000E+00+6.45532E-04+0.00000E+00+6.48778E-04+0.00000E+00+4.82464E-04+0.00000E+00+2.04904E-04+0.00000E+00-1.01725E-04+0.00000E+00-3.55056E-04+0.00000E+00-4.94058E-04+0.00000E+00-4.92968E-04+0.00000E+00-3.64712E-04+0.00000E+00-1.53942E-04+0.00000E+00+7.75194E-05+0.00000E+00+2.68272E-04+0.00000E+00+3.73118E-04+0.00000E+00+3.73138E-04+0.00000E+00+2.78002E-04+0.00000E+00+1.20744E-04+0.00000E+00-5.29412E-05+0.00000E+00-1.97535E-04+0.00000E+00-2.79208E-04+0.00000E+00-2.83208E-04+0.00000E+00-2.15680E-04+0.00000E+00-1.00068E-04+0.00000E+00+3.04418E-05+0.00000E+00+1.42114E-04+0.00000E+00+2.09036E-04+0.00000E+00+2.18690E-04+0.00000E+00+1.73672E-04+0.00000E+00+8.95560E-05+0.00000E+00-1.01214E-05+0.00000E+00-1.00242E-04+0.00000E+00-1.60164E-04+0.00000E+00-1.78068E-04+0.00000E+00-1.52783E-04+0.00000E+00-9.29802E-05+0.00000E+00-1.42499E-05+0.00000E+00+6.50032E-05+0.00000E+00+1.27774E-04+0.00000E+00+1.61835E-04+0.00000E+00+1.61671E-04+0.00000E+00+1.28752E-04+0.00000E+00+7.03544E-05+0.00000E+00-2.59160E-06+0.00000E+00-7.80380E-05+0.00000E+00-1.45142E-04+0.00000E+00-1.95955E-04+0.00000E+00-2.26268E-04+0.00000E+00-2.35600E-04+0.00000E+00-2.26532E-04+0.00000E+00-2.03638E-04+0.00000E+00-1.72307E-04+0.00000E+00-1.37722E-04+0.00000E+00-1.04124E-04+0.00000E+00-7.44366E-05+0.00000E+00-5.02182E-05+0.00000E+00-3.18550E-05+0.00000E+00-1.88893E-05+0.00000E+00-1.03793E-05+0.00000E+00-5.21464E-06+0.00000E+00-2.34472E-06+0.00000E+00-9.08544E-07+0.00000E+00-2.80036E-07+0.00000E+00-5.32080E-08+0.00000E+00+4.52378E-09+0.00000E+00+7.72762E-09+0.00000E+0000000570051071.0000E+030000500000+1.5900E-01+1.5900E-01058003507+1.00000E+00+5.00000E-0200058003500+2.03990E+05+5.00000E-02000520149 HNN0000003~004002+49.129100+008.148700+0128.0000.0000.0+00.00001122.0000E+022.0000E-020000TG~2015,008,10:45:00.0000~2015,078,13:00:00.0000~N0530382A01004003+1.00770E+18+1.00000E+00001-5.15000E+02+0.00000E+00+0.00000E+00+0.00000E+00006-9.77000E+02+3.28000E+02+0.00000E+00+0.00000E+00-9.77000E+02-3.28000E+02+0.00000E+00+0.00000E+00-1.48600E+03+2.51200E+03+0.00000E+00+0.00000E+00-1.48600E+03-2.51200E+03+0.00000E+00+0.00000E+00-5.73600E+03+4.94600E+03+0.00000E+00+0.00000E+00-5.73600E+03-4.94600E+03+0.00000E+00+0.00000E+00058003501+5.10000E-01+1.00000E+0000058003502+1.00000E+00+5.00000E-02000540048D030030040001+1.00000E+00+0.00000E+0000000570051031.9200E+050000100000+0.0000E+00+0.0000E+00058003503+4.00000E+05+5.00000E-02000541152D040040040047+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+3.81470E-06+0.00000E+00+2.28882E-05+0.00000E+00+8.01086E-05+0.00000E+00+2.13623E-04+0.00000E+00+4.80652E-04+0.00000E+00+9.61304E-04+0.00000E+00+1.76239E-03+0.00000E+00+3.02124E-03+0.00000E+00+4.88663E-03+0.00000E+00+7.49969E-03+0.00000E+00+1.09749E-02+0.00000E+00+1.53809E-02+0.00000E+00+2.07214E-02+0.00000E+00+2.69165E-02+0.00000E+00+3.37830E-02+0.00000E+00+4.10156E-02+0.00000E+00+4.82254E-02+0.00000E+00+5.49774E-02+0.00000E+00+6.08292E-02+0.00000E000019S*+00+6.53687E-02+0.00000E+00+6.82526E-02+0.00000E+00+6.92444E-02+0.00000E+00+6.82526E-02+0.00000E+00+6.53687E-02+0.00000E+00+6.08292E-02+0.00000E+00+5.49774E-02+0.00000E+00+4.82254E-02+0.00000E+00+4.10156E-02+0.00000E+00+3.37830E-02+0.00000E+00+2.69165E-02+0.00000E+00+2.07214E-02+0.00000E+00+1.53809E-02+0.00000E+00+1.09749E-02+0.00000E+00+7.49969E-03+0.00000E+00+4.88663E-03+0.00000E+00+3.02124E-03+0.00000E+00+1.76239E-03+0.00000E+00+9.61304E-04+0.00000E+00+4.80652E-04+0.00000E+00+2.13623E-04+0.00000E+00+8.01086E-05+0.00000E+00+2.28882E-05+0.00000E+00+3.81470E-06+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+0000000570051041.9200E+050000800000+1.1979E-04+1.1979E-04058003504+1.00000E+00+5.00000E-02000541776D050040040073+7.86395E-07+0.00000E+00+2.15223E-06+0.00000E+00+4.09013E-06+0.00000E+00+6.42053E-06+0.00000E+00+7.61300E-06+0.00000E+00+4.52134E-06+0.00000E+00-8.38839E-06+0.00000E+00-4.00745E-05+0.00000E+00-1.08702E-04+0.00000E+00-2.31570E-04+0.00000E+00-4.32673E-04+0.00000E+00-7.41861E-04+0.00000E+00-1.18635E-03+0.00000E+00-1.78887E-03+0.00000E+00-2.56156E-03+0.00000E+00-3.49756E-03+0.00000E+00-4.54784E-03+0.00000E+00-5.64473E-03+0.00000E+00-6.67437E-03+0.00000E+00-7.46932E-03+0.00000E+00-7.83206E-03+0.00000E+00-7.53472E-03+0.00000E+00-6.33480E-03+0.00000E+00-3.99943E-03+0.00000E+00-3.60688E-04+0.00000E+00+4.71408E-03+0.00000E+00+1.12572E-02+0.00000E+00+1.91611E-02+0.00000E+00+2.82115E-02+0.00000E+00+3.80655E-02+0.00000E+00+4.82646E-02+0.00000E+00+5.82654E-02+0.00000E+00+6.75164E-02+0.00000E+00+7.54318E-02+0.00000E+00+8.14859E-02+0.00000E+00+8.52972E-02+0.00000E+00+8.65986E-02+0.00000E+00+8.52972E-02+0.00000E+00+8.14859E-02+0.00000E+00+7.54318E-02+0.00000E+00+6.75164E-02+0.00000E+00+5.82654E-02+0.00000E+00+4.82646E-02+0.00000E+00+3.80655E-02+0.00000E+00+2.82115E-02+0.00000E+00+1.91611E-02+0.00000E+00+1.12572E-02+0.00000E+00+4.71408E-03+0.00000E+00-3.60688E-04+0.00000E+00-3.99943E-03+0.00000E+00-6.33480E-03+0.00000E+00-7.53472E-03+0.00000E+00-7.83206E-03+0.00000E+00-7.46932E-03+0.00000E+00-6.67437E-03+0.00000E+00-5.64473E-03+0.00000E+00-4.54784E-03+0.00000E+00-3.49756E-03+0.00000E+00-2.56156E-03+0.00000E+00-1.78887E-03+0.00000E+00-1.18635E-03+0.00000E+00-7.41861E-04+0.00000E+00-4.32673E-04+0.00000E+00-2.31570E-04+0.00000E+00-1.08702E-04+0.00000E+00-4.00745E-05+0.00000E+00-8.38839E-06+0.00000E+00+4.52134E-06+0.00000E+00+7.61300E-06+0.00000E+00+6.42053E-06+0.00000E+00+4.09013E-06+0.00000E+00+2.15223E-06+0.00000E+00+7.86395E-07+0.00000E+0000000570051052.4000E+040000800000+1.5000E-03+1.5000E-03058003505+1.00000E+00+5.00000E-02000544320D060040040179+1.65488E-07+0.00000E+00+7.48132E-07+0.00000E+00+1.76664E-06+0.00000E+00+1.62612E-06+0.00000E+00-5.16640E-06+0.00000E+00-3.00692E-05+0.00000E+00-8.97376E-05+0.00000E+00-1.99571E-04+0.00000E+00-3.61172E-04+0.00000E+00-5.48500E-04+0.00000E+00-7.02688E-04+0.00000E+00-7.45976E-04+0.00000E+00-6.17072E-04+0.00000E+00-3.15191E-04+0.00000E+00+7.38188E-05+0.00000E+00+3.95725E-04+0.00000E+00+4.96800E-04+0.00000E+00+3.15263E-04+0.00000E+00-5.96548E-05+0.00000E+00-4.11872E-04+0.00000E+00-5.12780E-04+0.00000E+00-2.69536E-04+0.00000E+00+1.89248E-04+0.00000E+00+5.66172E-04+0.00000E+00+5.78372E-04+0.00000E+00+1.64727E-04+0.00000E+00-4.31664E-04+0.00000E+00-7.92432E-04+0.00000E+00-6.08316E-04+0.00000E+00+6.76780E-05+0.00000E+00+7.98316E-04+0.00000E+00+1.03172E-03+0.00000E+00+5.07504E-04+0.00000E+00-4.91744E-04+0.00000E+00-1.26810E-03+0.00000E+00-1.18261E-03+0.00000E+00-1.64670E-04+0.00000E+00+1.13876E-03+0.00000E+00+1.75363E-03+0.00000E+00+1.09177E-03+0.00000E+00-5.24120E-04+0.00000E+00-1.97068E-03+0.00000E+00-2.08536E-03+0.00000E+00-5.79052E-04+0.00000E+00+1.60144E-03+0.00000E+00+2.83576E-03+0.00000E+00+2.01276E-03+0.00000E+00-5.13156E-04+0.00000E+00-2.98815E-03+0.00000E+00-3.44765E-03+0.00000E+00-1.24599E-03+0.00000E+00+2.24272E-03+0.00000E+00+4.43120E-03+0.00000E+00+3.40590E-03+0.00000E+00-4.57304E-04+0.00000E+00-4.47584E-03+0.00000E+00-5.47828E-03+0.00000E+00-2.26220E-03+0.00000E+00+3.18035E-03+0.00000E+00+6.81616E-03+0.00000E+00+5.50776E-03+0.00000E+00-3.65328E-04+0.00000E+00-000020S*6.73316E-03+0.00000E+00-8.58052E-03+0.00000E+00-3.81782E-03+0.00000E+00+4.65228E-03+0.00000E+00+1.05646E-02+0.00000E+00+8.82560E-03+0.00000E+00-2.56374E-04+0.00000E+00-1.04496E-02+0.00000E+00-1.37224E-02+0.00000E+00-6.39512E-03+0.00000E+00+7.26512E-03+0.00000E+00+1.72312E-02+0.00000E+00+1.48181E-02+0.00000E+00-1.54011E-04+0.00000E+00-1.77680E-02+0.00000E+00-2.41384E-02+0.00000E+00-1.17549E-02+0.00000E+00+1.32733E-02+0.00000E+00+3.32147E-02+0.00000E+00+3.01309E-02+0.00000E+00-8.13468E-05+0.00000E+00-4.08284E-02+0.00000E+00-6.13256E-02+0.00000E+00-3.42109E-02+0.00000E+00+4.58968E-02+0.00000E+00+1.54886E-01+0.00000E+00+2.48713E-01+0.00000E+00+2.85658E-01+0.00000E+00+2.48713E-01+0.00000E+00+1.54886E-01+0.00000E+00+4.58968E-02+0.00000E+00-3.42109E-02+0.00000E+00-6.13256E-02+0.00000E+00-4.08284E-02+0.00000E+00-8.13468E-05+0.00000E+00+3.01309E-02+0.00000E+00+3.32147E-02+0.00000E+00+1.32733E-02+0.00000E+00-1.17549E-02+0.00000E+00-2.41384E-02+0.00000E+00-1.77680E-02+0.00000E+00-1.54011E-04+0.00000E+00+1.48181E-02+0.00000E+00+1.72312E-02+0.00000E+00+7.26512E-03+0.00000E+00-6.39512E-03+0.00000E+00-1.37224E-02+0.00000E+00-1.04496E-02+0.00000E+00-2.56374E-04+0.00000E+00+8.82560E-03+0.00000E+00+1.05646E-02+0.00000E+00+4.65228E-03+0.00000E+00-3.81782E-03+0.00000E+00-8.58052E-03+0.00000E+00-6.73316E-03+0.00000E+00-3.65328E-04+0.00000E+00+5.50776E-03+0.00000E+00+6.81616E-03+0.00000E+00+3.18035E-03+0.00000E+00-2.26220E-03+0.00000E+00-5.47828E-03+0.00000E+00-4.47584E-03+0.00000E+00-4.57304E-04+0.00000E+00+3.40590E-03+0.00000E+00+4.43120E-03+0.00000E+00+2.24272E-03+0.00000E+00-1.24599E-03+0.00000E+00-3.44765E-03+0.00000E+00-2.98815E-03+0.00000E+00-5.13156E-04+0.00000E+00+2.01276E-03+0.00000E+00+2.83576E-03+0.00000E+00+1.60144E-03+0.00000E+00-5.79052E-04+0.00000E+00-2.08536E-03+0.00000E+00-1.97068E-03+0.00000E+00-5.24120E-04+0.00000E+00+1.09177E-03+0.00000E+00+1.75363E-03+0.00000E+00+1.13876E-03+0.00000E+00-1.64670E-04+0.00000E+00-1.18261E-03+0.00000E+00-1.26810E-03+0.00000E+00-4.91744E-04+0.00000E+00+5.07504E-04+0.00000E+00+1.03172E-03+0.00000E+00+7.98316E-04+0.00000E+00+6.76780E-05+0.00000E+00-6.08316E-04+0.00000E+00-7.92432E-04+0.00000E+00-4.31664E-04+0.00000E+00+1.64727E-04+0.00000E+00+5.78372E-04+0.00000E+00+5.66172E-04+0.00000E+00+1.89248E-04+0.00000E+00-2.69536E-04+0.00000E+00-5.12780E-04+0.00000E+00-4.11872E-04+0.00000E+00-5.96548E-05+0.00000E+00+3.15263E-04+0.00000E+00+4.96800E-04+0.00000E+00+3.95725E-04+0.00000E+00+7.38188E-05+0.00000E+00-3.15191E-04+0.00000E+00-6.17072E-04+0.00000E+00-7.45976E-04+0.00000E+00-7.02688E-04+0.00000E+00-5.48500E-04+0.00000E+00-3.61172E-04+0.00000E+00-1.99571E-04+0.00000E+00-8.97376E-05+0.00000E+00-3.00692E-05+0.00000E+00-5.16640E-06+0.00000E+00+1.62612E-06+0.00000E+00+1.76664E-06+0.00000E+00+7.48132E-07+0.00000E+00+1.65488E-07+0.00000E+0000000570051063.0000E+030000300000+2.9667E-02+2.9667E-02058003506+1.00000E+00+5.00000E-02000547680D070040040319+7.72762E-09+0.00000E+00+4.52378E-09+0.00000E+00-5.32080E-08+0.00000E+00-2.80036E-07+0.00000E+00-9.08544E-07+0.00000E+00-2.34472E-06+0.00000E+00-5.21464E-06+0.00000E+00-1.03793E-05+0.00000E+00-1.88893E-05+0.00000E+00-3.18550E-05+0.00000E+00-5.02182E-05+0.00000E+00-7.44366E-05+0.00000E+00-1.04124E-04+0.00000E+00-1.37722E-04+0.00000E+00-1.72307E-04+0.00000E+00-2.03638E-04+0.00000E+00-2.26532E-04+0.00000E+00-2.35600E-04+0.00000E+00-2.26268E-04+0.00000E+00-1.95955E-04+0.00000E+00-1.45142E-04+0.00000E+00-7.80380E-05+0.00000E+00-2.59160E-06+0.00000E+00+7.03544E-05+0.00000E+00+1.28752E-04+0.00000E+00+1.61671E-04+0.00000E+00+1.61835E-04+0.00000E+00+1.27774E-04+0.00000E+00+6.50032E-05+0.00000E+00-1.42499E-05+0.00000E+00-9.29802E-05+0.00000E+00-1.52783E-04+0.00000E+00-1.78068E-04+0.00000E+00-1.60164E-04+0.00000E+00-1.00242E-04+0.00000E+00-1.01214E-05+0.00000E+00+8.95560E-05+0.00000E+00+1.73672E-04+0.00000E+00+2.18690E-04+0.00000E+00+2.09036E-04+0.00000E+00+1.42114E-04+0.00000E+00+3.04418E-05+0.00000E+00-1.00068E-04+0.00000E+00-2.15680E-04+0.00000E+00-2.83208E-04+0.00000E+00-2.79208E-04+0.00000E+00-1.97535E-04+0.00000E+00-5.29412E-05+0.00000E+00+1.20744E-04+0.0000000021S*0E+00+2.78002E-04+0.00000E+00+3.73138E-04+0.00000E+00+3.73118E-04+0.00000E+00+2.68272E-04+0.00000E+00+7.75194E-05+0.00000E+00-1.53942E-04+0.00000E+00-3.64712E-04+0.00000E+00-4.92968E-04+0.00000E+00-4.94058E-04+0.00000E+00-3.55056E-04+0.00000E+00-1.01725E-04+0.00000E+00+2.04904E-04+0.00000E+00+4.82464E-04+0.00000E+00+6.48778E-04+0.00000E+00+6.45532E-04+0.00000E+00+4.57442E-04+0.00000E+00+1.20911E-04+0.00000E+00-2.81414E-04+0.00000E+00-6.40040E-04+0.00000E+00-8.47708E-04+0.00000E+00-8.30656E-04+0.00000E+00-5.73180E-04+0.00000E+00-1.27650E-04+0.00000E+00+3.94310E-04+0.00000E+00+8.48744E-04+0.00000E+00+1.09821E-03+0.00000E+00+1.05234E-03+0.00000E+00+6.98398E-04+0.00000E+00+1.11999E-04+0.00000E+00-5.57036E-04+0.00000E+00-1.12174E-03+0.00000E+00-1.40922E-03+0.00000E+00-1.31236E-03+0.00000E+00-8.26764E-04+0.00000E+00-6.09068E-05+0.00000E+00+7.85842E-04+0.00000E+00+1.47374E-03+0.00000E+00+1.78935E-03+0.00000E+00+1.61011E-03+0.00000E+00+9.47830E-04+0.00000E+00-4.36276E-05+0.00000E+00-1.10163E-03+0.00000E+00-1.92275E-03+0.00000E+00-2.24826E-03+0.00000E+00-1.94359E-03+0.00000E+00-1.04776E-03+0.00000E+00+2.24088E-04+0.00000E+00+1.52962E-03+0.00000E+00+2.48958E-03+0.00000E+00+2.79606E-03+0.00000E+00+2.30850E-03+0.00000E+00+1.10801E-03+0.00000E+00-5.08938E-04+0.00000E+00-2.10070E-03+0.00000E+00-3.19878E-03+0.00000E+00-3.44326E-03+0.00000E+00-2.69684E-03+0.00000E+00-1.10249E-03+0.00000E+00+9.36892E-04+0.00000E+00+2.85672E-03+0.00000E+00+4.08406E-03+0.00000E+00+4.20524E-03+0.00000E+00+3.09968E-03+0.00000E+00+9.97970E-04+0.00000E+00-1.55873E-03+0.00000E+00-3.85362E-03+0.00000E+00-5.19124E-03+0.00000E+00-5.10336E-03+0.00000E+00-3.50440E-03+0.00000E+00-7.46438E-04+0.00000E+00+2.44968E-03+0.00000E+00+5.17690E-03+0.00000E+00+6.59364E-03+0.00000E+00+6.17604E-03+0.00000E+00+3.89756E-03+0.00000E+00+2.77256E-04+0.00000E+00-3.72784E-03+0.00000E+00-6.96714E-03+0.00000E+00-8.41784E-03+0.00000E+00-7.49572E-03+0.00000E+00-4.26426E-03+0.00000E+00+5.27466E-04+0.00000E+00+5.60328E-03+0.00000E+00+9.48592E-03+0.00000E+00+1.09107E-02+0.00000E+00+9.21506E-03+0.00000E+00+4.58962E-03+0.00000E+00-1.89363E-03+0.00000E+00-8.50506E-03+0.00000E+00-1.32925E-02+0.00000E+00-1.46243E-02+0.00000E+00-1.16967E-02+0.00000E+00-4.85962E-03+0.00000E+00+4.34870E-03+0.00000E+00+1.34983E-02+0.00000E+00+1.98472E-02+0.00000E+00+2.10770E-02+0.00000E+00+1.60019E-02+0.00000E+00+5.06204E-03+0.00000E+00-9.55078E-03+0.00000E+00-2.42030E-02+0.00000E+00-3.45266E-02+0.00000E+00-3.63864E-02+0.00000E+00-2.68872E-02+0.00000E+00-5.18748E-03+0.00000E+00+2.70918E-02+0.00000E+00+6.59838E-02+0.00000E+00+1.05820E-01+0.00000E+00+1.40281E-01+0.00000E+00+1.63636E-01+0.00000E+00+1.71897E-01+0.00000E+00+1.63636E-01+0.00000E+00+1.40281E-01+0.00000E+00+1.05820E-01+0.00000E+00+6.59838E-02+0.00000E+00+2.70918E-02+0.00000E+00-5.18748E-03+0.00000E+00-2.68872E-02+0.00000E+00-3.63864E-02+0.00000E+00-3.45266E-02+0.00000E+00-2.42030E-02+0.00000E+00-9.55078E-03+0.00000E+00+5.06204E-03+0.00000E+00+1.60019E-02+0.00000E+00+2.10770E-02+0.00000E+00+1.98472E-02+0.00000E+00+1.34983E-02+0.00000E+00+4.34870E-03+0.00000E+00-4.85962E-03+0.00000E+00-1.16967E-02+0.00000E+00-1.46243E-02+0.00000E+00-1.32925E-02+0.00000E+00-8.50506E-03+0.00000E+00-1.89363E-03+0.00000E+00+4.58962E-03+0.00000E+00+9.21506E-03+0.00000E+00+1.09107E-02+0.00000E+00+9.48592E-03+0.00000E+00+5.60328E-03+0.00000E+00+5.27466E-04+0.00000E+00-4.26426E-03+0.00000E+00-7.49572E-03+0.00000E+00-8.41784E-03+0.00000E+00-6.96714E-03+0.00000E+00-3.72784E-03+0.00000E+00+2.77256E-04+0.00000E+00+3.89756E-03+0.00000E+00+6.17604E-03+0.00000E+00+6.59364E-03+0.00000E+00+5.17690E-03+0.00000E+00+2.44968E-03+0.00000E+00-7.46438E-04+0.00000E+00-3.50440E-03+0.00000E+00-5.10336E-03+0.00000E+00-5.19124E-03+0.00000E+00-3.85362E-03+0.00000E+00-1.55873E-03+0.00000E+00+9.97970E-04+0.00000E+00+3.09968E-03+0.00000E+00+4.20524E-03+0.00000E+00+4.08406E-03+0.00000E+00+2.85672E-03+0.00000E+00+9.36892E-04+0.00000E+00-1.10249E-03+0.00000E+00-2.69684E-03+0.00000E+00-3.44326E-03+0.00000E+00-3.19878E-03+0.00000E+00-2.10070E-03+0.00000E+00-5.08938E-04+0.00000E+00+1.10801E-03+0.00000E+00+2.000022S*30850E-03+0.00000E+00+2.79606E-03+0.00000E+00+2.48958E-03+0.00000E+00+1.52962E-03+0.00000E+00+2.24088E-04+0.00000E+00-1.04776E-03+0.00000E+00-1.94359E-03+0.00000E+00-2.24826E-03+0.00000E+00-1.92275E-03+0.00000E+00-1.10163E-03+0.00000E+00-4.36276E-05+0.00000E+00+9.47830E-04+0.00000E+00+1.61011E-03+0.00000E+00+1.78935E-03+0.00000E+00+1.47374E-03+0.00000E+00+7.85842E-04+0.00000E+00-6.09068E-05+0.00000E+00-8.26764E-04+0.00000E+00-1.31236E-03+0.00000E+00-1.40922E-03+0.00000E+00-1.12174E-03+0.00000E+00-5.57036E-04+0.00000E+00+1.11999E-04+0.00000E+00+6.98398E-04+0.00000E+00+1.05234E-03+0.00000E+00+1.09821E-03+0.00000E+00+8.48744E-04+0.00000E+00+3.94310E-04+0.00000E+00-1.27650E-04+0.00000E+00-5.73180E-04+0.00000E+00-8.30656E-04+0.00000E+00-8.47708E-04+0.00000E+00-6.40040E-04+0.00000E+00-2.81414E-04+0.00000E+00+1.20911E-04+0.00000E+00+4.57442E-04+0.00000E+00+6.45532E-04+0.00000E+00+6.48778E-04+0.00000E+00+4.82464E-04+0.00000E+00+2.04904E-04+0.00000E+00-1.01725E-04+0.00000E+00-3.55056E-04+0.00000E+00-4.94058E-04+0.00000E+00-4.92968E-04+0.00000E+00-3.64712E-04+0.00000E+00-1.53942E-04+0.00000E+00+7.75194E-05+0.00000E+00+2.68272E-04+0.00000E+00+3.73118E-04+0.00000E+00+3.73138E-04+0.00000E+00+2.78002E-04+0.00000E+00+1.20744E-04+0.00000E+00-5.29412E-05+0.00000E+00-1.97535E-04+0.00000E+00-2.79208E-04+0.00000E+00-2.83208E-04+0.00000E+00-2.15680E-04+0.00000E+00-1.00068E-04+0.00000E+00+3.04418E-05+0.00000E+00+1.42114E-04+0.00000E+00+2.09036E-04+0.00000E+00+2.18690E-04+0.00000E+00+1.73672E-04+0.00000E+00+8.95560E-05+0.00000E+00-1.01214E-05+0.00000E+00-1.00242E-04+0.00000E+00-1.60164E-04+0.00000E+00-1.78068E-04+0.00000E+00-1.52783E-04+0.00000E+00-9.29802E-05+0.00000E+00-1.42499E-05+0.00000E+00+6.50032E-05+0.00000E+00+1.27774E-04+0.00000E+00+1.61835E-04+0.00000E+00+1.61671E-04+0.00000E+00+1.28752E-04+0.00000E+00+7.03544E-05+0.00000E+00-2.59160E-06+0.00000E+00-7.80380E-05+0.00000E+00-1.45142E-04+0.00000E+00-1.95955E-04+0.00000E+00-2.26268E-04+0.00000E+00-2.35600E-04+0.00000E+00-2.26532E-04+0.00000E+00-2.03638E-04+0.00000E+00-1.72307E-04+0.00000E+00-1.37722E-04+0.00000E+00-1.04124E-04+0.00000E+00-7.44366E-05+0.00000E+00-5.02182E-05+0.00000E+00-3.18550E-05+0.00000E+00-1.88893E-05+0.00000E+00-1.03793E-05+0.00000E+00-5.21464E-06+0.00000E+00-2.34472E-06+0.00000E+00-9.08544E-07+0.00000E+00-2.80036E-07+0.00000E+00-5.32080E-08+0.00000E+00+4.52378E-09+0.00000E+00+7.72762E-09+0.00000E+0000000570051071.0000E+030000500000+1.5900E-01+1.5900E-01058003507+1.00000E+00+5.00000E-0200058003500+2.03990E+05+5.00000E-02000520149 HNZ0000003~004002+49.129100+008.148700+0128.0000.0000.0-90.00001122.0000E+022.0000E-020000TG~2015,008,10:45:00.0000~2015,078,13:00:00.0000~N0530382A01004003+1.00770E+18+1.00000E+00001-5.15000E+02+0.00000E+00+0.00000E+00+0.00000E+00006-9.77000E+02+3.28000E+02+0.00000E+00+0.00000E+00-9.77000E+02-3.28000E+02+0.00000E+00+0.00000E+00-1.48600E+03+2.51200E+03+0.00000E+00+0.00000E+00-1.48600E+03-2.51200E+03+0.00000E+00+0.00000E+00-5.73600E+03+4.94600E+03+0.00000E+00+0.00000E+00-5.73600E+03-4.94600E+03+0.00000E+00+0.00000E+00058003501+5.10000E-01+1.00000E+0000058003502+1.00000E+00+5.00000E-02000540048D030030040001+1.00000E+00+0.00000E+0000000570051031.9200E+050000100000+0.0000E+00+0.0000E+00058003503+4.00000E+05+5.00000E-02000541152D040040040047+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+3.81470E-06+0.00000E+00+2.28882E-05+0.00000E+00+8.01086E-05+0.00000E+00+2.13623E-04+0.00000E+00+4.80652E-04+0.00000E+00+9.61304E-04+0.00000E+00+1.76239E-03+0.00000E+00+3.02124E-03+0.00000E+00+4.88663E-03+0.00000E+00+7.49969E-03+0.00000E+00+1.09749E-02+0.00000E+00+1.53809E-02+0.00000E+00+2.07214E-02+0.00000E+00+2.69165E-02+0.00000E+00+3.37830E-02+0.00000E+00+4.10156E-02+0.00000E+00+4.82254E-02+0.00000E+00+5.49774E-02+0.00000E+00+6.08292E-02+0.00000E+00+6.53687E-02+0.00000E+00+6.82526E-02+0.00000E+00+6.92444E-02+0.00000E+00+6.82526E-02+0.00000E+00+6.53687E-02+0.00000E+00+6.08292E-02+0.00000E+00+5.49774E-02+0.00000E+00+4.82254E-02+0.00000E+00+4.10156E-02+0.00000E+00+3.37830E-02+0.00000E+00+2.69165E-02+0.00000E+00+2.07214E-02+0.00000E+00+1.53809E-02+0.0000000023S*0E+00+1.09749E-02+0.00000E+00+7.49969E-03+0.00000E+00+4.88663E-03+0.00000E+00+3.02124E-03+0.00000E+00+1.76239E-03+0.00000E+00+9.61304E-04+0.00000E+00+4.80652E-04+0.00000E+00+2.13623E-04+0.00000E+00+8.01086E-05+0.00000E+00+2.28882E-05+0.00000E+00+3.81470E-06+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+0000000570051041.9200E+050000800000+1.1979E-04+1.1979E-04058003504+1.00000E+00+5.00000E-02000541776D050040040073+7.86395E-07+0.00000E+00+2.15223E-06+0.00000E+00+4.09013E-06+0.00000E+00+6.42053E-06+0.00000E+00+7.61300E-06+0.00000E+00+4.52134E-06+0.00000E+00-8.38839E-06+0.00000E+00-4.00745E-05+0.00000E+00-1.08702E-04+0.00000E+00-2.31570E-04+0.00000E+00-4.32673E-04+0.00000E+00-7.41861E-04+0.00000E+00-1.18635E-03+0.00000E+00-1.78887E-03+0.00000E+00-2.56156E-03+0.00000E+00-3.49756E-03+0.00000E+00-4.54784E-03+0.00000E+00-5.64473E-03+0.00000E+00-6.67437E-03+0.00000E+00-7.46932E-03+0.00000E+00-7.83206E-03+0.00000E+00-7.53472E-03+0.00000E+00-6.33480E-03+0.00000E+00-3.99943E-03+0.00000E+00-3.60688E-04+0.00000E+00+4.71408E-03+0.00000E+00+1.12572E-02+0.00000E+00+1.91611E-02+0.00000E+00+2.82115E-02+0.00000E+00+3.80655E-02+0.00000E+00+4.82646E-02+0.00000E+00+5.82654E-02+0.00000E+00+6.75164E-02+0.00000E+00+7.54318E-02+0.00000E+00+8.14859E-02+0.00000E+00+8.52972E-02+0.00000E+00+8.65986E-02+0.00000E+00+8.52972E-02+0.00000E+00+8.14859E-02+0.00000E+00+7.54318E-02+0.00000E+00+6.75164E-02+0.00000E+00+5.82654E-02+0.00000E+00+4.82646E-02+0.00000E+00+3.80655E-02+0.00000E+00+2.82115E-02+0.00000E+00+1.91611E-02+0.00000E+00+1.12572E-02+0.00000E+00+4.71408E-03+0.00000E+00-3.60688E-04+0.00000E+00-3.99943E-03+0.00000E+00-6.33480E-03+0.00000E+00-7.53472E-03+0.00000E+00-7.83206E-03+0.00000E+00-7.46932E-03+0.00000E+00-6.67437E-03+0.00000E+00-5.64473E-03+0.00000E+00-4.54784E-03+0.00000E+00-3.49756E-03+0.00000E+00-2.56156E-03+0.00000E+00-1.78887E-03+0.00000E+00-1.18635E-03+0.00000E+00-7.41861E-04+0.00000E+00-4.32673E-04+0.00000E+00-2.31570E-04+0.00000E+00-1.08702E-04+0.00000E+00-4.00745E-05+0.00000E+00-8.38839E-06+0.00000E+00+4.52134E-06+0.00000E+00+7.61300E-06+0.00000E+00+6.42053E-06+0.00000E+00+4.09013E-06+0.00000E+00+2.15223E-06+0.00000E+00+7.86395E-07+0.00000E+0000000570051052.4000E+040000800000+1.5000E-03+1.5000E-03058003505+1.00000E+00+5.00000E-02000544320D060040040179+1.65488E-07+0.00000E+00+7.48132E-07+0.00000E+00+1.76664E-06+0.00000E+00+1.62612E-06+0.00000E+00-5.16640E-06+0.00000E+00-3.00692E-05+0.00000E+00-8.97376E-05+0.00000E+00-1.99571E-04+0.00000E+00-3.61172E-04+0.00000E+00-5.48500E-04+0.00000E+00-7.02688E-04+0.00000E+00-7.45976E-04+0.00000E+00-6.17072E-04+0.00000E+00-3.15191E-04+0.00000E+00+7.38188E-05+0.00000E+00+3.95725E-04+0.00000E+00+4.96800E-04+0.00000E+00+3.15263E-04+0.00000E+00-5.96548E-05+0.00000E+00-4.11872E-04+0.00000E+00-5.12780E-04+0.00000E+00-2.69536E-04+0.00000E+00+1.89248E-04+0.00000E+00+5.66172E-04+0.00000E+00+5.78372E-04+0.00000E+00+1.64727E-04+0.00000E+00-4.31664E-04+0.00000E+00-7.92432E-04+0.00000E+00-6.08316E-04+0.00000E+00+6.76780E-05+0.00000E+00+7.98316E-04+0.00000E+00+1.03172E-03+0.00000E+00+5.07504E-04+0.00000E+00-4.91744E-04+0.00000E+00-1.26810E-03+0.00000E+00-1.18261E-03+0.00000E+00-1.64670E-04+0.00000E+00+1.13876E-03+0.00000E+00+1.75363E-03+0.00000E+00+1.09177E-03+0.00000E+00-5.24120E-04+0.00000E+00-1.97068E-03+0.00000E+00-2.08536E-03+0.00000E+00-5.79052E-04+0.00000E+00+1.60144E-03+0.00000E+00+2.83576E-03+0.00000E+00+2.01276E-03+0.00000E+00-5.13156E-04+0.00000E+00-2.98815E-03+0.00000E+00-3.44765E-03+0.00000E+00-1.24599E-03+0.00000E+00+2.24272E-03+0.00000E+00+4.43120E-03+0.00000E+00+3.40590E-03+0.00000E+00-4.57304E-04+0.00000E+00-4.47584E-03+0.00000E+00-5.47828E-03+0.00000E+00-2.26220E-03+0.00000E+00+3.18035E-03+0.00000E+00+6.81616E-03+0.00000E+00+5.50776E-03+0.00000E+00-3.65328E-04+0.00000E+00-6.73316E-03+0.00000E+00-8.58052E-03+0.00000E+00-3.81782E-03+0.00000E+00+4.65228E-03+0.00000E+00+1.05646E-02+0.00000E+00+8.82560E-03+0.00000E+00-2.56374E-04+0.00000E+00-1.04496E-02+0.00000E+00-1.37224E-02+0.00000E+00-6.39512E-03+0.00000E+00+7.26512E-03+0.00000E+00+1.72312E-02+0.00000E+00+1.48181E-02+0.00000E+0000024S*0-1.54011E-04+0.00000E+00-1.77680E-02+0.00000E+00-2.41384E-02+0.00000E+00-1.17549E-02+0.00000E+00+1.32733E-02+0.00000E+00+3.32147E-02+0.00000E+00+3.01309E-02+0.00000E+00-8.13468E-05+0.00000E+00-4.08284E-02+0.00000E+00-6.13256E-02+0.00000E+00-3.42109E-02+0.00000E+00+4.58968E-02+0.00000E+00+1.54886E-01+0.00000E+00+2.48713E-01+0.00000E+00+2.85658E-01+0.00000E+00+2.48713E-01+0.00000E+00+1.54886E-01+0.00000E+00+4.58968E-02+0.00000E+00-3.42109E-02+0.00000E+00-6.13256E-02+0.00000E+00-4.08284E-02+0.00000E+00-8.13468E-05+0.00000E+00+3.01309E-02+0.00000E+00+3.32147E-02+0.00000E+00+1.32733E-02+0.00000E+00-1.17549E-02+0.00000E+00-2.41384E-02+0.00000E+00-1.77680E-02+0.00000E+00-1.54011E-04+0.00000E+00+1.48181E-02+0.00000E+00+1.72312E-02+0.00000E+00+7.26512E-03+0.00000E+00-6.39512E-03+0.00000E+00-1.37224E-02+0.00000E+00-1.04496E-02+0.00000E+00-2.56374E-04+0.00000E+00+8.82560E-03+0.00000E+00+1.05646E-02+0.00000E+00+4.65228E-03+0.00000E+00-3.81782E-03+0.00000E+00-8.58052E-03+0.00000E+00-6.73316E-03+0.00000E+00-3.65328E-04+0.00000E+00+5.50776E-03+0.00000E+00+6.81616E-03+0.00000E+00+3.18035E-03+0.00000E+00-2.26220E-03+0.00000E+00-5.47828E-03+0.00000E+00-4.47584E-03+0.00000E+00-4.57304E-04+0.00000E+00+3.40590E-03+0.00000E+00+4.43120E-03+0.00000E+00+2.24272E-03+0.00000E+00-1.24599E-03+0.00000E+00-3.44765E-03+0.00000E+00-2.98815E-03+0.00000E+00-5.13156E-04+0.00000E+00+2.01276E-03+0.00000E+00+2.83576E-03+0.00000E+00+1.60144E-03+0.00000E+00-5.79052E-04+0.00000E+00-2.08536E-03+0.00000E+00-1.97068E-03+0.00000E+00-5.24120E-04+0.00000E+00+1.09177E-03+0.00000E+00+1.75363E-03+0.00000E+00+1.13876E-03+0.00000E+00-1.64670E-04+0.00000E+00-1.18261E-03+0.00000E+00-1.26810E-03+0.00000E+00-4.91744E-04+0.00000E+00+5.07504E-04+0.00000E+00+1.03172E-03+0.00000E+00+7.98316E-04+0.00000E+00+6.76780E-05+0.00000E+00-6.08316E-04+0.00000E+00-7.92432E-04+0.00000E+00-4.31664E-04+0.00000E+00+1.64727E-04+0.00000E+00+5.78372E-04+0.00000E+00+5.66172E-04+0.00000E+00+1.89248E-04+0.00000E+00-2.69536E-04+0.00000E+00-5.12780E-04+0.00000E+00-4.11872E-04+0.00000E+00-5.96548E-05+0.00000E+00+3.15263E-04+0.00000E+00+4.96800E-04+0.00000E+00+3.95725E-04+0.00000E+00+7.38188E-05+0.00000E+00-3.15191E-04+0.00000E+00-6.17072E-04+0.00000E+00-7.45976E-04+0.00000E+00-7.02688E-04+0.00000E+00-5.48500E-04+0.00000E+00-3.61172E-04+0.00000E+00-1.99571E-04+0.00000E+00-8.97376E-05+0.00000E+00-3.00692E-05+0.00000E+00-5.16640E-06+0.00000E+00+1.62612E-06+0.00000E+00+1.76664E-06+0.00000E+00+7.48132E-07+0.00000E+00+1.65488E-07+0.00000E+0000000570051063.0000E+030000300000+2.9667E-02+2.9667E-02058003506+1.00000E+00+5.00000E-02000547680D070040040319+7.72762E-09+0.00000E+00+4.52378E-09+0.00000E+00-5.32080E-08+0.00000E+00-2.80036E-07+0.00000E+00-9.08544E-07+0.00000E+00-2.34472E-06+0.00000E+00-5.21464E-06+0.00000E+00-1.03793E-05+0.00000E+00-1.88893E-05+0.00000E+00-3.18550E-05+0.00000E+00-5.02182E-05+0.00000E+00-7.44366E-05+0.00000E+00-1.04124E-04+0.00000E+00-1.37722E-04+0.00000E+00-1.72307E-04+0.00000E+00-2.03638E-04+0.00000E+00-2.26532E-04+0.00000E+00-2.35600E-04+0.00000E+00-2.26268E-04+0.00000E+00-1.95955E-04+0.00000E+00-1.45142E-04+0.00000E+00-7.80380E-05+0.00000E+00-2.59160E-06+0.00000E+00+7.03544E-05+0.00000E+00+1.28752E-04+0.00000E+00+1.61671E-04+0.00000E+00+1.61835E-04+0.00000E+00+1.27774E-04+0.00000E+00+6.50032E-05+0.00000E+00-1.42499E-05+0.00000E+00-9.29802E-05+0.00000E+00-1.52783E-04+0.00000E+00-1.78068E-04+0.00000E+00-1.60164E-04+0.00000E+00-1.00242E-04+0.00000E+00-1.01214E-05+0.00000E+00+8.95560E-05+0.00000E+00+1.73672E-04+0.00000E+00+2.18690E-04+0.00000E+00+2.09036E-04+0.00000E+00+1.42114E-04+0.00000E+00+3.04418E-05+0.00000E+00-1.00068E-04+0.00000E+00-2.15680E-04+0.00000E+00-2.83208E-04+0.00000E+00-2.79208E-04+0.00000E+00-1.97535E-04+0.00000E+00-5.29412E-05+0.00000E+00+1.20744E-04+0.00000E+00+2.78002E-04+0.00000E+00+3.73138E-04+0.00000E+00+3.73118E-04+0.00000E+00+2.68272E-04+0.00000E+00+7.75194E-05+0.00000E+00-1.53942E-04+0.00000E+00-3.64712E-04+0.00000E+00-4.92968E-04+0.00000E+00-4.94058E-04+0.00000E+00-3.55056E-04+0.00000E+00-1.01725E-04+0.00000E+00+2.04904E-04+0.00000E+00+4.82464E-04+0.00000025S*000E+00+6.48778E-04+0.00000E+00+6.45532E-04+0.00000E+00+4.57442E-04+0.00000E+00+1.20911E-04+0.00000E+00-2.81414E-04+0.00000E+00-6.40040E-04+0.00000E+00-8.47708E-04+0.00000E+00-8.30656E-04+0.00000E+00-5.73180E-04+0.00000E+00-1.27650E-04+0.00000E+00+3.94310E-04+0.00000E+00+8.48744E-04+0.00000E+00+1.09821E-03+0.00000E+00+1.05234E-03+0.00000E+00+6.98398E-04+0.00000E+00+1.11999E-04+0.00000E+00-5.57036E-04+0.00000E+00-1.12174E-03+0.00000E+00-1.40922E-03+0.00000E+00-1.31236E-03+0.00000E+00-8.26764E-04+0.00000E+00-6.09068E-05+0.00000E+00+7.85842E-04+0.00000E+00+1.47374E-03+0.00000E+00+1.78935E-03+0.00000E+00+1.61011E-03+0.00000E+00+9.47830E-04+0.00000E+00-4.36276E-05+0.00000E+00-1.10163E-03+0.00000E+00-1.92275E-03+0.00000E+00-2.24826E-03+0.00000E+00-1.94359E-03+0.00000E+00-1.04776E-03+0.00000E+00+2.24088E-04+0.00000E+00+1.52962E-03+0.00000E+00+2.48958E-03+0.00000E+00+2.79606E-03+0.00000E+00+2.30850E-03+0.00000E+00+1.10801E-03+0.00000E+00-5.08938E-04+0.00000E+00-2.10070E-03+0.00000E+00-3.19878E-03+0.00000E+00-3.44326E-03+0.00000E+00-2.69684E-03+0.00000E+00-1.10249E-03+0.00000E+00+9.36892E-04+0.00000E+00+2.85672E-03+0.00000E+00+4.08406E-03+0.00000E+00+4.20524E-03+0.00000E+00+3.09968E-03+0.00000E+00+9.97970E-04+0.00000E+00-1.55873E-03+0.00000E+00-3.85362E-03+0.00000E+00-5.19124E-03+0.00000E+00-5.10336E-03+0.00000E+00-3.50440E-03+0.00000E+00-7.46438E-04+0.00000E+00+2.44968E-03+0.00000E+00+5.17690E-03+0.00000E+00+6.59364E-03+0.00000E+00+6.17604E-03+0.00000E+00+3.89756E-03+0.00000E+00+2.77256E-04+0.00000E+00-3.72784E-03+0.00000E+00-6.96714E-03+0.00000E+00-8.41784E-03+0.00000E+00-7.49572E-03+0.00000E+00-4.26426E-03+0.00000E+00+5.27466E-04+0.00000E+00+5.60328E-03+0.00000E+00+9.48592E-03+0.00000E+00+1.09107E-02+0.00000E+00+9.21506E-03+0.00000E+00+4.58962E-03+0.00000E+00-1.89363E-03+0.00000E+00-8.50506E-03+0.00000E+00-1.32925E-02+0.00000E+00-1.46243E-02+0.00000E+00-1.16967E-02+0.00000E+00-4.85962E-03+0.00000E+00+4.34870E-03+0.00000E+00+1.34983E-02+0.00000E+00+1.98472E-02+0.00000E+00+2.10770E-02+0.00000E+00+1.60019E-02+0.00000E+00+5.06204E-03+0.00000E+00-9.55078E-03+0.00000E+00-2.42030E-02+0.00000E+00-3.45266E-02+0.00000E+00-3.63864E-02+0.00000E+00-2.68872E-02+0.00000E+00-5.18748E-03+0.00000E+00+2.70918E-02+0.00000E+00+6.59838E-02+0.00000E+00+1.05820E-01+0.00000E+00+1.40281E-01+0.00000E+00+1.63636E-01+0.00000E+00+1.71897E-01+0.00000E+00+1.63636E-01+0.00000E+00+1.40281E-01+0.00000E+00+1.05820E-01+0.00000E+00+6.59838E-02+0.00000E+00+2.70918E-02+0.00000E+00-5.18748E-03+0.00000E+00-2.68872E-02+0.00000E+00-3.63864E-02+0.00000E+00-3.45266E-02+0.00000E+00-2.42030E-02+0.00000E+00-9.55078E-03+0.00000E+00+5.06204E-03+0.00000E+00+1.60019E-02+0.00000E+00+2.10770E-02+0.00000E+00+1.98472E-02+0.00000E+00+1.34983E-02+0.00000E+00+4.34870E-03+0.00000E+00-4.85962E-03+0.00000E+00-1.16967E-02+0.00000E+00-1.46243E-02+0.00000E+00-1.32925E-02+0.00000E+00-8.50506E-03+0.00000E+00-1.89363E-03+0.00000E+00+4.58962E-03+0.00000E+00+9.21506E-03+0.00000E+00+1.09107E-02+0.00000E+00+9.48592E-03+0.00000E+00+5.60328E-03+0.00000E+00+5.27466E-04+0.00000E+00-4.26426E-03+0.00000E+00-7.49572E-03+0.00000E+00-8.41784E-03+0.00000E+00-6.96714E-03+0.00000E+00-3.72784E-03+0.00000E+00+2.77256E-04+0.00000E+00+3.89756E-03+0.00000E+00+6.17604E-03+0.00000E+00+6.59364E-03+0.00000E+00+5.17690E-03+0.00000E+00+2.44968E-03+0.00000E+00-7.46438E-04+0.00000E+00-3.50440E-03+0.00000E+00-5.10336E-03+0.00000E+00-5.19124E-03+0.00000E+00-3.85362E-03+0.00000E+00-1.55873E-03+0.00000E+00+9.97970E-04+0.00000E+00+3.09968E-03+0.00000E+00+4.20524E-03+0.00000E+00+4.08406E-03+0.00000E+00+2.85672E-03+0.00000E+00+9.36892E-04+0.00000E+00-1.10249E-03+0.00000E+00-2.69684E-03+0.00000E+00-3.44326E-03+0.00000E+00-3.19878E-03+0.00000E+00-2.10070E-03+0.00000E+00-5.08938E-04+0.00000E+00+1.10801E-03+0.00000E+00+2.30850E-03+0.00000E+00+2.79606E-03+0.00000E+00+2.48958E-03+0.00000E+00+1.52962E-03+0.00000E+00+2.24088E-04+0.00000E+00-1.04776E-03+0.00000E+00-1.94359E-03+0.00000E+00-2.24826E-03+0.00000E+00-1.92275E-03+0.00000E+00-1.10163E-03+0.00000E+00-4.36276E-05+0.00000E+00+9.47830E-04+0.00000E+00+1.61011E-03+0.00000E+00+000026S*1.78935E-03+0.00000E+00+1.47374E-03+0.00000E+00+7.85842E-04+0.00000E+00-6.09068E-05+0.00000E+00-8.26764E-04+0.00000E+00-1.31236E-03+0.00000E+00-1.40922E-03+0.00000E+00-1.12174E-03+0.00000E+00-5.57036E-04+0.00000E+00+1.11999E-04+0.00000E+00+6.98398E-04+0.00000E+00+1.05234E-03+0.00000E+00+1.09821E-03+0.00000E+00+8.48744E-04+0.00000E+00+3.94310E-04+0.00000E+00-1.27650E-04+0.00000E+00-5.73180E-04+0.00000E+00-8.30656E-04+0.00000E+00-8.47708E-04+0.00000E+00-6.40040E-04+0.00000E+00-2.81414E-04+0.00000E+00+1.20911E-04+0.00000E+00+4.57442E-04+0.00000E+00+6.45532E-04+0.00000E+00+6.48778E-04+0.00000E+00+4.82464E-04+0.00000E+00+2.04904E-04+0.00000E+00-1.01725E-04+0.00000E+00-3.55056E-04+0.00000E+00-4.94058E-04+0.00000E+00-4.92968E-04+0.00000E+00-3.64712E-04+0.00000E+00-1.53942E-04+0.00000E+00+7.75194E-05+0.00000E+00+2.68272E-04+0.00000E+00+3.73118E-04+0.00000E+00+3.73138E-04+0.00000E+00+2.78002E-04+0.00000E+00+1.20744E-04+0.00000E+00-5.29412E-05+0.00000E+00-1.97535E-04+0.00000E+00-2.79208E-04+0.00000E+00-2.83208E-04+0.00000E+00-2.15680E-04+0.00000E+00-1.00068E-04+0.00000E+00+3.04418E-05+0.00000E+00+1.42114E-04+0.00000E+00+2.09036E-04+0.00000E+00+2.18690E-04+0.00000E+00+1.73672E-04+0.00000E+00+8.95560E-05+0.00000E+00-1.01214E-05+0.00000E+00-1.00242E-04+0.00000E+00-1.60164E-04+0.00000E+00-1.78068E-04+0.00000E+00-1.52783E-04+0.00000E+00-9.29802E-05+0.00000E+00-1.42499E-05+0.00000E+00+6.50032E-05+0.00000E+00+1.27774E-04+0.00000E+00+1.61835E-04+0.00000E+00+1.61671E-04+0.00000E+00+1.28752E-04+0.00000E+00+7.03544E-05+0.00000E+00-2.59160E-06+0.00000E+00-7.80380E-05+0.00000E+00-1.45142E-04+0.00000E+00-1.95955E-04+0.00000E+00-2.26268E-04+0.00000E+00-2.35600E-04+0.00000E+00-2.26532E-04+0.00000E+00-2.03638E-04+0.00000E+00-1.72307E-04+0.00000E+00-1.37722E-04+0.00000E+00-1.04124E-04+0.00000E+00-7.44366E-05+0.00000E+00-5.02182E-05+0.00000E+00-3.18550E-05+0.00000E+00-1.88893E-05+0.00000E+00-1.03793E-05+0.00000E+00-5.21464E-06+0.00000E+00-2.34472E-06+0.00000E+00-9.08544E-07+0.00000E+00-2.80036E-07+0.00000E+00-5.32080E-08+0.00000E+00+4.52378E-09+0.00000E+00+7.72762E-09+0.00000E+0000000570051071.0000E+030000500000+1.5900E-01+1.5900E-01058003507+1.00000E+00+5.00000E-0200058003500+2.03990E+05+5.00000E-0200 000027S 0500106ROTT +49.129100+008.148700+0128.00006000Rottmuehle Steinweiler~0013210102015,078,13:00:00.0000~~NLE0520127 EH10000002~001002+49.129100+008.148700-0177.0305.0000.0+00.00001122.0000E+022.0000E-020000TG~2015,078,13:00:00.0000~~N0530334A01001003+1.00000E+00+5.00000E+00003+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00003-4.44400E+00+4.44400E+00+0.00000E+00+0.00000E+00-4.44400E+00-4.44400E+00+0.00000E+00+0.00000E+00-1.08300E+00+0.00000E+00+0.00000E+00+0.00000E+00058003501+4.00000E+02+5.00000E+0000058003502+2.50000E+00+5.00000E-02000540048D030030040001+1.00000E+00+0.00000E+0000000570051031.9200E+050000100000+0.0000E+00+0.0000E+00058003503+4.00000E+05+5.00000E-02000541152D040040040047+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+3.81470E-06+0.00000E+00+2.28882E-05+0.00000E+00+8.01086E-05+0.00000E+00+2.13623E-04+0.00000E+00+4.80652E-04+0.00000E+00+9.61304E-04+0.00000E+00+1.76239E-03+0.00000E+00+3.02124E-03+0.00000E+00+4.88663E-03+0.00000E+00+7.49969E-03+0.00000E+00+1.09749E-02+0.00000E+00+1.53809E-02+0.00000E+00+2.07214E-02+0.00000E+00+2.69165E-02+0.00000E+00+3.37830E-02+0.00000E+00+4.10156E-02+0.00000E+00+4.82254E-02+0.00000E+00+5.49774E-02+0.00000E+00+6.08292E-02+0.00000E+00+6.53687E-02+0.00000E+00+6.82526E-02+0.00000E+00+6.92444E-02+0.00000E+00+6.82526E-02+0.00000E+00+6.53687E-02+0.00000E+00+6.08292E-02+0.00000E+00+5.49774E-02+0.00000E+00+4.82254E-02+0.00000E+00+4.10156E-02+0.00000E+00+3.37830E-02+0.00000E+00+2.69165E-02+0.00000E+00+2.07214E-02+0.00000E+00+1.53809E-02+0.00000E+00+1.09749E-02+0.00000E+00+7.49969E-03+0.00000E+00+4.88663E-03+0.00000E+00+3.02124E-03+0.00000E+00+1.76239E-03+0.00000E+00+9.61304E-04+0.00000E+00+4.80652E-04+0.00000E+00+2.13623E-04+0.00000E+00+8.01086E-05+0.00000E+00+2.28882E-05+0.00000E+00+3.81470E-06+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+0000000570051041.9200E+050000800000+1.1979E-04+1.1979E-04058003504+1.00000E+00+5.00000E-02000541776D050040040073+7.86395E-07+0.00000E+00+2.15223E-06+0.00000E+00+4.09013E-06+0.00000E+00+6.42053E-06+0.00000E+00+7.61300E-06+0.00000E+00+4.52134E-06+0.00000E+00-8.38839E-06+0.00000E+00-4.00745E-05+0.00000E+00-1.08702E-04+0.00000E+00-2.31570E-04+0.00000E+00-4.32673E-04+0.00000E+00-7.41861E-04+0.00000E+00-1.18635E-03+0.00000E+00-1.78887E-03+0.00000E+00-2.56156E-03+0.00000E+00-3.49756E-03+0.00000E+00-4.54784E-03+0.00000E+00-5.64473E-03+0.00000E+00-6.67437E-03+0.00000E+00-7.46932E-03+0.00000E+00-7.83206E-03+0.00000E+00-7.53472E-03+0.00000E+00-6.33480E-03+0.00000E+00-3.99943E-03+0.00000E+00-3.60688E-04+0.00000E+00+4.71408E-03+0.00000E+00+1.12572E-02+0.00000E+00+1.91611E-02+0.00000E+00+2.82115E-02+0.00000E+00+3.80655E-02+0.00000E+00+4.82646E-02+0.00000E+00+5.82654E-02+0.00000E+00+6.75164E-02+0.00000E+00+7.54318E-02+0.00000E+00+8.14859E-02+0.00000E+00+8.52972E-02+0.00000E+00+8.65986E-02+0.00000E+00+8.52972E-02+0.00000E+00+8.14859E-02+0.00000E+00+7.54318E-02+0.00000E+00+6.75164E-02+0.00000E+00+5.82654E-02+0.00000E+00+4.82646E-02+0.00000E+00+3.80655E-02+0.00000E+00+2.82115E-02+0.00000E+00+1.91611E-02+0.00000E+00+1.12572E-02+0.00000E+00+4.71408E-03+0.00000E+00-3.60688E-04+0.00000E+00-3.99943E-03+0.00000E+00-6.33480E-03+0.00000E+00-7.53472E-03+0.00000E+00-7.83206E-03+0.00000E+00-7.46932E-03+0.00000E+00-6.67437E-03+0.00000E+00-5.64473E-03+0.00000E+00-4.54784E-03+0.00000E+00-3.49756E-03+0.00000E+00-2.56156E-03+0.00000E+00-1.78887E-03+0.00000E+00-1.18635E-03+0.00000E+00-7.41861E-04+0.00000E+00-4.32673E-04+0.00000E+00-2.31570E-04+0.00000E+00-1.08702E-04+0.00000E+00-4.00745E-05+0.00000E+00-8.38839E-06+0.00000E+00+4.52134E-06+0.00000E+00+7.61300E-06+0.00000E+00+6.42053E-06+0.00000E+00+4.09013E-06+0.00000E+00+2.15223E-06+0.00000E+00+7.86395E-07+0.00000E+0000000570051052.4000E+040000800000+1.5000E-03+1.5000E-03058003505+1.00000E+00+5.00000E-02000544320D060040040179+1.65488E-07+0.00000E+00+7.48132E-07+0.00000E+00+1.76664E-06+0.00000E+00+1.62612E-06+0.00000E+00-5.16640E-06+0.00000E+00-3.00692E-05+0.00000E+00-8.97376E-05+0.00000E+00-1.99571E-04+0.00000E+00-3.61000028S*172E-04+0.00000E+00-5.48500E-04+0.00000E+00-7.02688E-04+0.00000E+00-7.45976E-04+0.00000E+00-6.17072E-04+0.00000E+00-3.15191E-04+0.00000E+00+7.38188E-05+0.00000E+00+3.95725E-04+0.00000E+00+4.96800E-04+0.00000E+00+3.15263E-04+0.00000E+00-5.96548E-05+0.00000E+00-4.11872E-04+0.00000E+00-5.12780E-04+0.00000E+00-2.69536E-04+0.00000E+00+1.89248E-04+0.00000E+00+5.66172E-04+0.00000E+00+5.78372E-04+0.00000E+00+1.64727E-04+0.00000E+00-4.31664E-04+0.00000E+00-7.92432E-04+0.00000E+00-6.08316E-04+0.00000E+00+6.76780E-05+0.00000E+00+7.98316E-04+0.00000E+00+1.03172E-03+0.00000E+00+5.07504E-04+0.00000E+00-4.91744E-04+0.00000E+00-1.26810E-03+0.00000E+00-1.18261E-03+0.00000E+00-1.64670E-04+0.00000E+00+1.13876E-03+0.00000E+00+1.75363E-03+0.00000E+00+1.09177E-03+0.00000E+00-5.24120E-04+0.00000E+00-1.97068E-03+0.00000E+00-2.08536E-03+0.00000E+00-5.79052E-04+0.00000E+00+1.60144E-03+0.00000E+00+2.83576E-03+0.00000E+00+2.01276E-03+0.00000E+00-5.13156E-04+0.00000E+00-2.98815E-03+0.00000E+00-3.44765E-03+0.00000E+00-1.24599E-03+0.00000E+00+2.24272E-03+0.00000E+00+4.43120E-03+0.00000E+00+3.40590E-03+0.00000E+00-4.57304E-04+0.00000E+00-4.47584E-03+0.00000E+00-5.47828E-03+0.00000E+00-2.26220E-03+0.00000E+00+3.18035E-03+0.00000E+00+6.81616E-03+0.00000E+00+5.50776E-03+0.00000E+00-3.65328E-04+0.00000E+00-6.73316E-03+0.00000E+00-8.58052E-03+0.00000E+00-3.81782E-03+0.00000E+00+4.65228E-03+0.00000E+00+1.05646E-02+0.00000E+00+8.82560E-03+0.00000E+00-2.56374E-04+0.00000E+00-1.04496E-02+0.00000E+00-1.37224E-02+0.00000E+00-6.39512E-03+0.00000E+00+7.26512E-03+0.00000E+00+1.72312E-02+0.00000E+00+1.48181E-02+0.00000E+00-1.54011E-04+0.00000E+00-1.77680E-02+0.00000E+00-2.41384E-02+0.00000E+00-1.17549E-02+0.00000E+00+1.32733E-02+0.00000E+00+3.32147E-02+0.00000E+00+3.01309E-02+0.00000E+00-8.13468E-05+0.00000E+00-4.08284E-02+0.00000E+00-6.13256E-02+0.00000E+00-3.42109E-02+0.00000E+00+4.58968E-02+0.00000E+00+1.54886E-01+0.00000E+00+2.48713E-01+0.00000E+00+2.85658E-01+0.00000E+00+2.48713E-01+0.00000E+00+1.54886E-01+0.00000E+00+4.58968E-02+0.00000E+00-3.42109E-02+0.00000E+00-6.13256E-02+0.00000E+00-4.08284E-02+0.00000E+00-8.13468E-05+0.00000E+00+3.01309E-02+0.00000E+00+3.32147E-02+0.00000E+00+1.32733E-02+0.00000E+00-1.17549E-02+0.00000E+00-2.41384E-02+0.00000E+00-1.77680E-02+0.00000E+00-1.54011E-04+0.00000E+00+1.48181E-02+0.00000E+00+1.72312E-02+0.00000E+00+7.26512E-03+0.00000E+00-6.39512E-03+0.00000E+00-1.37224E-02+0.00000E+00-1.04496E-02+0.00000E+00-2.56374E-04+0.00000E+00+8.82560E-03+0.00000E+00+1.05646E-02+0.00000E+00+4.65228E-03+0.00000E+00-3.81782E-03+0.00000E+00-8.58052E-03+0.00000E+00-6.73316E-03+0.00000E+00-3.65328E-04+0.00000E+00+5.50776E-03+0.00000E+00+6.81616E-03+0.00000E+00+3.18035E-03+0.00000E+00-2.26220E-03+0.00000E+00-5.47828E-03+0.00000E+00-4.47584E-03+0.00000E+00-4.57304E-04+0.00000E+00+3.40590E-03+0.00000E+00+4.43120E-03+0.00000E+00+2.24272E-03+0.00000E+00-1.24599E-03+0.00000E+00-3.44765E-03+0.00000E+00-2.98815E-03+0.00000E+00-5.13156E-04+0.00000E+00+2.01276E-03+0.00000E+00+2.83576E-03+0.00000E+00+1.60144E-03+0.00000E+00-5.79052E-04+0.00000E+00-2.08536E-03+0.00000E+00-1.97068E-03+0.00000E+00-5.24120E-04+0.00000E+00+1.09177E-03+0.00000E+00+1.75363E-03+0.00000E+00+1.13876E-03+0.00000E+00-1.64670E-04+0.00000E+00-1.18261E-03+0.00000E+00-1.26810E-03+0.00000E+00-4.91744E-04+0.00000E+00+5.07504E-04+0.00000E+00+1.03172E-03+0.00000E+00+7.98316E-04+0.00000E+00+6.76780E-05+0.00000E+00-6.08316E-04+0.00000E+00-7.92432E-04+0.00000E+00-4.31664E-04+0.00000E+00+1.64727E-04+0.00000E+00+5.78372E-04+0.00000E+00+5.66172E-04+0.00000E+00+1.89248E-04+0.00000E+00-2.69536E-04+0.00000E+00-5.12780E-04+0.00000E+00-4.11872E-04+0.00000E+00-5.96548E-05+0.00000E+00+3.15263E-04+0.00000E+00+4.96800E-04+0.00000E+00+3.95725E-04+0.00000E+00+7.38188E-05+0.00000E+00-3.15191E-04+0.00000E+00-6.17072E-04+0.00000E+00-7.45976E-04+0.00000E+00-7.02688E-04+0.00000E+00-5.48500E-04+0.00000E+00-3.61172E-04+0.00000E+00-1.99571E-04+0.00000E+00-8.97376E-05+0.00000E+00-3.00692E-05+0.00000E+00-5.16640E-06+0.00000E+00+1.62612E-06+0.00000E+00+1.76664E-06+0.00000E+00+7.48132E-07+0.00000E+00+1.65488E-07+000029S*0.00000E+0000000570051063.0000E+030000300000+2.9667E-02+2.9667E-02058003506+1.00000E+00+5.00000E-02000547680D070040040319+7.72762E-09+0.00000E+00+4.52378E-09+0.00000E+00-5.32080E-08+0.00000E+00-2.80036E-07+0.00000E+00-9.08544E-07+0.00000E+00-2.34472E-06+0.00000E+00-5.21464E-06+0.00000E+00-1.03793E-05+0.00000E+00-1.88893E-05+0.00000E+00-3.18550E-05+0.00000E+00-5.02182E-05+0.00000E+00-7.44366E-05+0.00000E+00-1.04124E-04+0.00000E+00-1.37722E-04+0.00000E+00-1.72307E-04+0.00000E+00-2.03638E-04+0.00000E+00-2.26532E-04+0.00000E+00-2.35600E-04+0.00000E+00-2.26268E-04+0.00000E+00-1.95955E-04+0.00000E+00-1.45142E-04+0.00000E+00-7.80380E-05+0.00000E+00-2.59160E-06+0.00000E+00+7.03544E-05+0.00000E+00+1.28752E-04+0.00000E+00+1.61671E-04+0.00000E+00+1.61835E-04+0.00000E+00+1.27774E-04+0.00000E+00+6.50032E-05+0.00000E+00-1.42499E-05+0.00000E+00-9.29802E-05+0.00000E+00-1.52783E-04+0.00000E+00-1.78068E-04+0.00000E+00-1.60164E-04+0.00000E+00-1.00242E-04+0.00000E+00-1.01214E-05+0.00000E+00+8.95560E-05+0.00000E+00+1.73672E-04+0.00000E+00+2.18690E-04+0.00000E+00+2.09036E-04+0.00000E+00+1.42114E-04+0.00000E+00+3.04418E-05+0.00000E+00-1.00068E-04+0.00000E+00-2.15680E-04+0.00000E+00-2.83208E-04+0.00000E+00-2.79208E-04+0.00000E+00-1.97535E-04+0.00000E+00-5.29412E-05+0.00000E+00+1.20744E-04+0.00000E+00+2.78002E-04+0.00000E+00+3.73138E-04+0.00000E+00+3.73118E-04+0.00000E+00+2.68272E-04+0.00000E+00+7.75194E-05+0.00000E+00-1.53942E-04+0.00000E+00-3.64712E-04+0.00000E+00-4.92968E-04+0.00000E+00-4.94058E-04+0.00000E+00-3.55056E-04+0.00000E+00-1.01725E-04+0.00000E+00+2.04904E-04+0.00000E+00+4.82464E-04+0.00000E+00+6.48778E-04+0.00000E+00+6.45532E-04+0.00000E+00+4.57442E-04+0.00000E+00+1.20911E-04+0.00000E+00-2.81414E-04+0.00000E+00-6.40040E-04+0.00000E+00-8.47708E-04+0.00000E+00-8.30656E-04+0.00000E+00-5.73180E-04+0.00000E+00-1.27650E-04+0.00000E+00+3.94310E-04+0.00000E+00+8.48744E-04+0.00000E+00+1.09821E-03+0.00000E+00+1.05234E-03+0.00000E+00+6.98398E-04+0.00000E+00+1.11999E-04+0.00000E+00-5.57036E-04+0.00000E+00-1.12174E-03+0.00000E+00-1.40922E-03+0.00000E+00-1.31236E-03+0.00000E+00-8.26764E-04+0.00000E+00-6.09068E-05+0.00000E+00+7.85842E-04+0.00000E+00+1.47374E-03+0.00000E+00+1.78935E-03+0.00000E+00+1.61011E-03+0.00000E+00+9.47830E-04+0.00000E+00-4.36276E-05+0.00000E+00-1.10163E-03+0.00000E+00-1.92275E-03+0.00000E+00-2.24826E-03+0.00000E+00-1.94359E-03+0.00000E+00-1.04776E-03+0.00000E+00+2.24088E-04+0.00000E+00+1.52962E-03+0.00000E+00+2.48958E-03+0.00000E+00+2.79606E-03+0.00000E+00+2.30850E-03+0.00000E+00+1.10801E-03+0.00000E+00-5.08938E-04+0.00000E+00-2.10070E-03+0.00000E+00-3.19878E-03+0.00000E+00-3.44326E-03+0.00000E+00-2.69684E-03+0.00000E+00-1.10249E-03+0.00000E+00+9.36892E-04+0.00000E+00+2.85672E-03+0.00000E+00+4.08406E-03+0.00000E+00+4.20524E-03+0.00000E+00+3.09968E-03+0.00000E+00+9.97970E-04+0.00000E+00-1.55873E-03+0.00000E+00-3.85362E-03+0.00000E+00-5.19124E-03+0.00000E+00-5.10336E-03+0.00000E+00-3.50440E-03+0.00000E+00-7.46438E-04+0.00000E+00+2.44968E-03+0.00000E+00+5.17690E-03+0.00000E+00+6.59364E-03+0.00000E+00+6.17604E-03+0.00000E+00+3.89756E-03+0.00000E+00+2.77256E-04+0.00000E+00-3.72784E-03+0.00000E+00-6.96714E-03+0.00000E+00-8.41784E-03+0.00000E+00-7.49572E-03+0.00000E+00-4.26426E-03+0.00000E+00+5.27466E-04+0.00000E+00+5.60328E-03+0.00000E+00+9.48592E-03+0.00000E+00+1.09107E-02+0.00000E+00+9.21506E-03+0.00000E+00+4.58962E-03+0.00000E+00-1.89363E-03+0.00000E+00-8.50506E-03+0.00000E+00-1.32925E-02+0.00000E+00-1.46243E-02+0.00000E+00-1.16967E-02+0.00000E+00-4.85962E-03+0.00000E+00+4.34870E-03+0.00000E+00+1.34983E-02+0.00000E+00+1.98472E-02+0.00000E+00+2.10770E-02+0.00000E+00+1.60019E-02+0.00000E+00+5.06204E-03+0.00000E+00-9.55078E-03+0.00000E+00-2.42030E-02+0.00000E+00-3.45266E-02+0.00000E+00-3.63864E-02+0.00000E+00-2.68872E-02+0.00000E+00-5.18748E-03+0.00000E+00+2.70918E-02+0.00000E+00+6.59838E-02+0.00000E+00+1.05820E-01+0.00000E+00+1.40281E-01+0.00000E+00+1.63636E-01+0.00000E+00+1.71897E-01+0.00000E+00+1.63636E-01+0.00000E+00+1.40281E-01+0.00000E+00+1.05820E-01+0.00000E+00+6.59838E-02+0.00000E+00+2.70918E-02+0.00000E+00-5.1874000030S*8E-03+0.00000E+00-2.68872E-02+0.00000E+00-3.63864E-02+0.00000E+00-3.45266E-02+0.00000E+00-2.42030E-02+0.00000E+00-9.55078E-03+0.00000E+00+5.06204E-03+0.00000E+00+1.60019E-02+0.00000E+00+2.10770E-02+0.00000E+00+1.98472E-02+0.00000E+00+1.34983E-02+0.00000E+00+4.34870E-03+0.00000E+00-4.85962E-03+0.00000E+00-1.16967E-02+0.00000E+00-1.46243E-02+0.00000E+00-1.32925E-02+0.00000E+00-8.50506E-03+0.00000E+00-1.89363E-03+0.00000E+00+4.58962E-03+0.00000E+00+9.21506E-03+0.00000E+00+1.09107E-02+0.00000E+00+9.48592E-03+0.00000E+00+5.60328E-03+0.00000E+00+5.27466E-04+0.00000E+00-4.26426E-03+0.00000E+00-7.49572E-03+0.00000E+00-8.41784E-03+0.00000E+00-6.96714E-03+0.00000E+00-3.72784E-03+0.00000E+00+2.77256E-04+0.00000E+00+3.89756E-03+0.00000E+00+6.17604E-03+0.00000E+00+6.59364E-03+0.00000E+00+5.17690E-03+0.00000E+00+2.44968E-03+0.00000E+00-7.46438E-04+0.00000E+00-3.50440E-03+0.00000E+00-5.10336E-03+0.00000E+00-5.19124E-03+0.00000E+00-3.85362E-03+0.00000E+00-1.55873E-03+0.00000E+00+9.97970E-04+0.00000E+00+3.09968E-03+0.00000E+00+4.20524E-03+0.00000E+00+4.08406E-03+0.00000E+00+2.85672E-03+0.00000E+00+9.36892E-04+0.00000E+00-1.10249E-03+0.00000E+00-2.69684E-03+0.00000E+00-3.44326E-03+0.00000E+00-3.19878E-03+0.00000E+00-2.10070E-03+0.00000E+00-5.08938E-04+0.00000E+00+1.10801E-03+0.00000E+00+2.30850E-03+0.00000E+00+2.79606E-03+0.00000E+00+2.48958E-03+0.00000E+00+1.52962E-03+0.00000E+00+2.24088E-04+0.00000E+00-1.04776E-03+0.00000E+00-1.94359E-03+0.00000E+00-2.24826E-03+0.00000E+00-1.92275E-03+0.00000E+00-1.10163E-03+0.00000E+00-4.36276E-05+0.00000E+00+9.47830E-04+0.00000E+00+1.61011E-03+0.00000E+00+1.78935E-03+0.00000E+00+1.47374E-03+0.00000E+00+7.85842E-04+0.00000E+00-6.09068E-05+0.00000E+00-8.26764E-04+0.00000E+00-1.31236E-03+0.00000E+00-1.40922E-03+0.00000E+00-1.12174E-03+0.00000E+00-5.57036E-04+0.00000E+00+1.11999E-04+0.00000E+00+6.98398E-04+0.00000E+00+1.05234E-03+0.00000E+00+1.09821E-03+0.00000E+00+8.48744E-04+0.00000E+00+3.94310E-04+0.00000E+00-1.27650E-04+0.00000E+00-5.73180E-04+0.00000E+00-8.30656E-04+0.00000E+00-8.47708E-04+0.00000E+00-6.40040E-04+0.00000E+00-2.81414E-04+0.00000E+00+1.20911E-04+0.00000E+00+4.57442E-04+0.00000E+00+6.45532E-04+0.00000E+00+6.48778E-04+0.00000E+00+4.82464E-04+0.00000E+00+2.04904E-04+0.00000E+00-1.01725E-04+0.00000E+00-3.55056E-04+0.00000E+00-4.94058E-04+0.00000E+00-4.92968E-04+0.00000E+00-3.64712E-04+0.00000E+00-1.53942E-04+0.00000E+00+7.75194E-05+0.00000E+00+2.68272E-04+0.00000E+00+3.73118E-04+0.00000E+00+3.73138E-04+0.00000E+00+2.78002E-04+0.00000E+00+1.20744E-04+0.00000E+00-5.29412E-05+0.00000E+00-1.97535E-04+0.00000E+00-2.79208E-04+0.00000E+00-2.83208E-04+0.00000E+00-2.15680E-04+0.00000E+00-1.00068E-04+0.00000E+00+3.04418E-05+0.00000E+00+1.42114E-04+0.00000E+00+2.09036E-04+0.00000E+00+2.18690E-04+0.00000E+00+1.73672E-04+0.00000E+00+8.95560E-05+0.00000E+00-1.01214E-05+0.00000E+00-1.00242E-04+0.00000E+00-1.60164E-04+0.00000E+00-1.78068E-04+0.00000E+00-1.52783E-04+0.00000E+00-9.29802E-05+0.00000E+00-1.42499E-05+0.00000E+00+6.50032E-05+0.00000E+00+1.27774E-04+0.00000E+00+1.61835E-04+0.00000E+00+1.61671E-04+0.00000E+00+1.28752E-04+0.00000E+00+7.03544E-05+0.00000E+00-2.59160E-06+0.00000E+00-7.80380E-05+0.00000E+00-1.45142E-04+0.00000E+00-1.95955E-04+0.00000E+00-2.26268E-04+0.00000E+00-2.35600E-04+0.00000E+00-2.26532E-04+0.00000E+00-2.03638E-04+0.00000E+00-1.72307E-04+0.00000E+00-1.37722E-04+0.00000E+00-1.04124E-04+0.00000E+00-7.44366E-05+0.00000E+00-5.02182E-05+0.00000E+00-3.18550E-05+0.00000E+00-1.88893E-05+0.00000E+00-1.03793E-05+0.00000E+00-5.21464E-06+0.00000E+00-2.34472E-06+0.00000E+00-9.08544E-07+0.00000E+00-2.80036E-07+0.00000E+00-5.32080E-08+0.00000E+00+4.52378E-09+0.00000E+00+7.72762E-09+0.00000E+0000000570051071.0000E+030000500000+1.5900E-01+1.5900E-01058003507+1.00000E+00+5.00000E-0200058003500+2.78845E+05+5.00000E-02000520127 EH20000002~001002+49.129100+008.148700-0177.0305.0000.0+00.00001122.0000E+022.0000E-020000TG~2015,078,13:00:00.0000~~N0530334A01001003+1.00000E+00+5.00000E+00003+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+0.00000000031S*E+00+0.00000E+00+0.00000E+00+0.00000E+00003-4.44400E+00+4.44400E+00+0.00000E+00+0.00000E+00-4.44400E+00-4.44400E+00+0.00000E+00+0.00000E+00-1.08300E+00+0.00000E+00+0.00000E+00+0.00000E+00058003501+4.00000E+02+5.00000E+0000058003502+2.50000E+00+5.00000E-02000540048D030030040001+1.00000E+00+0.00000E+0000000570051031.9200E+050000100000+0.0000E+00+0.0000E+00058003503+4.00000E+05+5.00000E-02000541152D040040040047+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+3.81470E-06+0.00000E+00+2.28882E-05+0.00000E+00+8.01086E-05+0.00000E+00+2.13623E-04+0.00000E+00+4.80652E-04+0.00000E+00+9.61304E-04+0.00000E+00+1.76239E-03+0.00000E+00+3.02124E-03+0.00000E+00+4.88663E-03+0.00000E+00+7.49969E-03+0.00000E+00+1.09749E-02+0.00000E+00+1.53809E-02+0.00000E+00+2.07214E-02+0.00000E+00+2.69165E-02+0.00000E+00+3.37830E-02+0.00000E+00+4.10156E-02+0.00000E+00+4.82254E-02+0.00000E+00+5.49774E-02+0.00000E+00+6.08292E-02+0.00000E+00+6.53687E-02+0.00000E+00+6.82526E-02+0.00000E+00+6.92444E-02+0.00000E+00+6.82526E-02+0.00000E+00+6.53687E-02+0.00000E+00+6.08292E-02+0.00000E+00+5.49774E-02+0.00000E+00+4.82254E-02+0.00000E+00+4.10156E-02+0.00000E+00+3.37830E-02+0.00000E+00+2.69165E-02+0.00000E+00+2.07214E-02+0.00000E+00+1.53809E-02+0.00000E+00+1.09749E-02+0.00000E+00+7.49969E-03+0.00000E+00+4.88663E-03+0.00000E+00+3.02124E-03+0.00000E+00+1.76239E-03+0.00000E+00+9.61304E-04+0.00000E+00+4.80652E-04+0.00000E+00+2.13623E-04+0.00000E+00+8.01086E-05+0.00000E+00+2.28882E-05+0.00000E+00+3.81470E-06+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+0000000570051041.9200E+050000800000+1.1979E-04+1.1979E-04058003504+1.00000E+00+5.00000E-02000541776D050040040073+7.86395E-07+0.00000E+00+2.15223E-06+0.00000E+00+4.09013E-06+0.00000E+00+6.42053E-06+0.00000E+00+7.61300E-06+0.00000E+00+4.52134E-06+0.00000E+00-8.38839E-06+0.00000E+00-4.00745E-05+0.00000E+00-1.08702E-04+0.00000E+00-2.31570E-04+0.00000E+00-4.32673E-04+0.00000E+00-7.41861E-04+0.00000E+00-1.18635E-03+0.00000E+00-1.78887E-03+0.00000E+00-2.56156E-03+0.00000E+00-3.49756E-03+0.00000E+00-4.54784E-03+0.00000E+00-5.64473E-03+0.00000E+00-6.67437E-03+0.00000E+00-7.46932E-03+0.00000E+00-7.83206E-03+0.00000E+00-7.53472E-03+0.00000E+00-6.33480E-03+0.00000E+00-3.99943E-03+0.00000E+00-3.60688E-04+0.00000E+00+4.71408E-03+0.00000E+00+1.12572E-02+0.00000E+00+1.91611E-02+0.00000E+00+2.82115E-02+0.00000E+00+3.80655E-02+0.00000E+00+4.82646E-02+0.00000E+00+5.82654E-02+0.00000E+00+6.75164E-02+0.00000E+00+7.54318E-02+0.00000E+00+8.14859E-02+0.00000E+00+8.52972E-02+0.00000E+00+8.65986E-02+0.00000E+00+8.52972E-02+0.00000E+00+8.14859E-02+0.00000E+00+7.54318E-02+0.00000E+00+6.75164E-02+0.00000E+00+5.82654E-02+0.00000E+00+4.82646E-02+0.00000E+00+3.80655E-02+0.00000E+00+2.82115E-02+0.00000E+00+1.91611E-02+0.00000E+00+1.12572E-02+0.00000E+00+4.71408E-03+0.00000E+00-3.60688E-04+0.00000E+00-3.99943E-03+0.00000E+00-6.33480E-03+0.00000E+00-7.53472E-03+0.00000E+00-7.83206E-03+0.00000E+00-7.46932E-03+0.00000E+00-6.67437E-03+0.00000E+00-5.64473E-03+0.00000E+00-4.54784E-03+0.00000E+00-3.49756E-03+0.00000E+00-2.56156E-03+0.00000E+00-1.78887E-03+0.00000E+00-1.18635E-03+0.00000E+00-7.41861E-04+0.00000E+00-4.32673E-04+0.00000E+00-2.31570E-04+0.00000E+00-1.08702E-04+0.00000E+00-4.00745E-05+0.00000E+00-8.38839E-06+0.00000E+00+4.52134E-06+0.00000E+00+7.61300E-06+0.00000E+00+6.42053E-06+0.00000E+00+4.09013E-06+0.00000E+00+2.15223E-06+0.00000E+00+7.86395E-07+0.00000E+0000000570051052.4000E+040000800000+1.5000E-03+1.5000E-03058003505+1.00000E+00+5.00000E-02000544320D060040040179+1.65488E-07+0.00000E+00+7.48132E-07+0.00000E+00+1.76664E-06+0.00000E+00+1.62612E-06+0.00000E+00-5.16640E-06+0.00000E+00-3.00692E-05+0.00000E+00-8.97376E-05+0.00000E+00-1.99571E-04+0.00000E+00-3.61172E-04+0.00000E+00-5.48500E-04+0.00000E+00-7.02688E-04+0.00000E+00-7.45976E-04+0.00000E+00-6.17072E-04+0.00000E+00-3.15191E-04+0.00000E+00+7.38188E-05+0.00000E+00+3.95725E-04+0.00000E+00+4.96800E-04+0.00000E+00+3.15263E-04+0.00000E+00-5.96548E-05+0.00000E+00-4.11872E-04+0.00000E+00-5.12780E-04+0.00000E+00-2.69536E-04+0.00000E+00+1.89248E-04+0.00000E+00+5.66172E-04+0.00000E+00+000032S*5.78372E-04+0.00000E+00+1.64727E-04+0.00000E+00-4.31664E-04+0.00000E+00-7.92432E-04+0.00000E+00-6.08316E-04+0.00000E+00+6.76780E-05+0.00000E+00+7.98316E-04+0.00000E+00+1.03172E-03+0.00000E+00+5.07504E-04+0.00000E+00-4.91744E-04+0.00000E+00-1.26810E-03+0.00000E+00-1.18261E-03+0.00000E+00-1.64670E-04+0.00000E+00+1.13876E-03+0.00000E+00+1.75363E-03+0.00000E+00+1.09177E-03+0.00000E+00-5.24120E-04+0.00000E+00-1.97068E-03+0.00000E+00-2.08536E-03+0.00000E+00-5.79052E-04+0.00000E+00+1.60144E-03+0.00000E+00+2.83576E-03+0.00000E+00+2.01276E-03+0.00000E+00-5.13156E-04+0.00000E+00-2.98815E-03+0.00000E+00-3.44765E-03+0.00000E+00-1.24599E-03+0.00000E+00+2.24272E-03+0.00000E+00+4.43120E-03+0.00000E+00+3.40590E-03+0.00000E+00-4.57304E-04+0.00000E+00-4.47584E-03+0.00000E+00-5.47828E-03+0.00000E+00-2.26220E-03+0.00000E+00+3.18035E-03+0.00000E+00+6.81616E-03+0.00000E+00+5.50776E-03+0.00000E+00-3.65328E-04+0.00000E+00-6.73316E-03+0.00000E+00-8.58052E-03+0.00000E+00-3.81782E-03+0.00000E+00+4.65228E-03+0.00000E+00+1.05646E-02+0.00000E+00+8.82560E-03+0.00000E+00-2.56374E-04+0.00000E+00-1.04496E-02+0.00000E+00-1.37224E-02+0.00000E+00-6.39512E-03+0.00000E+00+7.26512E-03+0.00000E+00+1.72312E-02+0.00000E+00+1.48181E-02+0.00000E+00-1.54011E-04+0.00000E+00-1.77680E-02+0.00000E+00-2.41384E-02+0.00000E+00-1.17549E-02+0.00000E+00+1.32733E-02+0.00000E+00+3.32147E-02+0.00000E+00+3.01309E-02+0.00000E+00-8.13468E-05+0.00000E+00-4.08284E-02+0.00000E+00-6.13256E-02+0.00000E+00-3.42109E-02+0.00000E+00+4.58968E-02+0.00000E+00+1.54886E-01+0.00000E+00+2.48713E-01+0.00000E+00+2.85658E-01+0.00000E+00+2.48713E-01+0.00000E+00+1.54886E-01+0.00000E+00+4.58968E-02+0.00000E+00-3.42109E-02+0.00000E+00-6.13256E-02+0.00000E+00-4.08284E-02+0.00000E+00-8.13468E-05+0.00000E+00+3.01309E-02+0.00000E+00+3.32147E-02+0.00000E+00+1.32733E-02+0.00000E+00-1.17549E-02+0.00000E+00-2.41384E-02+0.00000E+00-1.77680E-02+0.00000E+00-1.54011E-04+0.00000E+00+1.48181E-02+0.00000E+00+1.72312E-02+0.00000E+00+7.26512E-03+0.00000E+00-6.39512E-03+0.00000E+00-1.37224E-02+0.00000E+00-1.04496E-02+0.00000E+00-2.56374E-04+0.00000E+00+8.82560E-03+0.00000E+00+1.05646E-02+0.00000E+00+4.65228E-03+0.00000E+00-3.81782E-03+0.00000E+00-8.58052E-03+0.00000E+00-6.73316E-03+0.00000E+00-3.65328E-04+0.00000E+00+5.50776E-03+0.00000E+00+6.81616E-03+0.00000E+00+3.18035E-03+0.00000E+00-2.26220E-03+0.00000E+00-5.47828E-03+0.00000E+00-4.47584E-03+0.00000E+00-4.57304E-04+0.00000E+00+3.40590E-03+0.00000E+00+4.43120E-03+0.00000E+00+2.24272E-03+0.00000E+00-1.24599E-03+0.00000E+00-3.44765E-03+0.00000E+00-2.98815E-03+0.00000E+00-5.13156E-04+0.00000E+00+2.01276E-03+0.00000E+00+2.83576E-03+0.00000E+00+1.60144E-03+0.00000E+00-5.79052E-04+0.00000E+00-2.08536E-03+0.00000E+00-1.97068E-03+0.00000E+00-5.24120E-04+0.00000E+00+1.09177E-03+0.00000E+00+1.75363E-03+0.00000E+00+1.13876E-03+0.00000E+00-1.64670E-04+0.00000E+00-1.18261E-03+0.00000E+00-1.26810E-03+0.00000E+00-4.91744E-04+0.00000E+00+5.07504E-04+0.00000E+00+1.03172E-03+0.00000E+00+7.98316E-04+0.00000E+00+6.76780E-05+0.00000E+00-6.08316E-04+0.00000E+00-7.92432E-04+0.00000E+00-4.31664E-04+0.00000E+00+1.64727E-04+0.00000E+00+5.78372E-04+0.00000E+00+5.66172E-04+0.00000E+00+1.89248E-04+0.00000E+00-2.69536E-04+0.00000E+00-5.12780E-04+0.00000E+00-4.11872E-04+0.00000E+00-5.96548E-05+0.00000E+00+3.15263E-04+0.00000E+00+4.96800E-04+0.00000E+00+3.95725E-04+0.00000E+00+7.38188E-05+0.00000E+00-3.15191E-04+0.00000E+00-6.17072E-04+0.00000E+00-7.45976E-04+0.00000E+00-7.02688E-04+0.00000E+00-5.48500E-04+0.00000E+00-3.61172E-04+0.00000E+00-1.99571E-04+0.00000E+00-8.97376E-05+0.00000E+00-3.00692E-05+0.00000E+00-5.16640E-06+0.00000E+00+1.62612E-06+0.00000E+00+1.76664E-06+0.00000E+00+7.48132E-07+0.00000E+00+1.65488E-07+0.00000E+0000000570051063.0000E+030000300000+2.9667E-02+2.9667E-02058003506+1.00000E+00+5.00000E-02000547680D070040040319+7.72762E-09+0.00000E+00+4.52378E-09+0.00000E+00-5.32080E-08+0.00000E+00-2.80036E-07+0.00000E+00-9.08544E-07+0.00000E+00-2.34472E-06+0.00000E+00-5.21464E-06+0.00000E+00-1.03793E-05+0.00000E+00-1.88893E-05+0.00000E+00-3.18550E-05+0.00000E+00-5.02182E-05+0.0000000033S*0E+00-7.44366E-05+0.00000E+00-1.04124E-04+0.00000E+00-1.37722E-04+0.00000E+00-1.72307E-04+0.00000E+00-2.03638E-04+0.00000E+00-2.26532E-04+0.00000E+00-2.35600E-04+0.00000E+00-2.26268E-04+0.00000E+00-1.95955E-04+0.00000E+00-1.45142E-04+0.00000E+00-7.80380E-05+0.00000E+00-2.59160E-06+0.00000E+00+7.03544E-05+0.00000E+00+1.28752E-04+0.00000E+00+1.61671E-04+0.00000E+00+1.61835E-04+0.00000E+00+1.27774E-04+0.00000E+00+6.50032E-05+0.00000E+00-1.42499E-05+0.00000E+00-9.29802E-05+0.00000E+00-1.52783E-04+0.00000E+00-1.78068E-04+0.00000E+00-1.60164E-04+0.00000E+00-1.00242E-04+0.00000E+00-1.01214E-05+0.00000E+00+8.95560E-05+0.00000E+00+1.73672E-04+0.00000E+00+2.18690E-04+0.00000E+00+2.09036E-04+0.00000E+00+1.42114E-04+0.00000E+00+3.04418E-05+0.00000E+00-1.00068E-04+0.00000E+00-2.15680E-04+0.00000E+00-2.83208E-04+0.00000E+00-2.79208E-04+0.00000E+00-1.97535E-04+0.00000E+00-5.29412E-05+0.00000E+00+1.20744E-04+0.00000E+00+2.78002E-04+0.00000E+00+3.73138E-04+0.00000E+00+3.73118E-04+0.00000E+00+2.68272E-04+0.00000E+00+7.75194E-05+0.00000E+00-1.53942E-04+0.00000E+00-3.64712E-04+0.00000E+00-4.92968E-04+0.00000E+00-4.94058E-04+0.00000E+00-3.55056E-04+0.00000E+00-1.01725E-04+0.00000E+00+2.04904E-04+0.00000E+00+4.82464E-04+0.00000E+00+6.48778E-04+0.00000E+00+6.45532E-04+0.00000E+00+4.57442E-04+0.00000E+00+1.20911E-04+0.00000E+00-2.81414E-04+0.00000E+00-6.40040E-04+0.00000E+00-8.47708E-04+0.00000E+00-8.30656E-04+0.00000E+00-5.73180E-04+0.00000E+00-1.27650E-04+0.00000E+00+3.94310E-04+0.00000E+00+8.48744E-04+0.00000E+00+1.09821E-03+0.00000E+00+1.05234E-03+0.00000E+00+6.98398E-04+0.00000E+00+1.11999E-04+0.00000E+00-5.57036E-04+0.00000E+00-1.12174E-03+0.00000E+00-1.40922E-03+0.00000E+00-1.31236E-03+0.00000E+00-8.26764E-04+0.00000E+00-6.09068E-05+0.00000E+00+7.85842E-04+0.00000E+00+1.47374E-03+0.00000E+00+1.78935E-03+0.00000E+00+1.61011E-03+0.00000E+00+9.47830E-04+0.00000E+00-4.36276E-05+0.00000E+00-1.10163E-03+0.00000E+00-1.92275E-03+0.00000E+00-2.24826E-03+0.00000E+00-1.94359E-03+0.00000E+00-1.04776E-03+0.00000E+00+2.24088E-04+0.00000E+00+1.52962E-03+0.00000E+00+2.48958E-03+0.00000E+00+2.79606E-03+0.00000E+00+2.30850E-03+0.00000E+00+1.10801E-03+0.00000E+00-5.08938E-04+0.00000E+00-2.10070E-03+0.00000E+00-3.19878E-03+0.00000E+00-3.44326E-03+0.00000E+00-2.69684E-03+0.00000E+00-1.10249E-03+0.00000E+00+9.36892E-04+0.00000E+00+2.85672E-03+0.00000E+00+4.08406E-03+0.00000E+00+4.20524E-03+0.00000E+00+3.09968E-03+0.00000E+00+9.97970E-04+0.00000E+00-1.55873E-03+0.00000E+00-3.85362E-03+0.00000E+00-5.19124E-03+0.00000E+00-5.10336E-03+0.00000E+00-3.50440E-03+0.00000E+00-7.46438E-04+0.00000E+00+2.44968E-03+0.00000E+00+5.17690E-03+0.00000E+00+6.59364E-03+0.00000E+00+6.17604E-03+0.00000E+00+3.89756E-03+0.00000E+00+2.77256E-04+0.00000E+00-3.72784E-03+0.00000E+00-6.96714E-03+0.00000E+00-8.41784E-03+0.00000E+00-7.49572E-03+0.00000E+00-4.26426E-03+0.00000E+00+5.27466E-04+0.00000E+00+5.60328E-03+0.00000E+00+9.48592E-03+0.00000E+00+1.09107E-02+0.00000E+00+9.21506E-03+0.00000E+00+4.58962E-03+0.00000E+00-1.89363E-03+0.00000E+00-8.50506E-03+0.00000E+00-1.32925E-02+0.00000E+00-1.46243E-02+0.00000E+00-1.16967E-02+0.00000E+00-4.85962E-03+0.00000E+00+4.34870E-03+0.00000E+00+1.34983E-02+0.00000E+00+1.98472E-02+0.00000E+00+2.10770E-02+0.00000E+00+1.60019E-02+0.00000E+00+5.06204E-03+0.00000E+00-9.55078E-03+0.00000E+00-2.42030E-02+0.00000E+00-3.45266E-02+0.00000E+00-3.63864E-02+0.00000E+00-2.68872E-02+0.00000E+00-5.18748E-03+0.00000E+00+2.70918E-02+0.00000E+00+6.59838E-02+0.00000E+00+1.05820E-01+0.00000E+00+1.40281E-01+0.00000E+00+1.63636E-01+0.00000E+00+1.71897E-01+0.00000E+00+1.63636E-01+0.00000E+00+1.40281E-01+0.00000E+00+1.05820E-01+0.00000E+00+6.59838E-02+0.00000E+00+2.70918E-02+0.00000E+00-5.18748E-03+0.00000E+00-2.68872E-02+0.00000E+00-3.63864E-02+0.00000E+00-3.45266E-02+0.00000E+00-2.42030E-02+0.00000E+00-9.55078E-03+0.00000E+00+5.06204E-03+0.00000E+00+1.60019E-02+0.00000E+00+2.10770E-02+0.00000E+00+1.98472E-02+0.00000E+00+1.34983E-02+0.00000E+00+4.34870E-03+0.00000E+00-4.85962E-03+0.00000E+00-1.16967E-02+0.00000E+00-1.46243E-02+0.00000E+00-1.32925E-02+0.00000E+00-8.000034S*50506E-03+0.00000E+00-1.89363E-03+0.00000E+00+4.58962E-03+0.00000E+00+9.21506E-03+0.00000E+00+1.09107E-02+0.00000E+00+9.48592E-03+0.00000E+00+5.60328E-03+0.00000E+00+5.27466E-04+0.00000E+00-4.26426E-03+0.00000E+00-7.49572E-03+0.00000E+00-8.41784E-03+0.00000E+00-6.96714E-03+0.00000E+00-3.72784E-03+0.00000E+00+2.77256E-04+0.00000E+00+3.89756E-03+0.00000E+00+6.17604E-03+0.00000E+00+6.59364E-03+0.00000E+00+5.17690E-03+0.00000E+00+2.44968E-03+0.00000E+00-7.46438E-04+0.00000E+00-3.50440E-03+0.00000E+00-5.10336E-03+0.00000E+00-5.19124E-03+0.00000E+00-3.85362E-03+0.00000E+00-1.55873E-03+0.00000E+00+9.97970E-04+0.00000E+00+3.09968E-03+0.00000E+00+4.20524E-03+0.00000E+00+4.08406E-03+0.00000E+00+2.85672E-03+0.00000E+00+9.36892E-04+0.00000E+00-1.10249E-03+0.00000E+00-2.69684E-03+0.00000E+00-3.44326E-03+0.00000E+00-3.19878E-03+0.00000E+00-2.10070E-03+0.00000E+00-5.08938E-04+0.00000E+00+1.10801E-03+0.00000E+00+2.30850E-03+0.00000E+00+2.79606E-03+0.00000E+00+2.48958E-03+0.00000E+00+1.52962E-03+0.00000E+00+2.24088E-04+0.00000E+00-1.04776E-03+0.00000E+00-1.94359E-03+0.00000E+00-2.24826E-03+0.00000E+00-1.92275E-03+0.00000E+00-1.10163E-03+0.00000E+00-4.36276E-05+0.00000E+00+9.47830E-04+0.00000E+00+1.61011E-03+0.00000E+00+1.78935E-03+0.00000E+00+1.47374E-03+0.00000E+00+7.85842E-04+0.00000E+00-6.09068E-05+0.00000E+00-8.26764E-04+0.00000E+00-1.31236E-03+0.00000E+00-1.40922E-03+0.00000E+00-1.12174E-03+0.00000E+00-5.57036E-04+0.00000E+00+1.11999E-04+0.00000E+00+6.98398E-04+0.00000E+00+1.05234E-03+0.00000E+00+1.09821E-03+0.00000E+00+8.48744E-04+0.00000E+00+3.94310E-04+0.00000E+00-1.27650E-04+0.00000E+00-5.73180E-04+0.00000E+00-8.30656E-04+0.00000E+00-8.47708E-04+0.00000E+00-6.40040E-04+0.00000E+00-2.81414E-04+0.00000E+00+1.20911E-04+0.00000E+00+4.57442E-04+0.00000E+00+6.45532E-04+0.00000E+00+6.48778E-04+0.00000E+00+4.82464E-04+0.00000E+00+2.04904E-04+0.00000E+00-1.01725E-04+0.00000E+00-3.55056E-04+0.00000E+00-4.94058E-04+0.00000E+00-4.92968E-04+0.00000E+00-3.64712E-04+0.00000E+00-1.53942E-04+0.00000E+00+7.75194E-05+0.00000E+00+2.68272E-04+0.00000E+00+3.73118E-04+0.00000E+00+3.73138E-04+0.00000E+00+2.78002E-04+0.00000E+00+1.20744E-04+0.00000E+00-5.29412E-05+0.00000E+00-1.97535E-04+0.00000E+00-2.79208E-04+0.00000E+00-2.83208E-04+0.00000E+00-2.15680E-04+0.00000E+00-1.00068E-04+0.00000E+00+3.04418E-05+0.00000E+00+1.42114E-04+0.00000E+00+2.09036E-04+0.00000E+00+2.18690E-04+0.00000E+00+1.73672E-04+0.00000E+00+8.95560E-05+0.00000E+00-1.01214E-05+0.00000E+00-1.00242E-04+0.00000E+00-1.60164E-04+0.00000E+00-1.78068E-04+0.00000E+00-1.52783E-04+0.00000E+00-9.29802E-05+0.00000E+00-1.42499E-05+0.00000E+00+6.50032E-05+0.00000E+00+1.27774E-04+0.00000E+00+1.61835E-04+0.00000E+00+1.61671E-04+0.00000E+00+1.28752E-04+0.00000E+00+7.03544E-05+0.00000E+00-2.59160E-06+0.00000E+00-7.80380E-05+0.00000E+00-1.45142E-04+0.00000E+00-1.95955E-04+0.00000E+00-2.26268E-04+0.00000E+00-2.35600E-04+0.00000E+00-2.26532E-04+0.00000E+00-2.03638E-04+0.00000E+00-1.72307E-04+0.00000E+00-1.37722E-04+0.00000E+00-1.04124E-04+0.00000E+00-7.44366E-05+0.00000E+00-5.02182E-05+0.00000E+00-3.18550E-05+0.00000E+00-1.88893E-05+0.00000E+00-1.03793E-05+0.00000E+00-5.21464E-06+0.00000E+00-2.34472E-06+0.00000E+00-9.08544E-07+0.00000E+00-2.80036E-07+0.00000E+00-5.32080E-08+0.00000E+00+4.52378E-09+0.00000E+00+7.72762E-09+0.00000E+0000000570051071.0000E+030000500000+1.5900E-01+1.5900E-01058003507+1.00000E+00+5.00000E-0200058003500+2.78845E+05+5.00000E-02000520127 EHZ0000002~001002+49.129100+008.148700-0177.0305.0000.0-90.00001122.0000E+022.0000E-020000TG~2015,078,13:00:00.0000~~N0530334A01001003+1.00000E+00+5.00000E+00003+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00003-4.44400E+00+4.44400E+00+0.00000E+00+0.00000E+00-4.44400E+00-4.44400E+00+0.00000E+00+0.00000E+00-1.08300E+00+0.00000E+00+0.00000E+00+0.00000E+00058003501+4.00000E+02+5.00000E+0000058003502+2.50000E+00+5.00000E-02000540048D030030040001+1.00000E+00+0.00000E+0000000570051031.9200E+050000100000+0.0000E+00+0.0000E+00058003503+4.00000E+05+5.000035S*00000E-02000541152D040040040047+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+3.81470E-06+0.00000E+00+2.28882E-05+0.00000E+00+8.01086E-05+0.00000E+00+2.13623E-04+0.00000E+00+4.80652E-04+0.00000E+00+9.61304E-04+0.00000E+00+1.76239E-03+0.00000E+00+3.02124E-03+0.00000E+00+4.88663E-03+0.00000E+00+7.49969E-03+0.00000E+00+1.09749E-02+0.00000E+00+1.53809E-02+0.00000E+00+2.07214E-02+0.00000E+00+2.69165E-02+0.00000E+00+3.37830E-02+0.00000E+00+4.10156E-02+0.00000E+00+4.82254E-02+0.00000E+00+5.49774E-02+0.00000E+00+6.08292E-02+0.00000E+00+6.53687E-02+0.00000E+00+6.82526E-02+0.00000E+00+6.92444E-02+0.00000E+00+6.82526E-02+0.00000E+00+6.53687E-02+0.00000E+00+6.08292E-02+0.00000E+00+5.49774E-02+0.00000E+00+4.82254E-02+0.00000E+00+4.10156E-02+0.00000E+00+3.37830E-02+0.00000E+00+2.69165E-02+0.00000E+00+2.07214E-02+0.00000E+00+1.53809E-02+0.00000E+00+1.09749E-02+0.00000E+00+7.49969E-03+0.00000E+00+4.88663E-03+0.00000E+00+3.02124E-03+0.00000E+00+1.76239E-03+0.00000E+00+9.61304E-04+0.00000E+00+4.80652E-04+0.00000E+00+2.13623E-04+0.00000E+00+8.01086E-05+0.00000E+00+2.28882E-05+0.00000E+00+3.81470E-06+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+0000000570051041.9200E+050000800000+1.1979E-04+1.1979E-04058003504+1.00000E+00+5.00000E-02000541776D050040040073+7.86395E-07+0.00000E+00+2.15223E-06+0.00000E+00+4.09013E-06+0.00000E+00+6.42053E-06+0.00000E+00+7.61300E-06+0.00000E+00+4.52134E-06+0.00000E+00-8.38839E-06+0.00000E+00-4.00745E-05+0.00000E+00-1.08702E-04+0.00000E+00-2.31570E-04+0.00000E+00-4.32673E-04+0.00000E+00-7.41861E-04+0.00000E+00-1.18635E-03+0.00000E+00-1.78887E-03+0.00000E+00-2.56156E-03+0.00000E+00-3.49756E-03+0.00000E+00-4.54784E-03+0.00000E+00-5.64473E-03+0.00000E+00-6.67437E-03+0.00000E+00-7.46932E-03+0.00000E+00-7.83206E-03+0.00000E+00-7.53472E-03+0.00000E+00-6.33480E-03+0.00000E+00-3.99943E-03+0.00000E+00-3.60688E-04+0.00000E+00+4.71408E-03+0.00000E+00+1.12572E-02+0.00000E+00+1.91611E-02+0.00000E+00+2.82115E-02+0.00000E+00+3.80655E-02+0.00000E+00+4.82646E-02+0.00000E+00+5.82654E-02+0.00000E+00+6.75164E-02+0.00000E+00+7.54318E-02+0.00000E+00+8.14859E-02+0.00000E+00+8.52972E-02+0.00000E+00+8.65986E-02+0.00000E+00+8.52972E-02+0.00000E+00+8.14859E-02+0.00000E+00+7.54318E-02+0.00000E+00+6.75164E-02+0.00000E+00+5.82654E-02+0.00000E+00+4.82646E-02+0.00000E+00+3.80655E-02+0.00000E+00+2.82115E-02+0.00000E+00+1.91611E-02+0.00000E+00+1.12572E-02+0.00000E+00+4.71408E-03+0.00000E+00-3.60688E-04+0.00000E+00-3.99943E-03+0.00000E+00-6.33480E-03+0.00000E+00-7.53472E-03+0.00000E+00-7.83206E-03+0.00000E+00-7.46932E-03+0.00000E+00-6.67437E-03+0.00000E+00-5.64473E-03+0.00000E+00-4.54784E-03+0.00000E+00-3.49756E-03+0.00000E+00-2.56156E-03+0.00000E+00-1.78887E-03+0.00000E+00-1.18635E-03+0.00000E+00-7.41861E-04+0.00000E+00-4.32673E-04+0.00000E+00-2.31570E-04+0.00000E+00-1.08702E-04+0.00000E+00-4.00745E-05+0.00000E+00-8.38839E-06+0.00000E+00+4.52134E-06+0.00000E+00+7.61300E-06+0.00000E+00+6.42053E-06+0.00000E+00+4.09013E-06+0.00000E+00+2.15223E-06+0.00000E+00+7.86395E-07+0.00000E+0000000570051052.4000E+040000800000+1.5000E-03+1.5000E-03058003505+1.00000E+00+5.00000E-02000544320D060040040179+1.65488E-07+0.00000E+00+7.48132E-07+0.00000E+00+1.76664E-06+0.00000E+00+1.62612E-06+0.00000E+00-5.16640E-06+0.00000E+00-3.00692E-05+0.00000E+00-8.97376E-05+0.00000E+00-1.99571E-04+0.00000E+00-3.61172E-04+0.00000E+00-5.48500E-04+0.00000E+00-7.02688E-04+0.00000E+00-7.45976E-04+0.00000E+00-6.17072E-04+0.00000E+00-3.15191E-04+0.00000E+00+7.38188E-05+0.00000E+00+3.95725E-04+0.00000E+00+4.96800E-04+0.00000E+00+3.15263E-04+0.00000E+00-5.96548E-05+0.00000E+00-4.11872E-04+0.00000E+00-5.12780E-04+0.00000E+00-2.69536E-04+0.00000E+00+1.89248E-04+0.00000E+00+5.66172E-04+0.00000E+00+5.78372E-04+0.00000E+00+1.64727E-04+0.00000E+00-4.31664E-04+0.00000E+00-7.92432E-04+0.00000E+00-6.08316E-04+0.00000E+00+6.76780E-05+0.00000E+00+7.98316E-04+0.00000E+00+1.03172E-03+0.00000E+00+5.07504E-04+0.00000E+00-4.91744E-04+0.00000E+00-1.26810E-03+0.00000E+00-1.18261E-03+0.00000E+00-1.64670E-04+0.00000E+00+1.13876E-03+0.00000E+00+1.75363E-03+0.00000E+00+1.09177E-03+0.00000E000036S*+00-5.24120E-04+0.00000E+00-1.97068E-03+0.00000E+00-2.08536E-03+0.00000E+00-5.79052E-04+0.00000E+00+1.60144E-03+0.00000E+00+2.83576E-03+0.00000E+00+2.01276E-03+0.00000E+00-5.13156E-04+0.00000E+00-2.98815E-03+0.00000E+00-3.44765E-03+0.00000E+00-1.24599E-03+0.00000E+00+2.24272E-03+0.00000E+00+4.43120E-03+0.00000E+00+3.40590E-03+0.00000E+00-4.57304E-04+0.00000E+00-4.47584E-03+0.00000E+00-5.47828E-03+0.00000E+00-2.26220E-03+0.00000E+00+3.18035E-03+0.00000E+00+6.81616E-03+0.00000E+00+5.50776E-03+0.00000E+00-3.65328E-04+0.00000E+00-6.73316E-03+0.00000E+00-8.58052E-03+0.00000E+00-3.81782E-03+0.00000E+00+4.65228E-03+0.00000E+00+1.05646E-02+0.00000E+00+8.82560E-03+0.00000E+00-2.56374E-04+0.00000E+00-1.04496E-02+0.00000E+00-1.37224E-02+0.00000E+00-6.39512E-03+0.00000E+00+7.26512E-03+0.00000E+00+1.72312E-02+0.00000E+00+1.48181E-02+0.00000E+00-1.54011E-04+0.00000E+00-1.77680E-02+0.00000E+00-2.41384E-02+0.00000E+00-1.17549E-02+0.00000E+00+1.32733E-02+0.00000E+00+3.32147E-02+0.00000E+00+3.01309E-02+0.00000E+00-8.13468E-05+0.00000E+00-4.08284E-02+0.00000E+00-6.13256E-02+0.00000E+00-3.42109E-02+0.00000E+00+4.58968E-02+0.00000E+00+1.54886E-01+0.00000E+00+2.48713E-01+0.00000E+00+2.85658E-01+0.00000E+00+2.48713E-01+0.00000E+00+1.54886E-01+0.00000E+00+4.58968E-02+0.00000E+00-3.42109E-02+0.00000E+00-6.13256E-02+0.00000E+00-4.08284E-02+0.00000E+00-8.13468E-05+0.00000E+00+3.01309E-02+0.00000E+00+3.32147E-02+0.00000E+00+1.32733E-02+0.00000E+00-1.17549E-02+0.00000E+00-2.41384E-02+0.00000E+00-1.77680E-02+0.00000E+00-1.54011E-04+0.00000E+00+1.48181E-02+0.00000E+00+1.72312E-02+0.00000E+00+7.26512E-03+0.00000E+00-6.39512E-03+0.00000E+00-1.37224E-02+0.00000E+00-1.04496E-02+0.00000E+00-2.56374E-04+0.00000E+00+8.82560E-03+0.00000E+00+1.05646E-02+0.00000E+00+4.65228E-03+0.00000E+00-3.81782E-03+0.00000E+00-8.58052E-03+0.00000E+00-6.73316E-03+0.00000E+00-3.65328E-04+0.00000E+00+5.50776E-03+0.00000E+00+6.81616E-03+0.00000E+00+3.18035E-03+0.00000E+00-2.26220E-03+0.00000E+00-5.47828E-03+0.00000E+00-4.47584E-03+0.00000E+00-4.57304E-04+0.00000E+00+3.40590E-03+0.00000E+00+4.43120E-03+0.00000E+00+2.24272E-03+0.00000E+00-1.24599E-03+0.00000E+00-3.44765E-03+0.00000E+00-2.98815E-03+0.00000E+00-5.13156E-04+0.00000E+00+2.01276E-03+0.00000E+00+2.83576E-03+0.00000E+00+1.60144E-03+0.00000E+00-5.79052E-04+0.00000E+00-2.08536E-03+0.00000E+00-1.97068E-03+0.00000E+00-5.24120E-04+0.00000E+00+1.09177E-03+0.00000E+00+1.75363E-03+0.00000E+00+1.13876E-03+0.00000E+00-1.64670E-04+0.00000E+00-1.18261E-03+0.00000E+00-1.26810E-03+0.00000E+00-4.91744E-04+0.00000E+00+5.07504E-04+0.00000E+00+1.03172E-03+0.00000E+00+7.98316E-04+0.00000E+00+6.76780E-05+0.00000E+00-6.08316E-04+0.00000E+00-7.92432E-04+0.00000E+00-4.31664E-04+0.00000E+00+1.64727E-04+0.00000E+00+5.78372E-04+0.00000E+00+5.66172E-04+0.00000E+00+1.89248E-04+0.00000E+00-2.69536E-04+0.00000E+00-5.12780E-04+0.00000E+00-4.11872E-04+0.00000E+00-5.96548E-05+0.00000E+00+3.15263E-04+0.00000E+00+4.96800E-04+0.00000E+00+3.95725E-04+0.00000E+00+7.38188E-05+0.00000E+00-3.15191E-04+0.00000E+00-6.17072E-04+0.00000E+00-7.45976E-04+0.00000E+00-7.02688E-04+0.00000E+00-5.48500E-04+0.00000E+00-3.61172E-04+0.00000E+00-1.99571E-04+0.00000E+00-8.97376E-05+0.00000E+00-3.00692E-05+0.00000E+00-5.16640E-06+0.00000E+00+1.62612E-06+0.00000E+00+1.76664E-06+0.00000E+00+7.48132E-07+0.00000E+00+1.65488E-07+0.00000E+0000000570051063.0000E+030000300000+2.9667E-02+2.9667E-02058003506+1.00000E+00+5.00000E-02000547680D070040040319+7.72762E-09+0.00000E+00+4.52378E-09+0.00000E+00-5.32080E-08+0.00000E+00-2.80036E-07+0.00000E+00-9.08544E-07+0.00000E+00-2.34472E-06+0.00000E+00-5.21464E-06+0.00000E+00-1.03793E-05+0.00000E+00-1.88893E-05+0.00000E+00-3.18550E-05+0.00000E+00-5.02182E-05+0.00000E+00-7.44366E-05+0.00000E+00-1.04124E-04+0.00000E+00-1.37722E-04+0.00000E+00-1.72307E-04+0.00000E+00-2.03638E-04+0.00000E+00-2.26532E-04+0.00000E+00-2.35600E-04+0.00000E+00-2.26268E-04+0.00000E+00-1.95955E-04+0.00000E+00-1.45142E-04+0.00000E+00-7.80380E-05+0.00000E+00-2.59160E-06+0.00000E+00+7.03544E-05+0.00000E+00+1.28752E-04+0.00000E+00+1.61671E-04+0.00000E+00+1.61835E-04+0.000037S*00000E+00+1.27774E-04+0.00000E+00+6.50032E-05+0.00000E+00-1.42499E-05+0.00000E+00-9.29802E-05+0.00000E+00-1.52783E-04+0.00000E+00-1.78068E-04+0.00000E+00-1.60164E-04+0.00000E+00-1.00242E-04+0.00000E+00-1.01214E-05+0.00000E+00+8.95560E-05+0.00000E+00+1.73672E-04+0.00000E+00+2.18690E-04+0.00000E+00+2.09036E-04+0.00000E+00+1.42114E-04+0.00000E+00+3.04418E-05+0.00000E+00-1.00068E-04+0.00000E+00-2.15680E-04+0.00000E+00-2.83208E-04+0.00000E+00-2.79208E-04+0.00000E+00-1.97535E-04+0.00000E+00-5.29412E-05+0.00000E+00+1.20744E-04+0.00000E+00+2.78002E-04+0.00000E+00+3.73138E-04+0.00000E+00+3.73118E-04+0.00000E+00+2.68272E-04+0.00000E+00+7.75194E-05+0.00000E+00-1.53942E-04+0.00000E+00-3.64712E-04+0.00000E+00-4.92968E-04+0.00000E+00-4.94058E-04+0.00000E+00-3.55056E-04+0.00000E+00-1.01725E-04+0.00000E+00+2.04904E-04+0.00000E+00+4.82464E-04+0.00000E+00+6.48778E-04+0.00000E+00+6.45532E-04+0.00000E+00+4.57442E-04+0.00000E+00+1.20911E-04+0.00000E+00-2.81414E-04+0.00000E+00-6.40040E-04+0.00000E+00-8.47708E-04+0.00000E+00-8.30656E-04+0.00000E+00-5.73180E-04+0.00000E+00-1.27650E-04+0.00000E+00+3.94310E-04+0.00000E+00+8.48744E-04+0.00000E+00+1.09821E-03+0.00000E+00+1.05234E-03+0.00000E+00+6.98398E-04+0.00000E+00+1.11999E-04+0.00000E+00-5.57036E-04+0.00000E+00-1.12174E-03+0.00000E+00-1.40922E-03+0.00000E+00-1.31236E-03+0.00000E+00-8.26764E-04+0.00000E+00-6.09068E-05+0.00000E+00+7.85842E-04+0.00000E+00+1.47374E-03+0.00000E+00+1.78935E-03+0.00000E+00+1.61011E-03+0.00000E+00+9.47830E-04+0.00000E+00-4.36276E-05+0.00000E+00-1.10163E-03+0.00000E+00-1.92275E-03+0.00000E+00-2.24826E-03+0.00000E+00-1.94359E-03+0.00000E+00-1.04776E-03+0.00000E+00+2.24088E-04+0.00000E+00+1.52962E-03+0.00000E+00+2.48958E-03+0.00000E+00+2.79606E-03+0.00000E+00+2.30850E-03+0.00000E+00+1.10801E-03+0.00000E+00-5.08938E-04+0.00000E+00-2.10070E-03+0.00000E+00-3.19878E-03+0.00000E+00-3.44326E-03+0.00000E+00-2.69684E-03+0.00000E+00-1.10249E-03+0.00000E+00+9.36892E-04+0.00000E+00+2.85672E-03+0.00000E+00+4.08406E-03+0.00000E+00+4.20524E-03+0.00000E+00+3.09968E-03+0.00000E+00+9.97970E-04+0.00000E+00-1.55873E-03+0.00000E+00-3.85362E-03+0.00000E+00-5.19124E-03+0.00000E+00-5.10336E-03+0.00000E+00-3.50440E-03+0.00000E+00-7.46438E-04+0.00000E+00+2.44968E-03+0.00000E+00+5.17690E-03+0.00000E+00+6.59364E-03+0.00000E+00+6.17604E-03+0.00000E+00+3.89756E-03+0.00000E+00+2.77256E-04+0.00000E+00-3.72784E-03+0.00000E+00-6.96714E-03+0.00000E+00-8.41784E-03+0.00000E+00-7.49572E-03+0.00000E+00-4.26426E-03+0.00000E+00+5.27466E-04+0.00000E+00+5.60328E-03+0.00000E+00+9.48592E-03+0.00000E+00+1.09107E-02+0.00000E+00+9.21506E-03+0.00000E+00+4.58962E-03+0.00000E+00-1.89363E-03+0.00000E+00-8.50506E-03+0.00000E+00-1.32925E-02+0.00000E+00-1.46243E-02+0.00000E+00-1.16967E-02+0.00000E+00-4.85962E-03+0.00000E+00+4.34870E-03+0.00000E+00+1.34983E-02+0.00000E+00+1.98472E-02+0.00000E+00+2.10770E-02+0.00000E+00+1.60019E-02+0.00000E+00+5.06204E-03+0.00000E+00-9.55078E-03+0.00000E+00-2.42030E-02+0.00000E+00-3.45266E-02+0.00000E+00-3.63864E-02+0.00000E+00-2.68872E-02+0.00000E+00-5.18748E-03+0.00000E+00+2.70918E-02+0.00000E+00+6.59838E-02+0.00000E+00+1.05820E-01+0.00000E+00+1.40281E-01+0.00000E+00+1.63636E-01+0.00000E+00+1.71897E-01+0.00000E+00+1.63636E-01+0.00000E+00+1.40281E-01+0.00000E+00+1.05820E-01+0.00000E+00+6.59838E-02+0.00000E+00+2.70918E-02+0.00000E+00-5.18748E-03+0.00000E+00-2.68872E-02+0.00000E+00-3.63864E-02+0.00000E+00-3.45266E-02+0.00000E+00-2.42030E-02+0.00000E+00-9.55078E-03+0.00000E+00+5.06204E-03+0.00000E+00+1.60019E-02+0.00000E+00+2.10770E-02+0.00000E+00+1.98472E-02+0.00000E+00+1.34983E-02+0.00000E+00+4.34870E-03+0.00000E+00-4.85962E-03+0.00000E+00-1.16967E-02+0.00000E+00-1.46243E-02+0.00000E+00-1.32925E-02+0.00000E+00-8.50506E-03+0.00000E+00-1.89363E-03+0.00000E+00+4.58962E-03+0.00000E+00+9.21506E-03+0.00000E+00+1.09107E-02+0.00000E+00+9.48592E-03+0.00000E+00+5.60328E-03+0.00000E+00+5.27466E-04+0.00000E+00-4.26426E-03+0.00000E+00-7.49572E-03+0.00000E+00-8.41784E-03+0.00000E+00-6.96714E-03+0.00000E+00-3.72784E-03+0.00000E+00+2.77256E-04+0.00000E+00+3.89756E-03+0.00000E+00+6.17604E-03+0.00000E+0000038S*0+6.59364E-03+0.00000E+00+5.17690E-03+0.00000E+00+2.44968E-03+0.00000E+00-7.46438E-04+0.00000E+00-3.50440E-03+0.00000E+00-5.10336E-03+0.00000E+00-5.19124E-03+0.00000E+00-3.85362E-03+0.00000E+00-1.55873E-03+0.00000E+00+9.97970E-04+0.00000E+00+3.09968E-03+0.00000E+00+4.20524E-03+0.00000E+00+4.08406E-03+0.00000E+00+2.85672E-03+0.00000E+00+9.36892E-04+0.00000E+00-1.10249E-03+0.00000E+00-2.69684E-03+0.00000E+00-3.44326E-03+0.00000E+00-3.19878E-03+0.00000E+00-2.10070E-03+0.00000E+00-5.08938E-04+0.00000E+00+1.10801E-03+0.00000E+00+2.30850E-03+0.00000E+00+2.79606E-03+0.00000E+00+2.48958E-03+0.00000E+00+1.52962E-03+0.00000E+00+2.24088E-04+0.00000E+00-1.04776E-03+0.00000E+00-1.94359E-03+0.00000E+00-2.24826E-03+0.00000E+00-1.92275E-03+0.00000E+00-1.10163E-03+0.00000E+00-4.36276E-05+0.00000E+00+9.47830E-04+0.00000E+00+1.61011E-03+0.00000E+00+1.78935E-03+0.00000E+00+1.47374E-03+0.00000E+00+7.85842E-04+0.00000E+00-6.09068E-05+0.00000E+00-8.26764E-04+0.00000E+00-1.31236E-03+0.00000E+00-1.40922E-03+0.00000E+00-1.12174E-03+0.00000E+00-5.57036E-04+0.00000E+00+1.11999E-04+0.00000E+00+6.98398E-04+0.00000E+00+1.05234E-03+0.00000E+00+1.09821E-03+0.00000E+00+8.48744E-04+0.00000E+00+3.94310E-04+0.00000E+00-1.27650E-04+0.00000E+00-5.73180E-04+0.00000E+00-8.30656E-04+0.00000E+00-8.47708E-04+0.00000E+00-6.40040E-04+0.00000E+00-2.81414E-04+0.00000E+00+1.20911E-04+0.00000E+00+4.57442E-04+0.00000E+00+6.45532E-04+0.00000E+00+6.48778E-04+0.00000E+00+4.82464E-04+0.00000E+00+2.04904E-04+0.00000E+00-1.01725E-04+0.00000E+00-3.55056E-04+0.00000E+00-4.94058E-04+0.00000E+00-4.92968E-04+0.00000E+00-3.64712E-04+0.00000E+00-1.53942E-04+0.00000E+00+7.75194E-05+0.00000E+00+2.68272E-04+0.00000E+00+3.73118E-04+0.00000E+00+3.73138E-04+0.00000E+00+2.78002E-04+0.00000E+00+1.20744E-04+0.00000E+00-5.29412E-05+0.00000E+00-1.97535E-04+0.00000E+00-2.79208E-04+0.00000E+00-2.83208E-04+0.00000E+00-2.15680E-04+0.00000E+00-1.00068E-04+0.00000E+00+3.04418E-05+0.00000E+00+1.42114E-04+0.00000E+00+2.09036E-04+0.00000E+00+2.18690E-04+0.00000E+00+1.73672E-04+0.00000E+00+8.95560E-05+0.00000E+00-1.01214E-05+0.00000E+00-1.00242E-04+0.00000E+00-1.60164E-04+0.00000E+00-1.78068E-04+0.00000E+00-1.52783E-04+0.00000E+00-9.29802E-05+0.00000E+00-1.42499E-05+0.00000E+00+6.50032E-05+0.00000E+00+1.27774E-04+0.00000E+00+1.61835E-04+0.00000E+00+1.61671E-04+0.00000E+00+1.28752E-04+0.00000E+00+7.03544E-05+0.00000E+00-2.59160E-06+0.00000E+00-7.80380E-05+0.00000E+00-1.45142E-04+0.00000E+00-1.95955E-04+0.00000E+00-2.26268E-04+0.00000E+00-2.35600E-04+0.00000E+00-2.26532E-04+0.00000E+00-2.03638E-04+0.00000E+00-1.72307E-04+0.00000E+00-1.37722E-04+0.00000E+00-1.04124E-04+0.00000E+00-7.44366E-05+0.00000E+00-5.02182E-05+0.00000E+00-3.18550E-05+0.00000E+00-1.88893E-05+0.00000E+00-1.03793E-05+0.00000E+00-5.21464E-06+0.00000E+00-2.34472E-06+0.00000E+00-9.08544E-07+0.00000E+00-2.80036E-07+0.00000E+00-5.32080E-08+0.00000E+00+4.52378E-09+0.00000E+00+7.72762E-09+0.00000E+0000000570051071.0000E+030000500000+1.5900E-01+1.5900E-01058003507+1.00000E+00+5.00000E-0200058003500+2.78845E+05+5.00000E-02000520127 HNE0000003~004002+49.129100+008.148700+0128.0000.0090.0+00.00001122.0000E+022.0000E-020000TG~2015,078,13:00:00.0000~~N0530382A01004003+1.00770E+18+1.00000E+00001-5.15000E+02+0.00000E+00+0.00000E+00+0.00000E+00006-9.77000E+02+3.28000E+02+0.00000E+00+0.00000E+00-9.77000E+02-3.28000E+02+0.00000E+00+0.00000E+00-1.48600E+03+2.51200E+03+0.00000E+00+0.00000E+00-1.48600E+03-2.51200E+03+0.00000E+00+0.00000E+00-5.73600E+03+4.94600E+03+0.00000E+00+0.00000E+00-5.73600E+03-4.94600E+03+0.00000E+00+0.00000E+00058003501+5.10000E-01+1.00000E+0000058003502+1.00000E+00+5.00000E-02000540048D030030040001+1.00000E+00+0.00000E+0000000570051031.9200E+050000100000+0.0000E+00+0.0000E+00058003503+4.00000E+05+5.00000E-02000541152D040040040047+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+3.81470E-06+0.00000E+00+2.28882E-05+0.00000E+00+8.01086E-05+0.00000E+00+2.13623E-04+0.00000E+00+4.80652E-04+0.00000E+00+9.61304E-04+0.00000E+00+1.76239E-03+0.00000E+00+3.02124E-03+0.00000E+00+4.88663E-03+0.00000E+00+7.49969E-03+0.00000E+00+1.09749E-02+000039S*0.00000E+00+1.53809E-02+0.00000E+00+2.07214E-02+0.00000E+00+2.69165E-02+0.00000E+00+3.37830E-02+0.00000E+00+4.10156E-02+0.00000E+00+4.82254E-02+0.00000E+00+5.49774E-02+0.00000E+00+6.08292E-02+0.00000E+00+6.53687E-02+0.00000E+00+6.82526E-02+0.00000E+00+6.92444E-02+0.00000E+00+6.82526E-02+0.00000E+00+6.53687E-02+0.00000E+00+6.08292E-02+0.00000E+00+5.49774E-02+0.00000E+00+4.82254E-02+0.00000E+00+4.10156E-02+0.00000E+00+3.37830E-02+0.00000E+00+2.69165E-02+0.00000E+00+2.07214E-02+0.00000E+00+1.53809E-02+0.00000E+00+1.09749E-02+0.00000E+00+7.49969E-03+0.00000E+00+4.88663E-03+0.00000E+00+3.02124E-03+0.00000E+00+1.76239E-03+0.00000E+00+9.61304E-04+0.00000E+00+4.80652E-04+0.00000E+00+2.13623E-04+0.00000E+00+8.01086E-05+0.00000E+00+2.28882E-05+0.00000E+00+3.81470E-06+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+0000000570051041.9200E+050000800000+1.1979E-04+1.1979E-04058003504+1.00000E+00+5.00000E-02000541776D050040040073+7.86395E-07+0.00000E+00+2.15223E-06+0.00000E+00+4.09013E-06+0.00000E+00+6.42053E-06+0.00000E+00+7.61300E-06+0.00000E+00+4.52134E-06+0.00000E+00-8.38839E-06+0.00000E+00-4.00745E-05+0.00000E+00-1.08702E-04+0.00000E+00-2.31570E-04+0.00000E+00-4.32673E-04+0.00000E+00-7.41861E-04+0.00000E+00-1.18635E-03+0.00000E+00-1.78887E-03+0.00000E+00-2.56156E-03+0.00000E+00-3.49756E-03+0.00000E+00-4.54784E-03+0.00000E+00-5.64473E-03+0.00000E+00-6.67437E-03+0.00000E+00-7.46932E-03+0.00000E+00-7.83206E-03+0.00000E+00-7.53472E-03+0.00000E+00-6.33480E-03+0.00000E+00-3.99943E-03+0.00000E+00-3.60688E-04+0.00000E+00+4.71408E-03+0.00000E+00+1.12572E-02+0.00000E+00+1.91611E-02+0.00000E+00+2.82115E-02+0.00000E+00+3.80655E-02+0.00000E+00+4.82646E-02+0.00000E+00+5.82654E-02+0.00000E+00+6.75164E-02+0.00000E+00+7.54318E-02+0.00000E+00+8.14859E-02+0.00000E+00+8.52972E-02+0.00000E+00+8.65986E-02+0.00000E+00+8.52972E-02+0.00000E+00+8.14859E-02+0.00000E+00+7.54318E-02+0.00000E+00+6.75164E-02+0.00000E+00+5.82654E-02+0.00000E+00+4.82646E-02+0.00000E+00+3.80655E-02+0.00000E+00+2.82115E-02+0.00000E+00+1.91611E-02+0.00000E+00+1.12572E-02+0.00000E+00+4.71408E-03+0.00000E+00-3.60688E-04+0.00000E+00-3.99943E-03+0.00000E+00-6.33480E-03+0.00000E+00-7.53472E-03+0.00000E+00-7.83206E-03+0.00000E+00-7.46932E-03+0.00000E+00-6.67437E-03+0.00000E+00-5.64473E-03+0.00000E+00-4.54784E-03+0.00000E+00-3.49756E-03+0.00000E+00-2.56156E-03+0.00000E+00-1.78887E-03+0.00000E+00-1.18635E-03+0.00000E+00-7.41861E-04+0.00000E+00-4.32673E-04+0.00000E+00-2.31570E-04+0.00000E+00-1.08702E-04+0.00000E+00-4.00745E-05+0.00000E+00-8.38839E-06+0.00000E+00+4.52134E-06+0.00000E+00+7.61300E-06+0.00000E+00+6.42053E-06+0.00000E+00+4.09013E-06+0.00000E+00+2.15223E-06+0.00000E+00+7.86395E-07+0.00000E+0000000570051052.4000E+040000800000+1.5000E-03+1.5000E-03058003505+1.00000E+00+5.00000E-02000544320D060040040179+1.65488E-07+0.00000E+00+7.48132E-07+0.00000E+00+1.76664E-06+0.00000E+00+1.62612E-06+0.00000E+00-5.16640E-06+0.00000E+00-3.00692E-05+0.00000E+00-8.97376E-05+0.00000E+00-1.99571E-04+0.00000E+00-3.61172E-04+0.00000E+00-5.48500E-04+0.00000E+00-7.02688E-04+0.00000E+00-7.45976E-04+0.00000E+00-6.17072E-04+0.00000E+00-3.15191E-04+0.00000E+00+7.38188E-05+0.00000E+00+3.95725E-04+0.00000E+00+4.96800E-04+0.00000E+00+3.15263E-04+0.00000E+00-5.96548E-05+0.00000E+00-4.11872E-04+0.00000E+00-5.12780E-04+0.00000E+00-2.69536E-04+0.00000E+00+1.89248E-04+0.00000E+00+5.66172E-04+0.00000E+00+5.78372E-04+0.00000E+00+1.64727E-04+0.00000E+00-4.31664E-04+0.00000E+00-7.92432E-04+0.00000E+00-6.08316E-04+0.00000E+00+6.76780E-05+0.00000E+00+7.98316E-04+0.00000E+00+1.03172E-03+0.00000E+00+5.07504E-04+0.00000E+00-4.91744E-04+0.00000E+00-1.26810E-03+0.00000E+00-1.18261E-03+0.00000E+00-1.64670E-04+0.00000E+00+1.13876E-03+0.00000E+00+1.75363E-03+0.00000E+00+1.09177E-03+0.00000E+00-5.24120E-04+0.00000E+00-1.97068E-03+0.00000E+00-2.08536E-03+0.00000E+00-5.79052E-04+0.00000E+00+1.60144E-03+0.00000E+00+2.83576E-03+0.00000E+00+2.01276E-03+0.00000E+00-5.13156E-04+0.00000E+00-2.98815E-03+0.00000E+00-3.44765E-03+0.00000E+00-1.24599E-03+0.00000E+00+2.24272E-03+0.00000E+00+4.43120E-03+0.00000E+00+3.40590E-03+0.00000040S*000E+00-4.57304E-04+0.00000E+00-4.47584E-03+0.00000E+00-5.47828E-03+0.00000E+00-2.26220E-03+0.00000E+00+3.18035E-03+0.00000E+00+6.81616E-03+0.00000E+00+5.50776E-03+0.00000E+00-3.65328E-04+0.00000E+00-6.73316E-03+0.00000E+00-8.58052E-03+0.00000E+00-3.81782E-03+0.00000E+00+4.65228E-03+0.00000E+00+1.05646E-02+0.00000E+00+8.82560E-03+0.00000E+00-2.56374E-04+0.00000E+00-1.04496E-02+0.00000E+00-1.37224E-02+0.00000E+00-6.39512E-03+0.00000E+00+7.26512E-03+0.00000E+00+1.72312E-02+0.00000E+00+1.48181E-02+0.00000E+00-1.54011E-04+0.00000E+00-1.77680E-02+0.00000E+00-2.41384E-02+0.00000E+00-1.17549E-02+0.00000E+00+1.32733E-02+0.00000E+00+3.32147E-02+0.00000E+00+3.01309E-02+0.00000E+00-8.13468E-05+0.00000E+00-4.08284E-02+0.00000E+00-6.13256E-02+0.00000E+00-3.42109E-02+0.00000E+00+4.58968E-02+0.00000E+00+1.54886E-01+0.00000E+00+2.48713E-01+0.00000E+00+2.85658E-01+0.00000E+00+2.48713E-01+0.00000E+00+1.54886E-01+0.00000E+00+4.58968E-02+0.00000E+00-3.42109E-02+0.00000E+00-6.13256E-02+0.00000E+00-4.08284E-02+0.00000E+00-8.13468E-05+0.00000E+00+3.01309E-02+0.00000E+00+3.32147E-02+0.00000E+00+1.32733E-02+0.00000E+00-1.17549E-02+0.00000E+00-2.41384E-02+0.00000E+00-1.77680E-02+0.00000E+00-1.54011E-04+0.00000E+00+1.48181E-02+0.00000E+00+1.72312E-02+0.00000E+00+7.26512E-03+0.00000E+00-6.39512E-03+0.00000E+00-1.37224E-02+0.00000E+00-1.04496E-02+0.00000E+00-2.56374E-04+0.00000E+00+8.82560E-03+0.00000E+00+1.05646E-02+0.00000E+00+4.65228E-03+0.00000E+00-3.81782E-03+0.00000E+00-8.58052E-03+0.00000E+00-6.73316E-03+0.00000E+00-3.65328E-04+0.00000E+00+5.50776E-03+0.00000E+00+6.81616E-03+0.00000E+00+3.18035E-03+0.00000E+00-2.26220E-03+0.00000E+00-5.47828E-03+0.00000E+00-4.47584E-03+0.00000E+00-4.57304E-04+0.00000E+00+3.40590E-03+0.00000E+00+4.43120E-03+0.00000E+00+2.24272E-03+0.00000E+00-1.24599E-03+0.00000E+00-3.44765E-03+0.00000E+00-2.98815E-03+0.00000E+00-5.13156E-04+0.00000E+00+2.01276E-03+0.00000E+00+2.83576E-03+0.00000E+00+1.60144E-03+0.00000E+00-5.79052E-04+0.00000E+00-2.08536E-03+0.00000E+00-1.97068E-03+0.00000E+00-5.24120E-04+0.00000E+00+1.09177E-03+0.00000E+00+1.75363E-03+0.00000E+00+1.13876E-03+0.00000E+00-1.64670E-04+0.00000E+00-1.18261E-03+0.00000E+00-1.26810E-03+0.00000E+00-4.91744E-04+0.00000E+00+5.07504E-04+0.00000E+00+1.03172E-03+0.00000E+00+7.98316E-04+0.00000E+00+6.76780E-05+0.00000E+00-6.08316E-04+0.00000E+00-7.92432E-04+0.00000E+00-4.31664E-04+0.00000E+00+1.64727E-04+0.00000E+00+5.78372E-04+0.00000E+00+5.66172E-04+0.00000E+00+1.89248E-04+0.00000E+00-2.69536E-04+0.00000E+00-5.12780E-04+0.00000E+00-4.11872E-04+0.00000E+00-5.96548E-05+0.00000E+00+3.15263E-04+0.00000E+00+4.96800E-04+0.00000E+00+3.95725E-04+0.00000E+00+7.38188E-05+0.00000E+00-3.15191E-04+0.00000E+00-6.17072E-04+0.00000E+00-7.45976E-04+0.00000E+00-7.02688E-04+0.00000E+00-5.48500E-04+0.00000E+00-3.61172E-04+0.00000E+00-1.99571E-04+0.00000E+00-8.97376E-05+0.00000E+00-3.00692E-05+0.00000E+00-5.16640E-06+0.00000E+00+1.62612E-06+0.00000E+00+1.76664E-06+0.00000E+00+7.48132E-07+0.00000E+00+1.65488E-07+0.00000E+0000000570051063.0000E+030000300000+2.9667E-02+2.9667E-02058003506+1.00000E+00+5.00000E-02000547680D070040040319+7.72762E-09+0.00000E+00+4.52378E-09+0.00000E+00-5.32080E-08+0.00000E+00-2.80036E-07+0.00000E+00-9.08544E-07+0.00000E+00-2.34472E-06+0.00000E+00-5.21464E-06+0.00000E+00-1.03793E-05+0.00000E+00-1.88893E-05+0.00000E+00-3.18550E-05+0.00000E+00-5.02182E-05+0.00000E+00-7.44366E-05+0.00000E+00-1.04124E-04+0.00000E+00-1.37722E-04+0.00000E+00-1.72307E-04+0.00000E+00-2.03638E-04+0.00000E+00-2.26532E-04+0.00000E+00-2.35600E-04+0.00000E+00-2.26268E-04+0.00000E+00-1.95955E-04+0.00000E+00-1.45142E-04+0.00000E+00-7.80380E-05+0.00000E+00-2.59160E-06+0.00000E+00+7.03544E-05+0.00000E+00+1.28752E-04+0.00000E+00+1.61671E-04+0.00000E+00+1.61835E-04+0.00000E+00+1.27774E-04+0.00000E+00+6.50032E-05+0.00000E+00-1.42499E-05+0.00000E+00-9.29802E-05+0.00000E+00-1.52783E-04+0.00000E+00-1.78068E-04+0.00000E+00-1.60164E-04+0.00000E+00-1.00242E-04+0.00000E+00-1.01214E-05+0.00000E+00+8.95560E-05+0.00000E+00+1.73672E-04+0.00000E+00+2.18690E-04+0.00000E+00+2.09036E-04+0.00000E+00+1.42114E-0000041S*4+0.00000E+00+3.04418E-05+0.00000E+00-1.00068E-04+0.00000E+00-2.15680E-04+0.00000E+00-2.83208E-04+0.00000E+00-2.79208E-04+0.00000E+00-1.97535E-04+0.00000E+00-5.29412E-05+0.00000E+00+1.20744E-04+0.00000E+00+2.78002E-04+0.00000E+00+3.73138E-04+0.00000E+00+3.73118E-04+0.00000E+00+2.68272E-04+0.00000E+00+7.75194E-05+0.00000E+00-1.53942E-04+0.00000E+00-3.64712E-04+0.00000E+00-4.92968E-04+0.00000E+00-4.94058E-04+0.00000E+00-3.55056E-04+0.00000E+00-1.01725E-04+0.00000E+00+2.04904E-04+0.00000E+00+4.82464E-04+0.00000E+00+6.48778E-04+0.00000E+00+6.45532E-04+0.00000E+00+4.57442E-04+0.00000E+00+1.20911E-04+0.00000E+00-2.81414E-04+0.00000E+00-6.40040E-04+0.00000E+00-8.47708E-04+0.00000E+00-8.30656E-04+0.00000E+00-5.73180E-04+0.00000E+00-1.27650E-04+0.00000E+00+3.94310E-04+0.00000E+00+8.48744E-04+0.00000E+00+1.09821E-03+0.00000E+00+1.05234E-03+0.00000E+00+6.98398E-04+0.00000E+00+1.11999E-04+0.00000E+00-5.57036E-04+0.00000E+00-1.12174E-03+0.00000E+00-1.40922E-03+0.00000E+00-1.31236E-03+0.00000E+00-8.26764E-04+0.00000E+00-6.09068E-05+0.00000E+00+7.85842E-04+0.00000E+00+1.47374E-03+0.00000E+00+1.78935E-03+0.00000E+00+1.61011E-03+0.00000E+00+9.47830E-04+0.00000E+00-4.36276E-05+0.00000E+00-1.10163E-03+0.00000E+00-1.92275E-03+0.00000E+00-2.24826E-03+0.00000E+00-1.94359E-03+0.00000E+00-1.04776E-03+0.00000E+00+2.24088E-04+0.00000E+00+1.52962E-03+0.00000E+00+2.48958E-03+0.00000E+00+2.79606E-03+0.00000E+00+2.30850E-03+0.00000E+00+1.10801E-03+0.00000E+00-5.08938E-04+0.00000E+00-2.10070E-03+0.00000E+00-3.19878E-03+0.00000E+00-3.44326E-03+0.00000E+00-2.69684E-03+0.00000E+00-1.10249E-03+0.00000E+00+9.36892E-04+0.00000E+00+2.85672E-03+0.00000E+00+4.08406E-03+0.00000E+00+4.20524E-03+0.00000E+00+3.09968E-03+0.00000E+00+9.97970E-04+0.00000E+00-1.55873E-03+0.00000E+00-3.85362E-03+0.00000E+00-5.19124E-03+0.00000E+00-5.10336E-03+0.00000E+00-3.50440E-03+0.00000E+00-7.46438E-04+0.00000E+00+2.44968E-03+0.00000E+00+5.17690E-03+0.00000E+00+6.59364E-03+0.00000E+00+6.17604E-03+0.00000E+00+3.89756E-03+0.00000E+00+2.77256E-04+0.00000E+00-3.72784E-03+0.00000E+00-6.96714E-03+0.00000E+00-8.41784E-03+0.00000E+00-7.49572E-03+0.00000E+00-4.26426E-03+0.00000E+00+5.27466E-04+0.00000E+00+5.60328E-03+0.00000E+00+9.48592E-03+0.00000E+00+1.09107E-02+0.00000E+00+9.21506E-03+0.00000E+00+4.58962E-03+0.00000E+00-1.89363E-03+0.00000E+00-8.50506E-03+0.00000E+00-1.32925E-02+0.00000E+00-1.46243E-02+0.00000E+00-1.16967E-02+0.00000E+00-4.85962E-03+0.00000E+00+4.34870E-03+0.00000E+00+1.34983E-02+0.00000E+00+1.98472E-02+0.00000E+00+2.10770E-02+0.00000E+00+1.60019E-02+0.00000E+00+5.06204E-03+0.00000E+00-9.55078E-03+0.00000E+00-2.42030E-02+0.00000E+00-3.45266E-02+0.00000E+00-3.63864E-02+0.00000E+00-2.68872E-02+0.00000E+00-5.18748E-03+0.00000E+00+2.70918E-02+0.00000E+00+6.59838E-02+0.00000E+00+1.05820E-01+0.00000E+00+1.40281E-01+0.00000E+00+1.63636E-01+0.00000E+00+1.71897E-01+0.00000E+00+1.63636E-01+0.00000E+00+1.40281E-01+0.00000E+00+1.05820E-01+0.00000E+00+6.59838E-02+0.00000E+00+2.70918E-02+0.00000E+00-5.18748E-03+0.00000E+00-2.68872E-02+0.00000E+00-3.63864E-02+0.00000E+00-3.45266E-02+0.00000E+00-2.42030E-02+0.00000E+00-9.55078E-03+0.00000E+00+5.06204E-03+0.00000E+00+1.60019E-02+0.00000E+00+2.10770E-02+0.00000E+00+1.98472E-02+0.00000E+00+1.34983E-02+0.00000E+00+4.34870E-03+0.00000E+00-4.85962E-03+0.00000E+00-1.16967E-02+0.00000E+00-1.46243E-02+0.00000E+00-1.32925E-02+0.00000E+00-8.50506E-03+0.00000E+00-1.89363E-03+0.00000E+00+4.58962E-03+0.00000E+00+9.21506E-03+0.00000E+00+1.09107E-02+0.00000E+00+9.48592E-03+0.00000E+00+5.60328E-03+0.00000E+00+5.27466E-04+0.00000E+00-4.26426E-03+0.00000E+00-7.49572E-03+0.00000E+00-8.41784E-03+0.00000E+00-6.96714E-03+0.00000E+00-3.72784E-03+0.00000E+00+2.77256E-04+0.00000E+00+3.89756E-03+0.00000E+00+6.17604E-03+0.00000E+00+6.59364E-03+0.00000E+00+5.17690E-03+0.00000E+00+2.44968E-03+0.00000E+00-7.46438E-04+0.00000E+00-3.50440E-03+0.00000E+00-5.10336E-03+0.00000E+00-5.19124E-03+0.00000E+00-3.85362E-03+0.00000E+00-1.55873E-03+0.00000E+00+9.97970E-04+0.00000E+00+3.09968E-03+0.00000E+00+4.20524E-03+0.00000E+00+4.08406E-03+0.00000E+00+2.85672E-03+0.0000000042S*0E+00+9.36892E-04+0.00000E+00-1.10249E-03+0.00000E+00-2.69684E-03+0.00000E+00-3.44326E-03+0.00000E+00-3.19878E-03+0.00000E+00-2.10070E-03+0.00000E+00-5.08938E-04+0.00000E+00+1.10801E-03+0.00000E+00+2.30850E-03+0.00000E+00+2.79606E-03+0.00000E+00+2.48958E-03+0.00000E+00+1.52962E-03+0.00000E+00+2.24088E-04+0.00000E+00-1.04776E-03+0.00000E+00-1.94359E-03+0.00000E+00-2.24826E-03+0.00000E+00-1.92275E-03+0.00000E+00-1.10163E-03+0.00000E+00-4.36276E-05+0.00000E+00+9.47830E-04+0.00000E+00+1.61011E-03+0.00000E+00+1.78935E-03+0.00000E+00+1.47374E-03+0.00000E+00+7.85842E-04+0.00000E+00-6.09068E-05+0.00000E+00-8.26764E-04+0.00000E+00-1.31236E-03+0.00000E+00-1.40922E-03+0.00000E+00-1.12174E-03+0.00000E+00-5.57036E-04+0.00000E+00+1.11999E-04+0.00000E+00+6.98398E-04+0.00000E+00+1.05234E-03+0.00000E+00+1.09821E-03+0.00000E+00+8.48744E-04+0.00000E+00+3.94310E-04+0.00000E+00-1.27650E-04+0.00000E+00-5.73180E-04+0.00000E+00-8.30656E-04+0.00000E+00-8.47708E-04+0.00000E+00-6.40040E-04+0.00000E+00-2.81414E-04+0.00000E+00+1.20911E-04+0.00000E+00+4.57442E-04+0.00000E+00+6.45532E-04+0.00000E+00+6.48778E-04+0.00000E+00+4.82464E-04+0.00000E+00+2.04904E-04+0.00000E+00-1.01725E-04+0.00000E+00-3.55056E-04+0.00000E+00-4.94058E-04+0.00000E+00-4.92968E-04+0.00000E+00-3.64712E-04+0.00000E+00-1.53942E-04+0.00000E+00+7.75194E-05+0.00000E+00+2.68272E-04+0.00000E+00+3.73118E-04+0.00000E+00+3.73138E-04+0.00000E+00+2.78002E-04+0.00000E+00+1.20744E-04+0.00000E+00-5.29412E-05+0.00000E+00-1.97535E-04+0.00000E+00-2.79208E-04+0.00000E+00-2.83208E-04+0.00000E+00-2.15680E-04+0.00000E+00-1.00068E-04+0.00000E+00+3.04418E-05+0.00000E+00+1.42114E-04+0.00000E+00+2.09036E-04+0.00000E+00+2.18690E-04+0.00000E+00+1.73672E-04+0.00000E+00+8.95560E-05+0.00000E+00-1.01214E-05+0.00000E+00-1.00242E-04+0.00000E+00-1.60164E-04+0.00000E+00-1.78068E-04+0.00000E+00-1.52783E-04+0.00000E+00-9.29802E-05+0.00000E+00-1.42499E-05+0.00000E+00+6.50032E-05+0.00000E+00+1.27774E-04+0.00000E+00+1.61835E-04+0.00000E+00+1.61671E-04+0.00000E+00+1.28752E-04+0.00000E+00+7.03544E-05+0.00000E+00-2.59160E-06+0.00000E+00-7.80380E-05+0.00000E+00-1.45142E-04+0.00000E+00-1.95955E-04+0.00000E+00-2.26268E-04+0.00000E+00-2.35600E-04+0.00000E+00-2.26532E-04+0.00000E+00-2.03638E-04+0.00000E+00-1.72307E-04+0.00000E+00-1.37722E-04+0.00000E+00-1.04124E-04+0.00000E+00-7.44366E-05+0.00000E+00-5.02182E-05+0.00000E+00-3.18550E-05+0.00000E+00-1.88893E-05+0.00000E+00-1.03793E-05+0.00000E+00-5.21464E-06+0.00000E+00-2.34472E-06+0.00000E+00-9.08544E-07+0.00000E+00-2.80036E-07+0.00000E+00-5.32080E-08+0.00000E+00+4.52378E-09+0.00000E+00+7.72762E-09+0.00000E+0000000570051071.0000E+030000500000+1.5900E-01+1.5900E-01058003507+1.00000E+00+5.00000E-0200058003500+2.03990E+05+5.00000E-02000520127 HNN0000003~004002+49.129100+008.148700+0128.0000.0000.0+00.00001122.0000E+022.0000E-020000TG~2015,078,13:00:00.0000~~N0530382A01004003+1.00770E+18+1.00000E+00001-5.15000E+02+0.00000E+00+0.00000E+00+0.00000E+00006-9.77000E+02+3.28000E+02+0.00000E+00+0.00000E+00-9.77000E+02-3.28000E+02+0.00000E+00+0.00000E+00-1.48600E+03+2.51200E+03+0.00000E+00+0.00000E+00-1.48600E+03-2.51200E+03+0.00000E+00+0.00000E+00-5.73600E+03+4.94600E+03+0.00000E+00+0.00000E+00-5.73600E+03-4.94600E+03+0.00000E+00+0.00000E+00058003501+5.10000E-01+1.00000E+0000058003502+1.00000E+00+5.00000E-02000540048D030030040001+1.00000E+00+0.00000E+0000000570051031.9200E+050000100000+0.0000E+00+0.0000E+00058003503+4.00000E+05+5.00000E-02000541152D040040040047+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+3.81470E-06+0.00000E+00+2.28882E-05+0.00000E+00+8.01086E-05+0.00000E+00+2.13623E-04+0.00000E+00+4.80652E-04+0.00000E+00+9.61304E-04+0.00000E+00+1.76239E-03+0.00000E+00+3.02124E-03+0.00000E+00+4.88663E-03+0.00000E+00+7.49969E-03+0.00000E+00+1.09749E-02+0.00000E+00+1.53809E-02+0.00000E+00+2.07214E-02+0.00000E+00+2.69165E-02+0.00000E+00+3.37830E-02+0.00000E+00+4.10156E-02+0.00000E+00+4.82254E-02+0.00000E+00+5.49774E-02+0.00000E+00+6.08292E-02+0.00000E+00+6.53687E-02+0.00000E+00+6.82526E-02+0.00000E+00+6.92444E-02+0.00000E+00+6.82526E-02+0.00000E+00+6.53687E-02+0.00000E+00+6.08292E000043S*-02+0.00000E+00+5.49774E-02+0.00000E+00+4.82254E-02+0.00000E+00+4.10156E-02+0.00000E+00+3.37830E-02+0.00000E+00+2.69165E-02+0.00000E+00+2.07214E-02+0.00000E+00+1.53809E-02+0.00000E+00+1.09749E-02+0.00000E+00+7.49969E-03+0.00000E+00+4.88663E-03+0.00000E+00+3.02124E-03+0.00000E+00+1.76239E-03+0.00000E+00+9.61304E-04+0.00000E+00+4.80652E-04+0.00000E+00+2.13623E-04+0.00000E+00+8.01086E-05+0.00000E+00+2.28882E-05+0.00000E+00+3.81470E-06+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+0000000570051041.9200E+050000800000+1.1979E-04+1.1979E-04058003504+1.00000E+00+5.00000E-02000541776D050040040073+7.86395E-07+0.00000E+00+2.15223E-06+0.00000E+00+4.09013E-06+0.00000E+00+6.42053E-06+0.00000E+00+7.61300E-06+0.00000E+00+4.52134E-06+0.00000E+00-8.38839E-06+0.00000E+00-4.00745E-05+0.00000E+00-1.08702E-04+0.00000E+00-2.31570E-04+0.00000E+00-4.32673E-04+0.00000E+00-7.41861E-04+0.00000E+00-1.18635E-03+0.00000E+00-1.78887E-03+0.00000E+00-2.56156E-03+0.00000E+00-3.49756E-03+0.00000E+00-4.54784E-03+0.00000E+00-5.64473E-03+0.00000E+00-6.67437E-03+0.00000E+00-7.46932E-03+0.00000E+00-7.83206E-03+0.00000E+00-7.53472E-03+0.00000E+00-6.33480E-03+0.00000E+00-3.99943E-03+0.00000E+00-3.60688E-04+0.00000E+00+4.71408E-03+0.00000E+00+1.12572E-02+0.00000E+00+1.91611E-02+0.00000E+00+2.82115E-02+0.00000E+00+3.80655E-02+0.00000E+00+4.82646E-02+0.00000E+00+5.82654E-02+0.00000E+00+6.75164E-02+0.00000E+00+7.54318E-02+0.00000E+00+8.14859E-02+0.00000E+00+8.52972E-02+0.00000E+00+8.65986E-02+0.00000E+00+8.52972E-02+0.00000E+00+8.14859E-02+0.00000E+00+7.54318E-02+0.00000E+00+6.75164E-02+0.00000E+00+5.82654E-02+0.00000E+00+4.82646E-02+0.00000E+00+3.80655E-02+0.00000E+00+2.82115E-02+0.00000E+00+1.91611E-02+0.00000E+00+1.12572E-02+0.00000E+00+4.71408E-03+0.00000E+00-3.60688E-04+0.00000E+00-3.99943E-03+0.00000E+00-6.33480E-03+0.00000E+00-7.53472E-03+0.00000E+00-7.83206E-03+0.00000E+00-7.46932E-03+0.00000E+00-6.67437E-03+0.00000E+00-5.64473E-03+0.00000E+00-4.54784E-03+0.00000E+00-3.49756E-03+0.00000E+00-2.56156E-03+0.00000E+00-1.78887E-03+0.00000E+00-1.18635E-03+0.00000E+00-7.41861E-04+0.00000E+00-4.32673E-04+0.00000E+00-2.31570E-04+0.00000E+00-1.08702E-04+0.00000E+00-4.00745E-05+0.00000E+00-8.38839E-06+0.00000E+00+4.52134E-06+0.00000E+00+7.61300E-06+0.00000E+00+6.42053E-06+0.00000E+00+4.09013E-06+0.00000E+00+2.15223E-06+0.00000E+00+7.86395E-07+0.00000E+0000000570051052.4000E+040000800000+1.5000E-03+1.5000E-03058003505+1.00000E+00+5.00000E-02000544320D060040040179+1.65488E-07+0.00000E+00+7.48132E-07+0.00000E+00+1.76664E-06+0.00000E+00+1.62612E-06+0.00000E+00-5.16640E-06+0.00000E+00-3.00692E-05+0.00000E+00-8.97376E-05+0.00000E+00-1.99571E-04+0.00000E+00-3.61172E-04+0.00000E+00-5.48500E-04+0.00000E+00-7.02688E-04+0.00000E+00-7.45976E-04+0.00000E+00-6.17072E-04+0.00000E+00-3.15191E-04+0.00000E+00+7.38188E-05+0.00000E+00+3.95725E-04+0.00000E+00+4.96800E-04+0.00000E+00+3.15263E-04+0.00000E+00-5.96548E-05+0.00000E+00-4.11872E-04+0.00000E+00-5.12780E-04+0.00000E+00-2.69536E-04+0.00000E+00+1.89248E-04+0.00000E+00+5.66172E-04+0.00000E+00+5.78372E-04+0.00000E+00+1.64727E-04+0.00000E+00-4.31664E-04+0.00000E+00-7.92432E-04+0.00000E+00-6.08316E-04+0.00000E+00+6.76780E-05+0.00000E+00+7.98316E-04+0.00000E+00+1.03172E-03+0.00000E+00+5.07504E-04+0.00000E+00-4.91744E-04+0.00000E+00-1.26810E-03+0.00000E+00-1.18261E-03+0.00000E+00-1.64670E-04+0.00000E+00+1.13876E-03+0.00000E+00+1.75363E-03+0.00000E+00+1.09177E-03+0.00000E+00-5.24120E-04+0.00000E+00-1.97068E-03+0.00000E+00-2.08536E-03+0.00000E+00-5.79052E-04+0.00000E+00+1.60144E-03+0.00000E+00+2.83576E-03+0.00000E+00+2.01276E-03+0.00000E+00-5.13156E-04+0.00000E+00-2.98815E-03+0.00000E+00-3.44765E-03+0.00000E+00-1.24599E-03+0.00000E+00+2.24272E-03+0.00000E+00+4.43120E-03+0.00000E+00+3.40590E-03+0.00000E+00-4.57304E-04+0.00000E+00-4.47584E-03+0.00000E+00-5.47828E-03+0.00000E+00-2.26220E-03+0.00000E+00+3.18035E-03+0.00000E+00+6.81616E-03+0.00000E+00+5.50776E-03+0.00000E+00-3.65328E-04+0.00000E+00-6.73316E-03+0.00000E+00-8.58052E-03+0.00000E+00-3.81782E-03+0.00000E+00+4.65228E-03+0.00000E+00+1.05646E-02+0.00000E+00+8.82560E-03+000044S*0.00000E+00-2.56374E-04+0.00000E+00-1.04496E-02+0.00000E+00-1.37224E-02+0.00000E+00-6.39512E-03+0.00000E+00+7.26512E-03+0.00000E+00+1.72312E-02+0.00000E+00+1.48181E-02+0.00000E+00-1.54011E-04+0.00000E+00-1.77680E-02+0.00000E+00-2.41384E-02+0.00000E+00-1.17549E-02+0.00000E+00+1.32733E-02+0.00000E+00+3.32147E-02+0.00000E+00+3.01309E-02+0.00000E+00-8.13468E-05+0.00000E+00-4.08284E-02+0.00000E+00-6.13256E-02+0.00000E+00-3.42109E-02+0.00000E+00+4.58968E-02+0.00000E+00+1.54886E-01+0.00000E+00+2.48713E-01+0.00000E+00+2.85658E-01+0.00000E+00+2.48713E-01+0.00000E+00+1.54886E-01+0.00000E+00+4.58968E-02+0.00000E+00-3.42109E-02+0.00000E+00-6.13256E-02+0.00000E+00-4.08284E-02+0.00000E+00-8.13468E-05+0.00000E+00+3.01309E-02+0.00000E+00+3.32147E-02+0.00000E+00+1.32733E-02+0.00000E+00-1.17549E-02+0.00000E+00-2.41384E-02+0.00000E+00-1.77680E-02+0.00000E+00-1.54011E-04+0.00000E+00+1.48181E-02+0.00000E+00+1.72312E-02+0.00000E+00+7.26512E-03+0.00000E+00-6.39512E-03+0.00000E+00-1.37224E-02+0.00000E+00-1.04496E-02+0.00000E+00-2.56374E-04+0.00000E+00+8.82560E-03+0.00000E+00+1.05646E-02+0.00000E+00+4.65228E-03+0.00000E+00-3.81782E-03+0.00000E+00-8.58052E-03+0.00000E+00-6.73316E-03+0.00000E+00-3.65328E-04+0.00000E+00+5.50776E-03+0.00000E+00+6.81616E-03+0.00000E+00+3.18035E-03+0.00000E+00-2.26220E-03+0.00000E+00-5.47828E-03+0.00000E+00-4.47584E-03+0.00000E+00-4.57304E-04+0.00000E+00+3.40590E-03+0.00000E+00+4.43120E-03+0.00000E+00+2.24272E-03+0.00000E+00-1.24599E-03+0.00000E+00-3.44765E-03+0.00000E+00-2.98815E-03+0.00000E+00-5.13156E-04+0.00000E+00+2.01276E-03+0.00000E+00+2.83576E-03+0.00000E+00+1.60144E-03+0.00000E+00-5.79052E-04+0.00000E+00-2.08536E-03+0.00000E+00-1.97068E-03+0.00000E+00-5.24120E-04+0.00000E+00+1.09177E-03+0.00000E+00+1.75363E-03+0.00000E+00+1.13876E-03+0.00000E+00-1.64670E-04+0.00000E+00-1.18261E-03+0.00000E+00-1.26810E-03+0.00000E+00-4.91744E-04+0.00000E+00+5.07504E-04+0.00000E+00+1.03172E-03+0.00000E+00+7.98316E-04+0.00000E+00+6.76780E-05+0.00000E+00-6.08316E-04+0.00000E+00-7.92432E-04+0.00000E+00-4.31664E-04+0.00000E+00+1.64727E-04+0.00000E+00+5.78372E-04+0.00000E+00+5.66172E-04+0.00000E+00+1.89248E-04+0.00000E+00-2.69536E-04+0.00000E+00-5.12780E-04+0.00000E+00-4.11872E-04+0.00000E+00-5.96548E-05+0.00000E+00+3.15263E-04+0.00000E+00+4.96800E-04+0.00000E+00+3.95725E-04+0.00000E+00+7.38188E-05+0.00000E+00-3.15191E-04+0.00000E+00-6.17072E-04+0.00000E+00-7.45976E-04+0.00000E+00-7.02688E-04+0.00000E+00-5.48500E-04+0.00000E+00-3.61172E-04+0.00000E+00-1.99571E-04+0.00000E+00-8.97376E-05+0.00000E+00-3.00692E-05+0.00000E+00-5.16640E-06+0.00000E+00+1.62612E-06+0.00000E+00+1.76664E-06+0.00000E+00+7.48132E-07+0.00000E+00+1.65488E-07+0.00000E+0000000570051063.0000E+030000300000+2.9667E-02+2.9667E-02058003506+1.00000E+00+5.00000E-02000547680D070040040319+7.72762E-09+0.00000E+00+4.52378E-09+0.00000E+00-5.32080E-08+0.00000E+00-2.80036E-07+0.00000E+00-9.08544E-07+0.00000E+00-2.34472E-06+0.00000E+00-5.21464E-06+0.00000E+00-1.03793E-05+0.00000E+00-1.88893E-05+0.00000E+00-3.18550E-05+0.00000E+00-5.02182E-05+0.00000E+00-7.44366E-05+0.00000E+00-1.04124E-04+0.00000E+00-1.37722E-04+0.00000E+00-1.72307E-04+0.00000E+00-2.03638E-04+0.00000E+00-2.26532E-04+0.00000E+00-2.35600E-04+0.00000E+00-2.26268E-04+0.00000E+00-1.95955E-04+0.00000E+00-1.45142E-04+0.00000E+00-7.80380E-05+0.00000E+00-2.59160E-06+0.00000E+00+7.03544E-05+0.00000E+00+1.28752E-04+0.00000E+00+1.61671E-04+0.00000E+00+1.61835E-04+0.00000E+00+1.27774E-04+0.00000E+00+6.50032E-05+0.00000E+00-1.42499E-05+0.00000E+00-9.29802E-05+0.00000E+00-1.52783E-04+0.00000E+00-1.78068E-04+0.00000E+00-1.60164E-04+0.00000E+00-1.00242E-04+0.00000E+00-1.01214E-05+0.00000E+00+8.95560E-05+0.00000E+00+1.73672E-04+0.00000E+00+2.18690E-04+0.00000E+00+2.09036E-04+0.00000E+00+1.42114E-04+0.00000E+00+3.04418E-05+0.00000E+00-1.00068E-04+0.00000E+00-2.15680E-04+0.00000E+00-2.83208E-04+0.00000E+00-2.79208E-04+0.00000E+00-1.97535E-04+0.00000E+00-5.29412E-05+0.00000E+00+1.20744E-04+0.00000E+00+2.78002E-04+0.00000E+00+3.73138E-04+0.00000E+00+3.73118E-04+0.00000E+00+2.68272E-04+0.00000E+00+7.75194E-05+0.00000E+00-1.5394000045S*2E-04+0.00000E+00-3.64712E-04+0.00000E+00-4.92968E-04+0.00000E+00-4.94058E-04+0.00000E+00-3.55056E-04+0.00000E+00-1.01725E-04+0.00000E+00+2.04904E-04+0.00000E+00+4.82464E-04+0.00000E+00+6.48778E-04+0.00000E+00+6.45532E-04+0.00000E+00+4.57442E-04+0.00000E+00+1.20911E-04+0.00000E+00-2.81414E-04+0.00000E+00-6.40040E-04+0.00000E+00-8.47708E-04+0.00000E+00-8.30656E-04+0.00000E+00-5.73180E-04+0.00000E+00-1.27650E-04+0.00000E+00+3.94310E-04+0.00000E+00+8.48744E-04+0.00000E+00+1.09821E-03+0.00000E+00+1.05234E-03+0.00000E+00+6.98398E-04+0.00000E+00+1.11999E-04+0.00000E+00-5.57036E-04+0.00000E+00-1.12174E-03+0.00000E+00-1.40922E-03+0.00000E+00-1.31236E-03+0.00000E+00-8.26764E-04+0.00000E+00-6.09068E-05+0.00000E+00+7.85842E-04+0.00000E+00+1.47374E-03+0.00000E+00+1.78935E-03+0.00000E+00+1.61011E-03+0.00000E+00+9.47830E-04+0.00000E+00-4.36276E-05+0.00000E+00-1.10163E-03+0.00000E+00-1.92275E-03+0.00000E+00-2.24826E-03+0.00000E+00-1.94359E-03+0.00000E+00-1.04776E-03+0.00000E+00+2.24088E-04+0.00000E+00+1.52962E-03+0.00000E+00+2.48958E-03+0.00000E+00+2.79606E-03+0.00000E+00+2.30850E-03+0.00000E+00+1.10801E-03+0.00000E+00-5.08938E-04+0.00000E+00-2.10070E-03+0.00000E+00-3.19878E-03+0.00000E+00-3.44326E-03+0.00000E+00-2.69684E-03+0.00000E+00-1.10249E-03+0.00000E+00+9.36892E-04+0.00000E+00+2.85672E-03+0.00000E+00+4.08406E-03+0.00000E+00+4.20524E-03+0.00000E+00+3.09968E-03+0.00000E+00+9.97970E-04+0.00000E+00-1.55873E-03+0.00000E+00-3.85362E-03+0.00000E+00-5.19124E-03+0.00000E+00-5.10336E-03+0.00000E+00-3.50440E-03+0.00000E+00-7.46438E-04+0.00000E+00+2.44968E-03+0.00000E+00+5.17690E-03+0.00000E+00+6.59364E-03+0.00000E+00+6.17604E-03+0.00000E+00+3.89756E-03+0.00000E+00+2.77256E-04+0.00000E+00-3.72784E-03+0.00000E+00-6.96714E-03+0.00000E+00-8.41784E-03+0.00000E+00-7.49572E-03+0.00000E+00-4.26426E-03+0.00000E+00+5.27466E-04+0.00000E+00+5.60328E-03+0.00000E+00+9.48592E-03+0.00000E+00+1.09107E-02+0.00000E+00+9.21506E-03+0.00000E+00+4.58962E-03+0.00000E+00-1.89363E-03+0.00000E+00-8.50506E-03+0.00000E+00-1.32925E-02+0.00000E+00-1.46243E-02+0.00000E+00-1.16967E-02+0.00000E+00-4.85962E-03+0.00000E+00+4.34870E-03+0.00000E+00+1.34983E-02+0.00000E+00+1.98472E-02+0.00000E+00+2.10770E-02+0.00000E+00+1.60019E-02+0.00000E+00+5.06204E-03+0.00000E+00-9.55078E-03+0.00000E+00-2.42030E-02+0.00000E+00-3.45266E-02+0.00000E+00-3.63864E-02+0.00000E+00-2.68872E-02+0.00000E+00-5.18748E-03+0.00000E+00+2.70918E-02+0.00000E+00+6.59838E-02+0.00000E+00+1.05820E-01+0.00000E+00+1.40281E-01+0.00000E+00+1.63636E-01+0.00000E+00+1.71897E-01+0.00000E+00+1.63636E-01+0.00000E+00+1.40281E-01+0.00000E+00+1.05820E-01+0.00000E+00+6.59838E-02+0.00000E+00+2.70918E-02+0.00000E+00-5.18748E-03+0.00000E+00-2.68872E-02+0.00000E+00-3.63864E-02+0.00000E+00-3.45266E-02+0.00000E+00-2.42030E-02+0.00000E+00-9.55078E-03+0.00000E+00+5.06204E-03+0.00000E+00+1.60019E-02+0.00000E+00+2.10770E-02+0.00000E+00+1.98472E-02+0.00000E+00+1.34983E-02+0.00000E+00+4.34870E-03+0.00000E+00-4.85962E-03+0.00000E+00-1.16967E-02+0.00000E+00-1.46243E-02+0.00000E+00-1.32925E-02+0.00000E+00-8.50506E-03+0.00000E+00-1.89363E-03+0.00000E+00+4.58962E-03+0.00000E+00+9.21506E-03+0.00000E+00+1.09107E-02+0.00000E+00+9.48592E-03+0.00000E+00+5.60328E-03+0.00000E+00+5.27466E-04+0.00000E+00-4.26426E-03+0.00000E+00-7.49572E-03+0.00000E+00-8.41784E-03+0.00000E+00-6.96714E-03+0.00000E+00-3.72784E-03+0.00000E+00+2.77256E-04+0.00000E+00+3.89756E-03+0.00000E+00+6.17604E-03+0.00000E+00+6.59364E-03+0.00000E+00+5.17690E-03+0.00000E+00+2.44968E-03+0.00000E+00-7.46438E-04+0.00000E+00-3.50440E-03+0.00000E+00-5.10336E-03+0.00000E+00-5.19124E-03+0.00000E+00-3.85362E-03+0.00000E+00-1.55873E-03+0.00000E+00+9.97970E-04+0.00000E+00+3.09968E-03+0.00000E+00+4.20524E-03+0.00000E+00+4.08406E-03+0.00000E+00+2.85672E-03+0.00000E+00+9.36892E-04+0.00000E+00-1.10249E-03+0.00000E+00-2.69684E-03+0.00000E+00-3.44326E-03+0.00000E+00-3.19878E-03+0.00000E+00-2.10070E-03+0.00000E+00-5.08938E-04+0.00000E+00+1.10801E-03+0.00000E+00+2.30850E-03+0.00000E+00+2.79606E-03+0.00000E+00+2.48958E-03+0.00000E+00+1.52962E-03+0.00000E+00+2.24088E-04+0.00000E+00-1.04776E-03+0.000046S*00000E+00-1.94359E-03+0.00000E+00-2.24826E-03+0.00000E+00-1.92275E-03+0.00000E+00-1.10163E-03+0.00000E+00-4.36276E-05+0.00000E+00+9.47830E-04+0.00000E+00+1.61011E-03+0.00000E+00+1.78935E-03+0.00000E+00+1.47374E-03+0.00000E+00+7.85842E-04+0.00000E+00-6.09068E-05+0.00000E+00-8.26764E-04+0.00000E+00-1.31236E-03+0.00000E+00-1.40922E-03+0.00000E+00-1.12174E-03+0.00000E+00-5.57036E-04+0.00000E+00+1.11999E-04+0.00000E+00+6.98398E-04+0.00000E+00+1.05234E-03+0.00000E+00+1.09821E-03+0.00000E+00+8.48744E-04+0.00000E+00+3.94310E-04+0.00000E+00-1.27650E-04+0.00000E+00-5.73180E-04+0.00000E+00-8.30656E-04+0.00000E+00-8.47708E-04+0.00000E+00-6.40040E-04+0.00000E+00-2.81414E-04+0.00000E+00+1.20911E-04+0.00000E+00+4.57442E-04+0.00000E+00+6.45532E-04+0.00000E+00+6.48778E-04+0.00000E+00+4.82464E-04+0.00000E+00+2.04904E-04+0.00000E+00-1.01725E-04+0.00000E+00-3.55056E-04+0.00000E+00-4.94058E-04+0.00000E+00-4.92968E-04+0.00000E+00-3.64712E-04+0.00000E+00-1.53942E-04+0.00000E+00+7.75194E-05+0.00000E+00+2.68272E-04+0.00000E+00+3.73118E-04+0.00000E+00+3.73138E-04+0.00000E+00+2.78002E-04+0.00000E+00+1.20744E-04+0.00000E+00-5.29412E-05+0.00000E+00-1.97535E-04+0.00000E+00-2.79208E-04+0.00000E+00-2.83208E-04+0.00000E+00-2.15680E-04+0.00000E+00-1.00068E-04+0.00000E+00+3.04418E-05+0.00000E+00+1.42114E-04+0.00000E+00+2.09036E-04+0.00000E+00+2.18690E-04+0.00000E+00+1.73672E-04+0.00000E+00+8.95560E-05+0.00000E+00-1.01214E-05+0.00000E+00-1.00242E-04+0.00000E+00-1.60164E-04+0.00000E+00-1.78068E-04+0.00000E+00-1.52783E-04+0.00000E+00-9.29802E-05+0.00000E+00-1.42499E-05+0.00000E+00+6.50032E-05+0.00000E+00+1.27774E-04+0.00000E+00+1.61835E-04+0.00000E+00+1.61671E-04+0.00000E+00+1.28752E-04+0.00000E+00+7.03544E-05+0.00000E+00-2.59160E-06+0.00000E+00-7.80380E-05+0.00000E+00-1.45142E-04+0.00000E+00-1.95955E-04+0.00000E+00-2.26268E-04+0.00000E+00-2.35600E-04+0.00000E+00-2.26532E-04+0.00000E+00-2.03638E-04+0.00000E+00-1.72307E-04+0.00000E+00-1.37722E-04+0.00000E+00-1.04124E-04+0.00000E+00-7.44366E-05+0.00000E+00-5.02182E-05+0.00000E+00-3.18550E-05+0.00000E+00-1.88893E-05+0.00000E+00-1.03793E-05+0.00000E+00-5.21464E-06+0.00000E+00-2.34472E-06+0.00000E+00-9.08544E-07+0.00000E+00-2.80036E-07+0.00000E+00-5.32080E-08+0.00000E+00+4.52378E-09+0.00000E+00+7.72762E-09+0.00000E+0000000570051071.0000E+030000500000+1.5900E-01+1.5900E-01058003507+1.00000E+00+5.00000E-0200058003500+2.03990E+05+5.00000E-02000520127 HNZ0000003~004002+49.129100+008.148700+0128.0000.0000.0-90.00001122.0000E+022.0000E-020000TG~2015,078,13:00:00.0000~~N0530382A01004003+1.00770E+18+1.00000E+00001-5.15000E+02+0.00000E+00+0.00000E+00+0.00000E+00006-9.77000E+02+3.28000E+02+0.00000E+00+0.00000E+00-9.77000E+02-3.28000E+02+0.00000E+00+0.00000E+00-1.48600E+03+2.51200E+03+0.00000E+00+0.00000E+00-1.48600E+03-2.51200E+03+0.00000E+00+0.00000E+00-5.73600E+03+4.94600E+03+0.00000E+00+0.00000E+00-5.73600E+03-4.94600E+03+0.00000E+00+0.00000E+00058003501+5.10000E-01+1.00000E+0000058003502+1.00000E+00+5.00000E-02000540048D030030040001+1.00000E+00+0.00000E+0000000570051031.9200E+050000100000+0.0000E+00+0.0000E+00058003503+4.00000E+05+5.00000E-02000541152D040040040047+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+3.81470E-06+0.00000E+00+2.28882E-05+0.00000E+00+8.01086E-05+0.00000E+00+2.13623E-04+0.00000E+00+4.80652E-04+0.00000E+00+9.61304E-04+0.00000E+00+1.76239E-03+0.00000E+00+3.02124E-03+0.00000E+00+4.88663E-03+0.00000E+00+7.49969E-03+0.00000E+00+1.09749E-02+0.00000E+00+1.53809E-02+0.00000E+00+2.07214E-02+0.00000E+00+2.69165E-02+0.00000E+00+3.37830E-02+0.00000E+00+4.10156E-02+0.00000E+00+4.82254E-02+0.00000E+00+5.49774E-02+0.00000E+00+6.08292E-02+0.00000E+00+6.53687E-02+0.00000E+00+6.82526E-02+0.00000E+00+6.92444E-02+0.00000E+00+6.82526E-02+0.00000E+00+6.53687E-02+0.00000E+00+6.08292E-02+0.00000E+00+5.49774E-02+0.00000E+00+4.82254E-02+0.00000E+00+4.10156E-02+0.00000E+00+3.37830E-02+0.00000E+00+2.69165E-02+0.00000E+00+2.07214E-02+0.00000E+00+1.53809E-02+0.00000E+00+1.09749E-02+0.00000E+00+7.49969E-03+0.00000E+00+4.88663E-03+0.00000E+00+3.02124E-03+0.00000E+00+1.76239E-03+0.00000E+00+9.61304E-04+0.00000E+00+4.80000047S*652E-04+0.00000E+00+2.13623E-04+0.00000E+00+8.01086E-05+0.00000E+00+2.28882E-05+0.00000E+00+3.81470E-06+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+00+0.00000E+0000000570051041.9200E+050000800000+1.1979E-04+1.1979E-04058003504+1.00000E+00+5.00000E-02000541776D050040040073+7.86395E-07+0.00000E+00+2.15223E-06+0.00000E+00+4.09013E-06+0.00000E+00+6.42053E-06+0.00000E+00+7.61300E-06+0.00000E+00+4.52134E-06+0.00000E+00-8.38839E-06+0.00000E+00-4.00745E-05+0.00000E+00-1.08702E-04+0.00000E+00-2.31570E-04+0.00000E+00-4.32673E-04+0.00000E+00-7.41861E-04+0.00000E+00-1.18635E-03+0.00000E+00-1.78887E-03+0.00000E+00-2.56156E-03+0.00000E+00-3.49756E-03+0.00000E+00-4.54784E-03+0.00000E+00-5.64473E-03+0.00000E+00-6.67437E-03+0.00000E+00-7.46932E-03+0.00000E+00-7.83206E-03+0.00000E+00-7.53472E-03+0.00000E+00-6.33480E-03+0.00000E+00-3.99943E-03+0.00000E+00-3.60688E-04+0.00000E+00+4.71408E-03+0.00000E+00+1.12572E-02+0.00000E+00+1.91611E-02+0.00000E+00+2.82115E-02+0.00000E+00+3.80655E-02+0.00000E+00+4.82646E-02+0.00000E+00+5.82654E-02+0.00000E+00+6.75164E-02+0.00000E+00+7.54318E-02+0.00000E+00+8.14859E-02+0.00000E+00+8.52972E-02+0.00000E+00+8.65986E-02+0.00000E+00+8.52972E-02+0.00000E+00+8.14859E-02+0.00000E+00+7.54318E-02+0.00000E+00+6.75164E-02+0.00000E+00+5.82654E-02+0.00000E+00+4.82646E-02+0.00000E+00+3.80655E-02+0.00000E+00+2.82115E-02+0.00000E+00+1.91611E-02+0.00000E+00+1.12572E-02+0.00000E+00+4.71408E-03+0.00000E+00-3.60688E-04+0.00000E+00-3.99943E-03+0.00000E+00-6.33480E-03+0.00000E+00-7.53472E-03+0.00000E+00-7.83206E-03+0.00000E+00-7.46932E-03+0.00000E+00-6.67437E-03+0.00000E+00-5.64473E-03+0.00000E+00-4.54784E-03+0.00000E+00-3.49756E-03+0.00000E+00-2.56156E-03+0.00000E+00-1.78887E-03+0.00000E+00-1.18635E-03+0.00000E+00-7.41861E-04+0.00000E+00-4.32673E-04+0.00000E+00-2.31570E-04+0.00000E+00-1.08702E-04+0.00000E+00-4.00745E-05+0.00000E+00-8.38839E-06+0.00000E+00+4.52134E-06+0.00000E+00+7.61300E-06+0.00000E+00+6.42053E-06+0.00000E+00+4.09013E-06+0.00000E+00+2.15223E-06+0.00000E+00+7.86395E-07+0.00000E+0000000570051052.4000E+040000800000+1.5000E-03+1.5000E-03058003505+1.00000E+00+5.00000E-02000544320D060040040179+1.65488E-07+0.00000E+00+7.48132E-07+0.00000E+00+1.76664E-06+0.00000E+00+1.62612E-06+0.00000E+00-5.16640E-06+0.00000E+00-3.00692E-05+0.00000E+00-8.97376E-05+0.00000E+00-1.99571E-04+0.00000E+00-3.61172E-04+0.00000E+00-5.48500E-04+0.00000E+00-7.02688E-04+0.00000E+00-7.45976E-04+0.00000E+00-6.17072E-04+0.00000E+00-3.15191E-04+0.00000E+00+7.38188E-05+0.00000E+00+3.95725E-04+0.00000E+00+4.96800E-04+0.00000E+00+3.15263E-04+0.00000E+00-5.96548E-05+0.00000E+00-4.11872E-04+0.00000E+00-5.12780E-04+0.00000E+00-2.69536E-04+0.00000E+00+1.89248E-04+0.00000E+00+5.66172E-04+0.00000E+00+5.78372E-04+0.00000E+00+1.64727E-04+0.00000E+00-4.31664E-04+0.00000E+00-7.92432E-04+0.00000E+00-6.08316E-04+0.00000E+00+6.76780E-05+0.00000E+00+7.98316E-04+0.00000E+00+1.03172E-03+0.00000E+00+5.07504E-04+0.00000E+00-4.91744E-04+0.00000E+00-1.26810E-03+0.00000E+00-1.18261E-03+0.00000E+00-1.64670E-04+0.00000E+00+1.13876E-03+0.00000E+00+1.75363E-03+0.00000E+00+1.09177E-03+0.00000E+00-5.24120E-04+0.00000E+00-1.97068E-03+0.00000E+00-2.08536E-03+0.00000E+00-5.79052E-04+0.00000E+00+1.60144E-03+0.00000E+00+2.83576E-03+0.00000E+00+2.01276E-03+0.00000E+00-5.13156E-04+0.00000E+00-2.98815E-03+0.00000E+00-3.44765E-03+0.00000E+00-1.24599E-03+0.00000E+00+2.24272E-03+0.00000E+00+4.43120E-03+0.00000E+00+3.40590E-03+0.00000E+00-4.57304E-04+0.00000E+00-4.47584E-03+0.00000E+00-5.47828E-03+0.00000E+00-2.26220E-03+0.00000E+00+3.18035E-03+0.00000E+00+6.81616E-03+0.00000E+00+5.50776E-03+0.00000E+00-3.65328E-04+0.00000E+00-6.73316E-03+0.00000E+00-8.58052E-03+0.00000E+00-3.81782E-03+0.00000E+00+4.65228E-03+0.00000E+00+1.05646E-02+0.00000E+00+8.82560E-03+0.00000E+00-2.56374E-04+0.00000E+00-1.04496E-02+0.00000E+00-1.37224E-02+0.00000E+00-6.39512E-03+0.00000E+00+7.26512E-03+0.00000E+00+1.72312E-02+0.00000E+00+1.48181E-02+0.00000E+00-1.54011E-04+0.00000E+00-1.77680E-02+0.00000E+00-2.41384E-02+0.00000E+00-1.17549E-02+0.00000E+00+1.32733E-02+0.00000E+00+3.32147E-02+0.00000E+00+3.01309E000048S*-02+0.00000E+00-8.13468E-05+0.00000E+00-4.08284E-02+0.00000E+00-6.13256E-02+0.00000E+00-3.42109E-02+0.00000E+00+4.58968E-02+0.00000E+00+1.54886E-01+0.00000E+00+2.48713E-01+0.00000E+00+2.85658E-01+0.00000E+00+2.48713E-01+0.00000E+00+1.54886E-01+0.00000E+00+4.58968E-02+0.00000E+00-3.42109E-02+0.00000E+00-6.13256E-02+0.00000E+00-4.08284E-02+0.00000E+00-8.13468E-05+0.00000E+00+3.01309E-02+0.00000E+00+3.32147E-02+0.00000E+00+1.32733E-02+0.00000E+00-1.17549E-02+0.00000E+00-2.41384E-02+0.00000E+00-1.77680E-02+0.00000E+00-1.54011E-04+0.00000E+00+1.48181E-02+0.00000E+00+1.72312E-02+0.00000E+00+7.26512E-03+0.00000E+00-6.39512E-03+0.00000E+00-1.37224E-02+0.00000E+00-1.04496E-02+0.00000E+00-2.56374E-04+0.00000E+00+8.82560E-03+0.00000E+00+1.05646E-02+0.00000E+00+4.65228E-03+0.00000E+00-3.81782E-03+0.00000E+00-8.58052E-03+0.00000E+00-6.73316E-03+0.00000E+00-3.65328E-04+0.00000E+00+5.50776E-03+0.00000E+00+6.81616E-03+0.00000E+00+3.18035E-03+0.00000E+00-2.26220E-03+0.00000E+00-5.47828E-03+0.00000E+00-4.47584E-03+0.00000E+00-4.57304E-04+0.00000E+00+3.40590E-03+0.00000E+00+4.43120E-03+0.00000E+00+2.24272E-03+0.00000E+00-1.24599E-03+0.00000E+00-3.44765E-03+0.00000E+00-2.98815E-03+0.00000E+00-5.13156E-04+0.00000E+00+2.01276E-03+0.00000E+00+2.83576E-03+0.00000E+00+1.60144E-03+0.00000E+00-5.79052E-04+0.00000E+00-2.08536E-03+0.00000E+00-1.97068E-03+0.00000E+00-5.24120E-04+0.00000E+00+1.09177E-03+0.00000E+00+1.75363E-03+0.00000E+00+1.13876E-03+0.00000E+00-1.64670E-04+0.00000E+00-1.18261E-03+0.00000E+00-1.26810E-03+0.00000E+00-4.91744E-04+0.00000E+00+5.07504E-04+0.00000E+00+1.03172E-03+0.00000E+00+7.98316E-04+0.00000E+00+6.76780E-05+0.00000E+00-6.08316E-04+0.00000E+00-7.92432E-04+0.00000E+00-4.31664E-04+0.00000E+00+1.64727E-04+0.00000E+00+5.78372E-04+0.00000E+00+5.66172E-04+0.00000E+00+1.89248E-04+0.00000E+00-2.69536E-04+0.00000E+00-5.12780E-04+0.00000E+00-4.11872E-04+0.00000E+00-5.96548E-05+0.00000E+00+3.15263E-04+0.00000E+00+4.96800E-04+0.00000E+00+3.95725E-04+0.00000E+00+7.38188E-05+0.00000E+00-3.15191E-04+0.00000E+00-6.17072E-04+0.00000E+00-7.45976E-04+0.00000E+00-7.02688E-04+0.00000E+00-5.48500E-04+0.00000E+00-3.61172E-04+0.00000E+00-1.99571E-04+0.00000E+00-8.97376E-05+0.00000E+00-3.00692E-05+0.00000E+00-5.16640E-06+0.00000E+00+1.62612E-06+0.00000E+00+1.76664E-06+0.00000E+00+7.48132E-07+0.00000E+00+1.65488E-07+0.00000E+0000000570051063.0000E+030000300000+2.9667E-02+2.9667E-02058003506+1.00000E+00+5.00000E-02000547680D070040040319+7.72762E-09+0.00000E+00+4.52378E-09+0.00000E+00-5.32080E-08+0.00000E+00-2.80036E-07+0.00000E+00-9.08544E-07+0.00000E+00-2.34472E-06+0.00000E+00-5.21464E-06+0.00000E+00-1.03793E-05+0.00000E+00-1.88893E-05+0.00000E+00-3.18550E-05+0.00000E+00-5.02182E-05+0.00000E+00-7.44366E-05+0.00000E+00-1.04124E-04+0.00000E+00-1.37722E-04+0.00000E+00-1.72307E-04+0.00000E+00-2.03638E-04+0.00000E+00-2.26532E-04+0.00000E+00-2.35600E-04+0.00000E+00-2.26268E-04+0.00000E+00-1.95955E-04+0.00000E+00-1.45142E-04+0.00000E+00-7.80380E-05+0.00000E+00-2.59160E-06+0.00000E+00+7.03544E-05+0.00000E+00+1.28752E-04+0.00000E+00+1.61671E-04+0.00000E+00+1.61835E-04+0.00000E+00+1.27774E-04+0.00000E+00+6.50032E-05+0.00000E+00-1.42499E-05+0.00000E+00-9.29802E-05+0.00000E+00-1.52783E-04+0.00000E+00-1.78068E-04+0.00000E+00-1.60164E-04+0.00000E+00-1.00242E-04+0.00000E+00-1.01214E-05+0.00000E+00+8.95560E-05+0.00000E+00+1.73672E-04+0.00000E+00+2.18690E-04+0.00000E+00+2.09036E-04+0.00000E+00+1.42114E-04+0.00000E+00+3.04418E-05+0.00000E+00-1.00068E-04+0.00000E+00-2.15680E-04+0.00000E+00-2.83208E-04+0.00000E+00-2.79208E-04+0.00000E+00-1.97535E-04+0.00000E+00-5.29412E-05+0.00000E+00+1.20744E-04+0.00000E+00+2.78002E-04+0.00000E+00+3.73138E-04+0.00000E+00+3.73118E-04+0.00000E+00+2.68272E-04+0.00000E+00+7.75194E-05+0.00000E+00-1.53942E-04+0.00000E+00-3.64712E-04+0.00000E+00-4.92968E-04+0.00000E+00-4.94058E-04+0.00000E+00-3.55056E-04+0.00000E+00-1.01725E-04+0.00000E+00+2.04904E-04+0.00000E+00+4.82464E-04+0.00000E+00+6.48778E-04+0.00000E+00+6.45532E-04+0.00000E+00+4.57442E-04+0.00000E+00+1.20911E-04+0.00000E+00-2.81414E-04+0.00000E+00-6.40040E-04+0.00000E+00-8.000049S*47708E-04+0.00000E+00-8.30656E-04+0.00000E+00-5.73180E-04+0.00000E+00-1.27650E-04+0.00000E+00+3.94310E-04+0.00000E+00+8.48744E-04+0.00000E+00+1.09821E-03+0.00000E+00+1.05234E-03+0.00000E+00+6.98398E-04+0.00000E+00+1.11999E-04+0.00000E+00-5.57036E-04+0.00000E+00-1.12174E-03+0.00000E+00-1.40922E-03+0.00000E+00-1.31236E-03+0.00000E+00-8.26764E-04+0.00000E+00-6.09068E-05+0.00000E+00+7.85842E-04+0.00000E+00+1.47374E-03+0.00000E+00+1.78935E-03+0.00000E+00+1.61011E-03+0.00000E+00+9.47830E-04+0.00000E+00-4.36276E-05+0.00000E+00-1.10163E-03+0.00000E+00-1.92275E-03+0.00000E+00-2.24826E-03+0.00000E+00-1.94359E-03+0.00000E+00-1.04776E-03+0.00000E+00+2.24088E-04+0.00000E+00+1.52962E-03+0.00000E+00+2.48958E-03+0.00000E+00+2.79606E-03+0.00000E+00+2.30850E-03+0.00000E+00+1.10801E-03+0.00000E+00-5.08938E-04+0.00000E+00-2.10070E-03+0.00000E+00-3.19878E-03+0.00000E+00-3.44326E-03+0.00000E+00-2.69684E-03+0.00000E+00-1.10249E-03+0.00000E+00+9.36892E-04+0.00000E+00+2.85672E-03+0.00000E+00+4.08406E-03+0.00000E+00+4.20524E-03+0.00000E+00+3.09968E-03+0.00000E+00+9.97970E-04+0.00000E+00-1.55873E-03+0.00000E+00-3.85362E-03+0.00000E+00-5.19124E-03+0.00000E+00-5.10336E-03+0.00000E+00-3.50440E-03+0.00000E+00-7.46438E-04+0.00000E+00+2.44968E-03+0.00000E+00+5.17690E-03+0.00000E+00+6.59364E-03+0.00000E+00+6.17604E-03+0.00000E+00+3.89756E-03+0.00000E+00+2.77256E-04+0.00000E+00-3.72784E-03+0.00000E+00-6.96714E-03+0.00000E+00-8.41784E-03+0.00000E+00-7.49572E-03+0.00000E+00-4.26426E-03+0.00000E+00+5.27466E-04+0.00000E+00+5.60328E-03+0.00000E+00+9.48592E-03+0.00000E+00+1.09107E-02+0.00000E+00+9.21506E-03+0.00000E+00+4.58962E-03+0.00000E+00-1.89363E-03+0.00000E+00-8.50506E-03+0.00000E+00-1.32925E-02+0.00000E+00-1.46243E-02+0.00000E+00-1.16967E-02+0.00000E+00-4.85962E-03+0.00000E+00+4.34870E-03+0.00000E+00+1.34983E-02+0.00000E+00+1.98472E-02+0.00000E+00+2.10770E-02+0.00000E+00+1.60019E-02+0.00000E+00+5.06204E-03+0.00000E+00-9.55078E-03+0.00000E+00-2.42030E-02+0.00000E+00-3.45266E-02+0.00000E+00-3.63864E-02+0.00000E+00-2.68872E-02+0.00000E+00-5.18748E-03+0.00000E+00+2.70918E-02+0.00000E+00+6.59838E-02+0.00000E+00+1.05820E-01+0.00000E+00+1.40281E-01+0.00000E+00+1.63636E-01+0.00000E+00+1.71897E-01+0.00000E+00+1.63636E-01+0.00000E+00+1.40281E-01+0.00000E+00+1.05820E-01+0.00000E+00+6.59838E-02+0.00000E+00+2.70918E-02+0.00000E+00-5.18748E-03+0.00000E+00-2.68872E-02+0.00000E+00-3.63864E-02+0.00000E+00-3.45266E-02+0.00000E+00-2.42030E-02+0.00000E+00-9.55078E-03+0.00000E+00+5.06204E-03+0.00000E+00+1.60019E-02+0.00000E+00+2.10770E-02+0.00000E+00+1.98472E-02+0.00000E+00+1.34983E-02+0.00000E+00+4.34870E-03+0.00000E+00-4.85962E-03+0.00000E+00-1.16967E-02+0.00000E+00-1.46243E-02+0.00000E+00-1.32925E-02+0.00000E+00-8.50506E-03+0.00000E+00-1.89363E-03+0.00000E+00+4.58962E-03+0.00000E+00+9.21506E-03+0.00000E+00+1.09107E-02+0.00000E+00+9.48592E-03+0.00000E+00+5.60328E-03+0.00000E+00+5.27466E-04+0.00000E+00-4.26426E-03+0.00000E+00-7.49572E-03+0.00000E+00-8.41784E-03+0.00000E+00-6.96714E-03+0.00000E+00-3.72784E-03+0.00000E+00+2.77256E-04+0.00000E+00+3.89756E-03+0.00000E+00+6.17604E-03+0.00000E+00+6.59364E-03+0.00000E+00+5.17690E-03+0.00000E+00+2.44968E-03+0.00000E+00-7.46438E-04+0.00000E+00-3.50440E-03+0.00000E+00-5.10336E-03+0.00000E+00-5.19124E-03+0.00000E+00-3.85362E-03+0.00000E+00-1.55873E-03+0.00000E+00+9.97970E-04+0.00000E+00+3.09968E-03+0.00000E+00+4.20524E-03+0.00000E+00+4.08406E-03+0.00000E+00+2.85672E-03+0.00000E+00+9.36892E-04+0.00000E+00-1.10249E-03+0.00000E+00-2.69684E-03+0.00000E+00-3.44326E-03+0.00000E+00-3.19878E-03+0.00000E+00-2.10070E-03+0.00000E+00-5.08938E-04+0.00000E+00+1.10801E-03+0.00000E+00+2.30850E-03+0.00000E+00+2.79606E-03+0.00000E+00+2.48958E-03+0.00000E+00+1.52962E-03+0.00000E+00+2.24088E-04+0.00000E+00-1.04776E-03+0.00000E+00-1.94359E-03+0.00000E+00-2.24826E-03+0.00000E+00-1.92275E-03+0.00000E+00-1.10163E-03+0.00000E+00-4.36276E-05+0.00000E+00+9.47830E-04+0.00000E+00+1.61011E-03+0.00000E+00+1.78935E-03+0.00000E+00+1.47374E-03+0.00000E+00+7.85842E-04+0.00000E+00-6.09068E-05+0.00000E+00-8.26764E-04+0.00000E+00-1.31236E-03+0.00000E+00-1.40922E-0000050S*3+0.00000E+00-1.12174E-03+0.00000E+00-5.57036E-04+0.00000E+00+1.11999E-04+0.00000E+00+6.98398E-04+0.00000E+00+1.05234E-03+0.00000E+00+1.09821E-03+0.00000E+00+8.48744E-04+0.00000E+00+3.94310E-04+0.00000E+00-1.27650E-04+0.00000E+00-5.73180E-04+0.00000E+00-8.30656E-04+0.00000E+00-8.47708E-04+0.00000E+00-6.40040E-04+0.00000E+00-2.81414E-04+0.00000E+00+1.20911E-04+0.00000E+00+4.57442E-04+0.00000E+00+6.45532E-04+0.00000E+00+6.48778E-04+0.00000E+00+4.82464E-04+0.00000E+00+2.04904E-04+0.00000E+00-1.01725E-04+0.00000E+00-3.55056E-04+0.00000E+00-4.94058E-04+0.00000E+00-4.92968E-04+0.00000E+00-3.64712E-04+0.00000E+00-1.53942E-04+0.00000E+00+7.75194E-05+0.00000E+00+2.68272E-04+0.00000E+00+3.73118E-04+0.00000E+00+3.73138E-04+0.00000E+00+2.78002E-04+0.00000E+00+1.20744E-04+0.00000E+00-5.29412E-05+0.00000E+00-1.97535E-04+0.00000E+00-2.79208E-04+0.00000E+00-2.83208E-04+0.00000E+00-2.15680E-04+0.00000E+00-1.00068E-04+0.00000E+00+3.04418E-05+0.00000E+00+1.42114E-04+0.00000E+00+2.09036E-04+0.00000E+00+2.18690E-04+0.00000E+00+1.73672E-04+0.00000E+00+8.95560E-05+0.00000E+00-1.01214E-05+0.00000E+00-1.00242E-04+0.00000E+00-1.60164E-04+0.00000E+00-1.78068E-04+0.00000E+00-1.52783E-04+0.00000E+00-9.29802E-05+0.00000E+00-1.42499E-05+0.00000E+00+6.50032E-05+0.00000E+00+1.27774E-04+0.00000E+00+1.61835E-04+0.00000E+00+1.61671E-04+0.00000E+00+1.28752E-04+0.00000E+00+7.03544E-05+0.00000E+00-2.59160E-06+0.00000E+00-7.80380E-05+0.00000E+00-1.45142E-04+0.00000E+00-1.95955E-04+0.00000E+00-2.26268E-04+0.00000E+00-2.35600E-04+0.00000E+00-2.26532E-04+0.00000E+00-2.03638E-04+0.00000E+00-1.72307E-04+0.00000E+00-1.37722E-04+0.00000E+00-1.04124E-04+0.00000E+00-7.44366E-05+0.00000E+00-5.02182E-05+0.00000E+00-3.18550E-05+0.00000E+00-1.88893E-05+0.00000E+00-1.03793E-05+0.00000E+00-5.21464E-06+0.00000E+00-2.34472E-06+0.00000E+00-9.08544E-07+0.00000E+00-2.80036E-07+0.00000E+00-5.32080E-08+0.00000E+00+4.52378E-09+0.00000E+00+7.72762E-09+0.00000E+0000000570051071.0000E+030000500000+1.5900E-01+1.5900E-01058003507+1.00000E+00+5.00000E-0200058003500+2.03990E+05+5.00000E-0200 000051 000052 000053 000054 000055 000056 \ No newline at end of file From da29b286f17fe38462e6f53fc98e1480ec55cbbf Mon Sep 17 00:00:00 2001 From: Darius Arnold Date: Tue, 17 Jul 2018 10:56:53 +0200 Subject: [PATCH 114/169] [add] tests for read_single_file --- tests/test_Metadata/test_Metadata.py | 46 ++++++++++++++++++++++++++++ 1 file changed, 46 insertions(+) diff --git a/tests/test_Metadata/test_Metadata.py b/tests/test_Metadata/test_Metadata.py index 8cb4a08f..d58ddc6e 100644 --- a/tests/test_Metadata/test_Metadata.py +++ b/tests/test_Metadata/test_Metadata.py @@ -122,3 +122,49 @@ class TestMetadataRemoval(unittest.TestCase): self.assertDictEqual({}, metadata.seed_ids) self.assertEqual([], metadata.inventories) + +class TestMetadata_read_single_file(unittest.TestCase): + + def setUp(self): + self.station_id = 'BW.WETR..HHZ' + self.metadata_folders = (os.path.join('test_data', 'dless_multiple_files', 'metadata1'), + os.path.join('test_data', 'dless_multiple_files', 'metadata2')) + self.metadata_paths = [] + self.m = Metadata() + + def test_read_single_file(self): + """Test if reading a single file works""" + fname = os.path.join(self.metadata_folders[0], 'DATALESS.'+self.station_id) + with HidePrints(): + res = self.m.read_single_file(fname) + # method should return true if file is successfully read + self.assertTrue(res) + # list of inventories (folders) should be empty + self.assertEqual([], self.m.inventories) + # list of inventory files should contain the added file + self.assertIn(fname, self.m.inventory_files.keys()) + self.assertEqual({}, self.m.seed_ids) + + def test_read_single_file_invalid_path(self): + """Test if reading from a non existing file fails. The filename should not be + added to the metadata object""" + fname = os.path.join("this", "path", "doesnt", "exist") + with HidePrints(): + res = self.m.read_single_file(fname) + # method should return None if file reading fails + self.assertIsNone(res) + # list of inventories (folders) should be empty + self.assertEqual([], self.m.inventories) + # list of inventory files should not contain the added file + self.assertNotIn(fname, self.m.inventory_files.keys()) + self.assertEqual({}, self.m.seed_ids) + + def test_read_single_file_multiple_times(self): + """Test if reading a file twice doesnt add it twice to the metadata object""" + fname = os.path.join(self.metadata_folders[0], 'DATALESS.'+self.station_id) + with HidePrints(): + res1 = self.m.read_single_file(fname) + res2 = self.m.read_single_file(fname) + self.assertTrue(res1) + self.assertIsNone(res2) + self.assertItemsEqual([fname], self.m.inventory_files.keys()) From 787c46eeaf186b776ea5a9d1fcc59a4f7a542f5a Mon Sep 17 00:00:00 2001 From: Darius Arnold Date: Tue, 17 Jul 2018 11:17:23 +0200 Subject: [PATCH 115/169] [add] tests for file where metadata is available at multiple time intervals --- tests/test_Metadata/test_Metadata.py | 55 ++++++++++++++++++++++++++++ 1 file changed, 55 insertions(+) diff --git a/tests/test_Metadata/test_Metadata.py b/tests/test_Metadata/test_Metadata.py index d58ddc6e..5bcf3761 100644 --- a/tests/test_Metadata/test_Metadata.py +++ b/tests/test_Metadata/test_Metadata.py @@ -2,6 +2,8 @@ import unittest import os from obspy import UTCDateTime +from obspy.io.xseed.utils import SEEDParserException +from obspy.io.xseed import Parser from pylot.core.util.dataprocessing import Metadata from tests.utils import HidePrints @@ -168,3 +170,56 @@ class TestMetadata_read_single_file(unittest.TestCase): self.assertTrue(res1) self.assertIsNone(res2) self.assertItemsEqual([fname], self.m.inventory_files.keys()) + + +class TestMetadataMultipleTime(unittest.TestCase): + """Test if stations with multiple metadata entries in a single file are handled correctly. + The user must specify the time where he wants to get metadata. + + The station ROTT changed has metadata available at multiple times + LE.ROTT..HNE | 200.00 Hz | Titan 4g-EDR-209, Very Low gain, 200 sps | 2015-01-08 - 2015-03-19 | Lat: 49.1, Lng: 8.1 + LE.ROTT..HNE | 200.00 Hz | Titan 4g-EDR-209, Very Low gain, 200 sps | 2015-03-19 - | Lat: 49.1, Lng: 8.1 + LE.ROTT..HNN | 200.00 Hz | Titan 4g-EDR-209, Very Low gain, 200 sps | 2015-01-08 - 2015-03-19 | Lat: 49.1, Lng: 8.1 + LE.ROTT..HNN | 200.00 Hz | Titan 4g-EDR-209, Very Low gain, 200 sps | 2015-03-19 - | Lat: 49.1, Lng: 8.1 + LE.ROTT..HNZ | 200.00 Hz | Titan 4g-EDR-209, Very Low gain, 200 sps | 2015-01-08 - 2015-03-19 | Lat: 49.1, Lng: 8.1 + LE.ROTT..HNZ | 200.00 Hz | Titan 4g-EDR-209, Very Low gain, 200 sps | 2015-03-19 - | Lat: 49.1, Lng: 8.1 + """ + + def setUp(self): + self.seed_id = 'LE.ROTT..HN' + path = os.path.dirname(__file__) # gets path to currently running script + metadata = os.path.join('test_data', 'dless_multiple_times', 'MAGS2_LE_ROTT.dless') # specific subfolder of test data + metadata_path = os.path.join(path, metadata) + self.m = Metadata(metadata_path) + self.p = Parser(metadata_path) + + def test_get_metadata_works_without_datetime(self): + """Test if get_metadata works if multiple metadata entries are available but no time is + specified.""" + for channel in ('Z', 'N', 'E'): + with HidePrints(): + md = self.m.get_metadata(self.seed_id + channel) + self.assertDictEqual(md['data'].get_inventory(), self.p.get_inventory()) + + def test_get_metadata_works_with_first_datetime(self): + """Test if get_metadata works if multiple metadata entries are available and the older time is specified.""" + t = UTCDateTime('2015-02-08') + for channel in ('Z', 'N', 'E'): + with HidePrints(): + md = self.m.get_metadata(self.seed_id + channel, t) + self.assertDictEqual(md['data'].get_inventory(), self.p.get_inventory()) + + def test_get_metadata_fails_when_time_before_starttime(self): + """Tests if get_metadata returns None when given a data that is before the start date + of the metadata""" + with HidePrints(): + md = self.m.get_metadata(self.seed_id, UTCDateTime('1960-07-20')) + self.assertIs(md, None) + + def test_get_metadata_invalid_seed_id(self): + """Tes if get metadata returns none when asked for a seed id that does not exist""" + with HidePrints(): + res = self.m.get_metadata("this.doesnt..exist") + self.assertIsNone(res) + + self.assertIsNone(res) From d84be686941b9dcee96aeefb2911b04c064d5605 Mon Sep 17 00:00:00 2001 From: Darius Arnold Date: Tue, 17 Jul 2018 11:18:07 +0200 Subject: [PATCH 116/169] [add] tests for file where metadata has changed due to changed instruments --- tests/test_Metadata/test_Metadata.py | 100 +++++++++++++++++++++++++++ 1 file changed, 100 insertions(+) diff --git a/tests/test_Metadata/test_Metadata.py b/tests/test_Metadata/test_Metadata.py index 5bcf3761..9b362f5d 100644 --- a/tests/test_Metadata/test_Metadata.py +++ b/tests/test_Metadata/test_Metadata.py @@ -222,4 +222,104 @@ class TestMetadataMultipleTime(unittest.TestCase): res = self.m.get_metadata("this.doesnt..exist") self.assertIsNone(res) + +class TestMetadataMultipleEntries(unittest.TestCase): + """ + The station KB.TMO07 has changed instruments multiple times. + Networks: + KB (KB network) +Stations: + KB.TMO07 (Karlsruhe GPI) +Channels: + KB.TMO07.00.BHE | 50.00 Hz | Streckeisen KABBA-STS-2 | 2004-12-06 - 2005-04-18 | Lat: 49.0, Lng: 8.4 + KB.TMO07.00.BHE | 50.00 Hz | Streckeisen KABBA-STS-2 | 2005-04-18 - 2006-07-18 | Lat: 49.0, Lng: 8.4 + KB.TMO07.00.BHE | 50.00 Hz | Lennartz KABBA-LE-3D/5 | 2006-10-10 - 2006-11-14 | Lat: 49.0, Lng: 8.4 + KB.TMO07.00.BHE | 50.00 Hz | Lennartz KABBA-LE-3D/5 | 2006-11-24 - 2007-01-12 | Lat: 49.0, Lng: 8.4 + KB.TMO07.00.BHE | 50.00 Hz | Lennartz KABBA-LE-3D/5 | 2007-01-18 - 2007-03-15 | Lat: 49.0, Lng: 8.4 + KB.TMO07.00.BHE | 50.00 Hz | Lennartz KABBA-LE-3D/5 | 2007-10-25 - 2007-11-21 | Lat: 49.0, Lng: 8.4 + KB.TMO07.00.BHE | 50.00 Hz | Lennartz KABBA-LE-3D/5 | 2007-11-21 - 2008-01-17 | Lat: 49.0, Lng: 8.4 + KB.TMO07.00.BHN | 50.00 Hz | Streckeisen KABBA-STS-2 | 2004-12-06 - 2005-04-18 | Lat: 49.0, Lng: 8.4 + KB.TMO07.00.BHN | 50.00 Hz | Streckeisen KABBA-STS-2 | 2005-04-18 - 2006-07-18 | Lat: 49.0, Lng: 8.4 + KB.TMO07.00.BHN | 50.00 Hz | Lennartz KABBA-LE-3D/5 | 2006-10-10 - 2006-11-14 | Lat: 49.0, Lng: 8.4 + KB.TMO07.00.BHN | 50.00 Hz | Lennartz KABBA-LE-3D/5 | 2006-11-24 - 2007-01-12 | Lat: 49.0, Lng: 8.4 + KB.TMO07.00.BHN | 50.00 Hz | Lennartz KABBA-LE-3D/5 | 2007-01-18 - 2007-03-15 | Lat: 49.0, Lng: 8.4 + KB.TMO07.00.BHN | 50.00 Hz | Lennartz KABBA-LE-3D/5 | 2007-10-25 - 2007-11-21 | Lat: 49.0, Lng: 8.4 + KB.TMO07.00.BHN | 50.00 Hz | Lennartz KABBA-LE-3D/5 | 2007-11-21 - 2008-01-17 | Lat: 49.0, Lng: 8.4 + KB.TMO07.00.BHZ | 50.00 Hz | Streckeisen KABBA-STS-2 | 2004-12-06 - 2005-04-18 | Lat: 49.0, Lng: 8.4 + KB.TMO07.00.BHZ | 50.00 Hz | Streckeisen KABBA-STS-2 | 2005-04-18 - 2006-07-18 | Lat: 49.0, Lng: 8.4 + KB.TMO07.00.BHZ | 50.00 Hz | Lennartz KABBA-LE-3D/5 | 2006-10-10 - 2006-11-14 | Lat: 49.0, Lng: 8.4 + KB.TMO07.00.BHZ | 50.00 Hz | Lennartz KABBA-LE-3D/5 | 2006-11-24 - 2007-01-12 | Lat: 49.0, Lng: 8.4 + KB.TMO07.00.BHZ | 50.00 Hz | Lennartz KABBA-LE-3D/5 | 2007-01-18 - 2007-03-15 | Lat: 49.0, Lng: 8.4 + KB.TMO07.00.BHZ | 50.00 Hz | Lennartz KABBA-LE-3D/5 | 2007-10-25 - 2007-11-21 | Lat: 49.0, Lng: 8.4 + KB.TMO07.00.BHZ | 50.00 Hz | Lennartz KABBA-LE-3D/5 | 2007-11-21 - 2008-01-17 | Lat: 49.0, Lng: 8.4 + KB.TMO07.00.HHE | 100.00 Hz | Lennartz KABBA-LE-3D/5 | 2007-01-12 - 2007-01-18 | Lat: 49.0, Lng: 8.4 + KB.TMO07.00.HHE | 100.00 Hz | Lennartz KABBA-LE-3D/5 | 2007-10-10 - 2007-10-25 | Lat: 49.0, Lng: 8.4 + KB.TMO07.00.HHE | 100.00 Hz | Streckeisen KABBA-STS-2 | 2008-07-11 - 2008-12-05 | Lat: 49.0, Lng: 8.4 + KB.TMO07.00.HHE | 100.00 Hz | Streckeisen KABBA-STS-2 | 2009-05-12 - 2010-02-15 | Lat: 49.0, Lng: 8.4 + KB.TMO07.00.HHE | 100.00 Hz | Streckeisen KABBA-STS-2 | 2010-02-15 - 2010-04-07 | Lat: 49.0, Lng: 8.4 + KB.TMO07.00.HHE | 100.00 Hz | Lennartz KABBA-LE-3D/1 | 2010-04-07 - 2010-08-03 | Lat: 49.0, Lng: 8.4 + KB.TMO07.00.HHE | 200.00 Hz | Streckeisen KABBA-STS-2 | 2010-08-05 - 2010-12-20 | Lat: 49.0, Lng: 8.4 + KB.TMO07.00.HHE | 100.00 Hz | Streckeisen KABBA-STS-2 | 2010-12-20 - 2010-12-22 | Lat: 49.0, Lng: 8.4 + KB.TMO07.00.HHE | 200.00 Hz | Streckeisen KABBA-STS-2 | 2010-12-22 - 2011-04-02 | Lat: 49.0, Lng: 8.4 + KB.TMO07.00.HHE | 200.00 Hz | Streckeisen KABBA-STS-2 | 2011-04-15 - 2012-05-07 | Lat: 49.0, Lng: 8.4 + KB.TMO07.00.HHE | 200.00 Hz | Streckeisen KABBA-STS-2 | 2012-05-07 - | Lat: 49.0, Lng: 8.4 + KB.TMO07.00.HHN | 100.00 Hz | Lennartz KABBA-LE-3D/5 | 2007-01-12 - 2007-01-18 | Lat: 49.0, Lng: 8.4 + KB.TMO07.00.HHN | 100.00 Hz | Lennartz KABBA-LE-3D/5 | 2007-10-10 - 2007-10-25 | Lat: 49.0, Lng: 8.4 + KB.TMO07.00.HHN | 100.00 Hz | Streckeisen KABBA-STS-2 | 2008-07-11 - 2008-12-05 | Lat: 49.0, Lng: 8.4 + KB.TMO07.00.HHN | 100.00 Hz | Streckeisen KABBA-STS-2 | 2009-05-12 - 2010-02-15 | Lat: 49.0, Lng: 8.4 + KB.TMO07.00.HHN | 100.00 Hz | Streckeisen KABBA-STS-2 | 2010-02-15 - 2010-04-07 | Lat: 49.0, Lng: 8.4 + KB.TMO07.00.HHN | 100.00 Hz | Lennartz KABBA-LE-3D/1 | 2010-04-07 - 2010-08-03 | Lat: 49.0, Lng: 8.4 + KB.TMO07.00.HHN | 200.00 Hz | Streckeisen KABBA-STS-2 | 2010-08-05 - 2010-12-20 | Lat: 49.0, Lng: 8.4 + KB.TMO07.00.HHN | 100.00 Hz | Streckeisen KABBA-STS-2 | 2010-12-20 - 2010-12-22 | Lat: 49.0, Lng: 8.4 + KB.TMO07.00.HHN | 200.00 Hz | Streckeisen KABBA-STS-2 | 2010-12-22 - 2011-04-02 | Lat: 49.0, Lng: 8.4 + KB.TMO07.00.HHN | 200.00 Hz | Streckeisen KABBA-STS-2 | 2011-04-15 - 2012-05-07 | Lat: 49.0, Lng: 8.4 + KB.TMO07.00.HHN | 200.00 Hz | Streckeisen KABBA-STS-2 | 2012-05-07 - | Lat: 49.0, Lng: 8.4 + KB.TMO07.00.HHZ | 100.00 Hz | Lennartz KABBA-LE-3D/5 | 2007-01-12 - 2007-01-18 | Lat: 49.0, Lng: 8.4 + KB.TMO07.00.HHZ | 100.00 Hz | Lennartz KABBA-LE-3D/5 | 2007-10-10 - 2007-10-25 | Lat: 49.0, Lng: 8.4 + KB.TMO07.00.HHZ | 100.00 Hz | Streckeisen KABBA-STS-2 | 2008-07-11 - 2008-12-05 | Lat: 49.0, Lng: 8.4 + KB.TMO07.00.HHZ | 100.00 Hz | Streckeisen KABBA-STS-2 | 2009-05-12 - 2010-02-15 | Lat: 49.0, Lng: 8.4 + KB.TMO07.00.HHZ | 100.00 Hz | Streckeisen KABBA-STS-2 | 2010-02-15 - 2010-04-07 | Lat: 49.0, Lng: 8.4 + KB.TMO07.00.HHZ | 100.00 Hz | Lennartz KABBA-LE-3D/1 | 2010-04-07 - 2010-08-03 | Lat: 49.0, Lng: 8.4 + KB.TMO07.00.HHZ | 200.00 Hz | Streckeisen KABBA-STS-2 | 2010-08-05 - 2010-12-20 | Lat: 49.0, Lng: 8.4 + KB.TMO07.00.HHZ | 100.00 Hz | Streckeisen KABBA-STS-2 | 2010-12-20 - 2010-12-22 | Lat: 49.0, Lng: 8.4 + KB.TMO07.00.HHZ | 200.00 Hz | Streckeisen KABBA-STS-2 | 2010-12-22 - 2011-04-02 | Lat: 49.0, Lng: 8.4 + KB.TMO07.00.HHZ | 200.00 Hz | Streckeisen KABBA-STS-2 | 2011-04-15 - 2012-05-07 | Lat: 49.0, Lng: 8.4 + KB.TMO07.00.HHZ | 200.00 Hz | Streckeisen KABBA-STS-2 | 2012-05-07 - | Lat: 49.0, Lng: 8.4 + """ + + def setUp(self): + self.seed_id = 'KB.TMO07.00.HHZ' + path = os.path.dirname(__file__) # gets path to currently running script + metadata = os.path.join('test_data', 'dless_multiple_instruments', 'MAGS2_KB_TMO07.dless') # specific subfolder of test data + metadata_path = os.path.join(path, metadata) + self.m = Metadata(metadata_path) + self.p = Parser(metadata_path) + + def test_get_paz_current_time(self): + """Test if getting the paz from the metadata object with the current time works""" + t = UTCDateTime() + with HidePrints(): + pazm = self.m.get_paz(self.seed_id, t) + pazp = self.p.get_paz(self.seed_id, t) + self.assertEqual(pazm, pazp) + + def test_get_paz_past(self): + """Test if getting paz from metadata object with a time in the past works""" + t = UTCDateTime('2007-01-13') + with HidePrints(): + pazm = self.m.get_paz(self.seed_id, t) + pazp = self.p.get_paz(self.seed_id, t) + self.assertEqual(pazm, pazp) + + def test_get_paz_time_not_exisiting(self): + """Test if getting paz from metadata at a time where there is no metadata + available fails correctly""" + with self.assertRaises(SEEDParserException): + with HidePrints(): + self.m.get_paz(self.seed_id, UTCDateTime('1990-1-1')) + + def test_get_paz_seed_id_not_existing(self): + """Test if getting paz from a non existing seed id returns None as expected.""" + with HidePrints(): + res = self.m.get_paz('This.doesnt..exist', UTCDateTime) self.assertIsNone(res) From a9636caf732dc2f12960ecdddd5742427960f3fe Mon Sep 17 00:00:00 2001 From: Marcel Date: Tue, 17 Jul 2018 14:44:31 +0200 Subject: [PATCH 117/169] [bugfix] picks for S and P were deleted when wadati check failed --- pylot/core/pick/utils.py | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/pylot/core/pick/utils.py b/pylot/core/pick/utils.py index 96878c4d..b5a85149 100644 --- a/pylot/core/pick/utils.py +++ b/pylot/core/pick/utils.py @@ -639,11 +639,11 @@ def wadaticheck(pickdic, dttolerance, iplot=0, fig_dict=None): # check, if deviation is larger than adjusted if wddiff > dttolerance: # remove pick from dictionary - pickdic.pop(key) - # # mark onset and downgrade S-weight to 9 + # # mark onset and downgrade S-weight to 9, also set SPE to None (disregarded in GUI) # # (not used anymore) - # marker = 'badWadatiCheck' - # pickdic[key]['S']['weight'] = 9 + marker = 'badWadatiCheck' + pickdic[key]['S']['weight'] = 9 + pickdic[key]['S']['spe'] = None badstations.append(key) ibad += 1 else: @@ -655,8 +655,7 @@ def wadaticheck(pickdic, dttolerance, iplot=0, fig_dict=None): checkedSPtime = pickdic[key]['S']['mpp'] - pickdic[key]['P']['mpp'] checkedSPtimes.append(checkedSPtime) - pickdic[key]['S']['marked'] = marker - #pickdic[key]['S']['marked'] = marker + pickdic[key]['S']['marked'] = marker print("wadaticheck: the following stations failed the check:") print(badstations) From ad686d42db0cfc2a63ca4c9aeff96d001eee682f Mon Sep 17 00:00:00 2001 From: Marcel Date: Thu, 12 Jul 2018 16:36:56 +0200 Subject: [PATCH 118/169] [minor] update_status when loading multiple events --- PyLoT.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/PyLoT.py b/PyLoT.py index fdb41991..fd951794 100755 --- a/PyLoT.py +++ b/PyLoT.py @@ -935,7 +935,9 @@ class MainWindow(QMainWindow): return self.data = data - print('Loading event info from file {}.'.format(fname)) + message = 'Loading event info from file {}.'.format(fname) + print(message) + self.update_status(message) if not loc: self.updatePicks(type='auto', event=event) self.updatePicks(type='manual', event=event) From 0e70520a78e3dd64c2bb5f7fc8af27adc7880fd4 Mon Sep 17 00:00:00 2001 From: Marcel Date: Mon, 16 Jul 2018 11:07:47 +0200 Subject: [PATCH 119/169] [bugfix] Spick quality check doing random stuff caused by copy paste errors --- pylot/core/pick/autopick.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pylot/core/pick/autopick.py b/pylot/core/pick/autopick.py index 6da10085..7f48b6bc 100644 --- a/pylot/core/pick/autopick.py +++ b/pylot/core/pick/autopick.py @@ -877,7 +877,7 @@ def autopickstation(wfstream, pickparam, verbose=False, Sweight = 0 elif timeerrorsS[0] < Serror <= timeerrorsS[1]: Sweight = 1 - elif Perror > timeerrorsS[1] and Serror <= timeerrorsS[2]: + elif timeerrorsS[1] < Serror <= timeerrorsS[2]: Sweight = 2 elif timeerrorsS[2] < Serror <= timeerrorsS[3]: Sweight = 3 From e210bd87937aa25c7c522fe991783d5639bbc636 Mon Sep 17 00:00:00 2001 From: Marcel Date: Mon, 16 Jul 2018 13:51:18 +0200 Subject: [PATCH 120/169] [add] number of active picks (and total) --- PyLoT.py | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/PyLoT.py b/PyLoT.py index fd951794..6d7770ac 100755 --- a/PyLoT.py +++ b/PyLoT.py @@ -900,7 +900,7 @@ class MainWindow(QMainWindow): return if self.get_current_event().pylot_picks: self.refreshEvents() - self.fill_eventbox() + self.fill_eventbox() self.setDirty(True) def load_data(self, fname=None, loc=False, draw=True, event=None, overwrite=False): @@ -1260,6 +1260,8 @@ class MainWindow(QMainWindow): 'auto': event.pylot_autopicks} ma_count = {'manual': 0, 'auto': 0} + ma_count_total = {'manual': 0, + 'auto': 0} for ma in ma_props.keys(): if ma_props[ma]: @@ -1269,6 +1271,7 @@ class MainWindow(QMainWindow): continue if getQualityFromUncertainty(has_spe(pick), phaseErrors[self.getPhaseID(phasename)]) < 4: ma_count[ma] += 1 + ma_count_total[ma] += 1 event_ref = event.isRefEvent() event_test = event.isTestEvent() @@ -1296,9 +1299,9 @@ class MainWindow(QMainWindow): item_lon = QtGui.QStandardItem('{}'.format(lon)) item_depth = QtGui.QStandardItem('{}'.format(depth)) item_mag = QtGui.QStandardItem('{}'.format(mag)) - item_nmp = QtGui.QStandardItem(str(ma_count['manual'])) + item_nmp = QtGui.QStandardItem('{}({})'.format(ma_count['manual'], ma_count_total['manual'])) item_nmp.setIcon(self.manupicksicon_small) - item_nap = QtGui.QStandardItem(str(ma_count['auto'])) + item_nap = QtGui.QStandardItem('{}({})'.format(ma_count['auto'], ma_count_total['auto'])) item_nap.setIcon(self.autopicksicon_small) item_ref = QtGui.QStandardItem() # str(event_ref)) item_test = QtGui.QStandardItem() # str(event_test)) @@ -2987,6 +2990,8 @@ class MainWindow(QMainWindow): 'auto': event.pylot_autopicks} ma_count = {'manual': 0, 'auto': 0} + ma_count_total = {'manual': 0, + 'auto': 0} for ma in ma_props.keys(): if ma_props[ma]: @@ -2996,6 +3001,7 @@ class MainWindow(QMainWindow): continue if getQualityFromUncertainty(has_spe(pick), phaseErrors[self.getPhaseID(phasename)]) < 4: ma_count[ma] += 1 + ma_count_total[ma] += 1 # init table items for current row item_delete = QtGui.QTableWidgetItem() @@ -3006,9 +3012,9 @@ class MainWindow(QMainWindow): item_lon = QtGui.QTableWidgetItem() item_depth = QtGui.QTableWidgetItem() item_mag = QtGui.QTableWidgetItem() - item_nmp = QtGui.QTableWidgetItem(str(ma_count['manual'])) + item_nmp = QtGui.QTableWidgetItem('{}({})'.format(ma_count['manual'], ma_count_total['manual'])) item_nmp.setIcon(self.manupicksicon_small) - item_nap = QtGui.QTableWidgetItem(str(ma_count['auto'])) + item_nap = QtGui.QTableWidgetItem('{}({})'.format(ma_count['auto'], ma_count_total['auto'])) item_nap.setIcon(self.autopicksicon_small) item_ref = QtGui.QTableWidgetItem() item_test = QtGui.QTableWidgetItem() From b22d04db47c547270df9686154f60a39ac1a6d79 Mon Sep 17 00:00:00 2001 From: Marcel Date: Mon, 16 Jul 2018 13:52:28 +0200 Subject: [PATCH 121/169] [cleanup] replace equality by "is" --- autoPyLoT.py | 4 ++-- pylot/core/analysis/magnitude.py | 2 +- pylot/core/io/data.py | 4 ++-- pylot/core/io/phases.py | 2 +- pylot/core/pick/autopick.py | 2 +- pylot/core/pick/picker.py | 8 ++++---- pylot/core/util/dataprocessing.py | 4 ++-- pylot/core/util/utils.py | 2 +- pylot/core/util/widgets.py | 6 +++--- 9 files changed, 17 insertions(+), 17 deletions(-) diff --git a/autoPyLoT.py b/autoPyLoT.py index f253d420..2e07efe4 100755 --- a/autoPyLoT.py +++ b/autoPyLoT.py @@ -369,7 +369,7 @@ def autoPyLoT(input_dict=None, parameter=None, inputfile=None, fnames=None, even net_ml = local_mag.net_magnitude(magscaling) if net_ml: print("Network local magnitude: %4.1f" % net_ml.mag) - if magscaling == None: + if magscaling is None: scaling = False elif magscaling[0] != 0 and magscaling[1] != 0: scaling = False @@ -454,7 +454,7 @@ def autoPyLoT(input_dict=None, parameter=None, inputfile=None, fnames=None, even net_ml = local_mag.net_magnitude(magscaling) if net_ml: print("Network local magnitude: %4.1f" % net_ml.mag) - if magscaling == None: + if magscaling is None: scaling = False elif magscaling[0] != 0 and magscaling[1] != 0: scaling = False diff --git a/pylot/core/analysis/magnitude.py b/pylot/core/analysis/magnitude.py index cd1fe257..0a7e74ed 100644 --- a/pylot/core/analysis/magnitude.py +++ b/pylot/core/analysis/magnitude.py @@ -122,7 +122,7 @@ class Magnitude(object): def net_magnitude(self, magscaling=None): if self: - if magscaling == None: + if magscaling is None: scaling = False elif magscaling[0] != 0 and magscaling[1] != 0: scaling = False diff --git a/pylot/core/io/data.py b/pylot/core/io/data.py index 176f76ac..c6d99354 100644 --- a/pylot/core/io/data.py +++ b/pylot/core/io/data.py @@ -299,7 +299,7 @@ class Data(object): for i in range(len(picks_copy)): if picks_copy[i].phase_hint[0] == 'P': if (picks_copy[i].time_errors['upper_uncertainty'] >= upperErrors[0]) or \ - (picks_copy[i].time_errors['uncertainty'] == None): + (picks_copy[i].time_errors['uncertainty'] is None): print("Uncertainty exceeds or equal adjusted upper time error!") print("Adjusted uncertainty: {}".format(upperErrors[0])) print("Pick uncertainty: {}".format(picks_copy[i].time_errors['uncertainty'])) @@ -311,7 +311,7 @@ class Data(object): break if picks_copy[i].phase_hint[0] == 'S': if (picks_copy[i].time_errors['upper_uncertainty'] >= upperErrors[1]) or \ - (picks_copy[i].time_errors['uncertainty'] == None): + (picks_copy[i].time_errors['uncertainty'] is None): print("Uncertainty exceeds or equal adjusted upper time error!") print("Adjusted uncertainty: {}".format(upperErrors[1])) print("Pick uncertainty: {}".format(picks_copy[i].time_errors['uncertainty'])) diff --git a/pylot/core/io/phases.py b/pylot/core/io/phases.py index fa0e7587..ea14f548 100644 --- a/pylot/core/io/phases.py +++ b/pylot/core/io/phases.py @@ -499,7 +499,7 @@ def writephases(arrivals, fformat, filename, parameter=None, eventinfo=None): except KeyError as e: print(e) fm = None - if fm == None: + if fm is None: fm = '?' onset = arrivals[key]['P']['mpp'] year = onset.year diff --git a/pylot/core/pick/autopick.py b/pylot/core/pick/autopick.py index 7f48b6bc..d7bc487d 100644 --- a/pylot/core/pick/autopick.py +++ b/pylot/core/pick/autopick.py @@ -90,7 +90,7 @@ def autopickevent(data, param, iplot=0, fig_dict=None, fig_dict_wadatijack=None, if type(result) == dict: all_onsets[station] = result else: - if result == None: + if result is None: result = 'Picker exited unexpectedly.' print('Could not pick a station: {}\nReason: {}'.format(station, result)) diff --git a/pylot/core/pick/picker.py b/pylot/core/pick/picker.py index 952c47db..0ef817a2 100644 --- a/pylot/core/pick/picker.py +++ b/pylot/core/pick/picker.py @@ -291,7 +291,7 @@ class AICPicker(AutoPicker): print("AICPicker: Maximum for slope determination right at the beginning of the window!") print("Choose longer slope determination window!") if self.iplot > 1: - if self.fig == None or self.fig == 'None': + if self.fig is None or self.fig == 'None': fig = plt.figure() plt_flag = iplot else: @@ -337,7 +337,7 @@ class AICPicker(AutoPicker): self.slope = None if iplot > 1: - if self.fig == None or self.fig == 'None': + if self.fig is None or self.fig == 'None': fig = plt.figure() # self.iplot) plt_flag = iplot else: @@ -392,7 +392,7 @@ class AICPicker(AutoPicker): netstlc = '{}.{}.{}'.format(stats.network, stats.station, stats.location) fig.savefig('aicfig_{}_{}.png'.format(netstlc, stats.channel)) - if self.Pick == None: + if self.Pick is None: print('AICPicker: Could not find minimum, picking window too short?') return @@ -509,7 +509,7 @@ class PragPicker(AutoPicker): pickflag = 0 if iplot > 1: - if self.fig == None or self.fig == 'None': + if self.fig is None or self.fig == 'None': fig = plt.figure() # self.getiplot()) plt_flag = 1 else: diff --git a/pylot/core/util/dataprocessing.py b/pylot/core/util/dataprocessing.py index 491cfa37..a002bc75 100644 --- a/pylot/core/util/dataprocessing.py +++ b/pylot/core/util/dataprocessing.py @@ -148,7 +148,7 @@ class Metadata(object): try: invtype, robj = self._read_metadata_file(inv_fname) - if robj == None: + if robj is None: return except Exception as e: print('Could not read file {}'.format(inv_fname)) @@ -545,7 +545,7 @@ def restitute_trace(input_tuple): else: finv = invlist[0] inventory = read_inventory(finv, format='STATIONXML') - elif invtype == None: + elif invtype is None: return no_metadata(tr, seed_id) else: remove_trace = True diff --git a/pylot/core/util/utils.py b/pylot/core/util/utils.py index 80ef5d84..9dc73fcb 100644 --- a/pylot/core/util/utils.py +++ b/pylot/core/util/utils.py @@ -1110,7 +1110,7 @@ def loopIdentifyPhase(phase): """ from pylot.core.util.defaults import ALTSUFFIX - if phase == None: + if phase is None: raise NameError('Can not identify phase that is None') phase_copy = phase diff --git a/pylot/core/util/widgets.py b/pylot/core/util/widgets.py index 44506cb1..fbcb8b4c 100644 --- a/pylot/core/util/widgets.py +++ b/pylot/core/util/widgets.py @@ -2421,7 +2421,7 @@ class PickDlg(QDialog): if not x: return allpicks, pick_rel, phase, picktype = self.identify_selected_picks(x) - if pick_rel == None: + if pick_rel is None: return pick = allpicks[picktype][phase] message = '{} {}-pick'.format(picktype, phase) @@ -2442,7 +2442,7 @@ class PickDlg(QDialog): return x = event.mouseevent.xdata allpicks, pick_rel, phase, picktype = self.identify_selected_picks(x) - if pick_rel == None: + if pick_rel is None: return pick = allpicks[picktype][phase] message = '{} {}-pick'.format(picktype, phase) @@ -2499,7 +2499,7 @@ class PickDlg(QDialog): if not self.picks and not self.autopicks: return allpicks, pick_rel, phase, picktype = self.identify_selected_picks(x) - if pick_rel == None: + if pick_rel is None: return # delete the value from corresponding dictionary allpicks[picktype].pop(phase) From d151cdbc6d77c3b862c6bfbbfb03bb5788b1ea55 Mon Sep 17 00:00:00 2001 From: Marcel Date: Mon, 16 Jul 2018 13:59:21 +0200 Subject: [PATCH 122/169] [bugfix] added missing parameter "WAScaling" (not knowing what it does but it was missing!) --- PyLoT.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/PyLoT.py b/PyLoT.py index 6d7770ac..c9ec980d 100755 --- a/PyLoT.py +++ b/PyLoT.py @@ -3170,7 +3170,7 @@ class MainWindow(QMainWindow): # raise ProcessingError('Restitution of waveform data failed!') if type == 'ML': local_mag = LocalMagnitude(corr_wf, self.get_data().get_evt_data(), self.inputs.get('sstop'), - verbosity=True) ## MP MP missing parameter wascaling in function call! + self.inputs.get('WAScaling'), verbosity=True) return local_mag.updated_event() elif type == 'Mw': moment_mag = MomentMagnitude(corr_wf, self.get_data().get_evt_data(), self.inputs.get('vp'), From 415af11f63ee8a524a9d2c31af32fc0db9871f5a Mon Sep 17 00:00:00 2001 From: Marcel Date: Mon, 16 Jul 2018 14:09:06 +0200 Subject: [PATCH 123/169] [cleanup] add @staticmethod, some other stuff --- PyLoT.py | 18 ++++++---- autoPyLoT.py | 4 +-- pylot/core/loc/nll.py | 1 + pylot/core/pick/compare.py | 3 +- pylot/core/pick/utils.py | 6 ++-- pylot/core/util/dataprocessing.py | 9 +++-- pylot/core/util/event.py | 1 - pylot/core/util/utils.py | 2 +- pylot/core/util/widgets.py | 60 ++++++++++++++++++++----------- 9 files changed, 64 insertions(+), 40 deletions(-) diff --git a/PyLoT.py b/PyLoT.py index c9ec980d..6c3575e4 100755 --- a/PyLoT.py +++ b/PyLoT.py @@ -860,7 +860,8 @@ class MainWindow(QMainWindow): def inputs(self): return self._inputs - def getRoot(self): + @staticmethod + def getRoot(): settings = QSettings() return settings.value("data/dataRoot") @@ -1022,7 +1023,8 @@ class MainWindow(QMainWindow): raise DatastructureError('not specified') return fnames - def getPhaseID(self, phase): + @staticmethod + def getPhaseID(phase): return identifyPhaseID(phase) def get_current_event(self, eventbox=None): @@ -1150,7 +1152,8 @@ class MainWindow(QMainWindow): self.project.remove_event(event) self.init_events(True) - def createEventBox(self): + @staticmethod + def createEventBox(): ''' Eventbox generator. ''' @@ -1926,7 +1929,8 @@ class MainWindow(QMainWindow): self.compare_action.setEnabled(True) self.draw() - def checkEvent4comparison(self, event): + @staticmethod + def checkEvent4comparison(event): if event.pylot_picks and event.pylot_autopicks: for station in event.pylot_picks: if station in event.pylot_autopicks: @@ -2560,13 +2564,15 @@ class MainWindow(QMainWindow): if event.pylot_id == eventID: return event - def get_event_paths(self, eventlist): + @staticmethod + def get_event_paths(eventlist): eventPaths = [] for event in eventlist: eventPaths.append(event.path) return eventPaths - def get_event_ids(self, eventlist): + @staticmethod + def get_event_ids(eventlist): eventIDs = [] for event in eventlist: eventIDs.append(event.pylot_id) diff --git a/autoPyLoT.py b/autoPyLoT.py index 2e07efe4..24ddb415 100755 --- a/autoPyLoT.py +++ b/autoPyLoT.py @@ -38,6 +38,7 @@ def autoPyLoT(input_dict=None, parameter=None, inputfile=None, fnames=None, even """ Determine phase onsets automatically utilizing the automatic picking algorithms by Kueperkoch et al. 2010/2012. + :param obspyDMT_wfpath: if obspyDMT is used, name of data directory ("raw" or "processed") :param input_dict: :type input_dict: :param parameter: PylotParameter object containing parameters used for automatic picking @@ -200,8 +201,7 @@ def autoPyLoT(input_dict=None, parameter=None, inputfile=None, fnames=None, even events.append(os.path.join(datapath, eventID)) else: # autoPyLoT was initialized from GUI - events = [] - events.append(eventid) + events = [eventid] evID = os.path.split(eventid)[-1] locflag = 2 else: diff --git a/pylot/core/loc/nll.py b/pylot/core/loc/nll.py index 94986ed1..47ef4e10 100644 --- a/pylot/core/loc/nll.py +++ b/pylot/core/loc/nll.py @@ -76,6 +76,7 @@ def modify_inputs(ctrfn, root, nllocoutn, phasefn, tttn): def locate(fnin, parameter=None): """ takes an external program name and tries to run it + :param parameter: PyLoT Parameter object :param fnin: external program name :return: None """ diff --git a/pylot/core/pick/compare.py b/pylot/core/pick/compare.py index 148b1843..8b181d51 100644 --- a/pylot/core/pick/compare.py +++ b/pylot/core/pick/compare.py @@ -506,7 +506,8 @@ class PDFstatistics(object): return rlist - def writeThetaToFile(self, array, out_dir): + @staticmethod + def writeThetaToFile(array, out_dir): """ Method to write array like data to file. Useful since acquiring can take serious amount of time when dealing with large databases. diff --git a/pylot/core/pick/utils.py b/pylot/core/pick/utils.py index 96878c4d..5f54391c 100644 --- a/pylot/core/pick/utils.py +++ b/pylot/core/pick/utils.py @@ -226,8 +226,7 @@ def fmpicker(Xraw, Xfilt, pickwin, Pick, iplot=0, fig=None, linecolor='k'): # get zero crossings after most likely pick # initial onset is assumed to be the first zero crossing # first from unfiltered trace - zc1 = [] - zc1.append(Pick) + zc1 = [Pick] index1 = [] i = 0 for j in range(ipick[0][1], ipick[0][len(t[ipick]) - 1]): @@ -272,8 +271,7 @@ def fmpicker(Xraw, Xfilt, pickwin, Pick, iplot=0, fig=None, linecolor='k'): # now using filterd trace # next zero crossings after most likely pick - zc2 = [] - zc2.append(Pick) + zc2 = [Pick] index2 = [] i = 0 for j in range(ipick[0][1], ipick[0][len(t[ipick]) - 1]): diff --git a/pylot/core/util/dataprocessing.py b/pylot/core/util/dataprocessing.py index a002bc75..80ff3e32 100644 --- a/pylot/core/util/dataprocessing.py +++ b/pylot/core/util/dataprocessing.py @@ -263,7 +263,8 @@ class Metadata(object): return None, None - def _read_dless(self, path_to_inventory): + @staticmethod + def _read_dless(path_to_inventory): exc = None try: parser = Parser(path_to_inventory) @@ -272,7 +273,8 @@ class Metadata(object): return parser, exc - def _read_inventory_file(self, path_to_inventory): + @staticmethod + def _read_inventory_file(path_to_inventory): exc = None try: inv = read_inventory(path_to_inventory) @@ -582,9 +584,6 @@ def restitute_data(data, metadata, unit='VEL', force=False, ncores=0): takes a data stream and a path_to_inventory and returns the corrected waveform data stream :param data: seismic data stream - :param invtype: type of found metadata - :param inobj: either list of metadata files or `obspy.io.xseed.Parser` - object :param unit: unit to correct for (default: 'VEL') :param force: force restitution for already corrected traces (default: False) diff --git a/pylot/core/util/event.py b/pylot/core/util/event.py index a4f1e9cb..55ed8ea8 100644 --- a/pylot/core/util/event.py +++ b/pylot/core/util/event.py @@ -162,7 +162,6 @@ class Event(ObsPyEvent): """ Add automatic picks to event :param autopicks: automatic picks to add to event - :type autopicks dict: :return: :rtype: None """ diff --git a/pylot/core/util/utils.py b/pylot/core/util/utils.py index 9dc73fcb..e8568fd3 100644 --- a/pylot/core/util/utils.py +++ b/pylot/core/util/utils.py @@ -541,7 +541,7 @@ def isSorted(iterable): False """ assert isIterable(iterable), 'object is not iterable; object: {' \ - '0}'.format(iterable) + '}'.format(iterable) if type(iterable) is str: iterable = [s for s in iterable] return sorted(iterable) == iterable diff --git a/pylot/core/util/widgets.py b/pylot/core/util/widgets.py index fbcb8b4c..32b51b1a 100644 --- a/pylot/core/util/widgets.py +++ b/pylot/core/util/widgets.py @@ -242,7 +242,8 @@ class ComparisonWidget(QWidget): def clf(self): self.canvas.figure.clf() - def hasvalue(self, sender): + @staticmethod + def hasvalue(sender): text = sender.currentText() index = sender.findText(text.upper()) return index @@ -895,7 +896,8 @@ class PylotCanvas(FigureCanvas): fname += '.png' self.figure.savefig(fname) - def calcPanZoom(self, origin, lower_b, upper_b, factor, positive): + @staticmethod + def calcPanZoom(origin, lower_b, upper_b, factor, positive): d_lower = abs(origin - lower_b) d_upper = abs(origin - upper_b) @@ -1029,7 +1031,8 @@ class PylotCanvas(FigureCanvas): def clearPlotDict(self): self.plotdict = dict() - def calcPlotPositions(self, wfdata, compclass): + @staticmethod + def calcPlotPositions(wfdata, compclass): possible_plot_pos = list(range(len(wfdata))) plot_positions = {} for trace in wfdata: @@ -1173,16 +1176,20 @@ class PylotCanvas(FigureCanvas): self.setYLims(ax, zoomy) self.draw() - def getXLims(self, ax): + @staticmethod + def getXLims(ax): return ax.get_xlim() - def getYLims(self, ax): + @staticmethod + def getYLims(ax): return ax.get_ylim() - def setXLims(self, ax, lims): + @staticmethod + def setXLims(ax, lims): ax.set_xlim(lims) - def setYLims(self, ax, lims): + @staticmethod + def setYLims(ax, lims): ax.set_ylim(lims) def setYTickLabels(self, pos, labels): @@ -1298,7 +1305,8 @@ class PhaseDefaults(QtGui.QDialog): checkbox.setChecked(bool(phase in self.current_phases)) row += 1 - def create_phase_box(self, phase_name): + @staticmethod + def create_phase_box(phase_name): checkbox = QtGui.QCheckBox(phase_name) return checkbox @@ -1699,7 +1707,8 @@ class PickDlg(QDialog): phases) self.arrivals = arrivals - def prepare_phases(self): + @staticmethod + def prepare_phases(): settings = QtCore.QSettings() p_phases = settings.value('p_phases') s_phases = settings.value('s_phases') @@ -1875,7 +1884,8 @@ class PickDlg(QDialog): self.currentPhase = str(self.s_button.text()) self.activatePicking() - def getPhaseID(self, phase): + @staticmethod + def getPhaseID(phase): return identifyPhaseID(phase) def set_button_border_color(self, button, color=None): @@ -2087,7 +2097,8 @@ class PickDlg(QDialog): st += data.select(channel=action.text()) return st - def calcNoiseScaleFactor(self, noiselevel, zoomfactor=5., norm=1): + @staticmethod + def calcNoiseScaleFactor(noiselevel, zoomfactor=5., norm=1): # calculate factor to upscale a trace normed to 'norm' in a way that all values # zoomfactor*noiselevel are found within -0.5*norm and 0.5*norm scaleFactor = (norm/2.) / (zoomfactor * noiselevel) @@ -2626,15 +2637,18 @@ class PickDlg(QDialog): settings = QSettings() settings.setValue('autoFilter', self.autoFilterAction.isChecked()) - def updateChannelSettingsP(self, action): + @staticmethod + def updateChannelSettingsP(action): settings = QSettings() settings.setValue('p_channel_{}'.format(action.text()), action.isChecked()) - def updateChannelSettingsS(self, action): + @staticmethod + def updateChannelSettingsS(action): settings = QSettings() settings.setValue('s_channel_{}'.format(action.text()), action.isChecked()) - def getChannelSettingsP(self, channel): + @staticmethod + def getChannelSettingsP(channel): settings = QSettings() rval = real_Bool(settings.value('p_channel_{}'.format(channel))) compclass = settings.value('compclass') @@ -2648,7 +2662,8 @@ class PickDlg(QDialog): rval = False return rval - def getChannelSettingsS(self, channel): + @staticmethod + def getChannelSettingsS(channel): settings = QSettings() rval = real_Bool(settings.value('s_channel_{}'.format(channel))) compclass = settings.value('compclass') @@ -3220,7 +3235,8 @@ class TuneAutopicker(QWidget): def get_current_station_id(self): return str(self.stationBox.currentText()) - def gen_tab_widget(self, name, canvas): + @staticmethod + def gen_tab_widget(name, canvas): widget = QtGui.QWidget() v_layout = QtGui.QVBoxLayout() v_layout.addWidget(canvas) @@ -3650,7 +3666,8 @@ class PylotParaBox(QtGui.QWidget): grid.addWidget(box, index1, 2) return grid - def create_box(self, typ, tooltip): + @staticmethod + def create_box(typ, tooltip): if typ == str: box = QtGui.QLineEdit() elif typ == float: @@ -3665,7 +3682,8 @@ class PylotParaBox(QtGui.QWidget): raise TypeError('Unrecognized type {}'.format(typ)) return box - def create_multi_box(self, boxes, headline=None): + @staticmethod + def create_multi_box(boxes, headline=None): box = QtGui.QWidget() gl = QtGui.QGridLayout() column = 0 @@ -4366,7 +4384,8 @@ class PhasesTab(PropTab): self.PphasesEdit.setText(p_phases) self.SphasesEdit.setText(s_phases) - def sortPhases(self, phases): + @staticmethod + def sortPhases(phases): sorted_phases = {'P': [], 'S': []} for phase in phases: @@ -4607,7 +4626,8 @@ class LocalisationTab(PropTab): self.rootlabel.setText("{0} root directory".format(curtool)) self.binlabel.setText("{0} bin directory".format(curtool)) - def selectDirectory(self, edit): + @staticmethod + def selectDirectory(edit): selected_directory = QFileDialog.getExistingDirectory() # check if string is empty if selected_directory: From 754d42c8e3e137a08121032a1445305bb37998a8 Mon Sep 17 00:00:00 2001 From: Marcel Date: Mon, 16 Jul 2018 14:14:07 +0200 Subject: [PATCH 124/169] [cleanup] add requirements to setup.py --- setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.py b/setup.py index 76deed6e..09f8e357 100644 --- a/setup.py +++ b/setup.py @@ -8,7 +8,7 @@ setup( packages=['pylot', 'pylot.core', 'pylot.core.loc', 'pylot.core.pick', 'pylot.core.io', 'pylot.core.util', 'pylot.core.active', 'pylot.core.analysis', 'pylot.testing'], - requires=['obspy', 'PySide', 'matplotlib', 'numpy'], + requires=['obspy', 'PySide', 'matplotlib', 'numpy', 'scipy', 'pyqtgraph'], url='dummy', license='LGPLv3', author='Sebastian Wehling-Benatelli', From 7a0d3486a6d88e57cc4fcf806204a43db44cddd6 Mon Sep 17 00:00:00 2001 From: Marcel Date: Mon, 16 Jul 2018 14:21:41 +0200 Subject: [PATCH 125/169] [cleanup] code cleanup by PyCharm --- PyLoT.py | 115 ++++++++++++------------- autoPyLoT.py | 12 +-- pylot/core/analysis/magnitude.py | 20 +++-- pylot/core/io/data.py | 4 +- pylot/core/io/default_parameters.py | 10 +-- pylot/core/io/phases.py | 29 +++---- pylot/core/pick/autopick.py | 29 +++---- pylot/core/pick/picker.py | 57 +++++++------ pylot/core/pick/utils.py | 62 ++++++++------ pylot/core/util/array_map.py | 5 +- pylot/core/util/dataprocessing.py | 18 +--- pylot/core/util/defaults.py | 1 - pylot/core/util/obspyDMT_interface.py | 4 +- pylot/core/util/thread.py | 15 ++-- pylot/core/util/utils.py | 17 ++-- pylot/core/util/widgets.py | 116 +++++++++++++------------- pylot/styles/style_settings.py | 15 ++-- tests/test_Metadata/test_Metadata.py | 25 ++++-- 18 files changed, 285 insertions(+), 269 deletions(-) diff --git a/PyLoT.py b/PyLoT.py index 6c3575e4..9e879a54 100755 --- a/PyLoT.py +++ b/PyLoT.py @@ -48,7 +48,6 @@ from obspy.core.util import AttribDict from pylot.core.util.obspyDMT_interface import check_obspydmt_structure - try: import pyqtgraph as pg except Exception as e: @@ -195,7 +194,6 @@ class MainWindow(QMainWindow): self.loc = False - def init_config_files(self, infile): pylot_config_dir = os.path.join(os.path.expanduser('~'), '.pylot') if not os.path.exists(pylot_config_dir): @@ -210,7 +208,6 @@ class MainWindow(QMainWindow): self._inputs.export2File(infile) self.infile = infile - def setupUi(self): try: self.startTime = min( @@ -327,19 +324,19 @@ class MainWindow(QMainWindow): # "Create a new event.") self.openEventAction = self.createAction(self, "Load event information...", self.load_data, - "Ctrl+M", + "Ctrl+M", openEventIcon, - "Load event information for " - "the displayed event.") + "Load event information for " + "the displayed event.") self.openEventAction.setEnabled(False) self.openEventAction.setData(None) self.openEventsAutoAction = self.createAction(self, "Load event information &automatically ... ", self.load_multiple_data, - "Ctrl+A", + "Ctrl+A", openEventsIcon, - "Load event data automatically " - "for all events.") + "Load event data automatically " + "for all events.") self.openEventsAutoAction.setEnabled(False) self.openEventsAutoAction.setData(None) @@ -360,7 +357,7 @@ class MainWindow(QMainWindow): self.saveEventAction = self.createAction(self, "Save &event information ...", self.saveData, "Ctrl+P", saveEventsIcon, "Save event pick data," - " source origin and magnitude.") + " source origin and magnitude.") self.disableSaveEventAction() self.addEventDataAction = self.createAction(self, "Add &events ...", @@ -399,15 +396,15 @@ class MainWindow(QMainWindow): "Ctrl+F", self.filter_icon, """Adjust filter parameters.""") self.inventoryAction = self.createAction(self, "Select &Inventory ...", - self.get_new_metadata, - "Ctrl+I", self.inventoryIcon, - """Select metadata for current project""", - False) + self.get_new_metadata, + "Ctrl+I", self.inventoryIcon, + """Select metadata for current project""", + False) self.initMapAction = self.createAction(self, "Init array map ...", - self.init_array_map, - "Ctrl+M", self.mapIcon, - """Initialize array map with current metadata""", - False) + self.init_array_map, + "Ctrl+M", self.mapIcon, + """Initialize array map with current metadata""", + False) self.initMapAction.setEnabled(False) self.selectPAction = self.createAction(self, "&P", self.alterPhase, "Alt+P", @@ -424,9 +421,9 @@ class MainWindow(QMainWindow): "automatic pick " "data.", False) self.compare_action.setEnabled(False) - self.qualities_action = self.createAction(parent=self, text='Show pick qualitites...', - slot=self.pickQualities, shortcut='Alt+Q', - icon=qualities_icon, tip='Histogram of pick qualities') + self.qualities_action = self.createAction(parent=self, text='Show pick qualitites...', + slot=self.pickQualities, shortcut='Alt+Q', + icon=qualities_icon, tip='Histogram of pick qualities') self.qualities_action.setEnabled(False) printAction = self.createAction(self, "&Print event ...", @@ -471,7 +468,6 @@ class MainWindow(QMainWindow): checkable=True) self.e_action.setEnabled(False) - componentActions = (self.z_action, self.n_action, self.e_action) self.auto_tune = self.createAction(parent=self, text='autoTune', @@ -483,19 +479,19 @@ class MainWindow(QMainWindow): self.auto_pick = self.createAction(parent=self, text='Current event', slot=self.autoPick, shortcut='Alt+Ctrl+A', icon=autopylot_icon, tip='Automatically pick' - ' the displayed waveforms.') + ' the displayed waveforms.') self.auto_pick.setEnabled(False) self.auto_pick_local = self.createAction(parent=self, text='Whole project (local machine)...', slot=self.autoPickProject, shortcut=None, icon=self.autopicksicon_small, tip='Automatically pick' - ' the complete project on local machine.') + ' the complete project on local machine.') self.auto_pick_local.setEnabled(False) self.auto_pick_sge = self.createAction(parent=self, text='Whole project (grid engine)...', slot=self.autoPickProjectSGE, shortcut=None, icon=self.autopicksicon_small, tip='Automatically pick' - ' the complete project on grid engine.') + ' the complete project on grid engine.') self.auto_pick_sge.setEnabled(False) pickActions = (self.auto_tune, self.auto_pick, self.compare_action, self.qualities_action) @@ -527,10 +523,10 @@ class MainWindow(QMainWindow): self.editMenu = self.menuBar().addMenu('&Edit') editActions = (self.filterActionP, self.filterActionS, filterEditAction, None, - #self.selectPAction, self.selectSAction, None, + # self.selectPAction, self.selectSAction, None, self.inventoryAction, self.initMapAction, None, prefsEventAction) - #printAction) #TODO: print event? + # printAction) #TODO: print event? pickMenuActions = (self.parameterAction,) self.pickMenu = self.menuBar().addMenu('&Picking') @@ -546,13 +542,11 @@ class MainWindow(QMainWindow): self.openProjectAction, self.saveProjectAction, self.saveProjectAsAction) - eventToolActions = (self.addEventDataAction, self.openEventAction, self.openEventsAutoAction, self.saveEventAction, self.loadlocationaction, self.loadpilotevent) - toolbars_keys = [ "FileTools", "EventTools", @@ -892,7 +886,7 @@ class MainWindow(QMainWindow): fext = '.xml' for event in events: path = event.path - eventname = path.split('/')[-1] #or event.pylot_id + eventname = path.split('/')[-1] # or event.pylot_id filename = os.path.join(path, 'PyLoT_' + eventname + fext) if os.path.isfile(filename): self.load_data(filename, draw=False, event=event, overwrite=True) @@ -965,7 +959,7 @@ class MainWindow(QMainWindow): button.setAutoFillBackground(True) elif type(color) == str: button.setStyleSheet('QPushButton{border-color: %s}' - 'QPushButton:checked{background-color: rgba%s}'% (color, color)) + 'QPushButton:checked{background-color: rgba%s}' % (color, color)) elif type(color) == tuple: button.setStyleSheet('QPushButton{border-color: rgba%s}' 'QPushButton:checked{background-color: rgba%s}' % (str(color), str(color))) @@ -1195,7 +1189,7 @@ class MainWindow(QMainWindow): def user_modify_path(self, reason=''): dialog = QtGui.QInputDialog(parent=self) new_path, executed = dialog.getText(self, 'Change Project rootpath', - '{}Rename project path {}:'.format(reason, self.project.rootpath)) + '{}Rename project path {}:'.format(reason, self.project.rootpath)) return new_path, executed def data_check(self): @@ -1282,7 +1276,7 @@ class MainWindow(QMainWindow): time = lat = lon = depth = mag = None if len(event.origins) == 1: origin = event.origins[0] - time = origin.time + 0 # add 0 because there was an exception for time = 0s + time = origin.time + 0 # add 0 because there was an exception for time = 0s lat = origin.latitude lon = origin.longitude depth = origin.depth @@ -1335,7 +1329,7 @@ class MainWindow(QMainWindow): for item in itemlist: item.setEnabled(False) - #item color + # item color self.setItemColor(itemlist, id, event, current_event) model.appendRow(itemlist) @@ -1431,7 +1425,7 @@ class MainWindow(QMainWindow): upperErrors=[uppererrorP[3], uppererrorS[3]]) saved_as += str(outformat) + ' ' except TypeError: - print('WARNING: Format: {} not yet implemented'.format(outformat)) + print('WARNING: Format: {} not yet implemented'.format(outformat)) self.get_data().setEvtData(event) msg = 'Event {} saved as {} in format(s) {}'.format(event.pylot_id, fbasename, saved_as.strip()) @@ -1494,11 +1488,10 @@ class MainWindow(QMainWindow): if len(eventdict) < 1: return - # init event selection options for autopick - self.compareoptions =[('tune events', self.get_ref_events, self._style['ref']['rgba']), - ('test events', self.get_test_events, self._style['test']['rgba']), - ('all (picked) events', self.get_manu_picked_events, None)] + self.compareoptions = [('tune events', self.get_ref_events, self._style['ref']['rgba']), + ('test events', self.get_test_events, self._style['test']['rgba']), + ('all (picked) events', self.get_manu_picked_events, None)] self.cmpw = CompareEventsWidget(self, self.compareoptions, eventdict, comparisons) self.cmpw.start.connect(self.compareMulti) @@ -1521,7 +1514,6 @@ class MainWindow(QMainWindow): compare_widget = self.buildMultiCompareWidget(eventlist_overlap) compare_widget.show() - def buildMultiCompareWidget(self, eventlist): global_comparison = Comparison(eventlist=eventlist) compare_widget = ComparisonWidget(global_comparison, self) @@ -1793,7 +1785,7 @@ class MainWindow(QMainWindow): nth_sample = int(settings.value("nth_sample")) if settings.value("nth_sample") else 1 npts_max = 1e7 npts = self.get_npts_to_plot() - npts2plot = npts/nth_sample + npts2plot = npts / nth_sample if npts2plot < npts_max: settings.setValue('large_dataset', False) else: @@ -2091,7 +2083,8 @@ class MainWindow(QMainWindow): elif self.filterActionS.isChecked(): phase = 'S' if self.getFilterOptions(): - if (phase == 'P' and self.filterActionP.isChecked()) or (phase == 'S' and self.filterActionS.isChecked()): + if (phase == 'P' and self.filterActionP.isChecked()) or ( + phase == 'S' and self.filterActionS.isChecked()): kwargs = self.getFilterOptions()[phase].parseFilterOptions() self.pushFilterWF(kwargs) else: @@ -2102,8 +2095,8 @@ class MainWindow(QMainWindow): self.get_data().resetWFData() if plot: self.plotWaveformDataThread(filter=False) - #self.drawPicks() - #self.draw() + # self.drawPicks() + # self.draw() def getAutoFilteroptions(self, phase): return getAutoFilteroptions(phase, self._inputs) @@ -2423,7 +2416,7 @@ class MainWindow(QMainWindow): # thread to prevent handling of QPixmap objects outside of # the main thread self.init_fig_dict() - #if not self.tap: + # if not self.tap: # init TuneAutopicker object self.tap = TuneAutopicker(self, self.obspy_dmt) # first call of update to init tabs with empty canvas @@ -2432,7 +2425,7 @@ class MainWindow(QMainWindow): # creating and filling figure canvas self.tap.update.connect(self.update_autopicker) self.tap.figure_tabs.setCurrentIndex(0) - #else: + # else: # self.update_autopicker() # self.tap.fill_eventbox() self.tap.show() @@ -2463,11 +2456,11 @@ class MainWindow(QMainWindow): if not self.apw: # init event selection options for autopick - self.pickoptions =[('current event', self.get_current_event, None), - ('tune events', self.get_ref_events, self._style['ref']['rgba']), - ('test events', self.get_test_events, self._style['test']['rgba']), - ('all (picked) events', self.get_manu_picked_events, None), - ('all events', self.get_all_events, None)] + self.pickoptions = [('current event', self.get_current_event, None), + ('tune events', self.get_ref_events, self._style['ref']['rgba']), + ('test events', self.get_test_events, self._style['test']['rgba']), + ('all (picked) events', self.get_manu_picked_events, None), + ('all events', self.get_all_events, None)] self.listWidget = QListWidget() self.setDirty(True) @@ -2645,7 +2638,7 @@ class MainWindow(QMainWindow): picksdict = picksdict_from_picks(evt=self.get_data().get_evt_data()) if type == 'manual': event.addPicks(picksdict['manual']) - #event.picks.update(picks) MP MP idea + # event.picks.update(picks) MP MP idea elif type == 'auto': event.addAutopicks(picksdict['auto']) @@ -2682,7 +2675,7 @@ class MainWindow(QMainWindow): stat_picks = self.getPicks(type=picktype)[station] for phase in stat_picks: - if phase == 'SPt': continue # wadati SP time + if phase == 'SPt': continue # wadati SP time picks = stat_picks[phase] if type(stat_picks[phase]) is not dict and type(stat_picks[phase]) is not AttribDict: return @@ -2801,7 +2794,7 @@ class MainWindow(QMainWindow): lt.locate(ctrfile) except RuntimeError as e: print(e.message) - #finally: + # finally: # os.remove(phasefile) self.get_data().applyEVTData(lt.read_location(locpath), typ='event') @@ -2904,7 +2897,7 @@ class MainWindow(QMainWindow): self.array_map.eventLoc = (lat, lon) if self.get_current_event(): self.array_map.refresh_drawings(self.get_current_event().getPicks(), - self.get_current_event().getAutopicks(),) + self.get_current_event().getAutopicks(), ) self._eventChanged[1] = False def init_event_table(self, tabindex=2): @@ -3030,7 +3023,7 @@ class MainWindow(QMainWindow): if hasattr(event, 'origins'): if event.origins: origin = event.origins[0] - item_time.setText(str(origin.time + 0).split('.')[0]) # +0 as workaround in case time=0s + item_time.setText(str(origin.time + 0).split('.')[0]) # +0 as workaround in case time=0s item_lon.setText(str(origin.longitude)) item_lat.setText(str(origin.latitude)) item_depth.setText(str(origin.depth)) @@ -3164,7 +3157,6 @@ class MainWindow(QMainWindow): return set_inv(settings) - def calc_magnitude(self, type='ML'): self.init_metadata() if not self.metadata: @@ -3289,11 +3281,11 @@ class MainWindow(QMainWindow): if hasattr(self.project, 'metadata'): if self.project.metadata: self.init_metadata(ask_default=False) - #self.init_array_map(index=0) + # self.init_array_map(index=0) return if hasattr(self.project, 'inv_path'): self.init_metadata(ask_default=False) - #self.init_array_map(index=0) + # self.init_array_map(index=0) return self.init_array_tab() @@ -3350,7 +3342,6 @@ class MainWindow(QMainWindow): self.dataPlot.setPermText(1) self.dataPlot.setPermText(0, '| Number of traces: {} |'.format(len(self.getPlotWidget().getPlotDict()))) - def _setDirty(self): self.setDirty(True) @@ -3389,7 +3380,7 @@ class MainWindow(QMainWindow): def helpHelp(self): if checkurl(): form = HelpForm(self, - 'https://ariadne.geophysik.ruhr-uni-bochum.de/trac/PyLoT/wiki') + 'https://ariadne.geophysik.ruhr-uni-bochum.de/trac/PyLoT/wiki') else: form = HelpForm(self, ':/help.html') form.show() @@ -3594,7 +3585,7 @@ def create_window(): def main(args=None): project_filename = None - #args.project_filename = 'C:/Shared/AlpArray/alparray_data/project_alparray_test.plp' + # args.project_filename = 'C:/Shared/AlpArray/alparray_data/project_alparray_test.plp' pylot_infile = None if args: if args.project_filename: diff --git a/autoPyLoT.py b/autoPyLoT.py index 24ddb415..68ecbbd6 100755 --- a/autoPyLoT.py +++ b/autoPyLoT.py @@ -118,7 +118,7 @@ def autoPyLoT(input_dict=None, parameter=None, inputfile=None, fnames=None, even if not parameter: if inputfile: parameter = PylotParameter(inputfile) - #iplot = parameter['iplot'] + # iplot = parameter['iplot'] else: infile = os.path.join(os.path.expanduser('~'), '.pylot', 'pylot.in') print('Using default input file {}'.format(infile)) @@ -151,7 +151,7 @@ def autoPyLoT(input_dict=None, parameter=None, inputfile=None, fnames=None, even datastructure.setExpandFields(exf) # check if default location routine NLLoc is available and all stations are used - if real_None(parameter['nllocbin']) and station=='all': + if real_None(parameter['nllocbin']) and station == 'all': locflag = 1 # get NLLoc-root path nllocroot = parameter.get('nllocroot') @@ -289,7 +289,7 @@ def autoPyLoT(input_dict=None, parameter=None, inputfile=None, fnames=None, even corr_dat = None if metadata: # rotate stations to ZNE - #wfdat = check4rotated(wfdat, metadata) # MP MP TEMPORARILY DISABLED !!!!!!!!!!! + # wfdat = check4rotated(wfdat, metadata) # MP MP TEMPORARILY DISABLED !!!!!!!!!!! if locflag: print("Restitute data ...") corr_dat = restitute_data(wfdat.copy(), metadata, ncores=ncores) @@ -505,7 +505,7 @@ def autoPyLoT(input_dict=None, parameter=None, inputfile=None, fnames=None, even endsplash = '''------------------------------------------\n' -----Finished event %s!-----\n' ------------------------------------------'''.format \ - (version=_getVersionString()) % evID + (version=_getVersionString()) % evID print(endsplash) locflag = glocflag if locflag == 0: @@ -534,9 +534,9 @@ if __name__ == "__main__": action='store', help='''full path to the file containing the input parameters for autoPyLoT''') - parser.add_argument('-p', '-P', '--iplot', type=int, + parser.add_argument('-p', '-P', '--iplot', type=int, action='store', default=0, - help='''optional, logical variable for plotting: 0=none, 1=partial, 2=all''') + help='''optional, logical variable for plotting: 0=none, 1=partial, 2=all''') parser.add_argument('-f', '-F', '--fnames', type=str, action='store', help='''optional, list of data file names''') diff --git a/pylot/core/analysis/magnitude.py b/pylot/core/analysis/magnitude.py index 0a7e74ed..0fa854bc 100644 --- a/pylot/core/analysis/magnitude.py +++ b/pylot/core/analysis/magnitude.py @@ -17,6 +17,7 @@ from pylot.core.util.utils import common_range, fit_curve from scipy import integrate, signal from scipy.optimize import curve_fit + def richter_magnitude_scaling(delta): distance = np.array([0, 10, 20, 25, 30, 35, 40, 45, 50, 60, 70, 75, 85, 90, 100, 110, 120, 130, 140, 150, 160, 170, 180, 190, 200, 210, 230, 240, 250, @@ -225,7 +226,7 @@ class LocalMagnitude(Magnitude): sqH = np.sqrt(power_sum) # get time array - th=np.arange(0, st[0].stats.npts/st[0].stats.sampling_rate, st[0].stats.delta) + th = np.arange(0, st[0].stats.npts / st[0].stats.sampling_rate, st[0].stats.delta) # get maximum peak within pick window iwin = getsignalwin(th, t0 - stime, self.calc_win) ii = min([iwin[len(iwin) - 1], len(th)]) @@ -245,9 +246,9 @@ class LocalMagnitude(Magnitude): ax.plot(th[iwin], sqH[iwin], 'g') ax.plot([t0 - stime, t0 - stime], [0, max(sqH)], 'r', linewidth=2) ax.set_title('Station %s, Channel %s, RMS Horizontal Trace, ' - 'WA-peak-to-peak=%6.3f mm' % (st[0].stats.station, + 'WA-peak-to-peak=%6.3f mm' % (st[0].stats.station, st[0].stats.channel, - wapp)) + wapp)) ax.set_xlabel('Time [s]') ax.set_ylabel('Displacement [mm]') ax = fig.add_subplot(212) @@ -257,15 +258,16 @@ class LocalMagnitude(Magnitude): ax.plot([t0 - stime, t0 - stime], [0, max(sqH)], 'r', linewidth=2) ax.set_title('Channel %s, RMS Horizontal Trace, ' 'WA-peak-to-peak=%6.3f mm' % (st[1].stats.channel, - wapp)) + wapp)) ax.set_xlabel('Time [s]') ax.set_ylabel('Displacement [mm]') fig.show() - try: input() - except SyntaxError: pass + try: + input() + except SyntaxError: + pass plt.close(fig) - return wapp, fig def calc(self): @@ -309,7 +311,7 @@ class LocalMagnitude(Magnitude): a0 = a0 * 1e03 # mm to nm (see Havskov & Ottemöller, 2010) magnitude = ope.StationMagnitude(mag=np.log10(a0) \ + self.wascaling[0] * np.log10(delta) + self.wascaling[1] - * delta + self.wascaling[ + * delta + self.wascaling[ 2]) magnitude.origin_id = self.origin_id magnitude.waveform_id = pick.waveform_id @@ -372,7 +374,7 @@ class MomentMagnitude(Magnitude): def calc(self): for a in self.arrivals: - if a.phase not in 'pP': + if a.phase not in 'pP': continue # make sure calculating Mo only from reliable onsets # NLLoc: time_weight = 0 => do not use onset! diff --git a/pylot/core/io/data.py b/pylot/core/io/data.py index c6d99354..1701e10b 100644 --- a/pylot/core/io/data.py +++ b/pylot/core/io/data.py @@ -17,6 +17,7 @@ from pylot.core.util.utils import fnConstructor, full_range, remove_underscores, import pylot.core.loc.velest as velest from pylot.core.util.obspyDMT_interface import qml_from_obspyDMT + class Data(object): """ Data container with attributes wfdata holding ~obspy.core.stream. @@ -284,7 +285,7 @@ class Data(object): mstation_ext = mstation + '_' for k in range(len(picks_copy)): if ((picks_copy[k].waveform_id.station_code == mstation) or - (picks_copy[k].waveform_id.station_code == mstation_ext)) and \ + (picks_copy[k].waveform_id.station_code == mstation_ext)) and \ (picks_copy[k].method_id == 'auto'): del picks_copy[k] break @@ -416,7 +417,6 @@ class Data(object): self.dirty = False return True - def appendWFData(self, fnames, synthetic=False): """ Read waveform data from fnames and append it to current wf data diff --git a/pylot/core/io/default_parameters.py b/pylot/core/io/default_parameters.py index 78057056..71ea2377 100644 --- a/pylot/core/io/default_parameters.py +++ b/pylot/core/io/default_parameters.py @@ -456,11 +456,11 @@ defaults = {'rootpath': {'type': str, 'namestring': 'Wadati tolerance'}, 'jackfactor': {'type': float, - 'tooltip': 'pick is removed if the variance of the subgroup with the pick removed is larger than the mean variance of all subgroups times safety factor', - 'value': 5.0, - 'min': 0., - 'max': np.inf, - 'namestring': 'Jackknife safety factor'}, + 'tooltip': 'pick is removed if the variance of the subgroup with the pick removed is larger than the mean variance of all subgroups times safety factor', + 'value': 5.0, + 'min': 0., + 'max': np.inf, + 'namestring': 'Jackknife safety factor'}, 'WAscaling': {'type': (float, float, float), 'tooltip': 'Scaling relation (log(Ao)+Alog(r)+Br+C) of Wood-Anderson amplitude Ao [nm] \ diff --git a/pylot/core/io/phases.py b/pylot/core/io/phases.py index ea14f548..a041f833 100644 --- a/pylot/core/io/phases.py +++ b/pylot/core/io/phases.py @@ -245,7 +245,7 @@ def picksdict_from_picks(evt): if picker.startswith('smi:local/'): picker = picker.split('smi:local/')[1] except IndexError: - picker = 'manual' # MP MP TODO maybe improve statement + picker = 'manual' # MP MP TODO maybe improve statement try: onsets = picksdict[picker][station] except KeyError as e: @@ -346,6 +346,7 @@ def picks_from_picksdict(picks, creation_info=None): picks_list.append(pick) return picks_list + def reassess_pilot_db(root_dir, db_dir, out_dir=None, fn_param=None, verbosity=0): import glob @@ -916,9 +917,9 @@ def merge_picks(event, picks): network = pick.waveform_id.network_code method = pick.method_id for p in event.picks: - if p.waveform_id.station_code == station\ - and p.waveform_id.network_code == network\ - and p.phase_hint == phase\ + if p.waveform_id.station_code == station \ + and p.waveform_id.network_code == network \ + and p.phase_hint == phase \ and (str(p.method_id) in str(method) or str(method) in str(p.method_id)): p.time, p.time_errors, p.waveform_id.network_code, p.method_id = time, err, network, method @@ -972,14 +973,14 @@ def getQualitiesfromxml(xmlnames, ErrorsP, ErrorsS, plotflag=1): phase = identifyPhase(loopIdentifyPhase(Pick.phase_hint)) if phase == 'P': if ((mpick.waveform_id.station_code == mstation) or - (mpick.waveform_id.station_code == mstation_ext)) and \ + (mpick.waveform_id.station_code == mstation_ext)) and \ ((mpick.method_id).split('/')[1] == 'auto') and \ (mpick.time_errors['uncertainty'] <= ErrorsP[3]): del mpick break elif phase == 'S': if ((mpick.waveform_id.station_code == mstation) or - (mpick.waveform_id.station_code == mstation_ext)) and \ + (mpick.waveform_id.station_code == mstation_ext)) and \ ((mpick.method_id).split('/')[1] == 'auto') and \ (mpick.time_errors['uncertainty'] <= ErrorsS[3]): del mpick @@ -1032,19 +1033,19 @@ def getQualitiesfromxml(xmlnames, ErrorsP, ErrorsS, plotflag=1): P0perc = 0 if len(Pw1) > 0: P1perc = 100 / numPweights * len(Pw1) - else: + else: P1perc = 0 if len(Pw2) > 0: P2perc = 100 / numPweights * len(Pw2) - else: + else: P2perc = 0 if len(Pw3) > 0: P3perc = 100 / numPweights * len(Pw3) - else: + else: P3perc = 0 if len(Pw4) > 0: P4perc = 100 / numPweights * len(Pw4) - else: + else: P4perc = 0 if len(Sw0) > 0: S0perc = 100 / numSweights * len(Sw0) @@ -1052,19 +1053,19 @@ def getQualitiesfromxml(xmlnames, ErrorsP, ErrorsS, plotflag=1): S0perc = 0 if len(Sw1) > 0: S1perc = 100 / numSweights * len(Sw1) - else: + else: S1perc = 0 if len(Sw2) > 0: S2perc = 100 / numSweights * len(Sw2) - else: + else: S2perc = 0 if len(Sw3) > 0: S3perc = 100 / numSweights * len(Sw3) - else: + else: S3perc = 0 if len(Sw4) > 0: S4perc = 100 / numSweights * len(Sw4) - else: + else: S4perc = 0 weights = ('0', '1', '2', '3', '4') diff --git a/pylot/core/pick/autopick.py b/pylot/core/pick/autopick.py index d7bc487d..29f8d6eb 100644 --- a/pylot/core/pick/autopick.py +++ b/pylot/core/pick/autopick.py @@ -16,7 +16,7 @@ from pylot.core.pick.charfuns import HOScf, AICcf, ARZcf, ARHcf, AR3Ccf from pylot.core.pick.picker import AICPicker, PragPicker from pylot.core.pick.utils import checksignallength, checkZ4S, earllatepicker, \ getSNR, fmpicker, checkPonsets, wadaticheck -from pylot.core.util.utils import getPatternLine, gen_Pool,\ +from pylot.core.util.utils import getPatternLine, gen_Pool, \ real_Bool, identifyPhaseID from obspy.taup import TauPyModel @@ -95,7 +95,7 @@ def autopickevent(data, param, iplot=0, fig_dict=None, fig_dict_wadatijack=None, print('Could not pick a station: {}\nReason: {}'.format(station, result)) # no Wadati/JK for single station (also valid for tuning mode) - if len(stations) == 1: + if len(stations) == 1: return all_onsets # quality control @@ -133,7 +133,8 @@ def call_autopickstation(input_tuple): print('Running in interactive mode') # multiprocessing not possible with interactive plotting try: - return autopickstation(wfstream, pickparam, verbose, fig_dict=fig_dict, iplot=iplot, metadata=metadata, origin=origin) + return autopickstation(wfstream, pickparam, verbose, fig_dict=fig_dict, iplot=iplot, metadata=metadata, + origin=origin) except Exception as e: return e, wfstream[0].stats.station @@ -343,7 +344,7 @@ def autopickstation(wfstream, pickparam, verbose=False, # make sure pstart and pstop are inside zdat[0] pstart = max(pstart, 0) - pstop = min(pstop, len(zdat[0])*zdat[0].stats.delta) + pstop = min(pstop, len(zdat[0]) * zdat[0].stats.delta) if not use_taup is True or origin: Lc = pstop - pstart @@ -586,7 +587,7 @@ def autopickstation(wfstream, pickparam, verbose=False, FM) print(msg) msg = 'autopickstation: Refined P-Pick: {} s | P-Error: {} s'.format(zdat[0].stats.starttime \ - + mpickP, Perror) + + mpickP, Perror) print(msg) Sflag = 1 @@ -620,7 +621,7 @@ def autopickstation(wfstream, pickparam, verbose=False, ndat = edat pickSonset = (edat is not None and ndat is not None and len(edat) > 0 and len( - ndat) > 0 and Pweight < 4) + ndat) > 0 and Pweight < 4) if pickSonset: # determine time window for calculating CF after P onset @@ -628,8 +629,8 @@ def autopickstation(wfstream, pickparam, verbose=False, round(max([mpickP + sstart, 0])), # MP MP relative time axis round(min([ mpickP + sstop, - edat[0].stats.endtime-edat[0].stats.starttime, - ndat[0].stats.endtime-ndat[0].stats.starttime + edat[0].stats.endtime - edat[0].stats.starttime, + ndat[0].stats.endtime - ndat[0].stats.starttime ])) ] @@ -724,7 +725,7 @@ def autopickstation(wfstream, pickparam, verbose=False, if not slope: slope = 0 if (slope >= minAICSslope and - aicarhpick.getSNR() >= minAICSSNR and aicarhpick.getpick() is not None): + aicarhpick.getSNR() >= minAICSSNR and aicarhpick.getpick() is not None): aicSflag = 1 msg = 'AIC S-pick passes quality control: Slope: {0} counts/s, ' \ 'SNR: {1}\nGo on with refined picking ...\n' \ @@ -866,7 +867,7 @@ def autopickstation(wfstream, pickparam, verbose=False, Serror = pickerr[ipick] msg = 'autopickstation: Refined S-Pick: {} s | S-Error: {} s'.format(hdat[0].stats.starttime \ - + mpickS, Serror) + + mpickS, Serror) print(msg) # get SNR @@ -912,7 +913,7 @@ def autopickstation(wfstream, pickparam, verbose=False, # re-create stream object including both horizontal components hdat = edat.copy() hdat += ndat - + else: print('autopickstation: No horizontal component data available or ' 'bad P onset, skipping S picking!') @@ -1216,11 +1217,11 @@ def iteratepicker(wf, NLLocfile, picks, badpicks, pickparameter, fig_dict=None): print( "iteratepicker: The following picking parameters have been modified for iterative picking:") print( - "pstart: %fs => %fs" % (pstart_old, pickparameter.get('pstart'))) + "pstart: %fs => %fs" % (pstart_old, pickparameter.get('pstart'))) print( - "pstop: %fs => %fs" % (pstop_old, pickparameter.get('pstop'))) + "pstop: %fs => %fs" % (pstop_old, pickparameter.get('pstop'))) print( - "sstop: %fs => %fs" % (sstop_old, pickparameter.get('sstop'))) + "sstop: %fs => %fs" % (sstop_old, pickparameter.get('sstop'))) print("pickwinP: %fs => %fs" % ( pickwinP_old, pickparameter.get('pickwinP'))) print("Precalcwin: %fs => %fs" % ( diff --git a/pylot/core/pick/picker.py b/pylot/core/pick/picker.py index 0ef817a2..bb6d5efa 100644 --- a/pylot/core/pick/picker.py +++ b/pylot/core/pick/picker.py @@ -164,9 +164,9 @@ class AICPicker(AutoPicker): iplot = int(self.iplot) except: if self.iplot == True or self.iplot == 'True': - iplot = 2 + iplot = 2 else: - iplot = 0 + iplot = 0 # find NaN's nn = np.isnan(self.cf) @@ -215,8 +215,8 @@ class AICPicker(AutoPicker): tsafety = self.TSNR[1] # safety gap, AIC is usually a little bit too late left_corner_ind = max([icfmax - lpickwindow, 2]) right_corner_ind = icfmax + int(tsafety / self.dt) - aic_snip = aicsmooth[left_corner_ind : right_corner_ind] - minima = argrelmin(aic_snip)[0] # 0th entry of tuples for axes + aic_snip = aicsmooth[left_corner_ind: right_corner_ind] + minima = argrelmin(aic_snip)[0] # 0th entry of tuples for axes if len(minima) > 0: pickindex = minima[-1] + left_corner_ind self.Pick = self.Tcf[pickindex] @@ -261,10 +261,11 @@ class AICPicker(AutoPicker): tslope = self.TSNR[3] # slope determination window if tsafety >= 0: islope = np.where((self.Tcf <= min([self.Pick + tslope + tsafety, self.Tcf[-1]])) \ - & (self.Tcf >= self.Pick)) # TODO: put this in a seperate function like getsignalwin + & (self.Tcf >= self.Pick)) # TODO: put this in a seperate function like getsignalwin else: islope = np.where((self.Tcf <= min([self.Pick + tslope, self.Tcf[-1]])) \ - & (self.Tcf >= self.Pick + tsafety)) # TODO: put this in a seperate function like getsignalwin + & ( + self.Tcf >= self.Pick + tsafety)) # TODO: put this in a seperate function like getsignalwin # find maximum within slope determination window # 'cause slope should be calculated up to first local minimum only! try: @@ -306,11 +307,13 @@ class AICPicker(AutoPicker): ax.set_title(self.Data[0].stats.station) if plt_flag in [1, 2]: fig.show() - try: input() - except SyntaxError: pass + try: + input() + except SyntaxError: + pass plt.close(fig) return - iislope = islope[0][0:imax+1] + iislope = islope[0][0:imax + 1] # MP MP change slope calculation # get all maxima of aicsmooth iaicmaxima = argrelmax(aicsmooth)[0] @@ -320,7 +323,7 @@ class AICPicker(AutoPicker): iaicmax = aicmax[0] else: iaicmax = -1 - dataslope = aicsmooth[pickindex : iaicmax] + dataslope = aicsmooth[pickindex: iaicmax] # calculate slope as polynomal fit of order 1 xslope = np.arange(0, len(dataslope), 1) P = np.polyfit(xslope, dataslope, 1) @@ -344,8 +347,8 @@ class AICPicker(AutoPicker): fig = self.fig fig._tight = True ax1 = fig.add_subplot(211) - if len(self.Tcf) > len(cf): # why? LK - self.Tcf = self.Tcf[0:len(self.Tcf)-1] + if len(self.Tcf) > len(cf): # why? LK + self.Tcf = self.Tcf[0:len(self.Tcf) - 1] ax1.plot(self.Tcf, cf / max(cf), color=self._linecolor, linewidth=0.7, label='(HOS-/AR-) Data') ax1.plot(self.Tcf, aicsmooth / max(aicsmooth), 'r', label='Smoothed AIC-CF') if self.Pick is not None: @@ -368,7 +371,8 @@ class AICPicker(AutoPicker): label='Signal Window') ax2.axvspan(self.Tcf[iislope[0]], self.Tcf[iislope[-1]], color='g', alpha=0.2, lw=0, label='Slope Window') - ax2.plot(self.Tcf[pickindex : iaicmax], datafit, 'g', linewidth=2, label='Slope') # MP MP changed temporarily! + ax2.plot(self.Tcf[pickindex: iaicmax], datafit, 'g', linewidth=2, + label='Slope') # MP MP changed temporarily! if self.slope is not None: ax1.set_title('Station %s, SNR=%7.2f, Slope= %12.2f counts/s' % (self.Data[0].stats.station, @@ -384,8 +388,10 @@ class AICPicker(AutoPicker): if plt_flag in [1, 2]: fig.show() - try: input() - except SyntaxError: pass + try: + input() + except SyntaxError: + pass plt.close(fig) if plt_flag == 3: stats = self.Data[0].stats @@ -409,9 +415,9 @@ class PragPicker(AutoPicker): iplot = int(self.getiplot()) except: if self.getiplot() == True or self.getiplot() == 'True': - iplot = 2 + iplot = 2 else: - iplot = 0 + iplot = 0 if self.getpick1() is not None: print('PragPicker: Get most likely pick from HOS- or AR-CF using pragmatic picking algorithm ...') @@ -450,11 +456,11 @@ class PragPicker(AutoPicker): # prominent trend: decrease aus # flat: use given aus cfdiff = np.diff(cfipick) - if len(cfdiff)<20: + if len(cfdiff) < 20: print('PragPicker: Very few samples for CF. Check LTA window dimensions!') i0diff = np.where(cfdiff > 0) cfdiff = cfdiff[i0diff] - if len(cfdiff)<1: + if len(cfdiff) < 1: print('PragPicker: Negative slope for CF. Check LTA window dimensions! STOP') self.Pick = None return @@ -478,7 +484,7 @@ class PragPicker(AutoPicker): break # now we look to the left - if len(self.cf) > ipick1 +1: + if len(self.cf) > ipick1 + 1: for i in range(ipick1, max([ipick1 - lpickwindow + 1, 2]), -1): if self.cf[i + 1] > self.cf[i] and self.cf[i - 1] >= self.cf[i]: if cfsmooth[i - 1] * (1 + aus1) >= cfsmooth[i]: @@ -489,7 +495,7 @@ class PragPicker(AutoPicker): cfpick_l = self.cf[i] break else: - msg ='PragPicker: Initial onset too close to start of CF! \ + msg = 'PragPicker: Initial onset too close to start of CF! \ Stop finalizing pick to the left.' print(msg) @@ -519,15 +525,18 @@ class PragPicker(AutoPicker): ax.plot(Tcfpick, cfipick, color=self._linecolor, linewidth=0.7, label='CF') ax.plot(Tcfpick, cfsmoothipick, 'r', label='Smoothed CF') if pickflag > 0: - ax.plot([self.Pick, self.Pick], [min(cfipick), max(cfipick)], self._pickcolor_p, linewidth=2, label='Pick') + ax.plot([self.Pick, self.Pick], [min(cfipick), max(cfipick)], self._pickcolor_p, linewidth=2, + label='Pick') ax.set_xlabel('Time [s] since %s' % self.Data[0].stats.starttime) ax.set_yticks([]) ax.set_title(self.Data[0].stats.station) ax.legend(loc=1) if plt_flag == 1: fig.show() - try: input() - except SyntaxError: pass + try: + input() + except SyntaxError: + pass plt.close(fig) return diff --git a/pylot/core/pick/utils.py b/pylot/core/pick/utils.py index 5f54391c..e94c6883 100644 --- a/pylot/core/pick/utils.py +++ b/pylot/core/pick/utils.py @@ -16,7 +16,6 @@ from obspy.core import Stream, UTCDateTime from pylot.core.util.utils import real_Bool, real_None - def earllatepicker(X, nfac, TSNR, Pick1, iplot=0, verbosity=1, fig=None, linecolor='k'): """ Function to derive earliest and latest possible pick after Diehl & Kissling (2009) @@ -143,13 +142,16 @@ def earllatepicker(X, nfac, TSNR, Pick1, iplot=0, verbosity=1, fig=None, linecol ax.plot(t, x, color=linecolor, linewidth=0.7, label='Data') ax.axvspan(t[inoise[0]], t[inoise[-1]], color='y', alpha=0.2, lw=0, label='Noise Window') ax.axvspan(t[isignal[0]], t[isignal[-1]], color='b', alpha=0.2, lw=0, label='Signal Window') - ax.plot([t[0], t[int(len(t)) - 1]], [nlevel, nlevel], color=linecolor, linewidth=0.7, linestyle='dashed', label='Noise Level') + ax.plot([t[0], t[int(len(t)) - 1]], [nlevel, nlevel], color=linecolor, linewidth=0.7, linestyle='dashed', + label='Noise Level') ax.plot(t[pis[zc]], np.zeros(len(zc)), '*g', markersize=14, label='Zero Crossings') ax.plot([t[0], t[int(len(t)) - 1]], [-nlevel, -nlevel], color=linecolor, linewidth=0.7, linestyle='dashed') ax.plot([Pick1, Pick1], [max(x), -max(x)], 'b', linewidth=2, label='mpp') - ax.plot([LPick, LPick], [max(x) / 2, -max(x) / 2], color=linecolor, linewidth=0.7, linestyle='dashed', label='lpp') - ax.plot([EPick, EPick], [max(x) / 2, -max(x) / 2], color=linecolor, linewidth=0.7, linestyle='dashed', label='epp') + ax.plot([LPick, LPick], [max(x) / 2, -max(x) / 2], color=linecolor, linewidth=0.7, linestyle='dashed', + label='lpp') + ax.plot([EPick, EPick], [max(x) / 2, -max(x) / 2], color=linecolor, linewidth=0.7, linestyle='dashed', + label='epp') ax.plot([Pick1 + PickError, Pick1 + PickError], [max(x) / 2, -max(x) / 2], 'r--', label='spe') ax.plot([Pick1 - PickError, Pick1 - PickError], @@ -162,8 +164,10 @@ def earllatepicker(X, nfac, TSNR, Pick1, iplot=0, verbosity=1, fig=None, linecol ax.legend(loc=1) if plt_flag == 1: fig.show() - try: input() - except SyntaxError: pass + try: + input() + except SyntaxError: + pass plt.close(fig) return EPick, LPick, PickError @@ -197,9 +201,9 @@ def fmpicker(Xraw, Xfilt, pickwin, Pick, iplot=0, fig=None, linecolor='k'): iplot = int(iplot) except: if iplot == True or iplot == 'True': - iplot = 2 + iplot = 2 else: - iplot = 0 + iplot = 0 warnings.simplefilter('ignore', np.RankWarning) @@ -359,8 +363,10 @@ def fmpicker(Xraw, Xfilt, pickwin, Pick, iplot=0, fig=None, linecolor='k'): ax2.set_yticks([]) if plt_flag == 1: fig.show() - try: input() - except SyntaxError: pass + try: + input() + except SyntaxError: + pass plt.close(fig) return FM @@ -654,7 +660,7 @@ def wadaticheck(pickdic, dttolerance, iplot=0, fig_dict=None): checkedSPtimes.append(checkedSPtime) pickdic[key]['S']['marked'] = marker - #pickdic[key]['S']['marked'] = marker + # pickdic[key]['S']['marked'] = marker print("wadaticheck: the following stations failed the check:") print(badstations) @@ -696,8 +702,8 @@ def wadaticheck(pickdic, dttolerance, iplot=0, fig_dict=None): ax.plot(Ppicks, SPtimes, 'ro', label='Skipped S-Picks') if wfitflag == 0: ax.plot(Ppicks, wdfit, color=linecolor, linewidth=0.7, label='Wadati 1') - ax.plot(Ppicks, wdfit+dttolerance, color='0.9', linewidth=0.5, label='Wadati 1 Tolerance') - ax.plot(Ppicks, wdfit-dttolerance, color='0.9', linewidth=0.5) + ax.plot(Ppicks, wdfit + dttolerance, color='0.9', linewidth=0.5, label='Wadati 1 Tolerance') + ax.plot(Ppicks, wdfit - dttolerance, color='0.9', linewidth=0.5) ax.plot(checkedPpicks, wdfit2, 'g', label='Wadati 2') ax.plot(checkedPpicks, checkedSPtimes, color=linecolor, linewidth=0, marker='o', label='Reliable S-Picks') @@ -764,9 +770,9 @@ def checksignallength(X, pick, TSNR, minsiglength, nfac, minpercent, iplot=0, fi iplot = int(iplot) except: if real_Bool(iplot): - iplot = 2 + iplot = 2 else: - iplot = 0 + iplot = 0 assert isinstance(X, Stream), "%s is not a stream object" % str(X) @@ -828,8 +834,10 @@ def checksignallength(X, pick, TSNR, minsiglength, nfac, minpercent, iplot=0, fi ax.set_yticks([]) if plt_flag == 1: fig.show() - try: input() - except SyntaxError: pass + try: + input() + except SyntaxError: + pass plt.close(fig) return returnflag @@ -1054,16 +1062,15 @@ def checkZ4S(X, pick, zfac, checkwin, iplot, fig=None, linecolor='k'): :return: returnflag; 0 if onset failed test, 1 if onset passed test :rtype: int """ - + plt_flag = 0 try: iplot = int(iplot) except: if real_Bool(iplot): - iplot = 2 + iplot = 2 else: - iplot = 0 - + iplot = 0 assert isinstance(X, Stream), "%s is not a stream object" % str(X) @@ -1165,8 +1172,10 @@ def checkZ4S(X, pick, zfac, checkwin, iplot, fig=None, linecolor='k'): ax.set_xlabel('Time [s] since %s' % zdat[0].stats.starttime) if plt_flag == 1: fig.show() - try: input() - except SyntaxError: pass + try: + input() + except SyntaxError: + pass plt.close(fig) return returnflag @@ -1191,19 +1200,20 @@ def getQualityFromUncertainty(uncertainty, Errors): if uncertainty <= Errors[0]: quality = 0 elif (uncertainty > Errors[0]) and \ - (uncertainty <= Errors[1]): + (uncertainty <= Errors[1]): quality = 1 elif (uncertainty > Errors[1]) and \ - (uncertainty <= Errors[2]): + (uncertainty <= Errors[2]): quality = 2 elif (uncertainty > Errors[2]) and \ - (uncertainty <= Errors[3]): + (uncertainty <= Errors[3]): quality = 3 elif uncertainty > Errors[3]: quality = 4 return quality + if __name__ == '__main__': import doctest diff --git a/pylot/core/util/array_map.py b/pylot/core/util/array_map.py index de9a3bf3..97b4aa7e 100644 --- a/pylot/core/util/array_map.py +++ b/pylot/core/util/array_map.py @@ -94,7 +94,7 @@ class Array_map(QtGui.QWidget): self.comboBox_phase.currentIndexChanged.connect(self._refresh_drawings) self.comboBox_am.currentIndexChanged.connect(self._refresh_drawings) self.canvas.mpl_connect('motion_notify_event', self.mouse_moved) - #self.zoom_id = self.basemap.ax.figure.canvas.mpl_connect('scroll_event', self.zoom) + # self.zoom_id = self.basemap.ax.figure.canvas.mpl_connect('scroll_event', self.zoom) def _from_dict(self, function, key): return function(self.stations_dict.values(), key=lambda x: x[key])[key] @@ -159,7 +159,6 @@ class Array_map(QtGui.QWidget): self.main_box.addWidget(self.canvas, 1) self.main_box.addWidget(self.status_label, 0) - def init_stations(self): def stat_info_from_parser(parser): stations_dict = {} @@ -354,7 +353,7 @@ class Array_map(QtGui.QWidget): def add_cbar(self, label): self.cbax_bg = inset_axes(self.main_ax, width="6%", height="75%", loc=5) cbax = inset_axes(self.main_ax, width='2%', height='70%', loc=5) - cbar = self.main_ax.figure.colorbar(self.sc_picked, cax = cbax) + cbar = self.main_ax.figure.colorbar(self.sc_picked, cax=cbax) cbar.set_label(label) cbax.yaxis.tick_left() cbax.yaxis.set_label_position('left') diff --git a/pylot/core/util/dataprocessing.py b/pylot/core/util/dataprocessing.py index 80ff3e32..431b250b 100644 --- a/pylot/core/util/dataprocessing.py +++ b/pylot/core/util/dataprocessing.py @@ -33,7 +33,7 @@ class Metadata(object): for index, inventory in enumerate(self.inventories): if index < 2 or (ntotal - index) < 3: repr += '{}\n'.format(inventory) - if ntotal > 4 and int(ntotal/2) == index: + if ntotal > 4 and int(ntotal / 2) == index: repr += '...\n' if ntotal > 4: repr += '\nTotal of {} inventories. Use Metadata.inventories to see all.'.format(ntotal) @@ -79,11 +79,10 @@ class Metadata(object): self.inventories.remove(path_to_inventory) for filename in self.inventory_files.keys(): if filename.startswith(path_to_inventory): - del(self.inventory_files[filename]) + del (self.inventory_files[filename]) for seed_id in self.seed_ids.keys(): if self.seed_ids[seed_id].startswith(path_to_inventory): - del(self.seed_ids[seed_id]) - + del (self.seed_ids[seed_id]) def get_metadata(self, seed_id, time=None): """ @@ -123,7 +122,6 @@ class Metadata(object): fname = self.seed_ids[seed_id] return self.inventory_files[fname] - def read_all(self): """ Read all metadata files found in all inventories @@ -134,7 +132,6 @@ class Metadata(object): if not self.read_single_file(inv_fname): continue - def read_single_file(self, inv_fname): """ Try to read a single file as Parser/Inventory and add its dictionary to inventory files if reading sudceeded. @@ -157,7 +154,6 @@ class Metadata(object): 'data': robj} return True - def get_coordinates(self, seed_id, time=None): """ Get coordinates of given seed id. @@ -176,7 +172,6 @@ class Metadata(object): return return metadata['data'].get_coordinates(seed_id, time) - def get_paz(self, seed_id, time): """ @@ -195,13 +190,11 @@ class Metadata(object): resp = metadata['data'].get_response(seed_id, time) return resp.get_paz(seed_id) - def _read_inventory_data(self, seed_id=None): for inventory in self.inventories: if self._read_metadata_iterator(path_to_inventory=inventory, station_seed_id=seed_id): return - def _read_metadata_iterator(self, path_to_inventory, station_seed_id): """ Search for metadata for a specific station iteratively. @@ -236,7 +229,6 @@ class Metadata(object): continue print('Could not find metadata for station_seed_id {} in path {}'.format(station_seed_id, path_to_inventory)) - def _read_metadata_file(self, path_to_inventory_filename): """ function reading metadata files (either dataless seed, xml or resp) @@ -262,7 +254,6 @@ class Metadata(object): return file_type, robj return None, None - @staticmethod def _read_dless(path_to_inventory): exc = None @@ -272,7 +263,6 @@ class Metadata(object): parser = None return parser, exc - @staticmethod def _read_inventory_file(path_to_inventory): exc = None @@ -283,7 +273,6 @@ class Metadata(object): return inv, exc - def time_from_header(header): """ Function takes in the second line from a .gse file and takes out the date and time from that line. @@ -494,7 +483,6 @@ def read_metadata(path_to_inventory): # return metadata_objects - def restitute_trace(input_tuple): def no_metadata(tr, seed_id): print('no metadata file found ' diff --git a/pylot/core/util/defaults.py b/pylot/core/util/defaults.py index de3249fe..416cbd58 100644 --- a/pylot/core/util/defaults.py +++ b/pylot/core/util/defaults.py @@ -16,7 +16,6 @@ from pylot.core.loc import hyposat from pylot.core.loc import nll from pylot.core.loc import velest - # determine system dependent path separator system_name = platform.system() if system_name in ["Linux", "Darwin"]: diff --git a/pylot/core/util/obspyDMT_interface.py b/pylot/core/util/obspyDMT_interface.py index 47d5c687..b0587d13 100644 --- a/pylot/core/util/obspyDMT_interface.py +++ b/pylot/core/util/obspyDMT_interface.py @@ -4,6 +4,7 @@ import os from obspy import UTCDateTime + def check_obspydmt_structure(path): ''' Check path for obspyDMT event structure. @@ -16,6 +17,7 @@ def check_obspydmt_structure(path): return True return False + def check_obspydmt_eventfolder(folder): try: time = folder.split('.')[0] @@ -25,6 +27,7 @@ def check_obspydmt_eventfolder(folder): except Exception as e: return False, e + def qml_from_obspyDMT(path): import pickle from obspy.core.event import Event, Magnitude, Origin @@ -41,4 +44,3 @@ def qml_from_obspyDMT(path): ev.magnitudes.append(mag) ev.origins.append(origin) return ev - diff --git a/pylot/core/util/thread.py b/pylot/core/util/thread.py index 0a8151d0..e84ed398 100644 --- a/pylot/core/util/thread.py +++ b/pylot/core/util/thread.py @@ -33,8 +33,8 @@ class Thread(QThread): self._executed = False self._executedError = e traceback.print_exc() - exctype, value = sys.exc_info ()[:2] - self._executedErrorInfo = '{} {} {}'.\ + exctype, value = sys.exc_info()[:2] + self._executedErrorInfo = '{} {} {}'. \ format(exctype, value, traceback.format_exc()) sys.stdout = sys.__stdout__ @@ -75,6 +75,7 @@ class Worker(QRunnable): ''' Worker class to be run by MultiThread(QThread). ''' + def __init__(self, fun, args, progressText=None, pb_widget=None, @@ -82,7 +83,7 @@ class Worker(QRunnable): super(Worker, self).__init__() self.fun = fun self.args = args - #self.kwargs = kwargs + # self.kwargs = kwargs self.signals = WorkerSignals() self.progressText = progressText self.pb_widget = pb_widget @@ -96,9 +97,9 @@ class Worker(QRunnable): try: result = self.fun(self.args) except: - exctype, value = sys.exc_info ()[:2] + exctype, value = sys.exc_info()[:2] print(exctype, value, traceback.format_exc()) - self.signals.error.emit ((exctype, value, traceback.format_exc ())) + self.signals.error.emit((exctype, value, traceback.format_exc())) else: self.signals.result.emit(result) finally: @@ -140,13 +141,13 @@ class MultiThread(QThread): def run(self): if self.redirect_stdout: - sys.stdout = self + sys.stdout = self try: if not self.ncores: self.ncores = multiprocessing.cpu_count() pool = multiprocessing.Pool(self.ncores) self.data = pool.map_async(self.func, self.args, callback=self.emitDone) - #self.data = pool.apply_async(self.func, self.shotlist, callback=self.emitDone) #emit each time returned + # self.data = pool.apply_async(self.func, self.shotlist, callback=self.emitDone) #emit each time returned pool.close() self._executed = True except Exception as e: diff --git a/pylot/core/util/utils.py b/pylot/core/util/utils.py index e8568fd3..d848321e 100644 --- a/pylot/core/util/utils.py +++ b/pylot/core/util/utils.py @@ -28,12 +28,14 @@ except Exception as e: print('PyLoT: Could not import pyqtgraph. {}'.format(e)) pg = None + def _pickle_method(m): if m.im_self is None: return getattr, (m.im_class, m.im_func.func_name) else: return getattr, (m.im_self, m.im_func.func_name) + def getAutoFilteroptions(phase, parameter): filtername = {'P': 'bpz2', 'S': 'bph2'} @@ -41,9 +43,10 @@ def getAutoFilteroptions(phase, parameter): print('autoPickParameter: No filter options for phase {}.'.format(phase)) return freqmin, freqmax = parameter.get(filtername[phase]) - filteroptions = FilterOptions(type='bandpass', freq=[freqmin, freqmax], order=4) # order=4 default from obspy + filteroptions = FilterOptions(type='bandpass', freq=[freqmin, freqmax], order=4) # order=4 default from obspy return filteroptions + def readDefaultFilterInformation(fname): """ Read default filter information from pylot.in file @@ -679,7 +682,7 @@ def pick_color(picktype, phase, quality=0): bpc = base_phase_colors(picktype, phase) # returns dict like {'modifier': 'g', 'rgba': (0, 0, 255, 255)} rgba = bpc['rgba'] modifier = bpc['modifier'] - intensity = 255.*quality/min_quality + intensity = 255. * quality / min_quality rgba = modify_rgba(rgba, modifier, intensity) return rgba @@ -791,6 +794,7 @@ def base_phase_colors(picktype, phase): phasecolors = style_settings.phasecolors return phasecolors[picktype][phase] + def transform_colors_mpl_str(colors, no_alpha=False): """ Transforms rgba color values to a matplotlib string of color values with a range of [0, 1] @@ -809,6 +813,7 @@ def transform_colors_mpl_str(colors, no_alpha=False): colors_mpl = '({}, {}, {}, {})'.format(*colors_mpl) return colors_mpl + def transform_colors_mpl(colors): """ Transform rgba colors from [0, 255] to [0, 1] @@ -821,6 +826,7 @@ def transform_colors_mpl(colors): colors_mpl = tuple([color / 255. for color in colors]) return colors_mpl + def remove_underscores(data): """ takes a `obspy.core.stream.Stream` object and removes all underscores @@ -976,7 +982,8 @@ def check4rotated(data, metadata=None, verbosity=1): wfstream[2], azimuts[2], dips[2]) print('check4rotated: rotated trace {} to ZNE'.format(trace_id)) # replace old data with rotated data, change the channel code to ZNE - z_index = dips.index(min(dips)) # get z-trace index, z has minimum dip of -90 (dip is measured from 0 to -90, with -90 being vertical) + z_index = dips.index(min( + dips)) # get z-trace index, z has minimum dip of -90 (dip is measured from 0 to -90, with -90 being vertical) wfstream[z_index].data = z wfstream[z_index].stats.channel = wfstream[z_index].stats.channel[0:-1] + 'Z' del trace_ids[z_index] @@ -1206,8 +1213,8 @@ def check_event_folder(path): folder = path.split('/')[-1] # for pylot: select only folders that start with 'e', containin two dots and have length 12 if (folder.startswith('e') - and len(folder.split('.')) == 3 - and len(folder) == 12): + and len(folder.split('.')) == 3 + and len(folder) == 12): ev_type = 'pylot' elif check_obspydmt_eventfolder(folder)[0]: ev_type = 'obspydmt' diff --git a/pylot/core/util/widgets.py b/pylot/core/util/widgets.py index 32b51b1a..b8b64a93 100644 --- a/pylot/core/util/widgets.py +++ b/pylot/core/util/widgets.py @@ -17,6 +17,7 @@ import time import numpy as np import matplotlib + matplotlib.use('QT4Agg') from matplotlib.figure import Figure @@ -381,8 +382,8 @@ class ComparisonWidget(QWidget): ax = axes_dict[phase]['exp'] xlims = ax.get_xlim() ylims = ax.get_ylim() - #ax.fill_between([xlims[0], 0], ylims[0], ylims[1], color=(0.9, 1.0, 0.9, 0.5), label='earlier than manual') - #ax.fill_between([0, xlims[1]], ylims[0], ylims[1], color=(1.0, 0.9, 0.9, 0.5), label='later than manual') + # ax.fill_between([xlims[0], 0], ylims[0], ylims[1], color=(0.9, 1.0, 0.9, 0.5), label='earlier than manual') + # ax.fill_between([0, xlims[1]], ylims[0], ylims[1], color=(1.0, 0.9, 0.9, 0.5), label='later than manual') legend = ax.legend() legend.draggable() @@ -474,7 +475,7 @@ class WaveformWidgetPG(QtGui.QWidget): self.pen_linecolor_syn = self.pg.mkPen((100, 0, 255, 255)) self.reinitMoveProxy() self._proxy = self.pg.SignalProxy(self.plotWidget.scene().sigMouseMoved, rateLimit=60, slot=self.mouseMoved) - #self.plotWidget.getPlotItem().setDownsampling(auto=True) + # self.plotWidget.getPlotItem().setDownsampling(auto=True) def reinitMoveProxy(self): self.vLine = self.pg.InfiniteLine(angle=90, movable=False, pen=self.pen_multicursor) @@ -524,7 +525,7 @@ class WaveformWidgetPG(QtGui.QWidget): self.syn_checkbox = QtGui.QCheckBox('synthetics') self.addQCboxItem('processed', 'green') self.addQCboxItem('raw', 'black') - #self.perm_qcbox_right.setAlignment(2) + # self.perm_qcbox_right.setAlignment(2) self.setLayout(self.main_layout) def getPlotDict(self): @@ -608,7 +609,7 @@ class WaveformWidgetPG(QtGui.QWidget): print('Warning: Could not set zoom limits') for n, (network, station, channel) in enumerate(nsc): - n+=1 + n += 1 st = st_select.select(network=network, station=station, channel=channel) trace = st[0].copy() st_syn = wfsyn.select(network=network, station=station, channel=channel) @@ -645,10 +646,11 @@ class WaveformWidgetPG(QtGui.QWidget): trace_syn.normalize(np.max(np.abs(trace_syn.data)) * 2) # TODO: change this to numpy operations instead of lists? times = np.array([time for index, time in enumerate(time_ax) if not index % nth_sample]) - times_syn = np.array([time for index, time in enumerate(time_ax_syn) if not index % nth_sample] if st_syn else []) + times_syn = np.array( + [time for index, time in enumerate(time_ax_syn) if not index % nth_sample] if st_syn else []) trace.data = np.array([datum + n for index, datum in enumerate(trace.data) if not index % nth_sample]) trace_syn.data = np.array([datum + n for index, datum in enumerate(trace_syn.data) - if not index % nth_sample] if st_syn else []) + if not index % nth_sample] if st_syn else []) plots.append((times, trace.data, times_syn, trace_syn.data)) self.setPlotDict(n, (station, channel, network)) @@ -665,11 +667,11 @@ class WaveformWidgetPG(QtGui.QWidget): ''' npixel = self.orig_parent.width() ndata = len(trace.data) - pts_per_pixel = ndata/npixel + pts_per_pixel = ndata / npixel if pts_per_pixel < 2: return trace.data, time_ax - remaining_samples = ndata%pts_per_pixel - npixel = ndata//pts_per_pixel + remaining_samples = ndata % pts_per_pixel + npixel = ndata // pts_per_pixel if remaining_samples: data = trace.data[:-remaining_samples] else: @@ -849,7 +851,7 @@ class PylotCanvas(FigureCanvas): break if not ax_check: return - #self.updateCurrentLimits() #maybe put this down to else: + # self.updateCurrentLimits() #maybe put this down to else: # calculate delta (relative values in axis) old_x, old_y = self.press_rel @@ -902,13 +904,13 @@ class PylotCanvas(FigureCanvas): d_upper = abs(origin - upper_b) if positive: - d_lower *= 1 - 1/factor - d_upper *= 1 - 1/factor + d_lower *= 1 - 1 / factor + d_upper *= 1 - 1 / factor lower_b += d_lower upper_b -= d_upper else: - d_lower /= 1 + 1/factor - d_upper /= 1 + 1/factor + d_lower /= 1 + 1 / factor + d_upper /= 1 + 1 / factor lower_b -= d_lower upper_b += d_upper @@ -1133,9 +1135,9 @@ class PylotCanvas(FigureCanvas): if noiselevel is not None: for level in [-noiselevel[channel], noiselevel[channel]]: ax.plot([time_ax[0], time_ax[-1]], - [n+level, n+level], - color = linecolor, - linestyle = 'dashed') + [n + level, n + level], + color=linecolor, + linestyle='dashed') self.setPlotDict(n, (station, channel, network)) if plot_additional and additional_channel: compare_stream = wfdata.select(channel=additional_channel) @@ -1217,7 +1219,7 @@ class PylotCanvas(FigureCanvas): def insertLabel(self, pos, text): pos = pos / max(self.axes[0].ylim) axann = self.axes[0].annotate(text, xy=(.03, pos), - xycoords='axes fraction') + xycoords='axes fraction') axann.set_bbox(dict(facecolor='lightgrey', alpha=.6)) def setZoomBorders2content(self): @@ -1441,7 +1443,6 @@ class PickDlg(QDialog): self.multicompfig.draw() self.multicompfig.setFocus() - # set plot labels self.setPlotLabels() @@ -1467,7 +1468,6 @@ class PickDlg(QDialog): self.setWindowTitle('Pickwindow on station: {}'.format(self.getStation())) self.setWindowState(QtCore.Qt.WindowMaximized) - def setupUi(self): menuBar = QtGui.QMenuBar(self) if not self._embedded: @@ -1512,11 +1512,11 @@ class PickDlg(QDialog): checkable=True, shortcut='S') self.autoFilterAction = createAction(parent=self, text='Automatic Filtering', - slot=self.toggleAutoFilter, - icon=key_a_icon, - tip='Filter automatically before initial pick', - checkable=True, - shortcut='Ctrl+A') + slot=self.toggleAutoFilter, + icon=key_a_icon, + tip='Filter automatically before initial pick', + checkable=True, + shortcut='Ctrl+A') self.zoomAction = createAction(parent=self, text='Zoom', slot=self.zoom, icon=zoom_icon, tip='Zoom into waveform', @@ -1604,8 +1604,8 @@ class PickDlg(QDialog): _dialtoolbar.addSeparator() est_label = QLabel('Estimated onsets:') est_label.setStyleSheet('QLabel {' - 'padding:2px;' - 'padding-left:5px}') + 'padding:2px;' + 'padding-left:5px}') _dialtoolbar.addWidget(est_label) _dialtoolbar.addWidget(self.plot_arrivals_button) _dialtoolbar.addSeparator() @@ -1805,16 +1805,15 @@ class PickDlg(QDialog): picksMenu.addSeparator() filterOptionsAction = createAction(parent=self, text="&Filter parameter ...", - slot=self.filterOptions, - shortcut='Ctrl+F', - icon=self.orig_parent.filter_icon) + slot=self.filterOptions, + shortcut='Ctrl+F', + icon=self.orig_parent.filter_icon) filterMenu = menuBar.addMenu('Filter') filterMenu.addAction(self.filterActionP) filterMenu.addAction(self.filterActionS) filterMenu.addAction(self.autoFilterAction) filterMenu.addAction(filterOptionsAction) - def filterOptions(self): if self.orig_parent.adjustFilterOptions(): phase = None @@ -1953,7 +1952,7 @@ class PickDlg(QDialog): self.draw() else: self.draw() - #self.pick_block = self.togglePickBlocker() + # self.pick_block = self.togglePickBlocker() self.disconnect_pick_delete() def deactivatePicking(self): @@ -2101,7 +2100,7 @@ class PickDlg(QDialog): def calcNoiseScaleFactor(noiselevel, zoomfactor=5., norm=1): # calculate factor to upscale a trace normed to 'norm' in a way that all values # zoomfactor*noiselevel are found within -0.5*norm and 0.5*norm - scaleFactor = (norm/2.) / (zoomfactor * noiselevel) + scaleFactor = (norm / 2.) / (zoomfactor * noiselevel) return scaleFactor def setIniPick(self, gui_event): @@ -2175,7 +2174,7 @@ class PickDlg(QDialog): try: data.detrend('linear') data.filter(**filteroptions) - #wfdata.filter(**filteroptions)# MP MP removed filtering of original data + # wfdata.filter(**filteroptions)# MP MP removed filtering of original data except ValueError as e: self.qmb = QtGui.QMessageBox(QtGui.QMessageBox.Icon.Information, 'Denied', 'setIniPick{}: Could not filter waveform: {}'.format(phase, e)) @@ -2211,7 +2210,7 @@ class PickDlg(QDialog): x_res = getResolutionWindow(np.mean(snr), parameter.get('extent')) xlims = [ini_pick - x_res, ini_pick + x_res] - ylims = list(np.array([-.5, .5]) + [0, len(data)-1]) + ylims = list(np.array([-.5, .5]) + [0, len(data) - 1]) title = self.getStation() + ' picking mode' if filterphase: @@ -2298,8 +2297,8 @@ class PickDlg(QDialog): self.disconnectPressEvent() self.enable_ar_buttons() self.zoomAction.setEnabled(True) - #self.pick_block = self.togglPickBlocker() - #self.resetZoom() + # self.pick_block = self.togglPickBlocker() + # self.resetZoom() self.leave_picking_mode() def savePick(self, phase, phasepicks): @@ -2335,7 +2334,7 @@ class PickDlg(QDialog): if self.getPicks(picktype): if phase is not None and not phase == 'SPt': if (type(self.getPicks(picktype)[phase]) is dict - or type(self.getPicks(picktype)[phase]) is AttribDict): + or type(self.getPicks(picktype)[phase]) is AttribDict): picks = self.getPicks(picktype)[phase] elif phase is None: for phase in self.getPicks(picktype): @@ -2368,7 +2367,7 @@ class PickDlg(QDialog): label='{}-Pick (quality: {})'.format(phase, quality), picker=5) self.phaseLines[phase] = vl if spe: - ax.fill_between([mpp-spe, mpp+spe], ylims[0], ylims[1], + ax.fill_between([mpp - spe, mpp + spe], ylims[0], ylims[1], alpha=.25, color=color, label='{}-SPE'.format(phase)) if picks['epp']: linestyle_epp, width_epp = pick_linestyle_plt(picktype, 'epp') @@ -2414,7 +2413,7 @@ class PickDlg(QDialog): def on_motion(self, event): x = event.xdata if x is not None: - time_code = 'T = {}, t = {} [s]'.format(self.stime+x, x) + time_code = 'T = {}, t = {} [s]'.format(self.stime + x, x) user_help = ' - Left-Click to Drag | Right-Click to Pan-Zoom |' \ ' Mousewheel to Zoom | Middle-Click to Delete Pick' self.statusbar.showMessage(time_code + user_help) @@ -2516,10 +2515,10 @@ class PickDlg(QDialog): allpicks[picktype].pop(phase) # delete line from vlines dictionary if phase in self.phaseLines.keys(): - del(self.phaseLines[phase]) + del (self.phaseLines[phase]) # information output msg = 'Deleted {} pick for phase {}, at timestamp {} (relative time: {} s)' - print(msg.format(picktype, phase, self.getStartTime()+pick_rel, pick_rel)) + print(msg.format(picktype, phase, self.getStartTime() + pick_rel, pick_rel)) self.setDirty(True) def identify_selected_picks(self, x): @@ -2545,8 +2544,6 @@ class PickDlg(QDialog): pick_rel, phase, picktype = X[index] return allpicks, pick_rel, phase, picktype - - def drawPhaseText(self): self.drawPicks(picktype='manual', textOnly=True) self.drawPicks(picktype='auto', textOnly=True) @@ -2583,7 +2580,7 @@ class PickDlg(QDialog): return self.cur_xlim = self.multicompfig.axes[0].get_xlim() self.cur_ylim = self.multicompfig.axes[0].get_ylim() - #self.multicompfig.updateCurrentLimits() + # self.multicompfig.updateCurrentLimits() data = self.getWFData().copy() title = self.getStation() if filter: @@ -2677,7 +2674,6 @@ class PickDlg(QDialog): rval = False return rval - def resetPlot(self): self.resetZoom() self.refreshPlot() @@ -2716,8 +2712,8 @@ class PickDlg(QDialog): # set channel labels self.multicompfig.setYTickLabels(pos, labels) - #self.multicompfig.setXLims(ax, self.getXLims()) - #self.multicompfig.setYLims(ax, self.getYLims()) + # self.multicompfig.setXLims(ax, self.getXLims()) + # self.multicompfig.setYLims(ax, self.getYLims()) def zoom(self): if self.zoomAction.isChecked() and self.pick_block: @@ -2779,7 +2775,7 @@ class CanvasWidget(QWidget): ''' def __init__(self, parent, canvas): - QtGui.QWidget.__init__(self, parent)#, 1) + QtGui.QWidget.__init__(self, parent) # , 1) canvas = canvas self.main_layout = QtGui.QVBoxLayout() self.setLayout(self.main_layout) @@ -2792,6 +2788,7 @@ class MultiEventWidget(QWidget): ''' ''' + def __init__(self, options=None, parent=None, windowflag=1): QtGui.QWidget.__init__(self, parent, windowflag) @@ -2851,7 +2848,7 @@ class MultiEventWidget(QWidget): self.pb.setRange(0, 0) self.pb.setVisible(False) - #space holder for progressbar + # space holder for progressbar self._pb_space = QtGui.QWidget() self.rb_layout.addWidget(self.start_button) @@ -2869,7 +2866,7 @@ class MultiEventWidget(QWidget): eventlist = func() if not type(eventlist) == list: eventlist = [eventlist] - tooltip='' + tooltip = '' for index, event in enumerate(eventlist): if not event: continue @@ -2885,13 +2882,13 @@ class MultiEventWidget(QWidget): for rb in self.rb_dict.values(): if rb.isChecked(): check_events = (rb.toolTip() == 'No events for this selection') - self.start_button.setEnabled(not(check_events)) + self.start_button.setEnabled(not (check_events)) def enable(self, bool): for rb in self.rb_dict.values(): rb.setEnabled(bool) self.start_button.setEnabled(bool) - self.pb.setVisible(not(bool)) + self.pb.setVisible(not (bool)) self._pb_space.setVisible(bool) self.eventbox.setEnabled(bool) self.button_clear.setEnabled(bool) @@ -2973,7 +2970,7 @@ class AutoPickWidget(MultiEventWidget): def reinitEvents2plot(self): for eventID, eventDict in self.events2plot.items(): for widget_key, widget in eventDict.items(): - del(widget) + del (widget) self.events2plot = {} self.eventbox.clear() self.refresh_plot_tabs() @@ -3507,7 +3504,7 @@ class TuneAutopicker(QWidget): if hasattr(self, 'pdlg_widget'): if self.pdlg_widget: self.pdlg_widget.setParent(None) - del(self.pdlg_widget) + del (self.pdlg_widget) if hasattr(self, 'overview'): self.overview.setParent(None) if hasattr(self, 'p_tabs'): @@ -4725,8 +4722,9 @@ class FilterOptionsDialog(QDialog): 'S': FilterOptions()} self.setWindowTitle(titleString) - self.filterOptionWidgets = {'P': FilterOptionsWidget(self.filterOptions['P'], self.parent().getAutoFilteroptions('P')), - 'S': FilterOptionsWidget(self.filterOptions['S'], self.parent().getAutoFilteroptions('S'))} + self.filterOptionWidgets = { + 'P': FilterOptionsWidget(self.filterOptions['P'], self.parent().getAutoFilteroptions('P')), + 'S': FilterOptionsWidget(self.filterOptions['S'], self.parent().getAutoFilteroptions('S'))} self.setupUi() self.updateUi() self.connectButtons() @@ -5074,7 +5072,7 @@ class HelpForm(QDialog): toolBar.addWidget(self.pageLabel) self.webBrowser = QWebView() self.webBrowser.load(page) - #self.webBrowser.load('C:/Shared/code/git/pylot/pylot/core/util/map_test.html') + # self.webBrowser.load('C:/Shared/code/git/pylot/pylot/core/util/map_test.html') layout = QVBoxLayout() layout.addWidget(toolBar) diff --git a/pylot/styles/style_settings.py b/pylot/styles/style_settings.py index c84a8334..a7d317bc 100644 --- a/pylot/styles/style_settings.py +++ b/pylot/styles/style_settings.py @@ -5,18 +5,18 @@ # the base color phasecolors = { 'manual': { - 'P':{ + 'P': { 'rgba': (0, 0, 255, 255), 'modifier': 'g'}, - 'S':{ + 'S': { 'rgba': (255, 0, 0, 255), 'modifier': 'b'} }, - 'auto':{ - 'P':{ + 'auto': { + 'P': { 'rgba': (140, 0, 255, 255), 'modifier': 'g'}, - 'S':{ + 'S': { 'rgba': (255, 140, 0, 255), 'modifier': 'b'} } @@ -24,8 +24,8 @@ phasecolors = { # Set plot colors and stylesheet for each style stylecolors = { - 'default':{ - 'linecolor':{ + 'default': { + 'linecolor': { 'rgba': (0, 0, 0, 255)}, 'background': { 'rgba': (255, 255, 255, 255)}, @@ -67,4 +67,3 @@ stylecolors = { 'filename': 'bright.qss'} } } - diff --git a/tests/test_Metadata/test_Metadata.py b/tests/test_Metadata/test_Metadata.py index 9b362f5d..28e73e1d 100644 --- a/tests/test_Metadata/test_Metadata.py +++ b/tests/test_Metadata/test_Metadata.py @@ -7,6 +7,7 @@ from obspy.io.xseed import Parser from pylot.core.util.dataprocessing import Metadata from tests.utils import HidePrints + class TestMetadata(unittest.TestCase): def setUp(self): @@ -16,9 +17,12 @@ class TestMetadata(unittest.TestCase): self.m = Metadata(metadata_folder) def test_get_coordinates_sucess(self): - expected = {'Z': {u'elevation': 607.0, u'longitude': 12.87571, u'local_depth': 0.0, u'azimuth': 0.0, u'latitude': 49.14502, u'dip': -90.0}, - 'E': {u'azimuth': 90.0, u'dip': 0.0, u'elevation': 607.0, u'latitude': 49.14502, u'local_depth': 0.0, u'longitude': 12.87571}, - 'N': {u'azimuth': 0.0, u'dip': 0.0, u'elevation': 607.0, u'latitude': 49.14502, u'local_depth': 0.0, u'longitude': 12.87571} + expected = {'Z': {u'elevation': 607.0, u'longitude': 12.87571, u'local_depth': 0.0, u'azimuth': 0.0, + u'latitude': 49.14502, u'dip': -90.0}, + 'E': {u'azimuth': 90.0, u'dip': 0.0, u'elevation': 607.0, u'latitude': 49.14502, + u'local_depth': 0.0, u'longitude': 12.87571}, + 'N': {u'azimuth': 0.0, u'dip': 0.0, u'elevation': 607.0, u'latitude': 49.14502, u'local_depth': 0.0, + u'longitude': 12.87571} } result = {} for channel in ('Z', 'N', 'E'): @@ -28,9 +32,12 @@ class TestMetadata(unittest.TestCase): self.assertDictEqual(result[channel], expected[channel]) def test_get_coordinates_sucess_no_time(self): - expected = {'Z': {u'elevation': 607.0, u'longitude': 12.87571, u'local_depth': 0.0, u'azimuth': 0.0, u'latitude': 49.14502, u'dip': -90.0}, - 'E': {u'azimuth': 90.0, u'dip': 0.0, u'elevation': 607.0, u'latitude': 49.14502, u'local_depth': 0.0, u'longitude': 12.87571}, - 'N': {u'azimuth': 0.0, u'dip': 0.0, u'elevation': 607.0, u'latitude': 49.14502, u'local_depth': 0.0, u'longitude': 12.87571} + expected = {'Z': {u'elevation': 607.0, u'longitude': 12.87571, u'local_depth': 0.0, u'azimuth': 0.0, + u'latitude': 49.14502, u'dip': -90.0}, + 'E': {u'azimuth': 90.0, u'dip': 0.0, u'elevation': 607.0, u'latitude': 49.14502, + u'local_depth': 0.0, u'longitude': 12.87571}, + 'N': {u'azimuth': 0.0, u'dip': 0.0, u'elevation': 607.0, u'latitude': 49.14502, u'local_depth': 0.0, + u'longitude': 12.87571} } result = {} for channel in ('Z', 'N', 'E'): @@ -63,8 +70,10 @@ class TestMetadataAdding(unittest.TestCase): fpath = os.path.join(self.metadata_folders[0], 'DATALESS.BW.WETR..HHZ') self.m.add_inventory_file(fpath) # adding an inventory file should append its folder to the list of inventories and the file to the - self.assertEqual([os.path.join(self.metadata_folders[0], 'DATALESS.BW.WETR..HHZ')], self.m.inventory_files.keys()) # does the filename exist in inventory files? - self.assertEqual(['data', 'invtype'], self.m.inventory_files[os.path.join(self.metadata_folders[0], 'DATALESS.BW.WETR..HHZ')].keys()) # is the required information attacht to the filename? + self.assertEqual([os.path.join(self.metadata_folders[0], 'DATALESS.BW.WETR..HHZ')], + self.m.inventory_files.keys()) # does the filename exist in inventory files? + self.assertEqual(['data', 'invtype'], self.m.inventory_files[os.path.join(self.metadata_folders[0], + 'DATALESS.BW.WETR..HHZ')].keys()) # is the required information attacht to the filename? self.assertDictEqual({}, self.m.seed_ids) self.assertEqual([self.metadata_folders[0]], self.m.inventories) From 663d244f709dde824398239782a999e8b3743199 Mon Sep 17 00:00:00 2001 From: Marcel Date: Mon, 16 Jul 2018 16:05:43 +0200 Subject: [PATCH 126/169] [cleanup] removed some parentheses --- pylot/core/io/phases.py | 6 +++--- pylot/core/util/array_map.py | 8 ++++---- pylot/core/util/dataprocessing.py | 2 +- pylot/core/util/widgets.py | 8 ++++---- 4 files changed, 12 insertions(+), 12 deletions(-) diff --git a/pylot/core/io/phases.py b/pylot/core/io/phases.py index a041f833..1aee1936 100644 --- a/pylot/core/io/phases.py +++ b/pylot/core/io/phases.py @@ -966,7 +966,7 @@ def getQualitiesfromxml(xmlnames, ErrorsP, ErrorsS, plotflag=1): arrivals_copy = cat_copy.events[0].picks # Prefere manual picks if qualities are sufficient! for Pick in arrivals: - if (Pick.method_id.id).split('/')[1] == 'manual': + if Pick.method_id.id.split('/')[1] == 'manual': mstation = Pick.waveform_id.station_code mstation_ext = mstation + '_' for mpick in arrivals_copy: @@ -974,14 +974,14 @@ def getQualitiesfromxml(xmlnames, ErrorsP, ErrorsS, plotflag=1): if phase == 'P': if ((mpick.waveform_id.station_code == mstation) or (mpick.waveform_id.station_code == mstation_ext)) and \ - ((mpick.method_id).split('/')[1] == 'auto') and \ + (mpick.method_id.split('/')[1] == 'auto') and \ (mpick.time_errors['uncertainty'] <= ErrorsP[3]): del mpick break elif phase == 'S': if ((mpick.waveform_id.station_code == mstation) or (mpick.waveform_id.station_code == mstation_ext)) and \ - ((mpick.method_id).split('/')[1] == 'auto') and \ + (mpick.method_id.split('/')[1] == 'auto') and \ (mpick.time_errors['uncertainty'] <= ErrorsS[3]): del mpick break diff --git a/pylot/core/util/array_map.py b/pylot/core/util/array_map.py index 97b4aa7e..91f7fe9d 100644 --- a/pylot/core/util/array_map.py +++ b/pylot/core/util/array_map.py @@ -396,16 +396,16 @@ class Array_map(QtGui.QWidget): del (self.cbar, self.cbax_bg) if hasattr(self, 'sc_picked'): self.sc_picked.remove() - del (self.sc_picked) + del self.sc_picked if hasattr(self, 'sc_event'): self.sc_event.remove() - del (self.sc_event) + del self.sc_event if hasattr(self, 'contourf'): self.remove_contourf() - del (self.contourf) + del self.contourf if hasattr(self, 'cid'): self.canvas.mpl_disconnect(self.cid) - del (self.cid) + del self.cid try: self.sc.remove() except Exception as e: diff --git a/pylot/core/util/dataprocessing.py b/pylot/core/util/dataprocessing.py index 431b250b..7c575949 100644 --- a/pylot/core/util/dataprocessing.py +++ b/pylot/core/util/dataprocessing.py @@ -639,7 +639,7 @@ def get_prefilt(trace, tlow=(0.5, 0.9), thi=(5., 2.), verbosity=0): fny = trace.stats.sampling_rate / 2 fc21 = fny - (fny * thi[0] / 100.) fc22 = fny - (fny * thi[1] / 100.) - return (tlow[0], tlow[1], fc21, fc22) + return tlow[0], tlow[1], fc21, fc22 if __name__ == "__main__": diff --git a/pylot/core/util/widgets.py b/pylot/core/util/widgets.py index b8b64a93..cd527388 100644 --- a/pylot/core/util/widgets.py +++ b/pylot/core/util/widgets.py @@ -2882,13 +2882,13 @@ class MultiEventWidget(QWidget): for rb in self.rb_dict.values(): if rb.isChecked(): check_events = (rb.toolTip() == 'No events for this selection') - self.start_button.setEnabled(not (check_events)) + self.start_button.setEnabled(not check_events) def enable(self, bool): for rb in self.rb_dict.values(): rb.setEnabled(bool) self.start_button.setEnabled(bool) - self.pb.setVisible(not (bool)) + self.pb.setVisible(not bool) self._pb_space.setVisible(bool) self.eventbox.setEnabled(bool) self.button_clear.setEnabled(bool) @@ -2970,7 +2970,7 @@ class AutoPickWidget(MultiEventWidget): def reinitEvents2plot(self): for eventID, eventDict in self.events2plot.items(): for widget_key, widget in eventDict.items(): - del (widget) + del widget self.events2plot = {} self.eventbox.clear() self.refresh_plot_tabs() @@ -3504,7 +3504,7 @@ class TuneAutopicker(QWidget): if hasattr(self, 'pdlg_widget'): if self.pdlg_widget: self.pdlg_widget.setParent(None) - del (self.pdlg_widget) + del self.pdlg_widget if hasattr(self, 'overview'): self.overview.setParent(None) if hasattr(self, 'p_tabs'): From 469d91bfdc0e0d8058e645d836b453e66852f614 Mon Sep 17 00:00:00 2001 From: Marcel Date: Mon, 16 Jul 2018 16:10:49 +0200 Subject: [PATCH 127/169] [cleanup] removed has_spe function, using dict.get method instead! --- PyLoT.py | 6 +++--- pylot/core/util/utils.py | 14 -------------- 2 files changed, 3 insertions(+), 17 deletions(-) diff --git a/PyLoT.py b/PyLoT.py index 9e879a54..f250977b 100755 --- a/PyLoT.py +++ b/PyLoT.py @@ -76,7 +76,7 @@ from pylot.core.util.connection import checkurl from pylot.core.util.dataprocessing import read_metadata, restitute_data from pylot.core.util.utils import fnConstructor, getLogin, \ full_range, readFilterInformation, trim_station_components, check4gaps, make_pen, pick_color_plt, \ - pick_linestyle_plt, remove_underscores, check4doubled, identifyPhaseID, excludeQualityClasses, has_spe, \ + pick_linestyle_plt, remove_underscores, check4doubled, identifyPhaseID, excludeQualityClasses, \ check4rotated, transform_colors_mpl, transform_colors_mpl_str, getAutoFilteroptions, check_all_obspy, \ check_all_pylot, real_Bool from pylot.core.util.event import Event @@ -1266,7 +1266,7 @@ class MainWindow(QMainWindow): for phasename, pick in picks.items(): if not type(pick) in [dict, AttribDict]: continue - if getQualityFromUncertainty(has_spe(pick), phaseErrors[self.getPhaseID(phasename)]) < 4: + if getQualityFromUncertainty(pick.get('spe'), phaseErrors[self.getPhaseID(phasename)]) < 4: ma_count[ma] += 1 ma_count_total[ma] += 1 @@ -2998,7 +2998,7 @@ class MainWindow(QMainWindow): for phasename, pick in picks.items(): if not type(pick) in [dict, AttribDict]: continue - if getQualityFromUncertainty(has_spe(pick), phaseErrors[self.getPhaseID(phasename)]) < 4: + if getQualityFromUncertainty(pick.get('spe'), phaseErrors[self.getPhaseID(phasename)]) < 4: ma_count[ma] += 1 ma_count_total[ma] += 1 diff --git a/pylot/core/util/utils.py b/pylot/core/util/utils.py index d848321e..fecd15c8 100644 --- a/pylot/core/util/utils.py +++ b/pylot/core/util/utils.py @@ -1167,20 +1167,6 @@ def identifyPhaseID(phase): return identifyPhase(loopIdentifyPhase(phase)) -def has_spe(pick): - """ - Check for 'spe' key (symmetric picking error) in dict and return its value if found, else return None - :param pick: pick dictionary - :type pick: dict - :return: value of 'spe' key - :rtype: float or None - """ - if not 'spe' in pick.keys(): - return None - else: - return pick['spe'] - - def check_all_obspy(eventlist): ev_type = 'obspydmt' return check_event_folders(eventlist, ev_type) From 5b48b744fd67602864aa9654377d0e6c24f8196c Mon Sep 17 00:00:00 2001 From: Marcel Date: Mon, 16 Jul 2018 17:56:17 +0200 Subject: [PATCH 128/169] [update] plotting (added fill_between again now performance got increased) --- PyLoT.py | 59 ++++++++++++++-------------------- pylot/core/util/widgets.py | 65 ++++++++++++++++++-------------------- 2 files changed, 54 insertions(+), 70 deletions(-) diff --git a/PyLoT.py b/PyLoT.py index f250977b..4a4100b0 100755 --- a/PyLoT.py +++ b/PyLoT.py @@ -1266,7 +1266,7 @@ class MainWindow(QMainWindow): for phasename, pick in picks.items(): if not type(pick) in [dict, AttribDict]: continue - if getQualityFromUncertainty(pick.get('spe'), phaseErrors[self.getPhaseID(phasename)]) < 4: + if pick.get('spe'): ma_count[ma] += 1 ma_count_total[ma] += 1 @@ -2697,42 +2697,31 @@ class MainWindow(QMainWindow): lpp = None spe = picks['spe'] - if not spe and epp and lpp: - spe = symmetrize_error(mpp - epp, lpp - mpp) - if self.pg: - if picktype == 'manual': - if picks['epp'] and picks['lpp']: - pen = make_pen(picktype, phaseID, 'epp', quality) - pw.plot([epp, epp], ylims, - alpha=.25, pen=pen, name='EPP') - pen = make_pen(picktype, phaseID, 'lpp', quality) - pw.plot([lpp, lpp], ylims, - alpha=.25, pen=pen, name='LPP') - pen = make_pen(picktype, phaseID, 'mpp', quality) + if picktype == 'manual' or picktype == 'auto': if spe: - # pen = make_pen(picktype, phaseID, 'spe', quality) - # spe_l = pg.PlotDataItem([mpp - spe, mpp - spe], ylims, pen=pen, - # name='{}-SPE'.format(phase)) - # spe_r = pg.PlotDataItem([mpp + spe, mpp + spe], ylims, pen=pen) - # pw.addItem(spe_l) - # pw.addItem(spe_r) - # try: - # color = pen.color() - # color.setAlpha(100.) - # brush = pen.brush() - # brush.setColor(color) - # fill = pg.FillBetweenItem(spe_l, spe_r, brush=brush) - # fb = pw.addItem(fill) - # except: - # print('Warning: drawPicks: Could not create fill for symmetric pick error.') - pw.plot([mpp, mpp], ylims, pen=pen, name='{}-Pick'.format(phase)) - else: - pw.plot([mpp, mpp], ylims, pen=pen, name='{}-Pick (NO PICKERROR)'.format(phase)) - elif picktype == 'auto': - if quality < 4: + if picks['epp'] and picks['lpp']: + pen = make_pen(picktype, phaseID, 'epp', quality) + pw.plot([epp, epp], ylims, + alpha=.25, pen=pen, name='EPP') + pen = make_pen(picktype, phaseID, 'lpp', quality) + pw.plot([lpp, lpp], ylims, + alpha=.25, pen=pen, name='LPP') + pen = make_pen(picktype, phaseID, 'spe', quality) + spe_l = pg.PlotDataItem([mpp - spe, mpp - spe], ylims, pen=pen, + name='{}-SPE'.format(phase)) + spe_r = pg.PlotDataItem([mpp + spe, mpp + spe], ylims, pen=pen) + try: + color = pen.color() + color.setAlpha(100.) + brush = pen.brush() + brush.setColor(color) + fill = pg.FillBetweenItem(spe_l, spe_r, brush=brush) + fb = pw.addItem(fill) + except: + print('Warning: drawPicks: Could not create fill for symmetric pick error.') pen = make_pen(picktype, phaseID, 'mpp', quality) - pw.plot([mpp, mpp], ylims, pen=pen) + pw.plot([mpp, mpp], ylims, pen=pen, name='{}-Pick'.format(phase)) else: raise TypeError('Unknown picktype {0}'.format(picktype)) else: @@ -2998,7 +2987,7 @@ class MainWindow(QMainWindow): for phasename, pick in picks.items(): if not type(pick) in [dict, AttribDict]: continue - if getQualityFromUncertainty(pick.get('spe'), phaseErrors[self.getPhaseID(phasename)]) < 4: + if pick.get('spe'): ma_count[ma] += 1 ma_count_total[ma] += 1 diff --git a/pylot/core/util/widgets.py b/pylot/core/util/widgets.py index cd527388..e9bc5e4b 100644 --- a/pylot/core/util/widgets.py +++ b/pylot/core/util/widgets.py @@ -2359,43 +2359,38 @@ class PickDlg(QDialog): lpp = picks['lpp'] - self.getStartTime() spe = picks['spe'] - if picktype == 'manual': - color = pick_color_plt(picktype, phaseID, quality) - if not textOnly: - linestyle_mpp, width_mpp = pick_linestyle_plt(picktype, 'mpp') - vl = ax.axvline(mpp, ylims[0], ylims[1], color=color, linestyle=linestyle_mpp, linewidth=width_mpp, - label='{}-Pick (quality: {})'.format(phase, quality), picker=5) - self.phaseLines[phase] = vl - if spe: - ax.fill_between([mpp - spe, mpp + spe], ylims[0], ylims[1], - alpha=.25, color=color, label='{}-SPE'.format(phase)) - if picks['epp']: - linestyle_epp, width_epp = pick_linestyle_plt(picktype, 'epp') - ax.axvline(epp, ylims[0], ylims[1], color=color, linestyle=linestyle_epp, - linewidth=width_epp, label='{}-EPP'.format(phase)) - if picks['lpp']: - linestyle_lpp, width_lpp = pick_linestyle_plt(picktype, 'lpp') - ax.axvline(lpp, ylims[0], ylims[1], color=color, linestyle=linestyle_lpp, - linewidth=width_lpp, label='{}-LPP'.format(phase)) - # else: - # ax.plot([mpp, mpp], ylims, color=color, linestyle=linestyle_mpp, linewidth=width_mpp, - # label='{}-Pick (NO PICKERROR)'.format(phase), picker=5) - # append phase text (if textOnly: draw with current ylims) - self.phaseText.append(ax.text(mpp, ylims[1], phase, color=color)) - elif picktype == 'auto': - color = pick_color_plt(picktype, phaseID, quality) - linestyle_mpp, width_mpp = pick_linestyle_plt(picktype, 'mpp') - if not textOnly: - ax.plot(mpp, ylims[1], color=color, marker='v') - ax.plot(mpp, ylims[0], color=color, marker='^') - vl = ax.axvline(mpp, ylims[0], ylims[1], color=color, linestyle=linestyle_mpp, linewidth=width_mpp, - picker=5, label='{}-Autopick (quality: {})'.format(phase, quality)) - self.phaseLines[phase] = vl - # append phase text (if textOnly: draw with current ylims) - self.phaseText.append(ax.text(mpp, ylims[1], phase, color=color)) - else: + if not picktype in ['auto', 'manual']: raise TypeError('Unknown picktype {0}'.format(picktype)) + if picktype == 'manual': + baseorder = 5 + elif picktype == 'auto': + baseorder = 0 + + color = pick_color_plt(picktype, phaseID, quality) + if not textOnly: + linestyle_mpp, width_mpp = pick_linestyle_plt(picktype, 'mpp') + vl = ax.axvline(mpp, ylims[0], ylims[1], color=color, linestyle=linestyle_mpp, linewidth=width_mpp, + label='{}-{}-Pick (quality: {})'.format(phase, picktype, quality), picker=5, + zorder=baseorder+9) + phaseLineKey = '{}-{}'.format(phase, picktype) + self.phaseLines[phaseLineKey] = vl + if spe: + ax.fill_between([mpp - spe, mpp + spe], ylims[0], ylims[1], + alpha=.25, color=color, label='{}-{}-SPE'.format(phase, picktype), zorder=baseorder+1) + if picks['epp']: + linestyle_epp, width_epp = pick_linestyle_plt(picktype, 'epp') + ax.axvline(epp, ylims[0], ylims[1], color=color, linestyle=linestyle_epp, + linewidth=width_epp, label='{}-{}-EPP'.format(phase, picktype), zorder=baseorder+2) + if picks['lpp']: + linestyle_lpp, width_lpp = pick_linestyle_plt(picktype, 'lpp') + ax.axvline(lpp, ylims[0], ylims[1], color=color, linestyle=linestyle_lpp, + linewidth=width_lpp, label='{}-{}-LPP'.format(phase, picktype), zorder=baseorder+2) + if picktype == 'auto': + ax.plot(mpp, ylims[1], color=color, marker='v', zorder=baseorder+3) + ax.plot(mpp, ylims[0], color=color, marker='^', zorder=baseorder+3) + # append phase text (if textOnly: draw with current ylims) + self.phaseText.append(ax.text(mpp, ylims[1], phase, color=color, zorder=baseorder+10)) ax.legend(loc=1) def connect_mouse_motion(self): From 64885db214fb24c75d66106fb8c638e81802781e Mon Sep 17 00:00:00 2001 From: Marcel Date: Tue, 17 Jul 2018 09:42:13 +0200 Subject: [PATCH 129/169] [update] no more replotting of whole data when pick is changed --- PyLoT.py | 78 +++++++++++++++++++++++++++++++------------------------- 1 file changed, 43 insertions(+), 35 deletions(-) diff --git a/PyLoT.py b/PyLoT.py index 4a4100b0..fca18830 100755 --- a/PyLoT.py +++ b/PyLoT.py @@ -134,6 +134,9 @@ class MainWindow(QMainWindow): self._ctrl = False # control key pressed self._shift = False # shift key pressed + self.drawnPicks = {'auto': {}, + 'manual': {}} + # default factor for dataplot e.g. enabling/disabling scrollarea self.height_factor = 12 self.plot_method = 'normal' @@ -2324,16 +2327,14 @@ class MainWindow(QMainWindow): if pickDlg._dirty: self.setDirty(True) self.update_status('picks accepted ({0})'.format(station)) - replot1 = self.addPicks(station, pickDlg.getPicks(picktype='manual'), type='manual') - replot2 = self.addPicks(station, pickDlg.getPicks(picktype='auto'), type='auto') + self.addPicks(station, pickDlg.getPicks(picktype='manual'), type='manual') + self.addPicks(station, pickDlg.getPicks(picktype='auto'), type='auto') self.enableSaveEventAction() - if replot1 or replot2: - self.plotWaveformDataThread() - - self.draw() - else: - self.drawPicks(station) - self.draw() + self.comparable = self.checkEvents4comparison() + if True in self.comparable.values(): + self.compare_action.setEnabled(True) + self.drawPicks(station) + self.draw() if self.nextStation: self.pickDialog(wfID - 1) else: @@ -2652,6 +2653,9 @@ class MainWindow(QMainWindow): self.drawPicks(station, 'auto', stime) return + if not picktype in ['manual', 'auto']: + raise TypeError('Unknown picktype {0}'.format(picktype)) + # if picks to draw not specified, draw all picks available if not station: for station in self.getPicks(type=picktype): @@ -2674,6 +2678,11 @@ class MainWindow(QMainWindow): stat_picks = self.getPicks(type=picktype)[station] + if station in self.drawnPicks[picktype].keys(): + for item in self.drawnPicks[picktype][station]: + pw.removeItem(item) + self.drawnPicks[picktype][station] = [] + for phase in stat_picks: if phase == 'SPt': continue # wadati SP time picks = stat_picks[phase] @@ -2698,32 +2707,31 @@ class MainWindow(QMainWindow): spe = picks['spe'] if self.pg: - if picktype == 'manual' or picktype == 'auto': - if spe: - if picks['epp'] and picks['lpp']: - pen = make_pen(picktype, phaseID, 'epp', quality) - pw.plot([epp, epp], ylims, - alpha=.25, pen=pen, name='EPP') - pen = make_pen(picktype, phaseID, 'lpp', quality) - pw.plot([lpp, lpp], ylims, - alpha=.25, pen=pen, name='LPP') - pen = make_pen(picktype, phaseID, 'spe', quality) - spe_l = pg.PlotDataItem([mpp - spe, mpp - spe], ylims, pen=pen, - name='{}-SPE'.format(phase)) - spe_r = pg.PlotDataItem([mpp + spe, mpp + spe], ylims, pen=pen) - try: - color = pen.color() - color.setAlpha(100.) - brush = pen.brush() - brush.setColor(color) - fill = pg.FillBetweenItem(spe_l, spe_r, brush=brush) - fb = pw.addItem(fill) - except: - print('Warning: drawPicks: Could not create fill for symmetric pick error.') - pen = make_pen(picktype, phaseID, 'mpp', quality) - pw.plot([mpp, mpp], ylims, pen=pen, name='{}-Pick'.format(phase)) - else: - raise TypeError('Unknown picktype {0}'.format(picktype)) + if spe: + if picks['epp'] and picks['lpp']: + pen = make_pen(picktype, phaseID, 'epp', quality) + self.drawnPicks[picktype][station].append(pw.plot([epp, epp], ylims, + alpha=.25, pen=pen, name='EPP')) + pen = make_pen(picktype, phaseID, 'lpp', quality) + self.drawnPicks[picktype][station].append(pw.plot([lpp, lpp], ylims, + alpha=.25, pen=pen, name='LPP')) + pen = make_pen(picktype, phaseID, 'spe', quality) + spe_l = pg.PlotDataItem([mpp - spe, mpp - spe], ylims, pen=pen, + name='{}-SPE'.format(phase)) + spe_r = pg.PlotDataItem([mpp + spe, mpp + spe], ylims, pen=pen) + try: + color = pen.color() + color.setAlpha(100.) + brush = pen.brush() + brush.setColor(color) + fill = pg.FillBetweenItem(spe_l, spe_r, brush=brush) + fb = pw.addItem(fill) + self.drawnPicks[picktype][station].append(fill) + except: + print('Warning: drawPicks: Could not create fill for symmetric pick error.') + pen = make_pen(picktype, phaseID, 'mpp', quality) + self.drawnPicks[picktype][station].append( + pw.plot([mpp, mpp], ylims, pen=pen, name='{}-Pick'.format(phase))) else: if picktype == 'manual': linestyle_mpp, width_mpp = pick_linestyle_plt(picktype, 'mpp') From fbc01290d5724427ccb147e0c4a7b269cd3bdb38 Mon Sep 17 00:00:00 2001 From: Marcel Date: Tue, 17 Jul 2018 10:06:03 +0200 Subject: [PATCH 130/169] [update] make PYQTGRAPH mandatory for PyLoT (stop maintaining unused stuff)! --- PyLoT.py | 6 +----- pylot/core/util/utils.py | 7 +------ pylot/core/util/widgets.py | 9 ++------- 3 files changed, 4 insertions(+), 18 deletions(-) diff --git a/PyLoT.py b/PyLoT.py index fca18830..e38e5fb0 100755 --- a/PyLoT.py +++ b/PyLoT.py @@ -48,11 +48,7 @@ from obspy.core.util import AttribDict from pylot.core.util.obspyDMT_interface import check_obspydmt_structure -try: - import pyqtgraph as pg -except Exception as e: - print('PyLoT: Could not import pyqtgraph. {}'.format(e)) - pg = None +import pyqtgraph as pg try: from matplotlib.backends.backend_qt4agg import FigureCanvas diff --git a/pylot/core/util/utils.py b/pylot/core/util/utils.py index fecd15c8..73b732da 100644 --- a/pylot/core/util/utils.py +++ b/pylot/core/util/utils.py @@ -22,12 +22,7 @@ from pylot.styles import style_settings from scipy.interpolate import splrep, splev from PySide import QtCore, QtGui -try: - import pyqtgraph as pg -except Exception as e: - print('PyLoT: Could not import pyqtgraph. {}'.format(e)) - pg = None - +import pyqtgraph as pg def _pickle_method(m): if m.im_self is None: diff --git a/pylot/core/util/widgets.py b/pylot/core/util/widgets.py index e9bc5e4b..17c184aa 100644 --- a/pylot/core/util/widgets.py +++ b/pylot/core/util/widgets.py @@ -4404,7 +4404,7 @@ class GraphicsTab(PropTab): super(GraphicsTab, self).__init__(parent) self.pylot_mainwindow = parent._pylot_mainwindow self.init_layout() - self.add_pg_cb() + #self.add_pg_cb() self.add_nth_sample() self.add_style_settings() self.setLayout(self.main_layout) @@ -4441,12 +4441,7 @@ class GraphicsTab(PropTab): self.main_layout.addWidget(self.spinbox_nth_sample, 1, 1) def add_pg_cb(self): - try: - import pyqtgraph as pg - pg = True - except: - pg = False - + pg = True text = {True: 'Use pyqtgraphic library for plotting', False: 'Cannot use library: pyqtgraphic not found on system'} label = QLabel('PyQt graphic') From dda997e457299eb5822b98bc9c8e69b7349ae51f Mon Sep 17 00:00:00 2001 From: Marcel Date: Tue, 17 Jul 2018 10:53:37 +0200 Subject: [PATCH 131/169] [update] autopick -> only export necessary XML (WIP) --- PyLoT.py | 13 ++++++++----- pylot/core/util/widgets.py | 2 +- 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/PyLoT.py b/PyLoT.py index e38e5fb0..ad45582a 100755 --- a/PyLoT.py +++ b/PyLoT.py @@ -1433,8 +1433,11 @@ class MainWindow(QMainWindow): return True - def exportAllEvents(self, outformats=['.xml']): - for event in self.project.eventlist: + def exportEvents(self, outformats=['.xml'], events='all'): + if events == 'all': + events = self.project.eventlist + assert type(events) == list, 'Wrong input type: {}'.format(type(events)) + for event in events: self.get_data().setEvtData(event) try: self.saveData(event, event.path, outformats) @@ -2495,7 +2498,7 @@ class MainWindow(QMainWindow): self.apw.enable(False) # export current picks etc. - self.exportAllEvents(['.xml']) + self.exportEvents(['.xml'], events=events) wfpath = self.dataPlot.qcombo_processed.currentText() if self.obspy_dmt else '' # define arguments for picker @@ -3298,7 +3301,7 @@ class MainWindow(QMainWindow): self.project.save(filename) self.setDirty(False) self.saveProjectAsAction.setEnabled(True) - self.exportAllEvents() + self.exportEvents() self.update_status('Saved new project to {}'.format(filename), duration=5000) return True @@ -3314,7 +3317,7 @@ class MainWindow(QMainWindow): else: self.project.parameter = self._inputs self.project.save() - self.exportAllEvents() + self.exportEvents() if not self.project.dirty: self.update_status('Saved back project to file:\n{}'.format(self.project.location), duration=5000) self.setDirty(False) diff --git a/pylot/core/util/widgets.py b/pylot/core/util/widgets.py index 17c184aa..9ee49bc4 100644 --- a/pylot/core/util/widgets.py +++ b/pylot/core/util/widgets.py @@ -4003,7 +4003,7 @@ class AutoPickDlg(QDialog): self.gb.setLayout(self.jobLayout) def exportParameter(self): - self.parent().exportAllEvents() + self.parent().exportEvents() pylot_params = self.parent()._inputs self.addEvents2pp(pylot_params) pylot_params.export2File(self.pp_export) From cf34c9465cd54e22c5de86d442286da228d05a5d Mon Sep 17 00:00:00 2001 From: Marcel Date: Tue, 17 Jul 2018 14:22:14 +0200 Subject: [PATCH 132/169] [minor] cosmetics --- pylot/core/io/data.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pylot/core/io/data.py b/pylot/core/io/data.py index 1701e10b..1328a7b7 100644 --- a/pylot/core/io/data.py +++ b/pylot/core/io/data.py @@ -507,7 +507,7 @@ class Data(object): print("Writing phases to ObsPy-quakeml file") for key in picks: if picks[key]['P']['picker'] == 'auto': - print("Existing picks will be overwritten!") + print("Existing auto-picks will be overwritten in pick-dictionary!") picks = picks_from_picksdict(picks) break else: From 1fc62a5e9db039845147dfe57ab9aed5ce3f1384 Mon Sep 17 00:00:00 2001 From: Marcel Date: Tue, 17 Jul 2018 14:22:27 +0200 Subject: [PATCH 133/169] [bugfix] add trace starttime to metadata.get_coordinates call --- pylot/core/pick/autopick.py | 20 +------------------- 1 file changed, 1 insertion(+), 19 deletions(-) diff --git a/pylot/core/pick/autopick.py b/pylot/core/pick/autopick.py index 29f8d6eb..89fac64a 100644 --- a/pylot/core/pick/autopick.py +++ b/pylot/core/pick/autopick.py @@ -139,24 +139,6 @@ def call_autopickstation(input_tuple): return e, wfstream[0].stats.station -def get_source_coords(parser, station_id): - """ - retrieves station coordinates from metadata - :param parser: Parser object containing metadata read from inventory file - :type parser: ~obspy.io.xseed.parser.Parser - :param station_id: station id of which the coordinates should be retrieved - :type station_id: str - :return: dictionary containing 'latitude', 'longitude', 'elevation' and 'local_depth' of station - :rtype: dict - """ - station_coords = None - try: - station_coords = parser.get_coordinates(station_id) - except Exception as e: - print('Could not get source coordinates for station {}: {}'.format(station_id, e)) - return station_coords - - def autopickstation(wfstream, pickparam, verbose=False, iplot=0, fig_dict=None, metadata=None, origin=None): """ @@ -312,7 +294,7 @@ def autopickstation(wfstream, pickparam, verbose=False, print('Warning: Could not use TauPy to estimate onsets as there are no metadata given.') else: station_id = wfstream[0].get_id() - station_coords = metadata.get_coordinates(station_id) + station_coords = metadata.get_coordinates(station_id, time=wfstream[0].stats.starttime) if station_coords and origin: source_origin = origin[0] model = TauPyModel(taup_model) From 37da7327d0f302edfa0059f18a367f08b9434ea7 Mon Sep 17 00:00:00 2001 From: Marcel Date: Tue, 17 Jul 2018 16:04:20 +0200 Subject: [PATCH 134/169] [bugfix] using Metadata class for pickDlg, not yet working for array_map (WIP!) --- PyLoT.py | 13 ++++++++++--- pylot/core/util/widgets.py | 7 ++++--- 2 files changed, 14 insertions(+), 6 deletions(-) diff --git a/PyLoT.py b/PyLoT.py index ad45582a..14bcf7a3 100755 --- a/PyLoT.py +++ b/PyLoT.py @@ -69,7 +69,7 @@ from pylot.core.util.defaults import FILTERDEFAULTS, SetChannelComponents from pylot.core.util.errors import DatastructureError, \ OverwriteError from pylot.core.util.connection import checkurl -from pylot.core.util.dataprocessing import read_metadata, restitute_data +from pylot.core.util.dataprocessing import Metadata, restitute_data from pylot.core.util.utils import fnConstructor, getLogin, \ full_range, readFilterInformation, trim_station_components, check4gaps, make_pen, pick_color_plt, \ pick_linestyle_plt, remove_underscores, check4doubled, identifyPhaseID, excludeQualityClasses, \ @@ -1063,7 +1063,7 @@ class MainWindow(QMainWindow): self.dataStructure = DATASTRUCTURE['obspyDMT']() eventlist = check_all_obspy(eventlist) else: - print('Settings Datastructure to PILOT') + print('Setting Datastructure to PILOT') self.dataStructure = DATASTRUCTURE['PILOT']() eventlist = check_all_pylot(eventlist) if not eventlist: @@ -1922,6 +1922,13 @@ class MainWindow(QMainWindow): if True in self.comparable.values(): self.compare_action.setEnabled(True) self.draw() + # MP MP ++++ + # TODO: Quick and dirty, improve this on later iteration + if self.obspy_dmt: + self.metadata = Metadata(os.path.join(self.get_current_event_path(), 'resp')) + self.inventoryAction.setEnabled(not self.obspy_dmt) + # MP MP --- + @staticmethod def checkEvent4comparison(event): @@ -3094,7 +3101,7 @@ class MainWindow(QMainWindow): set_background_color(item_list, QtGui.QColor(*(0, 143, 143, 255))) def read_metadata_thread(self, fninv): - self.rm_thread = Thread(self, read_metadata, arg=fninv, progressText='Reading metadata...', + self.rm_thread = Thread(self, Metadata, arg=fninv, progressText='Reading metadata...', pb_widget=self.mainProgressBarWidget) self.rm_thread.finished.connect(self.set_metadata) self.rm_thread.start() diff --git a/pylot/core/util/widgets.py b/pylot/core/util/widgets.py index 9ee49bc4..af80727f 100644 --- a/pylot/core/util/widgets.py +++ b/pylot/core/util/widgets.py @@ -1691,9 +1691,10 @@ class PickDlg(QDialog): func = {True: self.model.get_ray_paths_geo, False: self.model.get_travel_times_geo} phases = self.prepare_phases() - station_id = self.data.traces[0].get_id() - parser = self.metadata[1] - station_coords = parser.get_coordinates(station_id) + trace = self.data.traces[0] + station_id = trace.get_id() + starttime = trace.stats.starttime + station_coords = self.metadata.get_coordinates(station_id, starttime) origins = self.pylot_event.origins if origins: source_origin = origins[0] From ed7ee5d944af0cbe4282a56e862a81b9a6f55857 Mon Sep 17 00:00:00 2001 From: Marcel Date: Wed, 18 Jul 2018 11:13:29 +0200 Subject: [PATCH 135/169] [bugfix] progressText not updating in progressBar --- PyLoT.py | 5 +++-- pylot/core/util/thread.py | 22 ++++++---------------- pylot/core/util/widgets.py | 12 ++++++++++++ 3 files changed, 21 insertions(+), 18 deletions(-) diff --git a/PyLoT.py b/PyLoT.py index 14bcf7a3..e857eb11 100755 --- a/PyLoT.py +++ b/PyLoT.py @@ -80,7 +80,7 @@ from pylot.core.io.location import create_creation_info, create_event from pylot.core.util.widgets import FilterOptionsDialog, NewEventDlg, \ PylotCanvas, WaveformWidgetPG, PropertiesDlg, HelpForm, createAction, PickDlg, \ getDataType, ComparisonWidget, TuneAutopicker, PylotParaBox, AutoPickDlg, CanvasWidget, AutoPickWidget, \ - CompareEventsWidget + CompareEventsWidget, ProgressBarWidget from pylot.core.util.array_map import Array_map from pylot.core.util.structure import DATASTRUCTURE from pylot.core.util.thread import Thread, Worker @@ -609,7 +609,8 @@ class MainWindow(QMainWindow): self.tabs.currentChanged.connect(self.refreshTabs) # add progressbar - self.mainProgressBarWidget = QtGui.QWidget() + self.mainProgressBarWidget = ProgressBarWidget(self) + self.mainProgressBarWidget.hide() self._main_layout.addWidget(self.mainProgressBarWidget) # add scroll area used in case number of traces gets too high diff --git a/pylot/core/util/thread.py b/pylot/core/util/thread.py index e84ed398..17f54c12 100644 --- a/pylot/core/util/thread.py +++ b/pylot/core/util/thread.py @@ -41,23 +41,13 @@ class Thread(QThread): def showProgressbar(self): if self.progressText: - # generate widget if not given in init - if not self.pb_widget: - self.pb_widget = QDialog(self.parent()) - self.pb_widget.setWindowFlags(Qt.SplashScreen) - self.pb_widget.setModal(True) + # # generate widget if not given in init + # if not self.pb_widget: + # self.pb_widget = ProgressBarWidget(self.parent()) + # self.pb_widget.setWindowFlags(Qt.SplashScreen) + # self.pb_widget.setModal(True) - # add button - delete_button = QPushButton('X') - delete_button.clicked.connect(self.exit) - hl = QHBoxLayout() - pb = QProgressBar() - pb.setRange(0, 0) - hl.addWidget(pb) - hl.addWidget(QLabel(self.progressText)) - if self.abortButton: - hl.addWidget(delete_button) - self.pb_widget.setLayout(hl) + self.pb_widget.label.setText(self.progressText) self.pb_widget.show() def hideProgressbar(self): diff --git a/pylot/core/util/widgets.py b/pylot/core/util/widgets.py index af80727f..ededd0c1 100644 --- a/pylot/core/util/widgets.py +++ b/pylot/core/util/widgets.py @@ -119,6 +119,18 @@ def createAction(parent, text, slot=None, shortcut=None, icon=None, return action +class ProgressBarWidget(QtGui.QWidget): + def __init__(self, parent=None): + super(ProgressBarWidget, self).__init__(parent) + self.hlayout = QtGui.QHBoxLayout() + self.pb = QtGui.QProgressBar() + self.pb.setRange(0, 0) + self.label = QLabel() + self.hlayout.addWidget(self.pb) + self.hlayout.addWidget(self.label) + self.setLayout(self.hlayout) + + class ComparisonWidget(QWidget): def __init__(self, c, parent=None, windowflag=1): self._data = c From 17c27f9294bce206c04cf7869c29e0de9994201e Mon Sep 17 00:00:00 2001 From: Marcel Date: Wed, 18 Jul 2018 11:38:33 +0200 Subject: [PATCH 136/169] [bugfix] add time to metadata.get_coordinates in check4rotated --- pylot/core/util/utils.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/pylot/core/util/utils.py b/pylot/core/util/utils.py index 73b732da..cac064d0 100644 --- a/pylot/core/util/utils.py +++ b/pylot/core/util/utils.py @@ -964,9 +964,10 @@ def check4rotated(data, metadata=None, verbosity=1): orientations = [trace_id[-1] for trace_id in trace_ids] rotation_required = [orientation.isnumeric() for orientation in orientations] if any(rotation_required): + t_start = full_range(wfstream) try: - azimuts = [metadata.get_coordinates(tr_id)['azimuth'] for tr_id in trace_ids] - dips = [metadata.get_coordinates(tr_id)['dip'] for tr_id in trace_ids] + azimuts = [metadata.get_coordinates(tr_id, t_start)['azimuth'] for tr_id in trace_ids] + dips = [metadata.get_coordinates(tr_id, t_start)['dip'] for tr_id in trace_ids] except (KeyError, TypeError) as e: print('Failed to rotate trace {}, no azimuth or dip available in metadata'.format(trace_id)) return wfstream @@ -983,7 +984,7 @@ def check4rotated(data, metadata=None, verbosity=1): wfstream[z_index].stats.channel = wfstream[z_index].stats.channel[0:-1] + 'Z' del trace_ids[z_index] for trace_id in trace_ids: - coordinates = metadata.get_coordinates(trace_id) + coordinates = metadata.get_coordinates(trace_id, t_start) dip, az = coordinates['dip'], coordinates['azimuth'] trace = wfstream.select(id=trace_id)[0] if az > 315 or az <= 45 or az > 135 and az <= 225: From ed654024b2d7e421cfb8ff2cc5453b63e3f7e589 Mon Sep 17 00:00:00 2001 From: Marcel Date: Wed, 18 Jul 2018 11:39:01 +0200 Subject: [PATCH 137/169] [update] reinstated check4rotated in autoPyLoT --- autoPyLoT.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/autoPyLoT.py b/autoPyLoT.py index 68ecbbd6..415fdbe7 100755 --- a/autoPyLoT.py +++ b/autoPyLoT.py @@ -289,7 +289,7 @@ def autoPyLoT(input_dict=None, parameter=None, inputfile=None, fnames=None, even corr_dat = None if metadata: # rotate stations to ZNE - # wfdat = check4rotated(wfdat, metadata) # MP MP TEMPORARILY DISABLED !!!!!!!!!!! + wfdat = check4rotated(wfdat, metadata) if locflag: print("Restitute data ...") corr_dat = restitute_data(wfdat.copy(), metadata, ncores=ncores) From 12082cb2a9e9b6a9548a85b33addabde11a40e7b Mon Sep 17 00:00:00 2001 From: Marcel Date: Wed, 18 Jul 2018 11:42:46 +0200 Subject: [PATCH 138/169] [minor] removed old code --- autoPyLoT.py | 6 ------ 1 file changed, 6 deletions(-) diff --git a/autoPyLoT.py b/autoPyLoT.py index 415fdbe7..0b35cc47 100755 --- a/autoPyLoT.py +++ b/autoPyLoT.py @@ -280,12 +280,6 @@ def autoPyLoT(input_dict=None, parameter=None, inputfile=None, fnames=None, even metadata = Metadata(parameter.get('invdir')) else: metadata = Metadata(os.path.join(eventpath, 'resp')) - # metadata = read_metadata(parameter.get('invdir')) - # TODO: (idea) read metadata from obspy_dmt database - # if not wfpath_extension: - # metadata = read_metadata(parameter.get('invdir')) - # else: - # metadata = None corr_dat = None if metadata: # rotate stations to ZNE From 90e26cbd8f0f00957e53fcf093f7aae3ec9fa082 Mon Sep 17 00:00:00 2001 From: Marcel Date: Wed, 18 Jul 2018 14:12:59 +0200 Subject: [PATCH 139/169] [bugfix] various, pick delete/plot behaviour --- PyLoT.py | 19 ++++++++++--------- autoPyLoT.py | 2 +- pylot/core/io/data.py | 2 +- pylot/core/util/dataprocessing.py | 2 +- pylot/core/util/event.py | 6 ++++-- pylot/core/util/utils.py | 10 +++++++--- pylot/core/util/widgets.py | 7 ++++--- 7 files changed, 28 insertions(+), 20 deletions(-) diff --git a/PyLoT.py b/PyLoT.py index e857eb11..177fa7d5 100755 --- a/PyLoT.py +++ b/PyLoT.py @@ -2669,6 +2669,16 @@ class MainWindow(QMainWindow): self.drawPicks(station, picktype=picktype, stime=stime) return + if self.pg: + pw = self.getPlotWidget().plotWidget + else: + ax = self.getPlotWidget().axes[0] + + if station in self.drawnPicks[picktype].keys(): + for item in self.drawnPicks[picktype][station]: + pw.removeItem(item) + self.drawnPicks[picktype][station] = [] + # check for station key in dictionary, else return if not station in self.getPicks(type=picktype): return @@ -2677,19 +2687,10 @@ class MainWindow(QMainWindow): plotID = self.getStationID(station) if plotID is None: return - if self.pg: - pw = self.getPlotWidget().plotWidget - else: - ax = self.getPlotWidget().axes[0] ylims = np.array([-.5, +.5]) + plotID stat_picks = self.getPicks(type=picktype)[station] - if station in self.drawnPicks[picktype].keys(): - for item in self.drawnPicks[picktype][station]: - pw.removeItem(item) - self.drawnPicks[picktype][station] = [] - for phase in stat_picks: if phase == 'SPt': continue # wadati SP time picks = stat_picks[phase] diff --git a/autoPyLoT.py b/autoPyLoT.py index 0b35cc47..f9079aac 100755 --- a/autoPyLoT.py +++ b/autoPyLoT.py @@ -271,7 +271,7 @@ def autoPyLoT(input_dict=None, parameter=None, inputfile=None, fnames=None, even if not wfdat: print('Could not find station {}. STOP!'.format(station)) return - wfdat = remove_underscores(wfdat) + #wfdat = remove_underscores(wfdat) # trim components for each station to avoid problems with different trace starttimes for one station wfdat = check4gaps(wfdat) wfdat = check4doubled(wfdat) diff --git a/pylot/core/io/data.py b/pylot/core/io/data.py index 1328a7b7..445af803 100644 --- a/pylot/core/io/data.py +++ b/pylot/core/io/data.py @@ -405,7 +405,7 @@ class Data(object): # various pre-processing steps: # remove possible underscores in station names - self.wfdata = remove_underscores(self.wfdata) + #self.wfdata = remove_underscores(self.wfdata) # check for stations with rotated components if checkRotated and metadata is not None: self.wfdata = check4rotated(self.wfdata, metadata, verbosity=0) diff --git a/pylot/core/util/dataprocessing.py b/pylot/core/util/dataprocessing.py index 7c575949..0789187a 100644 --- a/pylot/core/util/dataprocessing.py +++ b/pylot/core/util/dataprocessing.py @@ -580,7 +580,7 @@ def restitute_data(data, metadata, unit='VEL', force=False, ncores=0): restflag = list() - data = remove_underscores(data) + #data = remove_underscores(data) # loop over traces input_tuples = [] diff --git a/pylot/core/util/event.py b/pylot/core/util/event.py index 55ed8ea8..8146d1f8 100644 --- a/pylot/core/util/event.py +++ b/pylot/core/util/event.py @@ -185,7 +185,8 @@ class Event(ObsPyEvent): self.pylot_picks[station] = pick else: try: - self.pylot_picks.pop(station) + if station in self.pylot_picks: + self.pylot_picks.pop(station) except Exception as e: print('Could not remove pick {} from station {}: {}'.format(pick, station, e)) self.clearObsPyPicks('manual') @@ -236,7 +237,8 @@ class Event(ObsPyEvent): self.pylot_autopicks[station] = pick else: try: - self.pylot_autopicks.pop(station) + if station in self.pylot_autopicks: + self.pylot_autopicks.pop(station) except Exception as e: print('Could not remove pick {} from station {}: {}'.format(pick, station, e)) self.clearObsPyPicks('auto') diff --git a/pylot/core/util/utils.py b/pylot/core/util/utils.py index cac064d0..b751690c 100644 --- a/pylot/core/util/utils.py +++ b/pylot/core/util/utils.py @@ -399,6 +399,10 @@ def full_range(stream): :return: minimum start time and maximum end time :rtype: (`~maximum start time and minimum end time`, maximum start time and minimum end time) """ + if not stream: + print('full_range: Empty Stream!') + return None, None + min_start = min([trace.stats.starttime for trace in stream]) max_end = max([trace.stats.endtime for trace in stream]) @@ -831,9 +835,9 @@ def remove_underscores(data): :return: data stream :rtype: `~obspy.core.stream.Stream` """ - for tr in data: - # remove underscores - tr.stats.station = tr.stats.station.strip('_') + #for tr in data: + # # remove underscores + # tr.stats.station = tr.stats.station.strip('_') return data diff --git a/pylot/core/util/widgets.py b/pylot/core/util/widgets.py index ededd0c1..791ba196 100644 --- a/pylot/core/util/widgets.py +++ b/pylot/core/util/widgets.py @@ -2525,8 +2525,9 @@ class PickDlg(QDialog): if phase in self.phaseLines.keys(): del (self.phaseLines[phase]) # information output - msg = 'Deleted {} pick for phase {}, at timestamp {} (relative time: {} s)' - print(msg.format(picktype, phase, self.getStartTime() + pick_rel, pick_rel)) + msg = 'Deleted {} pick for phase {}, station {} at timestamp {} (relative time: {} s)' + print(msg.format(picktype, phase, '{}.{}'.format(self.network, self.station), + self.getStartTime() + pick_rel, pick_rel)) self.setDirty(True) def identify_selected_picks(self, x): @@ -3167,7 +3168,7 @@ class TuneAutopicker(QWidget): self.data.setWFData(fnames) wfdat = self.data.getWFData() # all available streams # remove possible underscores in station names - wfdat = remove_underscores(wfdat) + #wfdat = remove_underscores(wfdat) # rotate misaligned stations to ZNE # check for gaps and doubled channels check4gaps(wfdat) From b348117d5a590ef154c4f31a556f373d7fdae744 Mon Sep 17 00:00:00 2001 From: Marcel Date: Wed, 18 Jul 2018 15:04:07 +0200 Subject: [PATCH 140/169] [bugfix] tuneAutopicker not using new pb_widget --- PyLoT.py | 1 - pylot/core/util/widgets.py | 3 ++- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/PyLoT.py b/PyLoT.py index 177fa7d5..75fc9df6 100755 --- a/PyLoT.py +++ b/PyLoT.py @@ -610,7 +610,6 @@ class MainWindow(QMainWindow): # add progressbar self.mainProgressBarWidget = ProgressBarWidget(self) - self.mainProgressBarWidget.hide() self._main_layout.addWidget(self.mainProgressBarWidget) # add scroll area used in case number of traces gets too high diff --git a/pylot/core/util/widgets.py b/pylot/core/util/widgets.py index 791ba196..4b80ba03 100644 --- a/pylot/core/util/widgets.py +++ b/pylot/core/util/widgets.py @@ -129,6 +129,7 @@ class ProgressBarWidget(QtGui.QWidget): self.hlayout.addWidget(self.pb) self.hlayout.addWidget(self.label) self.setLayout(self.hlayout) + self.hide() class ComparisonWidget(QWidget): @@ -3182,7 +3183,7 @@ class TuneAutopicker(QWidget): self.fill_figure_tabs() def init_pbwidget(self): - self.pb_widget = QtGui.QWidget() + self.pb_widget = ProgressBarWidget() def init_tab_names(self): self.ptb_names = ['aicFig', 'slength', 'checkZ4s', 'refPpick', 'el_Ppick', 'fm_picker'] From f802f1db5805193dc18bd91a3f8ec3af5cac0728 Mon Sep 17 00:00:00 2001 From: Marcel Date: Thu, 19 Jul 2018 11:50:29 +0200 Subject: [PATCH 141/169] [new] working on metadata/inventory selection from GUI --- PyLoT.py | 21 +++-- pylot/core/util/widgets.py | 158 +++++++++++++++++++++++++++++++++++++ 2 files changed, 172 insertions(+), 7 deletions(-) diff --git a/PyLoT.py b/PyLoT.py index 75fc9df6..de3f9a35 100755 --- a/PyLoT.py +++ b/PyLoT.py @@ -80,7 +80,7 @@ from pylot.core.io.location import create_creation_info, create_event from pylot.core.util.widgets import FilterOptionsDialog, NewEventDlg, \ PylotCanvas, WaveformWidgetPG, PropertiesDlg, HelpForm, createAction, PickDlg, \ getDataType, ComparisonWidget, TuneAutopicker, PylotParaBox, AutoPickDlg, CanvasWidget, AutoPickWidget, \ - CompareEventsWidget, ProgressBarWidget + CompareEventsWidget, ProgressBarWidget, AddMetadataWidget from pylot.core.util.array_map import Array_map from pylot.core.util.structure import DATASTRUCTURE from pylot.core.util.thread import Thread, Worker @@ -394,10 +394,10 @@ class MainWindow(QMainWindow): self.adjustFilterOptions, "Ctrl+F", self.filter_icon, """Adjust filter parameters.""") - self.inventoryAction = self.createAction(self, "Select &Inventory ...", + self.inventoryAction = self.createAction(self, "Manage &Inventories ...", self.get_new_metadata, "Ctrl+I", self.inventoryIcon, - """Select metadata for current project""", + """Manage metadata for current project""", False) self.initMapAction = self.createAction(self, "Init array map ...", self.init_array_map, @@ -2435,7 +2435,7 @@ class MainWindow(QMainWindow): # else: # self.update_autopicker() # self.tap.fill_eventbox() - self.tap.show() + self.tap.showMaximized() def update_autopicker(self): ''' @@ -2826,7 +2826,7 @@ class MainWindow(QMainWindow): self.inventory_label = QLabel('No inventory set...') # init inventory button - self.new_inv_button = QPushButton('Set inventory file') + self.new_inv_button = QPushButton('Manage inventory files') self.new_inv_button.setIcon(self.inventoryIcon) self.new_inv_button.clicked.connect(self.inventoryAction.trigger) @@ -2839,7 +2839,7 @@ class MainWindow(QMainWindow): grid_layout.addWidget(self.new_inv_button, 2, 1) grid_layout.addWidget(self.init_map_button, 3, 1) - self.metadata = None + self.metadata = Metadata() self.metadata_widget.setLayout(grid_layout) self.array_layout.addWidget(self.metadata_widget) @@ -3119,7 +3119,14 @@ class MainWindow(QMainWindow): self.new_inv_button.setText('Set another inventory file') def get_new_metadata(self): - self.init_metadata(new=True) + if hasattr(self, 'add_metadata_widget'): + self.add_metadata_widget.show() + else: + self.add_metadata_widget = AddMetadataWidget(self, metadata=self.metadata) + #self.init_metadata(new=True) + + def add_metadata(self): + pass def init_metadata(self, new=False, ask_default=True): def set_inv(settings): diff --git a/pylot/core/util/widgets.py b/pylot/core/util/widgets.py index 4b80ba03..a5198995 100644 --- a/pylot/core/util/widgets.py +++ b/pylot/core/util/widgets.py @@ -58,6 +58,7 @@ from pylot.core.util.utils import prepTimeAxis, full_range, scaleWFData, \ identifyPhaseID, real_Bool, pick_color, getAutoFilteroptions from autoPyLoT import autoPyLoT from pylot.core.util.thread import Thread +from pylot.core.util.dataprocessing import Metadata if sys.version_info.major == 3: import icons_rc_3 as icons_rc @@ -132,6 +133,121 @@ class ProgressBarWidget(QtGui.QWidget): self.hide() +class AddMetadataWidget(QWidget): + def __init__(self, parent=None, metadata=None, windowflag=1): + super(AddMetadataWidget, self).__init__(parent, windowflag) + self.inventories = {} + + self.main_layout = QVBoxLayout() + self.setLayout(self.main_layout) + self.setupUI() + self.connect_signals() + self.resize(600, 800) + + self.metadata = metadata if metadata else Metadata() + + self.center() + self.show() + #self.__test__() + + def __test__(self): + self.add_item(r'/rscratch/minos14/marcel/git/pylot/tests') + self.add_item(r'/rscratch/minos14/marcel/git/pylot/inputs') + self.add_item(r'/rscratch/minos14/marcel/git/pylot/pylot') + self.add_item(r'/rscratch/minos14/marcel/git/pylot/pylot_not_existing') + + def center(self): + fm = self.frameGeometry() + screen = QtGui.QApplication.desktop().screenNumber(QtGui.QApplication.desktop().cursor().pos()) + centerPoint = QtGui.QApplication.desktop().screenGeometry(screen).center() + fm.moveCenter(centerPoint) + self.move(fm.topLeft()) + + def setupUI(self): + self.init_selection_layout() + self.init_add_remove_layout() + self.init_list_widget() + self.init_close() + + def init_selection_layout(self): + self.selection_layout = QHBoxLayout() + self.selection_box = QtGui.QLineEdit() + self.selection_button = QtGui.QPushButton('...') + self.selection_layout.addWidget(self.selection_box, 1) + self.selection_layout.addWidget(self.selection_button, 0) + self.main_layout.insertLayout(0, self.selection_layout, 0) + + def init_add_remove_layout(self): + self.add_remove_layout = QHBoxLayout() + self.add_button = QtGui.QPushButton('+') + self.add_button.setShortcut(QtGui.QKeySequence(QtCore.Qt.Key_Return)) + self.remove_button = QtGui.QPushButton('-') + self.remove_button.setShortcut(QtGui.QKeySequence(QtCore.Qt.Key_Delete)) + self.add_remove_layout.addWidget(self.add_button, 1) + self.add_remove_layout.addWidget(self.remove_button, 1) + self.main_layout.insertLayout(1, self.add_remove_layout, 0) + + def init_list_widget(self): + self.list_view = QtGui.QListView() + self.list_view.setSelectionMode(QtGui.QAbstractItemView.ExtendedSelection) + self.list_model = QtGui.QStandardItemModel(self.list_view) + self.list_view.setModel(self.list_model) + self.main_layout.insertWidget(2, self.list_view, 1) + + def init_close(self): + self.close_button = QPushButton('Close') + self.close_button.setShortcut(QtGui.QKeySequence(QtCore.Qt.Key_Escape)) + self.main_layout.addWidget(self.close_button) + + + def refresh_list(self): + self.clear_list() + for inventory_path in self.inventories.keys(): + self.add_item(inventory_path) + + def connect_signals(self): + self.selection_button.clicked.connect(self.open_directory) + self.add_button.clicked.connect(self.add_item_from_box) + self.remove_button.clicked.connect(self.remove_item) + self.close_button.clicked.connect(self.hide) + + def open_directory(self): + fninv = QFileDialog.getExistingDirectory(self, self.tr( + "Select inventory..."), self.tr("Select folder")) + if not fninv: + return + self.selection_box.setText(fninv) + + def add_item_from_box(self): + inventory_path = self.selection_box.text() + self.add_item(inventory_path) + self.selection_box.setText('') + + def add_item(self, inventory_path): + if not inventory_path: + return + if inventory_path in self.metadata.inventories: + QMessageBox.warning(self, 'Info', 'Path already in list!') + return + if not os.path.isdir(inventory_path): + QMessageBox.warning(self, 'Warning', 'Path is no directory!') + return + item = QtGui.QStandardItem(inventory_path) + item.setEditable(False) + self.inventories[inventory_path] = item + self.list_model.appendRow(item) + + self.metadata.add_inventory(inventory_path) + + def remove_item(self): + for index in reversed(self.list_view.selectionModel().selectedIndexes()): + item = self.list_model.itemData(index) + inventory_path = item[0] + del (self.inventories[inventory_path]) + self.metadata.remove_inventory(inventory_path) + self.list_model.removeRow(index.row()) + + class ComparisonWidget(QWidget): def __init__(self, c, parent=None, windowflag=1): self._data = c @@ -146,6 +262,14 @@ class ComparisonWidget(QWidget): self.setupUI() self.resize(1280, 720) self.plotcomparison() + self.center() + + def center(self): + fm = self.frameGeometry() + screen = QtGui.QApplication.desktop().screenNumber(QtGui.QApplication.desktop().cursor().pos()) + centerPoint = QtGui.QApplication.desktop().screenGeometry(screen).center() + fm.moveCenter(centerPoint) + self.move(fm.topLeft()) def setupUI(self): @@ -2806,6 +2930,14 @@ class MultiEventWidget(QWidget): self.setupUi() # set initial size self.resize(1280, 720) + self.center() + + def center(self): + fm = self.frameGeometry() + screen = QtGui.QApplication.desktop().screenNumber(QtGui.QApplication.desktop().cursor().pos()) + centerPoint = QtGui.QApplication.desktop().screenGeometry(screen).center() + fm.moveCenter(centerPoint) + self.move(fm.topLeft()) def setupUi(self): # init main layout @@ -3008,6 +3140,14 @@ class CompareEventsWidget(MultiEventWidget): self.connect_buttons() self.setWindowTitle('Compare events') self.set_main_stretch() + self.center() + + def center(self): + fm = self.frameGeometry() + screen = QtGui.QApplication.desktop().screenNumber(QtGui.QApplication.desktop().cursor().pos()) + centerPoint = QtGui.QApplication.desktop().screenGeometry(screen).center() + fm.moveCenter(centerPoint) + self.move(fm.topLeft()) def connect_buttons(self): self.start_button.clicked.connect(self.run) @@ -3084,6 +3224,7 @@ class TuneAutopicker(QWidget): self.add_log() self.set_stretch() self.resize(1280, 720) + self.center() self._manual_pick_plots = [] if hasattr(self.parent(), 'metadata'): self.metadata = self.parent().metadata @@ -3092,6 +3233,13 @@ class TuneAutopicker(QWidget): # self.setWindowModality(QtCore.Qt.WindowModality.ApplicationModal) # self.setWindowFlags(self.windowFlags() | QtCore.Qt.WindowStaysOnTopHint) + def center(self): + fm = self.frameGeometry() + screen = QtGui.QApplication.desktop().screenNumber(QtGui.QApplication.desktop().cursor().pos()) + centerPoint = QtGui.QApplication.desktop().screenGeometry(screen).center() + fm.moveCenter(centerPoint) + self.move(fm.topLeft()) + def set_fig_dict(self, fig_dict): for key, value in fig_dict.items(): if key is not 'mainFig': @@ -3569,10 +3717,18 @@ class PylotParaBox(QtGui.QWidget): self.params_to_gui() self._toggle_advanced_settings() self.resize(720, 860) + self.center() self.setWindowModality(QtCore.Qt.WindowModality.ApplicationModal) self.accepted.connect(self.params_from_gui) self.rejected.connect(self.params_to_gui) + def center(self): + fm = self.frameGeometry() + screen = QtGui.QApplication.desktop().screenNumber(QtGui.QApplication.desktop().cursor().pos()) + centerPoint = QtGui.QApplication.desktop().screenGeometry(screen).center() + fm.moveCenter(centerPoint) + self.move(fm.topLeft()) + def _init_sublayouts(self): self._main_layout = QtGui.QVBoxLayout() self._advanced_layout = QtGui.QVBoxLayout() @@ -4923,6 +5079,8 @@ class FilterOptionsWidget(QWidget): self.freqmaxSpinBox.valueChanged.connect(self.checkAutoManu) self.checkAutoManu() + self.setWindowModality(QtCore.Qt.WindowModality.ApplicationModal) + def checkAutoManu(self): self.updateMFfromWidget() From eb07c19c2e6ef63e1ac04e914cd3916408bae45d Mon Sep 17 00:00:00 2001 From: Marcel Date: Mon, 23 Jul 2018 14:54:53 +0200 Subject: [PATCH 142/169] [update] metadata/inventory management [bugfix] errors when there were no manual picks using array_map --- PyLoT.py | 87 ++++++------------------------- pylot/core/util/array_map.py | 55 +++++++------------ pylot/core/util/dataprocessing.py | 32 ++++++++++++ pylot/core/util/widgets.py | 11 ++-- 4 files changed, 73 insertions(+), 112 deletions(-) diff --git a/PyLoT.py b/PyLoT.py index de3f9a35..e33d4abe 100755 --- a/PyLoT.py +++ b/PyLoT.py @@ -116,7 +116,7 @@ class MainWindow(QMainWindow): self.apw = None self.paraBox = None self.array_map = None - self._metadata = None + self._metadata = Metadata() self._eventChanged = [False, False] self.apd_local = None self.apd_sge = None @@ -1927,6 +1927,7 @@ class MainWindow(QMainWindow): if self.obspy_dmt: self.metadata = Metadata(os.path.join(self.get_current_event_path(), 'resp')) self.inventoryAction.setEnabled(not self.obspy_dmt) + self.initMapAction.setEnabled(self.obspy_dmt) # MP MP --- @@ -2839,7 +2840,6 @@ class MainWindow(QMainWindow): grid_layout.addWidget(self.new_inv_button, 2, 1) grid_layout.addWidget(self.init_map_button, 3, 1) - self.metadata = Metadata() self.metadata_widget.setLayout(grid_layout) self.array_layout.addWidget(self.metadata_widget) @@ -3101,72 +3101,23 @@ class MainWindow(QMainWindow): if event == current_event: set_background_color(item_list, QtGui.QColor(*(0, 143, 143, 255))) - def read_metadata_thread(self, fninv): - self.rm_thread = Thread(self, Metadata, arg=fninv, progressText='Reading metadata...', - pb_widget=self.mainProgressBarWidget) - self.rm_thread.finished.connect(self.set_metadata) - self.rm_thread.start() - def set_metadata(self): - settings = QSettings() - self.metadata = self.rm_thread.data - if settings.value('saveMetadata'): - self.project.metadata = self.rm_thread.data - self.project.inv_path = settings.value("inventoryFile") - self.init_map_button.setEnabled(True) - self.initMapAction.setEnabled(True) - self.inventory_label.setText('Inventory set!') - self.new_inv_button.setText('Set another inventory file') + self.project.inventories = self.metadata.inventories + if self.metadata.inventories: + self.init_map_button.setEnabled(True) + self.initMapAction.setEnabled(True) + self.inventory_label.setText('Inventory set!') + self.setDirty(True) def get_new_metadata(self): - if hasattr(self, 'add_metadata_widget'): - self.add_metadata_widget.show() - else: - self.add_metadata_widget = AddMetadataWidget(self, metadata=self.metadata) - #self.init_metadata(new=True) - - def add_metadata(self): - pass + self.add_metadata_widget = AddMetadataWidget(self, metadata=self.metadata) + self.add_metadata_widget.close_button.clicked.connect(self.set_metadata) def init_metadata(self, new=False, ask_default=True): - def set_inv(settings): - fninv, _ = QFileDialog.getOpenFileName(self, self.tr( - "Select inventory..."), self.tr("Select file")) - if not fninv: - return False - ans = QMessageBox.question(self, self.tr("Make default..."), - self.tr( - "New inventory filename set.\n" + \ - "Do you want to make it the default value?"), - QMessageBox.Yes | QMessageBox.No, - QMessageBox.No) - if ans == QMessageBox.Yes: - settings.setValue("inventoryFile", fninv) - settings.sync() - self.read_metadata_thread(fninv) - return True - - settings = QSettings() - - if hasattr(self.project, 'metadata') and not new: - self.metadata = self.project.metadata - return True - if self.metadata and not new: - return True - if hasattr(self.project, 'inv_path') and not new: - settings.setValue("inventoryFile", self.project.inv_path) - - fninv = settings.value("inventoryFile", None) - if (fninv and ask_default) and not new: - ans = QMessageBox.question(self, self.tr("Use default metadata..."), - self.tr( - "Do you want to use the default value for metadata?\n({})".format(fninv)), - QMessageBox.Yes | QMessageBox.No, - QMessageBox.Yes) - if ans == QMessageBox.Yes: - self.read_metadata_thread(fninv) - return - set_inv(settings) + if hasattr(self.project, 'inventories'): + self.metadata = Metadata() + for inventory in self.project.inventories: + self.metadata.add_inventory(inventory) def calc_magnitude(self, type='ML'): self.init_metadata() @@ -3289,15 +3240,7 @@ class MainWindow(QMainWindow): self.tabs.setCurrentIndex(0) # implemented to prevent double-loading of waveform data self.init_events(new=True) self.setDirty(False) - if hasattr(self.project, 'metadata'): - if self.project.metadata: - self.init_metadata(ask_default=False) - # self.init_array_map(index=0) - return - if hasattr(self.project, 'inv_path'): - self.init_metadata(ask_default=False) - # self.init_array_map(index=0) - return + self.init_metadata() self.init_array_tab() diff --git a/pylot/core/util/array_map.py b/pylot/core/util/array_map.py index 91f7fe9d..85fb59a9 100644 --- a/pylot/core/util/array_map.py +++ b/pylot/core/util/array_map.py @@ -23,8 +23,7 @@ class Array_map(QtGui.QWidget): ''' QtGui.QWidget.__init__(self) self._parent = parent - self.metadata_type = parent.metadata[0] - self.metadata = parent.metadata[1] + self.metadata = parent.metadata self.picks = None self.picks_dict = None self.autopicks_dict = None @@ -160,33 +159,7 @@ class Array_map(QtGui.QWidget): self.main_box.addWidget(self.status_label, 0) def init_stations(self): - def stat_info_from_parser(parser): - stations_dict = {} - for station in parser.stations: - station_name = station[0].station_call_letters - network_name = station[0].network_code - if not station_name in stations_dict.keys(): - st_id = network_name + '.' + station_name - stations_dict[st_id] = {'latitude': station[0].latitude, - 'longitude': station[0].longitude} - return stations_dict - - def stat_info_from_inventory(inventory): - stations_dict = {} - for network in inventory.networks: - for station in network.stations: - station_name = station.code - network_name = network_name.code - if not station_name in stations_dict.keys(): - st_id = network_name + '.' + station_name - stations_dict[st_id] = {'latitude': station[0].latitude, - 'longitude': station[0].longitude} - return stations_dict - - read_stat = {'xml': stat_info_from_inventory, - 'dless': stat_info_from_parser} - - self.stations_dict = read_stat[self.metadata_type](self.metadata) + self.stations_dict = self.metadata.get_all_coordinates() self.latmin = self.get_min_from_stations('latitude') self.lonmin = self.get_min_from_stations('longitude') self.latmax = self.get_max_from_stations('latitude') @@ -195,13 +168,15 @@ class Array_map(QtGui.QWidget): def init_picks(self): def get_picks(station_dict): picks = {} + # selected phase phase = self.comboBox_phase.currentText() for st_id in station_dict.keys(): try: station_name = st_id.split('.')[-1] + # current_picks_dict: auto or manual pick = self.current_picks_dict()[station_name][phase] if pick['picker'] == 'auto': - if pick['weight'] > 3: + if not pick['spe']: continue picks[st_id] = pick['mpp'] except KeyError: @@ -216,11 +191,12 @@ class Array_map(QtGui.QWidget): for pick in picks.values(): if type(pick) is obspy.core.utcdatetime.UTCDateTime: picks_utc.append(pick) - self._earliest_picktime = min(picks_utc) - for st_id, pick in picks.items(): - if type(pick) is obspy.core.utcdatetime.UTCDateTime: - pick -= self._earliest_picktime - picks_rel[st_id] = pick + if picks_utc: + self._earliest_picktime = min(picks_utc) + for st_id, pick in picks.items(): + if type(pick) is obspy.core.utcdatetime.UTCDateTime: + pick -= self._earliest_picktime + picks_rel[st_id] = pick return picks_rel self.picks = get_picks(self.stations_dict) @@ -330,6 +306,8 @@ class Array_map(QtGui.QWidget): def scatter_picked_stations(self): picks, lats, lons = self.get_picks_lat_lon() + if len(lons) < 1 and len(lats) < 1: + return # workaround because of an issue with latlon transformation of arrays with len <3 if len(lons) <= 2 and len(lats) <= 2: self.sc_picked = self.basemap.scatter(lons[0], lats[0], s=50, facecolor='white', @@ -374,13 +352,16 @@ class Array_map(QtGui.QWidget): self.draw_everything() def draw_everything(self): - if self.picks_dict or self.autopicks_dict: + picktype = self.comboBox_am.currentText() + if (self.picks_dict and picktype == 'manual') \ + or (self.autopicks_dict and picktype == 'auto'): self.init_picks() if len(self.picks) >= 3: self.init_picksgrid() self.draw_contour_filled() self.scatter_all_stations() - if self.picks_dict or self.autopicks_dict: + if (self.picks_dict and picktype == 'manual') \ + or (self.autopicks_dict and picktype == 'auto'): self.scatter_picked_stations() self.cbar = self.add_cbar(label='Time relative to first onset ({}) [s]'.format(self._earliest_picktime)) self.comboBox_phase.setEnabled(True) diff --git a/pylot/core/util/dataprocessing.py b/pylot/core/util/dataprocessing.py index 0789187a..9dc95cf4 100644 --- a/pylot/core/util/dataprocessing.py +++ b/pylot/core/util/dataprocessing.py @@ -21,6 +21,7 @@ class Metadata(object): # saves filenames holding metadata for a seed_id # seed id as key, path to file as value self.seed_ids = {} + self.stations_dict = {} if inventory: if os.path.isdir(inventory): self.add_inventory(inventory) @@ -172,6 +173,37 @@ class Metadata(object): return return metadata['data'].get_coordinates(seed_id, time) + def get_all_coordinates(self): + def stat_info_from_parser(parser): + for station in parser.stations: + station_name = station[0].station_call_letters + network_name = station[0].network_code + if not station_name in self.stations_dict.keys(): + st_id = network_name + '.' + station_name + self.stations_dict[st_id] = {'latitude': station[0].latitude, + 'longitude': station[0].longitude} + + def stat_info_from_inventory(inventory): + for network in inventory.networks: + for station in network.stations: + station_name = station.code + network_name = network_name.code + if not station_name in self.stations_dict.keys(): + st_id = network_name + '.' + station_name + self.stations_dict[st_id] = {'latitude': station[0].latitude, + 'longitude': station[0].longitude} + + read_stat = {'xml': stat_info_from_inventory, + 'dless': stat_info_from_parser} + + self.read_all() + for item in self.inventory_files.values(): + inventory = item['data'] + invtype = item['invtype'] + read_stat[invtype](inventory) + + return self.stations_dict + def get_paz(self, seed_id, time): """ diff --git a/pylot/core/util/widgets.py b/pylot/core/util/widgets.py index a5198995..44d7b08b 100644 --- a/pylot/core/util/widgets.py +++ b/pylot/core/util/widgets.py @@ -145,6 +145,7 @@ class AddMetadataWidget(QWidget): self.resize(600, 800) self.metadata = metadata if metadata else Metadata() + self.from_metadata() self.center() self.show() @@ -199,6 +200,9 @@ class AddMetadataWidget(QWidget): self.close_button.setShortcut(QtGui.QKeySequence(QtCore.Qt.Key_Escape)) self.main_layout.addWidget(self.close_button) + def from_metadata(self): + for inventory_path in self.metadata.inventories: + self.add_item(inventory_path, from_metadata=True) def refresh_list(self): self.clear_list() @@ -223,10 +227,10 @@ class AddMetadataWidget(QWidget): self.add_item(inventory_path) self.selection_box.setText('') - def add_item(self, inventory_path): + def add_item(self, inventory_path, from_metadata=False): if not inventory_path: return - if inventory_path in self.metadata.inventories: + if inventory_path in self.inventories.keys(): QMessageBox.warning(self, 'Info', 'Path already in list!') return if not os.path.isdir(inventory_path): @@ -237,7 +241,8 @@ class AddMetadataWidget(QWidget): self.inventories[inventory_path] = item self.list_model.appendRow(item) - self.metadata.add_inventory(inventory_path) + if not from_metadata: + self.metadata.add_inventory(inventory_path) def remove_item(self): for index in reversed(self.list_view.selectionModel().selectedIndexes()): From ef6e011d227d705c826241e64159646cf5d5187d Mon Sep 17 00:00:00 2001 From: Marcel Date: Mon, 23 Jul 2018 16:03:15 +0200 Subject: [PATCH 143/169] [update] slightly improved feasibility using obspy_dmt with metadata and array map --- PyLoT.py | 17 +++++++++-------- pylot/core/util/widgets.py | 2 +- 2 files changed, 10 insertions(+), 9 deletions(-) diff --git a/PyLoT.py b/PyLoT.py index e33d4abe..f96ba9a1 100755 --- a/PyLoT.py +++ b/PyLoT.py @@ -395,7 +395,7 @@ class MainWindow(QMainWindow): "Ctrl+F", self.filter_icon, """Adjust filter parameters.""") self.inventoryAction = self.createAction(self, "Manage &Inventories ...", - self.get_new_metadata, + self.add_metadata, "Ctrl+I", self.inventoryIcon, """Manage metadata for current project""", False) @@ -1922,14 +1922,15 @@ class MainWindow(QMainWindow): if True in self.comparable.values(): self.compare_action.setEnabled(True) self.draw() - # MP MP ++++ # TODO: Quick and dirty, improve this on later iteration if self.obspy_dmt: - self.metadata = Metadata(os.path.join(self.get_current_event_path(), 'resp')) - self.inventoryAction.setEnabled(not self.obspy_dmt) - self.initMapAction.setEnabled(self.obspy_dmt) - # MP MP --- - + invpath = os.path.join(self.get_current_event_path(), 'resp') + if not invpath in self.metadata.inventories: + self.metadata.add_inventory(invpath) + # check if directory is empty + if os.listdir(invpath): + self.init_map_button.setEnabled(True) + self.initMapAction.setEnabled(True) @staticmethod def checkEvent4comparison(event): @@ -3109,7 +3110,7 @@ class MainWindow(QMainWindow): self.inventory_label.setText('Inventory set!') self.setDirty(True) - def get_new_metadata(self): + def add_metadata(self): self.add_metadata_widget = AddMetadataWidget(self, metadata=self.metadata) self.add_metadata_widget.close_button.clicked.connect(self.set_metadata) diff --git a/pylot/core/util/widgets.py b/pylot/core/util/widgets.py index 44d7b08b..fc5cfa18 100644 --- a/pylot/core/util/widgets.py +++ b/pylot/core/util/widgets.py @@ -196,7 +196,7 @@ class AddMetadataWidget(QWidget): self.main_layout.insertWidget(2, self.list_view, 1) def init_close(self): - self.close_button = QPushButton('Close') + self.close_button = QPushButton('Update') self.close_button.setShortcut(QtGui.QKeySequence(QtCore.Qt.Key_Escape)) self.main_layout.addWidget(self.close_button) From 9e75f8d4f265ec1a7bd434121df3ff6f9eda2055 Mon Sep 17 00:00:00 2001 From: Marcel Date: Tue, 24 Jul 2018 13:54:40 +0200 Subject: [PATCH 144/169] [bugfix] closes #255 filtering should work as intended now --- pylot/core/util/widgets.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/pylot/core/util/widgets.py b/pylot/core/util/widgets.py index 44506cb1..631aa99e 100644 --- a/pylot/core/util/widgets.py +++ b/pylot/core/util/widgets.py @@ -1936,11 +1936,11 @@ class PickDlg(QDialog): self.zoomAction.trigger() self.multicompfig.disconnectEvents() self.cidpress = self.multicompfig.connectPressEvent(self.setIniPick) - if not self.filterActionP.isChecked() and not self.filterActionS.isChecked(): - if self.autoFilterAction.isChecked(): - self.filterWFData() - else: - self.draw() + if self.autoFilterAction.isChecked(): + for filteraction in [self.filterActionP, self.filterActionS]: + filteraction.setChecked(False) + self.filterWFData() + self.draw() else: self.draw() #self.pick_block = self.togglePickBlocker() From b3524c562d8eca7fc8194426a049ee06393ef2b3 Mon Sep 17 00:00:00 2001 From: Marcel Date: Tue, 24 Jul 2018 14:15:32 +0200 Subject: [PATCH 145/169] [bugfix] closes #260 checking for filtertype first --- pylot/core/util/widgets.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/pylot/core/util/widgets.py b/pylot/core/util/widgets.py index 631aa99e..fdf23968 100644 --- a/pylot/core/util/widgets.py +++ b/pylot/core/util/widgets.py @@ -4773,6 +4773,9 @@ class FilterOptionsDialog(QDialog): def checkMinMax(self): returnvals = [] for foWidget in self.filterOptionWidgets.values(): + if foWidget.filterOptions._filtertype in ['highpass', 'lowpass']: + returnvals.append(True) + continue returnvals.append(foWidget.checkMin()) returnvals.append(foWidget.checkMax()) if all(returnvals): From 62287df1b4c44e4963b275bf7744489839cb65a5 Mon Sep 17 00:00:00 2001 From: Marcel Date: Tue, 24 Jul 2018 14:16:24 +0200 Subject: [PATCH 146/169] [minor] removed "None" from filteroptions --- pylot/core/util/widgets.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pylot/core/util/widgets.py b/pylot/core/util/widgets.py index fdf23968..1f5abdc5 100644 --- a/pylot/core/util/widgets.py +++ b/pylot/core/util/widgets.py @@ -4834,7 +4834,7 @@ class FilterOptionsWidget(QWidget): # self.getFilterOptions().getFreq()[1]) # else: - self.typeOptions = [None, "bandpass", "bandstop", "lowpass", "highpass"] + self.typeOptions = ["bandpass", "bandstop", "lowpass", "highpass"] self.resetButton = QPushButton('Reset') self.resetButton.setToolTip('Reset filter settings to settings for automatic picking.') From 6d6179bb552be0c4a2923ca8da50ea288a1919ab Mon Sep 17 00:00:00 2001 From: Marcel Date: Tue, 24 Jul 2018 14:32:15 +0200 Subject: [PATCH 147/169] [bugfix] closes #251 also fixed for histogram and locateAction --- PyLoT.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/PyLoT.py b/PyLoT.py index 8fa43a6f..e893ac42 100755 --- a/PyLoT.py +++ b/PyLoT.py @@ -1972,6 +1972,9 @@ class MainWindow(QMainWindow): self.openEventAction.setEnabled(False) self.openEventsAutoAction.setEnabled(False) self.loadpilotevent.setEnabled(False) + self.compare_action.setEnabled(False) + self.qualities_action.setEnabled(False) + self.locateEvent.setEnabled(False) if not refresh_plot: self.wf_scroll_area.setVisible(False) self.no_data_label.setVisible(True) From f310afb4c68c7615b61d3b0b6229208d17927704 Mon Sep 17 00:00:00 2001 From: Marcel Date: Tue, 24 Jul 2018 14:33:38 +0200 Subject: [PATCH 148/169] [minor] renaming QtAction --- PyLoT.py | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/PyLoT.py b/PyLoT.py index e893ac42..385a5065 100755 --- a/PyLoT.py +++ b/PyLoT.py @@ -504,15 +504,15 @@ class MainWindow(QMainWindow): # pickToolActions = (selectStation, ) # pickToolBar.setObjectName("PickTools") # self.addActions(pickToolBar, pickToolActions) - self.locateEvent = self.createAction(parent=self, text='locate the event', - slot=self.locate_event, - shortcut='Alt+Ctrl+L', - icon=locate_icon, - tip='Locate the event using ' + self.locateEventAction = self.createAction(parent=self, text='locate the event', + slot=self.locate_event, + shortcut='Alt+Ctrl+L', + icon=locate_icon, + tip='Locate the event using ' 'the displayed manual arrivals.') - self.locateEvent.setEnabled(False) + self.locateEventAction.setEnabled(False) - locationToolActions = (self.locateEvent,) + locationToolActions = (self.locateEventAction,) # add top menu self.fileMenu = self.menuBar().addMenu('&File') @@ -1911,7 +1911,7 @@ class MainWindow(QMainWindow): event = self.get_current_event() if event.pylot_picks: self.drawPicks(picktype='manual') - self.locateEvent.setEnabled(True) + self.locateEventAction.setEnabled(True) self.qualities_action.setEnabled(True) if event.pylot_autopicks: self.drawPicks(picktype='auto') @@ -1974,7 +1974,7 @@ class MainWindow(QMainWindow): self.loadpilotevent.setEnabled(False) self.compare_action.setEnabled(False) self.qualities_action.setEnabled(False) - self.locateEvent.setEnabled(False) + self.locateEventAction.setEnabled(False) if not refresh_plot: self.wf_scroll_area.setVisible(False) self.no_data_label.setVisible(True) @@ -2339,7 +2339,7 @@ class MainWindow(QMainWindow): else: self.update_status('picks discarded ({0})'.format(station)) if not self.get_loc_flag() and self.check4Loc(): - self.locateEvent.setEnabled(True) + self.locateEventAction.setEnabled(True) self.set_loc_flag(True) elif self.get_loc_flag() and not self.check4Loc(): self.set_loc_flag(False) From 974ee12076eabbbd6ccc3c7c15da7c8b8eafb033 Mon Sep 17 00:00:00 2001 From: Marcel Date: Tue, 24 Jul 2018 15:20:00 +0200 Subject: [PATCH 149/169] [update] closes #242 - dpi change added, figures using PylotCanvas can be saved with CTRL+S --- PyLoT.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/PyLoT.py b/PyLoT.py index 6679664b..5e55f5d0 100755 --- a/PyLoT.py +++ b/PyLoT.py @@ -32,6 +32,8 @@ import matplotlib matplotlib.use('Qt4Agg') matplotlib.rcParams['backend.qt4'] = 'PySide' +matplotlib.rcParams['savefig.dpi'] = 300 + from PySide import QtGui, QtCore from PySide.QtCore import QCoreApplication, QSettings, Signal, QFile, \ From 146ef7098c94cf50a0e0395eed29eda2db026e7e Mon Sep 17 00:00:00 2001 From: Marcel Date: Wed, 25 Jul 2018 10:46:20 +0200 Subject: [PATCH 150/169] [bugfix] closes #233 closes #234 can cope with stations without horizontal components now, removed dangerous try/except construct --- PyLoT.py | 14 ++- pylot/core/pick/autopick.py | 235 ++++++++++++++++++------------------ 2 files changed, 127 insertions(+), 122 deletions(-) diff --git a/PyLoT.py b/PyLoT.py index 385a5065..db40e866 100755 --- a/PyLoT.py +++ b/PyLoT.py @@ -2440,12 +2440,14 @@ class MainWindow(QMainWindow): canvas.setZoomBorders2content() if self.tap.pylot_picks: station = self.tap.get_current_station() - p_pick = self.tap.pylot_picks[station]['P'] - s_pick = self.tap.pylot_picks[station]['S'] - self.tap.pickDlg.autopicks['P_tuning'] = p_pick - self.tap.pickDlg.autopicks['S_tuning'] = s_pick - self.tap.pickDlg.drawPicks(phase='P_tuning', picktype='auto', picks=p_pick) - self.tap.pickDlg.drawPicks(phase='S_tuning', picktype='auto', picks=s_pick) + p_pick = self.tap.pylot_picks[station].get('P') + if p_pick: + self.tap.pickDlg.autopicks['P_tuning'] = p_pick + self.tap.pickDlg.drawPicks(phase='P_tuning', picktype='auto', picks=p_pick) + s_pick = self.tap.pylot_picks[station].get('S') + if s_pick: + self.tap.pickDlg.autopicks['S_tuning'] = s_pick + self.tap.pickDlg.drawPicks(phase='S_tuning', picktype='auto', picks=s_pick) def autoPick(self): autosave = self.get_current_event_path() diff --git a/pylot/core/pick/autopick.py b/pylot/core/pick/autopick.py index 75756e9a..fd06d810 100644 --- a/pylot/core/pick/autopick.py +++ b/pylot/core/pick/autopick.py @@ -8,6 +8,7 @@ function conglomerate utils. :author: MAGS2 EP3 working group / Ludger Kueperkoch """ +import traceback import matplotlib.pyplot as plt import numpy as np @@ -975,115 +976,114 @@ def autopickstation(wfstream, pickparam, verbose=False, ax1.set_ylim([-1.5, 1.5]) ax1.set_ylabel('Normalized Counts') # fig.suptitle(tr_filt.stats.starttime) - try: - len(edat[0]) - except: - edat = ndat - try: - len(ndat[0]) - except: - ndat = edat - if len(edat[0]) > 1 and len(ndat[0]) > 1 and Sflag == 1: - # plot horizontal traces - ax2 = fig.add_subplot(3, 1, 2, sharex=ax1) - th1data = np.arange(0, - trH1_filt.stats.npts / - trH1_filt.stats.sampling_rate, - trH1_filt.stats.delta) - # check equal length of arrays, sometimes they are different!? - wfldiff = len(trH1_filt.data) - len(th1data) - if wfldiff < 0: - th1data = th1data[0:len(th1data) - abs(wfldiff)] - ax2.plot(th1data, trH1_filt.data / max(trH1_filt.data), color=linecolor, linewidth=0.7, label='Data') - if Pweight < 4: - ax2.plot(arhcf1.getTimeArray(), - arhcf1.getCF() / max(arhcf1.getCF()), 'b', label='CF1') - if aicSflag == 1 and Sweight < 4: - ax2.plot(arhcf2.getTimeArray(), - arhcf2.getCF() / max(arhcf2.getCF()), 'm', label='CF2') - ax2.plot( - [aicarhpick.getpick(), aicarhpick.getpick()], - [-1, 1], 'g', label='Initial S Onset') - ax2.plot( - [aicarhpick.getpick() - 0.5, - aicarhpick.getpick() + 0.5], - [1, 1], 'g') - ax2.plot( - [aicarhpick.getpick() - 0.5, - aicarhpick.getpick() + 0.5], - [-1, -1], 'g') - ax2.plot([refSpick.getpick(), refSpick.getpick()], - [-1.3, 1.3], 'g', linewidth=2, label='Final S Pick') - ax2.plot( - [refSpick.getpick() - 0.5, refSpick.getpick() + 0.5], - [1.3, 1.3], 'g', linewidth=2) - ax2.plot( - [refSpick.getpick() - 0.5, refSpick.getpick() + 0.5], - [-1.3, -1.3], 'g', linewidth=2) - ax2.plot([lpickS, lpickS], [-1.1, 1.1], 'g--', label='lpp') - ax2.plot([epickS, epickS], [-1.1, 1.1], 'g--', label='epp') - ax2.set_title('%s, S Weight=%d, SNR=%7.2f, SNR[dB]=%7.2f' % ( - trH1_filt.stats.channel, - Sweight, SNRS, SNRSdB)) - else: - ax2.set_title('%s, S Weight=%d, SNR=None, SNRdB=None' % ( - trH1_filt.stats.channel, Sweight)) - ax2.legend(loc=1) - ax2.set_yticks([]) - ax2.set_ylim([-1.5, 1.5]) - ax2.set_ylabel('Normalized Counts') - # fig.suptitle(trH1_filt.stats.starttime) + # only continue if one horizontal stream exists + if (ndat or edat) and Sflag == 1: + # mirror components in case one does not exist + if not edat: + edat = ndat + if not ndat: + ndat = edat + if len(edat[0]) > 1 and len(ndat[0]) > 1: + # plot horizontal traces + ax2 = fig.add_subplot(3, 1, 2, sharex=ax1) + th1data = np.arange(0, + trH1_filt.stats.npts / + trH1_filt.stats.sampling_rate, + trH1_filt.stats.delta) + # check equal length of arrays, sometimes they are different!? + wfldiff = len(trH1_filt.data) - len(th1data) + if wfldiff < 0: + th1data = th1data[0:len(th1data) - abs(wfldiff)] + ax2.plot(th1data, trH1_filt.data / max(trH1_filt.data), color=linecolor, linewidth=0.7, label='Data') + if Pweight < 4: + ax2.plot(arhcf1.getTimeArray(), + arhcf1.getCF() / max(arhcf1.getCF()), 'b', label='CF1') + if aicSflag == 1 and Sweight < 4: + ax2.plot(arhcf2.getTimeArray(), + arhcf2.getCF() / max(arhcf2.getCF()), 'm', label='CF2') + ax2.plot( + [aicarhpick.getpick(), aicarhpick.getpick()], + [-1, 1], 'g', label='Initial S Onset') + ax2.plot( + [aicarhpick.getpick() - 0.5, + aicarhpick.getpick() + 0.5], + [1, 1], 'g') + ax2.plot( + [aicarhpick.getpick() - 0.5, + aicarhpick.getpick() + 0.5], + [-1, -1], 'g') + ax2.plot([refSpick.getpick(), refSpick.getpick()], + [-1.3, 1.3], 'g', linewidth=2, label='Final S Pick') + ax2.plot( + [refSpick.getpick() - 0.5, refSpick.getpick() + 0.5], + [1.3, 1.3], 'g', linewidth=2) + ax2.plot( + [refSpick.getpick() - 0.5, refSpick.getpick() + 0.5], + [-1.3, -1.3], 'g', linewidth=2) + ax2.plot([lpickS, lpickS], [-1.1, 1.1], 'g--', label='lpp') + ax2.plot([epickS, epickS], [-1.1, 1.1], 'g--', label='epp') + ax2.set_title('%s, S Weight=%d, SNR=%7.2f, SNR[dB]=%7.2f' % ( + trH1_filt.stats.channel, + Sweight, SNRS, SNRSdB)) + else: + ax2.set_title('%s, S Weight=%d, SNR=None, SNRdB=None' % ( + trH1_filt.stats.channel, Sweight)) + ax2.legend(loc=1) + ax2.set_yticks([]) + ax2.set_ylim([-1.5, 1.5]) + ax2.set_ylabel('Normalized Counts') + # fig.suptitle(trH1_filt.stats.starttime) - ax3 = fig.add_subplot(3, 1, 3, sharex=ax1) - th2data = np.arange(0, - trH2_filt.stats.npts / - trH2_filt.stats.sampling_rate, - trH2_filt.stats.delta) - # check equal length of arrays, sometimes they are different!? - wfldiff = len(trH2_filt.data) - len(th2data) - if wfldiff < 0: - th2data = th2data[0:len(th2data) - abs(wfldiff)] - ax3.plot(th2data, trH2_filt.data / max(trH2_filt.data), color=linecolor, linewidth=0.7, label='Data') - if Pweight < 4: - p22, = ax3.plot(arhcf1.getTimeArray(), - arhcf1.getCF() / max(arhcf1.getCF()), 'b', label='CF1') - if aicSflag == 1: - ax3.plot(arhcf2.getTimeArray(), - arhcf2.getCF() / max(arhcf2.getCF()), 'm', label='CF2') - ax3.plot( - [aicarhpick.getpick(), aicarhpick.getpick()], - [-1, 1], 'g', label='Initial S Onset') - ax3.plot( - [aicarhpick.getpick() - 0.5, - aicarhpick.getpick() + 0.5], - [1, 1], 'g') - ax3.plot( - [aicarhpick.getpick() - 0.5, - aicarhpick.getpick() + 0.5], - [-1, -1], 'g') - ax3.plot([refSpick.getpick(), refSpick.getpick()], - [-1.3, 1.3], 'g', linewidth=2, label='Final S Pick') - ax3.plot( - [refSpick.getpick() - 0.5, refSpick.getpick() + 0.5], - [1.3, 1.3], 'g', linewidth=2) - ax3.plot( - [refSpick.getpick() - 0.5, refSpick.getpick() + 0.5], - [-1.3, -1.3], 'g', linewidth=2) - ax3.plot([lpickS, lpickS], [-1.1, 1.1], 'g--', label='lpp') - ax3.plot([epickS, epickS], [-1.1, 1.1], 'g--', label='epp') - ax3.legend(loc=1) - ax3.set_yticks([]) - ax3.set_ylim([-1.5, 1.5]) - ax3.set_xlabel('Time [s] after %s' % tr_filt.stats.starttime) - ax3.set_ylabel('Normalized Counts') - ax3.set_title(trH2_filt.stats.channel) - if plt_flag == 1: - fig.show() - try: - input() - except SyntaxError: - pass - plt.close(fig) + ax3 = fig.add_subplot(3, 1, 3, sharex=ax1) + th2data = np.arange(0, + trH2_filt.stats.npts / + trH2_filt.stats.sampling_rate, + trH2_filt.stats.delta) + # check equal length of arrays, sometimes they are different!? + wfldiff = len(trH2_filt.data) - len(th2data) + if wfldiff < 0: + th2data = th2data[0:len(th2data) - abs(wfldiff)] + ax3.plot(th2data, trH2_filt.data / max(trH2_filt.data), color=linecolor, linewidth=0.7, label='Data') + if Pweight < 4: + p22, = ax3.plot(arhcf1.getTimeArray(), + arhcf1.getCF() / max(arhcf1.getCF()), 'b', label='CF1') + if aicSflag == 1: + ax3.plot(arhcf2.getTimeArray(), + arhcf2.getCF() / max(arhcf2.getCF()), 'm', label='CF2') + ax3.plot( + [aicarhpick.getpick(), aicarhpick.getpick()], + [-1, 1], 'g', label='Initial S Onset') + ax3.plot( + [aicarhpick.getpick() - 0.5, + aicarhpick.getpick() + 0.5], + [1, 1], 'g') + ax3.plot( + [aicarhpick.getpick() - 0.5, + aicarhpick.getpick() + 0.5], + [-1, -1], 'g') + ax3.plot([refSpick.getpick(), refSpick.getpick()], + [-1.3, 1.3], 'g', linewidth=2, label='Final S Pick') + ax3.plot( + [refSpick.getpick() - 0.5, refSpick.getpick() + 0.5], + [1.3, 1.3], 'g', linewidth=2) + ax3.plot( + [refSpick.getpick() - 0.5, refSpick.getpick() + 0.5], + [-1.3, -1.3], 'g', linewidth=2) + ax3.plot([lpickS, lpickS], [-1.1, 1.1], 'g--', label='lpp') + ax3.plot([epickS, epickS], [-1.1, 1.1], 'g--', label='epp') + ax3.legend(loc=1) + ax3.set_yticks([]) + ax3.set_ylim([-1.5, 1.5]) + ax3.set_xlabel('Time [s] after %s' % tr_filt.stats.starttime) + ax3.set_ylabel('Normalized Counts') + ax3.set_title(trH2_filt.stats.channel) + if plt_flag == 1: + fig.show() + try: + input() + except SyntaxError: + pass + plt.close(fig) ########################################################################## # calculate "real" onset times if lpickP is not None and lpickP == mpickP: @@ -1101,12 +1101,22 @@ def autopickstation(wfstream, pickparam, verbose=False, epickP = zdat[0].stats.starttime - timeerrorsP[3] mpickP = zdat[0].stats.starttime + # create dictionary + # for P phase + ccode = zdat[0].stats.channel + ncode = zdat[0].stats.network + ppick = dict(channel=ccode, network=ncode, lpp=lpickP, epp=epickP, mpp=mpickP, spe=Perror, snr=SNRP, + snrdb=SNRPdB, weight=Pweight, fm=FM, w0=None, fc=None, Mo=None, + Mw=None, picker=picker, marked=Pmarker) + if edat: hdat = edat[0] elif ndat: hdat = ndat[0] else: - return + # no horizontal components given + picks = dict(P=ppick) + return picks if lpickS is not None and lpickS == mpickS: lpickS += hdat.stats.delta @@ -1123,13 +1133,6 @@ def autopickstation(wfstream, pickparam, verbose=False, epickS = hdat.stats.starttime - timeerrorsS[3] mpickS = hdat.stats.starttime - # create dictionary - # for P phase - ccode = zdat[0].stats.channel - ncode = zdat[0].stats.network - ppick = dict(channel=ccode, network=ncode, lpp=lpickP, epp=epickP, mpp=mpickP, spe=Perror, snr=SNRP, - snrdb=SNRPdB, weight=Pweight, fm=FM, w0=None, fc=None, Mo=None, - Mw=None, picker=picker, marked=Pmarker) # add S phase ccode = hdat.stats.channel ncode = hdat.stats.network From bf5c37145969acaacb4584c9c9b63ccdc6966ff0 Mon Sep 17 00:00:00 2001 From: Marcel Date: Wed, 25 Jul 2018 14:05:15 +0200 Subject: [PATCH 151/169] [bugfix] various bugfixes originating from changes (more picks) in dictionary (refs #233 refs #234) --- autoPyLoT.py | 7 ++++++- pylot/core/pick/autopick.py | 11 +++++++---- pylot/core/pick/picker.py | 2 +- pylot/core/pick/utils.py | 19 +++++++++++++------ pylot/core/util/utils.py | 3 +++ 5 files changed, 30 insertions(+), 12 deletions(-) diff --git a/autoPyLoT.py b/autoPyLoT.py index f9079aac..e24500fe 100755 --- a/autoPyLoT.py +++ b/autoPyLoT.py @@ -7,6 +7,7 @@ import argparse import datetime import glob import os +import traceback import pylot.core.loc.focmec as focmec import pylot.core.loc.hash as hash @@ -283,7 +284,11 @@ def autoPyLoT(input_dict=None, parameter=None, inputfile=None, fnames=None, even corr_dat = None if metadata: # rotate stations to ZNE - wfdat = check4rotated(wfdat, metadata) + try: + wfdat = check4rotated(wfdat, metadata) + except Exception as e: + print('Could not rotate station {} to ZNE:\n{}'.format(wfdat[0].stats.station, + traceback.format_exc())) if locflag: print("Restitute data ...") corr_dat = restitute_data(wfdat.copy(), metadata, ncores=ncores) diff --git a/pylot/core/pick/autopick.py b/pylot/core/pick/autopick.py index e843b7a8..b25b38bf 100644 --- a/pylot/core/pick/autopick.py +++ b/pylot/core/pick/autopick.py @@ -137,8 +137,8 @@ def call_autopickstation(input_tuple): return autopickstation(wfstream, pickparam, verbose, fig_dict=fig_dict, iplot=iplot, metadata=metadata, origin=origin) except Exception as e: - traceback.print_exc() - return traceback.format_exc(), wfstream[0].stats.station + tbe = traceback.format_exc() + return tbe, wfstream[0].stats.station def autopickstation(wfstream, pickparam, verbose=False, @@ -254,19 +254,22 @@ def autopickstation(wfstream, pickparam, verbose=False, # split components zdat = wfstream.select(component="Z") if len(zdat) == 0: # check for other components + print('HIT: 3') zdat = wfstream.select(component="3") edat = wfstream.select(component="E") if len(edat) == 0: # check for other components edat = wfstream.select(component="2") + print('HIT: 2') ndat = wfstream.select(component="N") if len(ndat) == 0: # check for other components ndat = wfstream.select(component="1") + print('HIT: 1') picks = {} - station = zdat[0].stats.station + station = wfstream[0].stats.station if not zdat: - print('No z-component found for station {}. STOP'.format(wfstream[0].stats.station)) + print('No z-component found for station {}. STOP'.format(station)) return picks, station if algoP == 'HOS' or algoP == 'ARZ' and zdat is not None: diff --git a/pylot/core/pick/picker.py b/pylot/core/pick/picker.py index bb6d5efa..f13e0d65 100644 --- a/pylot/core/pick/picker.py +++ b/pylot/core/pick/picker.py @@ -279,7 +279,7 @@ class AICPicker(AutoPicker): try: imaxs, = argrelmax(dataslope) imax = imaxs[0] - except ValueError as e: + except (ValueError, IndexError) as e: print(e, 'picker: argrelmax not working!') imax = np.argmax(dataslope) iislope = islope[0][0:imax + 1] diff --git a/pylot/core/pick/utils.py b/pylot/core/pick/utils.py index e3e311c6..744cd358 100644 --- a/pylot/core/pick/utils.py +++ b/pylot/core/pick/utils.py @@ -606,14 +606,18 @@ def wadaticheck(pickdic, dttolerance, iplot=0, fig_dict=None): ibad = 0 for key in list(pickdic.keys()): - if pickdic[key]['P']['weight'] < 4 and pickdic[key]['S']['weight'] < 4: + ppick = pickdic[key].get('P') + spick = pickdic[key].get('S') + if not ppick or not spick: + continue + if ppick['weight'] < 4 and spick['weight'] < 4: # calculate S-P time - spt = pickdic[key]['S']['mpp'] - pickdic[key]['P']['mpp'] + spt = spick['mpp'] - ppick['mpp'] # add S-P time to dictionary pickdic[key]['SPt'] = spt # add P onsets and corresponding S-P times to list - UTCPpick = UTCDateTime(pickdic[key]['P']['mpp']) - UTCSpick = UTCDateTime(pickdic[key]['S']['mpp']) + UTCPpick = UTCDateTime(ppick['mpp']) + UTCSpick = UTCDateTime(spick['mpp']) Ppicks.append(UTCPpick.timestamp) Spicks.append(UTCSpick.timestamp) SPtimes.append(spt) @@ -870,9 +874,12 @@ def checkPonsets(pickdic, dttolerance, jackfactor=5, iplot=0, fig_dict=None): Ppicks = [] stations = [] for station in pickdic: - if pickdic[station]['P']['weight'] < 4: + pick = pickdic[station].get('P') + if not pick: + continue + if pick['weight'] < 4: # add P onsets to list - UTCPpick = UTCDateTime(pickdic[station]['P']['mpp']) + UTCPpick = UTCDateTime(pick['mpp']) Ppicks.append(UTCPpick.timestamp) stations.append(station) diff --git a/pylot/core/util/utils.py b/pylot/core/util/utils.py index b751690c..abf10921 100644 --- a/pylot/core/util/utils.py +++ b/pylot/core/util/utils.py @@ -975,6 +975,9 @@ def check4rotated(data, metadata=None, verbosity=1): except (KeyError, TypeError) as e: print('Failed to rotate trace {}, no azimuth or dip available in metadata'.format(trace_id)) return wfstream + if len(wfstream) < 3: + print('Failed to rotate Stream {}, not enough components available.'.format(wfstream)) + return wfstream # to rotate all traces must have same length, so trim them wfstream = trim_station_components(wfstream, trim_start=True, trim_end=True) z, n, e = rotate2zne(wfstream[0], azimuts[0], dips[0], From db9a1371b129682f64a701c26d97056859fecee0 Mon Sep 17 00:00:00 2001 From: Marcel Date: Wed, 25 Jul 2018 15:16:14 +0200 Subject: [PATCH 152/169] [bugfix] closes #223 --- pylot/core/util/widgets.py | 1 + 1 file changed, 1 insertion(+) diff --git a/pylot/core/util/widgets.py b/pylot/core/util/widgets.py index 7e5d738c..57e74a01 100644 --- a/pylot/core/util/widgets.py +++ b/pylot/core/util/widgets.py @@ -1018,6 +1018,7 @@ class PylotCanvas(FigureCanvas): new_ylim = self.calcPanZoom(self.ypress, y_bot, y_top, factor, (ydiff > 0)) self.setYLims(ax, new_ylim) + self.refreshPickDlgText() self.draw() def set_frame_color(self, color='k'): From cc9ae9c146840943340596c1afc68fbd6e21a74a Mon Sep 17 00:00:00 2001 From: Marcel Date: Tue, 31 Jul 2018 09:24:43 +0200 Subject: [PATCH 153/169] [bugfix] empty picks dictionary leading to KeyError --- pylot/core/io/data.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/pylot/core/io/data.py b/pylot/core/io/data.py index 445af803..3802bfd3 100644 --- a/pylot/core/io/data.py +++ b/pylot/core/io/data.py @@ -506,6 +506,8 @@ class Data(object): # check for automatic picks print("Writing phases to ObsPy-quakeml file") for key in picks: + if not picks[key].get('P'): + continue if picks[key]['P']['picker'] == 'auto': print("Existing auto-picks will be overwritten in pick-dictionary!") picks = picks_from_picksdict(picks) From e68b634f250c410eefb3651fdc0f4e45dbdb8987 Mon Sep 17 00:00:00 2001 From: Marcel Date: Tue, 31 Jul 2018 09:41:48 +0200 Subject: [PATCH 154/169] [new] event modification status saved with "dirty" attribute, only save event-XML when modified --- PyLoT.py | 32 +++++++++++++++++++++++++------- pylot/core/util/event.py | 10 ++++++++++ 2 files changed, 35 insertions(+), 7 deletions(-) diff --git a/PyLoT.py b/PyLoT.py index 88448276..e188f9b7 100755 --- a/PyLoT.py +++ b/PyLoT.py @@ -1028,7 +1028,7 @@ class MainWindow(QMainWindow): ''' if not eventbox: eventbox = self.eventBox - path = eventbox.currentText() + path = eventbox.currentText().split('*')[0] return self.project.getEventFromPath(path) def get_current_event_path(self, eventbox=None): @@ -1291,7 +1291,10 @@ class MainWindow(QMainWindow): # p=event_npicks, # a=event_nautopicks) - item_path = QtGui.QStandardItem('{path:{plen}}'.format(path=event_path, plen=plmax)) + event_str = '{path:{plen}}'.format(path=event_path, plen=plmax) + if event.dirty: + event_str += '*' + item_path = QtGui.QStandardItem(event_str) item_time = QtGui.QStandardItem('{}'.format(time)) item_lat = QtGui.QStandardItem('{}'.format(lat)) item_lon = QtGui.QStandardItem('{}'.format(lon)) @@ -1334,7 +1337,7 @@ class MainWindow(QMainWindow): self.setItemColor(itemlist, id, event, current_event) model.appendRow(itemlist) - if not event.path == self.eventBox.itemText(id).strip(): + if not event.path == self.eventBox.itemText(id).split('*')[0].strip(): message = ('Path missmatch creating eventbox.\n' '{} unequal {}.' .format(event.path, self.eventBox.itemText(id))) @@ -1433,6 +1436,8 @@ class MainWindow(QMainWindow): self.update_status(msg) print(msg) + event.dirty = False + self.fill_eventbox() return True def exportEvents(self, outformats=['.xml'], events='all'): @@ -1440,11 +1445,15 @@ class MainWindow(QMainWindow): events = self.project.eventlist assert type(events) == list, 'Wrong input type: {}'.format(type(events)) for event in events: + if not event.dirty: + continue self.get_data().setEvtData(event) try: self.saveData(event, event.path, outformats) + event.dirty = False except Exception as e: print('WARNING! Could not save event {}. Reason: {}'.format(event.path, e)) + self.fill_eventbox() def enableSaveEventAction(self): self.saveEventAction.setEnabled(True) @@ -3031,7 +3040,11 @@ class MainWindow(QMainWindow): item_test = QtGui.QTableWidgetItem() item_notes = QtGui.QTableWidgetItem() - item_path.setText(event.path) + event_str = event.path + if event.dirty: + event_str += '*' + + item_path.setText(event_str) if hasattr(event, 'origins'): if event.origins: origin = event.origins[0] @@ -3245,6 +3258,10 @@ class MainWindow(QMainWindow): if self.project.parameter: self._inputs = self.project.parameter self.updateFilteroptions() + # added for backwards compatibility with older events not having a 'dirty' attribute + for event in self.project.eventlist: + if not hasattr(event, 'dirty'): + event.dirty = False self.tabs.setCurrentIndex(0) # implemented to prevent double-loading of waveform data self.init_events(new=True) self.setDirty(False) @@ -3264,10 +3281,10 @@ class MainWindow(QMainWindow): if not filename.split('.')[-1] == 'plp': filename = fnm[0] + '.plp' self.project.parameter = self._inputs + self.exportEvents() self.project.save(filename) self.setDirty(False) self.saveProjectAsAction.setEnabled(True) - self.exportEvents() self.update_status('Saved new project to {}'.format(filename), duration=5000) return True @@ -3282,11 +3299,11 @@ class MainWindow(QMainWindow): return False else: self.project.parameter = self._inputs - self.project.save() self.exportEvents() + self.project.save() if not self.project.dirty: - self.update_status('Saved back project to file:\n{}'.format(self.project.location), duration=5000) self.setDirty(False) + self.update_status('Saved back project to file:\n{}'.format(self.project.location), duration=5000) return True else: # if still dirty because saving failed @@ -3312,6 +3329,7 @@ class MainWindow(QMainWindow): self.saveProjectAsAction.setEnabled(True) self.project.setDirty(value) self.dirty = value + self.fill_eventbox() def closeEvent(self, event): if self.okToContinue(): diff --git a/pylot/core/util/event.py b/pylot/core/util/event.py index 8146d1f8..d721a7fe 100644 --- a/pylot/core/util/event.py +++ b/pylot/core/util/event.py @@ -35,6 +35,7 @@ class Event(ObsPyEvent): self._refEvent = False self.get_notes() self.get_obspy_event_info() + self.dirty = False def get_notes_path(self): """ @@ -143,6 +144,7 @@ class Event(ObsPyEvent): for index, pick in reversed(list(enumerate(self.picks))): if picktype in str(pick.method_id): self.picks.pop(index) + self.dirty = True def addPicks(self, picks): """ @@ -157,6 +159,7 @@ class Event(ObsPyEvent): # add ObsPy picks (clear old manual and copy all new manual from pylot) self.clearObsPyPicks('manual') self.picks += picks_from_picksdict(self.pylot_picks) + self.dirty = True def addAutopicks(self, autopicks): """ @@ -170,6 +173,7 @@ class Event(ObsPyEvent): # add ObsPy picks (clear old auto and copy all new auto from pylot) self.clearObsPyPicks('auto') self.picks += picks_from_picksdict(self.pylot_autopicks) + self.dirty = True def setPick(self, station, pick): """ @@ -191,6 +195,7 @@ class Event(ObsPyEvent): print('Could not remove pick {} from station {}: {}'.format(pick, station, e)) self.clearObsPyPicks('manual') self.picks += picks_from_picksdict(self.pylot_picks) + self.dirty = True def setPicks(self, picks): """ @@ -203,6 +208,7 @@ class Event(ObsPyEvent): self.pylot_picks = picks self.clearObsPyPicks('manual') self.picks += picks_from_picksdict(self.pylot_picks) + self.dirty = True def getPick(self, station): """ @@ -243,6 +249,7 @@ class Event(ObsPyEvent): print('Could not remove pick {} from station {}: {}'.format(pick, station, e)) self.clearObsPyPicks('auto') self.picks += picks_from_picksdict(self.pylot_autopicks) + self.dirty = True def setAutopicks(self, picks): """ @@ -255,6 +262,7 @@ class Event(ObsPyEvent): self.pylot_autopicks = picks self.clearObsPyPicks('auto') self.picks += picks_from_picksdict(self.pylot_autopicks) + self.dirty = True def getAutopick(self, station): """ @@ -293,6 +301,7 @@ class Event(ObsPyEvent): try: outfile = open(filename, 'wb') cPickle.dump(self, outfile, -1) + self.dirty = False except Exception as e: print('Could not pickle PyLoT event. Reason: {}'.format(e)) @@ -311,5 +320,6 @@ class Event(ObsPyEvent): import _pickle as cPickle infile = open(filename, 'rb') event = cPickle.load(infile) + event.dirty = False print('Loaded %s' % filename) return event From 93bdaa89981a5ad2adf93a959f766d236180a17e Mon Sep 17 00:00:00 2001 From: Marcel Date: Tue, 31 Jul 2018 10:22:45 +0200 Subject: [PATCH 155/169] [bugfix] forgot to split * in getFromPath --- pylot/core/util/widgets.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pylot/core/util/widgets.py b/pylot/core/util/widgets.py index 57e74a01..fd706d07 100644 --- a/pylot/core/util/widgets.py +++ b/pylot/core/util/widgets.py @@ -3575,7 +3575,7 @@ class TuneAutopicker(QWidget): if index == -1: index += 1 nevents = self.eventBox.model().rowCount() - path = self.eventBox.itemText(index) + path = self.eventBox.itemText(index).split('*')[0] if project.getEventFromPath(path).isTestEvent(): for index in range(nevents): path = self.eventBox.itemText(index) From c898f93293c232e820513f001d1244488dec911a Mon Sep 17 00:00:00 2001 From: Marcel Date: Wed, 1 Aug 2018 13:25:27 +0200 Subject: [PATCH 156/169] [new] idea for new quality check using SNR --- PyLoT.py | 19 +++++++---- pylot/core/pick/utils.py | 70 ++++++++++++++++++++++++++++++++++++++-- 2 files changed, 80 insertions(+), 9 deletions(-) diff --git a/PyLoT.py b/PyLoT.py index e188f9b7..04b5b509 100755 --- a/PyLoT.py +++ b/PyLoT.py @@ -64,7 +64,7 @@ from pylot.core.io.data import Data from pylot.core.io.inputs import FilterOptions, PylotParameter from autoPyLoT import autoPyLoT from pylot.core.pick.compare import Comparison -from pylot.core.pick.utils import symmetrize_error, getQualityFromUncertainty +from pylot.core.pick.utils import symmetrize_error, getQualityFromUncertainty, getPickQuality from pylot.core.io.phases import picksdict_from_picks import pylot.core.loc.nll as nll from pylot.core.util.defaults import FILTERDEFAULTS, SetChannelComponents @@ -2707,6 +2707,8 @@ class MainWindow(QMainWindow): ylims = np.array([-.5, +.5]) + plotID stat_picks = self.getPicks(type=picktype)[station] + settings = QSettings() + compclass = settings.value('compclass') for phase in stat_picks: if phase == 'SPt': continue # wadati SP time @@ -2714,13 +2716,16 @@ class MainWindow(QMainWindow): if type(stat_picks[phase]) is not dict and type(stat_picks[phase]) is not AttribDict: return + phaseID = self.getPhaseID(phase) # get quality classes - if self.getPhaseID(phase) == 'P': - quality = getQualityFromUncertainty(picks['spe'], self._inputs['timeerrorsP']) - phaseID = 'P' - elif self.getPhaseID(phase) == 'S': - quality = getQualityFromUncertainty(picks['spe'], self._inputs['timeerrorsS']) - phaseID = 'S' + # if phaseID == 'P': + # quality = getQualityFromUncertainty(picks['spe'], self._inputs['timeerrorsP']) + # elif phaseID == 'S': + # quality = getQualityFromUncertainty(picks['spe'], self._inputs['timeerrorsS']) + + quality = getPickQuality(self.get_data().getWFData(), + stat_picks, self._inputs, phaseID, + compclass) mpp = picks['mpp'] - stime if picks['epp'] and picks['lpp']: diff --git a/pylot/core/pick/utils.py b/pylot/core/pick/utils.py index 744cd358..11d10aa9 100644 --- a/pylot/core/pick/utils.py +++ b/pylot/core/pick/utils.py @@ -14,6 +14,7 @@ import matplotlib.pyplot as plt import numpy as np from obspy.core import Stream, UTCDateTime from pylot.core.util.utils import real_Bool, real_None +from pylot.core.util.defaults import SetChannelComponents def earllatepicker(X, nfac, TSNR, Pick1, iplot=0, verbosity=1, fig=None, linecolor='k'): @@ -556,8 +557,6 @@ def select_for_phase(st, phase): :rtype: `~obspy.core.stream.Stream` """ - from pylot.core.util.defaults import SetChannelComponents - sel_st = Stream() compclass = SetChannelComponents() if phase.upper() == 'P': @@ -1186,6 +1185,73 @@ def checkZ4S(X, pick, zfac, checkwin, iplot, fig=None, linecolor='k'): return returnflag +def getPickQuality(wfdata, picks, inputs, phase, compclass=None): + quality = 4 + components4phases = {'P': ['Z'], + 'S': ['N', 'E']} + timeErrors4phases = {'P': 'timeerrorsP', + 'S': 'timeerrorsS'} + tsnr4phases = {'P': 'tsnrz', + 'S': 'tsnrh'} + + if not phase in components4phases.keys(): + raise IOError('getPickQuality: Could not understand phase: {}'.format(phase)) + + if not compclass: + print('Warning: No settings for channel components found. Using default') + compclass = SetChannelComponents() + + picks = picks[phase] + mpp = picks.get('mpp') + uncertainty = picks.get('spe') + if not mpp: + print('getPickQuality: No pick found!') + return quality + if not uncertainty: + print('getPickQuality: No pick uncertainty (spe) found!') + return quality + + tsnr = inputs[tsnr4phases[phase]] + timeErrors = inputs[timeErrors4phases[phase]] + snrdb_final = 0 + + for component in components4phases[phase]: + alter_comp = compclass.getCompPosition(component) + st_select = wfdata.select(component=component) + st_select += wfdata.select(component=alter_comp) + if st_select: + trace = st_select[0] + _, snrdb, _ = getSNR(st_select, tsnr, + mpp - trace.stats.starttime) + if snrdb > snrdb_final: + snrdb_final = snrdb + + quality = getQualityFromUncertainty(uncertainty, timeErrors) + quality += getQualityFromSNR(snrdb_final) + + return quality + + +def getQualityFromSNR(snrdb): + quality_modifier = 4 + if not snrdb: + print('getQualityFromSNR: No snrdb!') + return quality_modifier + # MP MP ++++ experimental, + # raise pick quality by x classes if snrdb is lower than corresponding key + quality4snrdb = {3: 4, + 5: 3, + 7: 2, + 9: 1, + 11: 0} + # MP MP --- + # iterate over all thresholds and check whether snrdb is larger, if so, set new quality_modifier + for snrdb_threshold in sorted(list(quality4snrdb.keys())): + if snrdb > snrdb_threshold: + quality_modifier = quality4snrdb[snrdb_threshold] + return quality_modifier + + def getQualityFromUncertainty(uncertainty, Errors): """ Script to transform uncertainty into quality classes 0-4 regarding adjusted time errors From 017683806b0067d7a1deffc42d8fa567f6861cd8 Mon Sep 17 00:00:00 2001 From: Marcel Date: Wed, 1 Aug 2018 13:49:01 +0200 Subject: [PATCH 157/169] [new] if QSettings fails, ask to reset! [bugfix] checkBoxPG outdated in QSettings [bugfix] moved SetChannelComponents to utils (produced circular imports) --- PyLoT.py | 50 +++++++++++++++++++++------------- pylot/core/pick/utils.py | 3 +-- pylot/core/util/defaults.py | 51 ----------------------------------- pylot/core/util/utils.py | 53 +++++++++++++++++++++++++++++++++++++ pylot/core/util/widgets.py | 24 +++-------------- 5 files changed, 89 insertions(+), 92 deletions(-) diff --git a/PyLoT.py b/PyLoT.py index 04b5b509..54ede24c 100755 --- a/PyLoT.py +++ b/PyLoT.py @@ -67,7 +67,7 @@ from pylot.core.pick.compare import Comparison from pylot.core.pick.utils import symmetrize_error, getQualityFromUncertainty, getPickQuality from pylot.core.io.phases import picksdict_from_picks import pylot.core.loc.nll as nll -from pylot.core.util.defaults import FILTERDEFAULTS, SetChannelComponents +from pylot.core.util.defaults import FILTERDEFAULTS from pylot.core.util.errors import DatastructureError, \ OverwriteError from pylot.core.util.connection import checkurl @@ -76,7 +76,7 @@ from pylot.core.util.utils import fnConstructor, getLogin, \ full_range, readFilterInformation, trim_station_components, check4gaps, make_pen, pick_color_plt, \ pick_linestyle_plt, remove_underscores, check4doubled, identifyPhaseID, excludeQualityClasses, \ check4rotated, transform_colors_mpl, transform_colors_mpl_str, getAutoFilteroptions, check_all_obspy, \ - check_all_pylot, real_Bool + check_all_pylot, real_Bool, SetChannelComponents from pylot.core.util.event import Event from pylot.core.io.location import create_creation_info, create_event from pylot.core.util.widgets import FilterOptionsDialog, NewEventDlg, \ @@ -155,15 +155,32 @@ class MainWindow(QMainWindow): self.data._new = False self.autodata = Data(self) - if settings.value("user/FullName", None) is None: - fulluser = QInputDialog.getText(self, "Enter Name:", "Full name") - settings.setValue("user/FullName", fulluser) - settings.setValue("user/Login", getLogin()) - if settings.value("agency_id", None) is None: - agency = QInputDialog.getText(self, - "Enter authority/institution name:", - "Authority") - settings.setValue("agency_id", agency) + while True: + try: + if settings.value("user/FullName", None) is None: + fulluser = QInputDialog.getText(self, "Enter Name:", "Full name") + settings.setValue("user/FullName", fulluser) + settings.setValue("user/Login", getLogin()) + if settings.value("agency_id", None) is None: + agency = QInputDialog.getText(self, + "Enter authority/institution name:", + "Authority") + settings.setValue("agency_id", agency) + break + except Exception as e: + qmb = QMessageBox(self, icon=QMessageBox.Question, + text='Could not init application settings: {}.' + 'Do you want to reset application settings?'.format(e), + windowTitle='PyLoT - Init QSettings warning') + qmb.setStandardButtons(QMessageBox.Yes | QMessageBox.No) + qmb.setDefaultButton(QMessageBox.No) + ret = qmb.exec_() + if ret == qmb.Yes: + settings.clear() + else: + sys.exit() + print('Settings cleared!') + self.fnames = None self._stime = None structure_setting = settings.value("data/Structure", "PILOT") @@ -671,14 +688,9 @@ class MainWindow(QMainWindow): xlab = self.startTime.strftime('seconds since %Y/%m/%d %H:%M:%S (%Z)') plottitle = None # "Overview: {0} components ".format(self.getComponent()) self.disconnectWFplotEvents() - if str(settings.value('pyqtgraphic')) == 'false' or not pg: - self.pg = False - self.dataPlot = PylotCanvas(parent=self, connect_events=False, multicursor=True) - self.dataPlot.updateWidget(xlab, None, plottitle) - else: - self.pg = pg - self.dataPlot = WaveformWidgetPG(parent=self, - title=plottitle) + self.pg = pg + self.dataPlot = WaveformWidgetPG(parent=self, + title=plottitle) self.dataPlot.setCursor(Qt.CrossCursor) self.wf_scroll_area.setWidget(self.dataPlot) if self.get_current_event(): diff --git a/pylot/core/pick/utils.py b/pylot/core/pick/utils.py index 11d10aa9..20385535 100644 --- a/pylot/core/pick/utils.py +++ b/pylot/core/pick/utils.py @@ -13,8 +13,7 @@ import warnings import matplotlib.pyplot as plt import numpy as np from obspy.core import Stream, UTCDateTime -from pylot.core.util.utils import real_Bool, real_None -from pylot.core.util.defaults import SetChannelComponents +from pylot.core.util.utils import real_Bool, real_None, SetChannelComponents def earllatepicker(X, nfac, TSNR, Pick1, iplot=0, verbosity=1, fig=None, linecolor='k'): diff --git a/pylot/core/util/defaults.py b/pylot/core/util/defaults.py index 416cbd58..04ae60a4 100644 --- a/pylot/core/util/defaults.py +++ b/pylot/core/util/defaults.py @@ -41,54 +41,3 @@ OUTPUTFORMATS = {'.xml': 'QUAKEML', LOCTOOLS = dict(nll=nll, hyposat=hyposat, velest=velest, hypo71=hypo71, hypodd=hypodd) -class SetChannelComponents(object): - def __init__(self): - self.setDefaultCompPosition() - - def setDefaultCompPosition(self): - # default component order - self.compPosition_Map = dict(Z=2, N=1, E=0) - self.compName_Map = {'3': 'Z', - '1': 'N', - '2': 'E'} - - def _getCurrentPosition(self, component): - for key, value in self.compName_Map.items(): - if value == component: - return key, value - errMsg = 'getCurrentPosition: Could not find former position of component {}.'.format(component) - raise ValueError(errMsg) - - def _switch(self, component, component_alter): - # Without switching, multiple definitions of the same alter_comp are possible - old_alter_comp, _ = self._getCurrentPosition(component) - old_comp = self.compName_Map[component_alter] - if not old_alter_comp == component_alter and not old_comp == component: - self.compName_Map[old_alter_comp] = old_comp - print('switch: Automatically switched component {} to {}'.format(old_alter_comp, old_comp)) - - def setCompPosition(self, component_alter, component, switch=True): - component_alter = str(component_alter) - if not component_alter in self.compName_Map.keys(): - errMsg = 'setCompPosition: Unrecognized alternative component {}. Expecting one of {}.' - raise ValueError(errMsg.format(component_alter, self.compName_Map.keys())) - if not component in self.compPosition_Map.keys(): - errMsg = 'setCompPosition: Unrecognized target component {}. Expecting one of {}.' - raise ValueError(errMsg.format(component, self.compPosition_Map.keys())) - print('setCompPosition: set component {} to {}'.format(component_alter, component)) - if switch: - self._switch(component, component_alter) - self.compName_Map[component_alter] = component - - def getCompPosition(self, component): - return self._getCurrentPosition(component)[0] - - def getPlotPosition(self, component): - component = str(component) - if component in self.compPosition_Map.keys(): - return self.compPosition_Map[component] - elif component in self.compName_Map.keys(): - return self.compPosition_Map[self.compName_Map[component]] - else: - errMsg = 'getCompPosition: Unrecognized component {}. Expecting one of {} or {}.' - raise ValueError(errMsg.format(component, self.compPosition_Map.keys(), self.compName_Map.keys())) diff --git a/pylot/core/util/utils.py b/pylot/core/util/utils.py index abf10921..6d8dc235 100644 --- a/pylot/core/util/utils.py +++ b/pylot/core/util/utils.py @@ -1214,3 +1214,56 @@ if __name__ == "__main__": import doctest doctest.testmod() + + +class SetChannelComponents(object): + def __init__(self): + self.setDefaultCompPosition() + + def setDefaultCompPosition(self): + # default component order + self.compPosition_Map = dict(Z=2, N=1, E=0) + self.compName_Map = {'3': 'Z', + '1': 'N', + '2': 'E'} + + def _getCurrentPosition(self, component): + for key, value in self.compName_Map.items(): + if value == component: + return key, value + errMsg = 'getCurrentPosition: Could not find former position of component {}.'.format(component) + raise ValueError(errMsg) + + def _switch(self, component, component_alter): + # Without switching, multiple definitions of the same alter_comp are possible + old_alter_comp, _ = self._getCurrentPosition(component) + old_comp = self.compName_Map[component_alter] + if not old_alter_comp == component_alter and not old_comp == component: + self.compName_Map[old_alter_comp] = old_comp + print('switch: Automatically switched component {} to {}'.format(old_alter_comp, old_comp)) + + def setCompPosition(self, component_alter, component, switch=True): + component_alter = str(component_alter) + if not component_alter in self.compName_Map.keys(): + errMsg = 'setCompPosition: Unrecognized alternative component {}. Expecting one of {}.' + raise ValueError(errMsg.format(component_alter, self.compName_Map.keys())) + if not component in self.compPosition_Map.keys(): + errMsg = 'setCompPosition: Unrecognized target component {}. Expecting one of {}.' + raise ValueError(errMsg.format(component, self.compPosition_Map.keys())) + print('setCompPosition: set component {} to {}'.format(component_alter, component)) + if switch: + self._switch(component, component_alter) + self.compName_Map[component_alter] = component + + def getCompPosition(self, component): + return self._getCurrentPosition(component)[0] + + def getPlotPosition(self, component): + component = str(component) + if component in self.compPosition_Map.keys(): + return self.compPosition_Map[component] + elif component in self.compName_Map.keys(): + return self.compPosition_Map[self.compName_Map[component]] + else: + errMsg = 'getCompPosition: Unrecognized component {}. Expecting one of {} or {}.' + raise ValueError(errMsg.format(component, self.compPosition_Map.keys(), self.compName_Map.keys())) \ No newline at end of file diff --git a/pylot/core/util/widgets.py b/pylot/core/util/widgets.py index fd706d07..eead217e 100644 --- a/pylot/core/util/widgets.py +++ b/pylot/core/util/widgets.py @@ -49,13 +49,12 @@ from pylot.core.io.inputs import FilterOptions, PylotParameter from pylot.core.pick.utils import getSNR, earllatepicker, getnoisewin, \ getResolutionWindow, getQualityFromUncertainty from pylot.core.pick.compare import Comparison -from pylot.core.util.defaults import OUTPUTFORMATS, FILTERDEFAULTS, \ - SetChannelComponents +from pylot.core.util.defaults import OUTPUTFORMATS, FILTERDEFAULTS from pylot.core.util.utils import prepTimeAxis, full_range, scaleWFData, \ demeanTrace, isSorted, findComboBoxIndex, clims, pick_linestyle_plt, pick_color_plt, \ check4rotated, check4doubled, check4gaps, remove_underscores, find_horizontals, identifyPhase, \ loopIdentifyPhase, trim_station_components, transformFilteroptions2String, \ - identifyPhaseID, real_Bool, pick_color, getAutoFilteroptions + identifyPhaseID, real_Bool, pick_color, getAutoFilteroptions, SetChannelComponents from autoPyLoT import autoPyLoT from pylot.core.util.thread import Thread from pylot.core.util.dataprocessing import Metadata @@ -4617,31 +4616,16 @@ class GraphicsTab(PropTab): self.main_layout.addWidget(label, 1, 0) self.main_layout.addWidget(self.spinbox_nth_sample, 1, 1) - def add_pg_cb(self): - pg = True - text = {True: 'Use pyqtgraphic library for plotting', - False: 'Cannot use library: pyqtgraphic not found on system'} - label = QLabel('PyQt graphic') - label.setToolTip(text[bool(pg)]) - label.setEnabled(bool(pg)) - self.checkbox_pg = QtGui.QCheckBox() - self.checkbox_pg.setEnabled(bool(pg)) - self.checkbox_pg.setChecked(bool(pg)) - self.main_layout.addWidget(label, 0, 0) - self.main_layout.addWidget(self.checkbox_pg, 0, 1) - def set_current_style(self): selected_style = self.style_cb.currentText() self.pylot_mainwindow.set_style(selected_style) def getValues(self): - values = {'nth_sample': self.spinbox_nth_sample.value(), - 'pyqtgraphic': self.checkbox_pg.isChecked()} + values = {'nth_sample': self.spinbox_nth_sample.value()} return values def resetValues(self, infile=None): - values = {'nth_sample': self.spinbox_nth_sample.setValue(1), - 'pyqtgraphic': self.checkbox_pg.setChecked(True)} + values = {'nth_sample': self.spinbox_nth_sample.setValue(1)} return values From 7dae8e11073615163dff04e099f598de0dbfb1e6 Mon Sep 17 00:00:00 2001 From: Marcel Date: Thu, 2 Aug 2018 13:00:36 +0200 Subject: [PATCH 158/169] [bugfix] not regarding possible * in eventpath in eventbox --- pylot/core/util/widgets.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pylot/core/util/widgets.py b/pylot/core/util/widgets.py index eead217e..44466701 100644 --- a/pylot/core/util/widgets.py +++ b/pylot/core/util/widgets.py @@ -3376,7 +3376,7 @@ class TuneAutopicker(QWidget): return self.eventBox.currentText().split('/')[-1] def get_current_event_fp(self): - return self.eventBox.currentText() + return self.eventBox.currentText().split('*')[0] def get_current_event_picks(self, station): event = self.get_current_event() From 529939b4b83721a3a9b5e1e92cc442831f9a1d74 Mon Sep 17 00:00:00 2001 From: Marcel Date: Thu, 2 Aug 2018 13:32:45 +0200 Subject: [PATCH 159/169] [minor] removed unused object --- PyLoT.py | 1 - 1 file changed, 1 deletion(-) diff --git a/PyLoT.py b/PyLoT.py index 54ede24c..03fc50ff 100755 --- a/PyLoT.py +++ b/PyLoT.py @@ -684,7 +684,6 @@ class MainWindow(QMainWindow): self.setCentralWidget(_widget) def init_wfWidget(self): - settings = QSettings() xlab = self.startTime.strftime('seconds since %Y/%m/%d %H:%M:%S (%Z)') plottitle = None # "Overview: {0} components ".format(self.getComponent()) self.disconnectWFplotEvents() From d5e9cd07d4570efb1456d7515d3eb5641a082d64 Mon Sep 17 00:00:00 2001 From: Marcel Date: Thu, 2 Aug 2018 14:18:20 +0200 Subject: [PATCH 160/169] [revert] went back to old quality assessment without SNR --- PyLoT.py | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/PyLoT.py b/PyLoT.py index 03fc50ff..799e3460 100755 --- a/PyLoT.py +++ b/PyLoT.py @@ -2719,7 +2719,6 @@ class MainWindow(QMainWindow): stat_picks = self.getPicks(type=picktype)[station] settings = QSettings() - compclass = settings.value('compclass') for phase in stat_picks: if phase == 'SPt': continue # wadati SP time @@ -2729,14 +2728,14 @@ class MainWindow(QMainWindow): phaseID = self.getPhaseID(phase) # get quality classes - # if phaseID == 'P': - # quality = getQualityFromUncertainty(picks['spe'], self._inputs['timeerrorsP']) - # elif phaseID == 'S': - # quality = getQualityFromUncertainty(picks['spe'], self._inputs['timeerrorsS']) + if phaseID == 'P': + quality = getQualityFromUncertainty(picks['spe'], self._inputs['timeerrorsP']) + elif phaseID == 'S': + quality = getQualityFromUncertainty(picks['spe'], self._inputs['timeerrorsS']) - quality = getPickQuality(self.get_data().getWFData(), - stat_picks, self._inputs, phaseID, - compclass) + # quality = getPickQuality(self.get_data().getWFData(), + # stat_picks, self._inputs, phaseID, + # compclass) mpp = picks['mpp'] - stime if picks['epp'] and picks['lpp']: From 393413d6fc3404bb1bf16d53c3a674b5c77a54dc Mon Sep 17 00:00:00 2001 From: Marcel Date: Thu, 2 Aug 2018 15:42:34 +0200 Subject: [PATCH 161/169] [bugfix] closes #215 --- pylot/core/util/array_map.py | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/pylot/core/util/array_map.py b/pylot/core/util/array_map.py index 85fb59a9..7a428006 100644 --- a/pylot/core/util/array_map.py +++ b/pylot/core/util/array_map.py @@ -73,15 +73,11 @@ class Array_map(QtGui.QWidget): if pickDlg.exec_(): pyl_mw.setDirty(True) pyl_mw.update_status('picks accepted ({0})'.format(station)) - replot = pyl_mw.get_current_event().setPick(station, pickDlg.getPicks()) + pyl_mw.addPicks(station, pickDlg.getPicks(picktype='manual'), type='manual') + pyl_mw.addPicks(station, pickDlg.getPicks(picktype='auto'), type='auto') self._refresh_drawings() - if replot: - pyl_mw.plotWaveformData() - pyl_mw.drawPicks() - pyl_mw.draw() - else: - pyl_mw.drawPicks(station) - pyl_mw.draw() + pyl_mw.drawPicks(station) + pyl_mw.draw() else: pyl_mw.update_status('picks discarded ({0})'.format(station)) except Exception as e: From e211a901ff531106c992207dfef634e43382ae70 Mon Sep 17 00:00:00 2001 From: Marcel Date: Fri, 3 Aug 2018 09:33:37 +0200 Subject: [PATCH 162/169] [bugfix] could not init array map when loading project --- PyLoT.py | 1 + 1 file changed, 1 insertion(+) diff --git a/PyLoT.py b/PyLoT.py index 799e3460..067af2a3 100755 --- a/PyLoT.py +++ b/PyLoT.py @@ -3283,6 +3283,7 @@ class MainWindow(QMainWindow): self.init_metadata() self.init_array_tab() + self.set_metadata() def saveProjectAs(self, exists=False): ''' From d9a4c40d0be1f687a8b470dd0a60511d997c2ef0 Mon Sep 17 00:00:00 2001 From: Marcel Date: Fri, 3 Aug 2018 11:16:08 +0200 Subject: [PATCH 163/169] [minor] hide pick qualities histogram action (not implemented yet) --- PyLoT.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/PyLoT.py b/PyLoT.py index 067af2a3..b8eb7b39 100755 --- a/PyLoT.py +++ b/PyLoT.py @@ -443,6 +443,8 @@ class MainWindow(QMainWindow): slot=self.pickQualities, shortcut='Alt+Q', icon=qualities_icon, tip='Histogram of pick qualities') self.qualities_action.setEnabled(False) + # MP MP not yet implemented, therefore hide: + self.qualities_action.setVisible(False) printAction = self.createAction(self, "&Print event ...", self.show_event_information, QKeySequence.Print, From e75beff8835a77d21b74c939504233efd329c3b2 Mon Sep 17 00:00:00 2001 From: Marcel Date: Fri, 3 Aug 2018 11:16:56 +0200 Subject: [PATCH 164/169] [minor] cosmetics on dataPlot bottom layout --- pylot/core/util/widgets.py | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/pylot/core/util/widgets.py b/pylot/core/util/widgets.py index 44466701..e1e21104 100644 --- a/pylot/core/util/widgets.py +++ b/pylot/core/util/widgets.py @@ -646,8 +646,17 @@ class WaveformWidgetPG(QtGui.QWidget): self.label_layout.addWidget(self.status_label) for label in self.perm_labels: self.label_layout.addWidget(label) - self.label_layout.addWidget(self.syn_checkbox) - self.label_layout.addWidget(self.qcombo_processed) + mid_widget = QWidget() + right_widget = QWidget() + # use widgets as placeholder, so that child widgets keep position when others are hidden + mid_layout = QHBoxLayout() + right_layout = QHBoxLayout() + mid_layout.addWidget(self.syn_checkbox) + right_layout.addWidget(self.qcombo_processed) + mid_widget.setLayout(mid_layout) + right_widget.setLayout(right_layout) + self.label_layout.addWidget(mid_widget) + self.label_layout.addWidget(right_widget) self.syn_checkbox.setLayoutDirection(Qt.RightToLeft) self.label_layout.setStretch(0, 4) self.label_layout.setStretch(1, 0) From 5f2848d5845ca0c32e5517a7f937749e8e2dfeab Mon Sep 17 00:00:00 2001 From: Marcel Date: Fri, 3 Aug 2018 14:03:27 +0200 Subject: [PATCH 165/169] [bugfix] do not read the same files multiple times for each channel --- pylot/core/io/data.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pylot/core/io/data.py b/pylot/core/io/data.py index 3802bfd3..f1f3443d 100644 --- a/pylot/core/io/data.py +++ b/pylot/core/io/data.py @@ -434,7 +434,7 @@ class Data(object): False: self.wfdata} warnmsg = '' - for fname in fnames: + for fname in set(fnames): try: real_or_syn_data[synthetic] += read(fname) except TypeError: From a85b79e432c978435bd94cd9463ece986001642e Mon Sep 17 00:00:00 2001 From: Marcel Date: Mon, 6 Aug 2018 09:00:55 +0200 Subject: [PATCH 166/169] [change] try to merge streams instead of deleting them when they have gaps --- pylot/core/util/utils.py | 13 +++++++++++++ pylot/core/util/widgets.py | 36 +++++++++++++++++------------------- 2 files changed, 30 insertions(+), 19 deletions(-) diff --git a/pylot/core/util/utils.py b/pylot/core/util/utils.py index 6d8dc235..d8daf39c 100644 --- a/pylot/core/util/utils.py +++ b/pylot/core/util/utils.py @@ -869,6 +869,19 @@ def trim_station_components(data, trim_start=True, trim_end=True): return data +def merge_stream(stream): + gaps = stream.get_gaps() + if gaps: + # list of merged stations (seed_ids) + merged = ['{}.{}.{}.{}'.format(*gap[:4]) for gap in gaps] + stream.merge() + print('Merged the following stations because of gaps:') + for merged_station in merged: + print(merged_station) + + return stream, gaps + + def check4gaps(data): """ check for gaps in Stream and remove them diff --git a/pylot/core/util/widgets.py b/pylot/core/util/widgets.py index e1e21104..0f66e664 100644 --- a/pylot/core/util/widgets.py +++ b/pylot/core/util/widgets.py @@ -52,7 +52,7 @@ from pylot.core.pick.compare import Comparison from pylot.core.util.defaults import OUTPUTFORMATS, FILTERDEFAULTS from pylot.core.util.utils import prepTimeAxis, full_range, scaleWFData, \ demeanTrace, isSorted, findComboBoxIndex, clims, pick_linestyle_plt, pick_color_plt, \ - check4rotated, check4doubled, check4gaps, remove_underscores, find_horizontals, identifyPhase, \ + check4rotated, check4doubled, check4gaps, merge_stream, remove_underscores, find_horizontals, identifyPhase, \ loopIdentifyPhase, trim_station_components, transformFilteroptions2String, \ identifyPhaseID, real_Bool, pick_color, getAutoFilteroptions, SetChannelComponents from autoPyLoT import autoPyLoT @@ -734,13 +734,7 @@ class WaveformWidgetPG(QtGui.QWidget): else: st_select = wfdata - gaps = st_select.get_gaps() - if gaps: - merged = ['{}.{}.{}.{}'.format(*gap[:4]) for gap in gaps] - st_select.merge() - print('Merged the following stations because of gaps:') - for merged_station in merged: - print(merged_station) + st_select, gaps = merge_stream(st_select) # list containing tuples of network, station, channel (for sorting) nsc = [] @@ -3240,6 +3234,7 @@ class TuneAutopicker(QWidget): self.resize(1280, 720) self.center() self._manual_pick_plots = [] + self.fnames = None if hasattr(self.parent(), 'metadata'): self.metadata = self.parent().metadata else: @@ -3328,17 +3323,20 @@ class TuneAutopicker(QWidget): def load_wf_data(self): fnames = self.station_ids[self.get_current_station_id()] - self.data.setWFData(fnames) - wfdat = self.data.getWFData() # all available streams - # remove possible underscores in station names - #wfdat = remove_underscores(wfdat) - # rotate misaligned stations to ZNE - # check for gaps and doubled channels - check4gaps(wfdat) - check4doubled(wfdat) - wfdat = check4rotated(wfdat, self.parent().metadata, verbosity=0) - # trim station components to same start value - trim_station_components(wfdat, trim_start=True, trim_end=False) + if not fnames == self.fnames: + self.fnames = fnames + self.data.setWFData(fnames) + wfdat = self.data.getWFData() # all available streams + # remove possible underscores in station names + #wfdat = remove_underscores(wfdat) + # rotate misaligned stations to ZNE + # check for gaps and doubled channels + wfdat, gaps = merge_stream(wfdat) + #check4gaps(wfdat) + check4doubled(wfdat) + wfdat = check4rotated(wfdat, self.parent().metadata, verbosity=0) + # trim station components to same start value + trim_station_components(wfdat, trim_start=True, trim_end=False) def init_figure_tabs(self): self.figure_tabs = QtGui.QTabWidget() From 34891d3dc1fbcb09ffaa3ee247c94fa33c81cb9f Mon Sep 17 00:00:00 2001 From: Marcel Date: Mon, 6 Aug 2018 09:19:30 +0200 Subject: [PATCH 167/169] [minor] added verbosity flag for Metadata to reduce output in GUI --- PyLoT.py | 4 ++-- pylot/core/util/dataprocessing.py | 14 +++++++++----- pylot/core/util/widgets.py | 2 +- 3 files changed, 12 insertions(+), 8 deletions(-) diff --git a/PyLoT.py b/PyLoT.py index b8eb7b39..cdbbb801 100755 --- a/PyLoT.py +++ b/PyLoT.py @@ -118,7 +118,7 @@ class MainWindow(QMainWindow): self.apw = None self.paraBox = None self.array_map = None - self._metadata = Metadata() + self._metadata = Metadata(verbosity=0) self._eventChanged = [False, False] self.apd_local = None self.apd_sge = None @@ -3153,7 +3153,7 @@ class MainWindow(QMainWindow): def init_metadata(self, new=False, ask_default=True): if hasattr(self.project, 'inventories'): - self.metadata = Metadata() + self.metadata = Metadata(verbosity=0) for inventory in self.project.inventories: self.metadata.add_inventory(inventory) diff --git a/pylot/core/util/dataprocessing.py b/pylot/core/util/dataprocessing.py index 9dc95cf4..756486e0 100644 --- a/pylot/core/util/dataprocessing.py +++ b/pylot/core/util/dataprocessing.py @@ -14,7 +14,7 @@ from pylot.core.util.utils import key_for_set_value, find_in_list, \ class Metadata(object): - def __init__(self, inventory=None): + def __init__(self, inventory=None, verbosity=1): self.inventories = [] # saves read metadata objects (Parser/inventory) for a filename self.inventory_files = {} @@ -27,6 +27,7 @@ class Metadata(object): self.add_inventory(inventory) if os.path.isfile(inventory): self.add_inventory_file(inventory) + self.verbosity = verbosity def __str__(self): repr = 'PyLoT Metadata object including the following inventories:\n\n' @@ -107,14 +108,16 @@ class Metadata(object): self._read_inventory_data(seed_id) # if seed id is not found read all inventories and try to find it there if not seed_id in self.seed_ids.keys(): - print('No data found for seed id {}. Trying to find it in all known inventories...'.format(seed_id)) + if self.verbosity: + print('No data found for seed id {}. Trying to find it in all known inventories...'.format(seed_id)) self.read_all() for inv_fname, metadata_dict in self.inventory_files.items(): # use get_coordinates to check for seed_id try: metadata_dict['data'].get_coordinates(seed_id, time) self.seed_ids[seed_id] = inv_fname - print('Found metadata for station {}!'.format(seed_id)) + if self.verbosity: + print('Found metadata for station {}!'.format(seed_id)) return metadata_dict except Exception as e: continue @@ -181,7 +184,7 @@ class Metadata(object): if not station_name in self.stations_dict.keys(): st_id = network_name + '.' + station_name self.stations_dict[st_id] = {'latitude': station[0].latitude, - 'longitude': station[0].longitude} + 'longitude': station[0].longitude} def stat_info_from_inventory(inventory): for network in inventory.networks: @@ -241,7 +244,8 @@ class Metadata(object): # search for network name in filename fnames = glob.glob(os.path.join(path_to_inventory, '*' + network + '*')) if not fnames: - print('Could not find filenames matching station name, network name or seed id') + if self.verbosity: + print('Could not find filenames matching station name, network name or seed id') return for fname in fnames: if fname in self.inventory_files.keys(): diff --git a/pylot/core/util/widgets.py b/pylot/core/util/widgets.py index 0f66e664..4754f466 100644 --- a/pylot/core/util/widgets.py +++ b/pylot/core/util/widgets.py @@ -143,7 +143,7 @@ class AddMetadataWidget(QWidget): self.connect_signals() self.resize(600, 800) - self.metadata = metadata if metadata else Metadata() + self.metadata = metadata if metadata else Metadata(verbosity=0) self.from_metadata() self.center() From a2af6b44f39c9be6b5ed8df589bbb6273a42922d Mon Sep 17 00:00:00 2001 From: Marcel Date: Mon, 6 Aug 2018 16:03:54 +0200 Subject: [PATCH 168/169] [bugfix] regard location ID in PyLoT! (WIP) --- PyLoT.py | 212 +++++++++++++++++++------------------ pylot/core/util/widgets.py | 66 ++++++------ 2 files changed, 143 insertions(+), 135 deletions(-) diff --git a/PyLoT.py b/PyLoT.py index cdbbb801..316173a9 100755 --- a/PyLoT.py +++ b/PyLoT.py @@ -1566,12 +1566,13 @@ class MainWindow(QMainWindow): return statID - def getStationID(self, station): + def getStationIDs(self, station): + wfIDs = [] for wfID in self.getPlotWidget().getPlotDict().keys(): - actual_station = self.getPlotWidget().getPlotDict()[wfID][0] + actual_station = self.getPlotWidget().getPlotDict()[wfID].split('.')[1] if station == actual_station: - return wfID - return None + wfIDs.append(wfID) + return wfIDs def getStime(self): if self.get_data(): @@ -1915,7 +1916,7 @@ class MainWindow(QMainWindow): plotWidget = self.getPlotWidget() plotDict = plotWidget.getPlotDict() pos = plotDict.keys() - labels = [plotDict[n][2] + '.' + plotDict[n][0] for n in pos] + labels = ['{}.{}'.format(*plotDict[n].split('.')[:-2]) for n in pos] plotWidget.setYTickLabels(pos, labels) try: plotWidget.figure.tight_layout() @@ -2233,15 +2234,19 @@ class MainWindow(QMainWindow): def getSeismicPhase(self): return self.seismicPhase + def getTraceID(self, wfID): + plot_dict = self.getPlotWidget().getPlotDict() + return plot_dict.get(wfID) + def getStationName(self, wfID): plot_dict = self.getPlotWidget().getPlotDict() if wfID in plot_dict.keys(): - return plot_dict[wfID][0] + return plot_dict[wfID].split('.')[1] def getNetworkName(self, wfID): plot_dict = self.getPlotWidget().getPlotDict() if wfID in plot_dict.keys(): - return plot_dict[wfID][2] + return plot_dict[wfID].split('.')[0] def alterPhase(self): pass @@ -2308,38 +2313,38 @@ class MainWindow(QMainWindow): network = self.getNetworkName(wfID) station = self.getStationName(wfID) + seed_id = self.getTraceID(wfID) if button == 1: - self.pickDialog(wfID, network, station) + self.pickDialog(wfID, seed_id) elif button == 4: self.toggle_station_color(wfID, network, station) - def toggle_station_color(self, wfID, network, station): + def toggle_station_color(self, wfID, network, station, location): black_pen = pg.mkPen((0, 0, 0)) red_pen = pg.mkPen((200, 50, 50)) line_item = self.dataPlot.plotWidget.getPlotItem().listDataItems()[wfID - 1] current_pen = line_item.opts['pen'] - nwst = '{}.{}'.format(network, station) + nsl = '{}.{}.{}'.format(network, station, location) if current_pen == black_pen: line_item.setPen(red_pen) - if not nwst in self.stations_highlighted: - self.stations_highlighted.append(nwst) + if not nsl in self.stations_highlighted: + self.stations_highlighted.append(nsl) else: line_item.setPen(black_pen) - if nwst in self.stations_highlighted: - self.stations_highlighted.pop(self.stations_highlighted.index(nwst)) + if nsl in self.stations_highlighted: + self.stations_highlighted.pop(self.stations_highlighted.index(nsl)) def highlight_stations(self): for wfID, value in self.getPlotWidget().getPlotDict().items(): - station, channel, network = value - nwst = '{}.{}'.format(network, station) - if nwst in self.stations_highlighted: - self.toggle_station_color(wfID, network, station) + station, channel, location, network = value.split('.') + nsl = '{}.{}.{}'.format(network, station, location) + if nsl in self.stations_highlighted: + self.toggle_station_color(wfID, network, station, location) - def pickDialog(self, wfID, network=None, station=None): - if not network: - network = self.getNetworkName(wfID) - if not station: - station = self.getStationName(wfID) + def pickDialog(self, wfID, seed_id=None): + if not seed_id: + seed_id = self.getTraceID(wfID) + network, station, location = seed_id.split('.')[:3] if not station or not network: return self.update_status('picking on station {0}'.format(station)) @@ -2349,6 +2354,7 @@ class MainWindow(QMainWindow): pickDlg = PickDlg(self, parameter=self._inputs, data=data.select(station=station), station=station, network=network, + location=location, picks=self.getPicksOnStation(station, 'manual'), autopicks=self.getPicksOnStation(station, 'auto'), metadata=self.metadata, event=event, @@ -2714,93 +2720,95 @@ class MainWindow(QMainWindow): return # plotting picks - plotID = self.getStationID(station) - if plotID is None: + plotIDs = self.getStationIDs(station) + if not plotIDs: return - ylims = np.array([-.5, +.5]) + plotID - stat_picks = self.getPicks(type=picktype)[station] - settings = QSettings() + for plotID in plotIDs: + ylims = np.array([-.5, +.5]) + plotID - for phase in stat_picks: - if phase == 'SPt': continue # wadati SP time - picks = stat_picks[phase] - if type(stat_picks[phase]) is not dict and type(stat_picks[phase]) is not AttribDict: - return + stat_picks = self.getPicks(type=picktype)[station] + settings = QSettings() - phaseID = self.getPhaseID(phase) - # get quality classes - if phaseID == 'P': - quality = getQualityFromUncertainty(picks['spe'], self._inputs['timeerrorsP']) - elif phaseID == 'S': - quality = getQualityFromUncertainty(picks['spe'], self._inputs['timeerrorsS']) + for phase in stat_picks: + if phase == 'SPt': continue # wadati SP time + picks = stat_picks[phase] + if type(stat_picks[phase]) is not dict and type(stat_picks[phase]) is not AttribDict: + return - # quality = getPickQuality(self.get_data().getWFData(), - # stat_picks, self._inputs, phaseID, - # compclass) + phaseID = self.getPhaseID(phase) + # get quality classes + if phaseID == 'P': + quality = getQualityFromUncertainty(picks['spe'], self._inputs['timeerrorsP']) + elif phaseID == 'S': + quality = getQualityFromUncertainty(picks['spe'], self._inputs['timeerrorsS']) - mpp = picks['mpp'] - stime - if picks['epp'] and picks['lpp']: - epp = picks['epp'] - stime - lpp = picks['lpp'] - stime - else: - epp = None - lpp = None - spe = picks['spe'] + # quality = getPickQuality(self.get_data().getWFData(), + # stat_picks, self._inputs, phaseID, + # compclass) - if self.pg: - if spe: - if picks['epp'] and picks['lpp']: - pen = make_pen(picktype, phaseID, 'epp', quality) - self.drawnPicks[picktype][station].append(pw.plot([epp, epp], ylims, - alpha=.25, pen=pen, name='EPP')) - pen = make_pen(picktype, phaseID, 'lpp', quality) - self.drawnPicks[picktype][station].append(pw.plot([lpp, lpp], ylims, - alpha=.25, pen=pen, name='LPP')) - pen = make_pen(picktype, phaseID, 'spe', quality) - spe_l = pg.PlotDataItem([mpp - spe, mpp - spe], ylims, pen=pen, - name='{}-SPE'.format(phase)) - spe_r = pg.PlotDataItem([mpp + spe, mpp + spe], ylims, pen=pen) - try: - color = pen.color() - color.setAlpha(100.) - brush = pen.brush() - brush.setColor(color) - fill = pg.FillBetweenItem(spe_l, spe_r, brush=brush) - fb = pw.addItem(fill) - self.drawnPicks[picktype][station].append(fill) - except: - print('Warning: drawPicks: Could not create fill for symmetric pick error.') - pen = make_pen(picktype, phaseID, 'mpp', quality) - self.drawnPicks[picktype][station].append( - pw.plot([mpp, mpp], ylims, pen=pen, name='{}-Pick'.format(phase))) - else: - if picktype == 'manual': - linestyle_mpp, width_mpp = pick_linestyle_plt(picktype, 'mpp') - color = pick_color_plt(picktype, self.getPhaseID(phase), quality) - if picks['epp'] and picks['lpp']: - ax.fill_between([epp, lpp], ylims[0], ylims[1], - alpha=.25, color=color, label='EPP, LPP') - if spe: - linestyle_spe, width_spe = pick_linestyle_plt(picktype, 'spe') - ax.plot([mpp - spe, mpp - spe], ylims, color=color, linestyle=linestyle_spe, - linewidth=width_spe, label='{}-SPE'.format(phase)) - ax.plot([mpp + spe, mpp + spe], ylims, color=color, linestyle=linestyle_spe, - linewidth=width_spe) - ax.plot([mpp, mpp], ylims, color=color, linestyle=linestyle_mpp, linewidth=width_mpp, - label='{}-Pick (quality: {})'.format(phase, quality), picker=5) - else: - ax.plot([mpp, mpp], ylims, color=color, linestyle=linestyle_mpp, linewidth=width_mpp, - label='{}-Pick (NO PICKERROR)'.format(phase), picker=5) - elif picktype == 'auto': - color = pick_color_plt(picktype, phase, quality) - linestyle_mpp, width_mpp = pick_linestyle_plt(picktype, 'mpp') - ax.plot(mpp, ylims[1], color=color, marker='v') - ax.plot(mpp, ylims[0], color=color, marker='^') - ax.vlines(mpp, ylims[0], ylims[1], color=color, linestyle=linestyle_mpp, linewidth=width_mpp, - picker=5, label='{}-Autopick (quality: {})'.format(phase, quality)) + mpp = picks['mpp'] - stime + if picks['epp'] and picks['lpp']: + epp = picks['epp'] - stime + lpp = picks['lpp'] - stime else: - raise TypeError('Unknown picktype {0}'.format(picktype)) + epp = None + lpp = None + spe = picks['spe'] + + if self.pg: + if spe: + if picks['epp'] and picks['lpp']: + pen = make_pen(picktype, phaseID, 'epp', quality) + self.drawnPicks[picktype][station].append(pw.plot([epp, epp], ylims, + alpha=.25, pen=pen, name='EPP')) + pen = make_pen(picktype, phaseID, 'lpp', quality) + self.drawnPicks[picktype][station].append(pw.plot([lpp, lpp], ylims, + alpha=.25, pen=pen, name='LPP')) + pen = make_pen(picktype, phaseID, 'spe', quality) + spe_l = pg.PlotDataItem([mpp - spe, mpp - spe], ylims, pen=pen, + name='{}-SPE'.format(phase)) + spe_r = pg.PlotDataItem([mpp + spe, mpp + spe], ylims, pen=pen) + try: + color = pen.color() + color.setAlpha(100.) + brush = pen.brush() + brush.setColor(color) + fill = pg.FillBetweenItem(spe_l, spe_r, brush=brush) + fb = pw.addItem(fill) + self.drawnPicks[picktype][station].append(fill) + except: + print('Warning: drawPicks: Could not create fill for symmetric pick error.') + pen = make_pen(picktype, phaseID, 'mpp', quality) + self.drawnPicks[picktype][station].append( + pw.plot([mpp, mpp], ylims, pen=pen, name='{}-Pick'.format(phase))) + else: + if picktype == 'manual': + linestyle_mpp, width_mpp = pick_linestyle_plt(picktype, 'mpp') + color = pick_color_plt(picktype, self.getPhaseID(phase), quality) + if picks['epp'] and picks['lpp']: + ax.fill_between([epp, lpp], ylims[0], ylims[1], + alpha=.25, color=color, label='EPP, LPP') + if spe: + linestyle_spe, width_spe = pick_linestyle_plt(picktype, 'spe') + ax.plot([mpp - spe, mpp - spe], ylims, color=color, linestyle=linestyle_spe, + linewidth=width_spe, label='{}-SPE'.format(phase)) + ax.plot([mpp + spe, mpp + spe], ylims, color=color, linestyle=linestyle_spe, + linewidth=width_spe) + ax.plot([mpp, mpp], ylims, color=color, linestyle=linestyle_mpp, linewidth=width_mpp, + label='{}-Pick (quality: {})'.format(phase, quality), picker=5) + else: + ax.plot([mpp, mpp], ylims, color=color, linestyle=linestyle_mpp, linewidth=width_mpp, + label='{}-Pick (NO PICKERROR)'.format(phase), picker=5) + elif picktype == 'auto': + color = pick_color_plt(picktype, phase, quality) + linestyle_mpp, width_mpp = pick_linestyle_plt(picktype, 'mpp') + ax.plot(mpp, ylims[1], color=color, marker='v') + ax.plot(mpp, ylims[0], color=color, marker='^') + ax.vlines(mpp, ylims[0], ylims[1], color=color, linestyle=linestyle_mpp, linewidth=width_mpp, + picker=5, label='{}-Autopick (quality: {})'.format(phase, quality)) + else: + raise TypeError('Unknown picktype {0}'.format(picktype)) def locate_event(self): """ diff --git a/pylot/core/util/widgets.py b/pylot/core/util/widgets.py index 4754f466..29644904 100644 --- a/pylot/core/util/widgets.py +++ b/pylot/core/util/widgets.py @@ -631,7 +631,7 @@ class WaveformWidgetPG(QtGui.QWidget): x, y, = (mousePoint.x(), mousePoint.y()) # if x > 0:# and index < len(data1): wfID = self.orig_parent.getWFID(y) - station = self.orig_parent.getStationName(wfID) + station = self.orig_parent.getTraceID(wfID) abstime = self.wfstart + x if self.orig_parent.get_current_event(): self.status_label.setText("station = {}, T = {}, t = {} [s]".format(station, abstime, x)) @@ -737,26 +737,27 @@ class WaveformWidgetPG(QtGui.QWidget): st_select, gaps = merge_stream(st_select) # list containing tuples of network, station, channel (for sorting) - nsc = [] + nslc = [] for trace in st_select: - nsc.append((trace.stats.network, trace.stats.station, trace.stats.channel)) - nsc.sort() - nsc.reverse() + nslc.append(trace.get_id())#(trace.stats.network, trace.stats.station, trace.stats.location trace.stats.channel)) + nslc.sort() + nslc.reverse() plots = [] try: self.plotWidget.getPlotItem().vb.setLimits(xMin=float(0), xMax=float(self.wfend - self.wfstart), yMin=.5, - yMax=len(nsc) + .5) + yMax=len(nslc) + .5) except: print('Warning: Could not set zoom limits') - for n, (network, station, channel) in enumerate(nsc): + for n, seed_id in enumerate(nslc): n += 1 - st = st_select.select(network=network, station=station, channel=channel) + network, station, location, channel = seed_id.split('.') + st = st_select.select(id=seed_id) trace = st[0].copy() - st_syn = wfsyn.select(network=network, station=station, channel=channel) + st_syn = wfsyn.select(id=seed_id) if st_syn: trace_syn = st_syn[0].copy() else: @@ -797,7 +798,7 @@ class WaveformWidgetPG(QtGui.QWidget): if not index % nth_sample] if st_syn else []) plots.append((times, trace.data, times_syn, trace_syn.data)) - self.setPlotDict(n, (station, channel, network)) + self.setPlotDict(n, seed_id) self.xlabel = 'seconds since {0}'.format(self.wfstart) self.ylabel = '' self.setXLims([0, self.wfend - self.wfstart]) @@ -1237,20 +1238,21 @@ class PylotCanvas(FigureCanvas): print(merged_station) # list containing tuples of network, station, channel and plot position (for sorting) - nsc = [] + nslc = [] for plot_pos, trace in enumerate(st_select): if not trace.stats.channel[-1] in ['Z', 'N', 'E', '1', '2', '3']: print('Warning: Unrecognized channel {}'.format(trace.stats.channel)) continue - nsc.append((trace.stats.network, trace.stats.station, trace.stats.channel)) - nsc.sort() - nsc.reverse() + nslc.append(trace.get_id()) + nslc.sort() + nslc.reverse() style = self.orig_parent._style linecolor = style['linecolor']['rgba_mpl'] - for n, (network, station, channel) in enumerate(nsc): - st = st_select.select(network=network, station=station, channel=channel) + for n, seed_id in enumerate(nslc): + network, station, location, channel = seed_id.split('.') + st = st_select.select(id=seed_id) trace = st[0].copy() if mapping: n = plot_positions[trace.stats.channel] @@ -1283,7 +1285,7 @@ class PylotCanvas(FigureCanvas): [n + level, n + level], color=linecolor, linestyle='dashed') - self.setPlotDict(n, (station, channel, network)) + self.setPlotDict(n, seed_id) if plot_additional and additional_channel: compare_stream = wfdata.select(channel=additional_channel) if compare_stream: @@ -1471,7 +1473,7 @@ class PhaseDefaults(QtGui.QDialog): class PickDlg(QDialog): update_picks = QtCore.Signal(dict) - def __init__(self, parent=None, data=None, station=None, network=None, picks=None, + def __init__(self, parent=None, data=None, station=None, network=None, location=None, picks=None, autopicks=None, rotate=False, parameter=None, embedded=False, metadata=None, event=None, filteroptions=None, model='iasp91', wftype=None): super(PickDlg, self).__init__(parent, 1) @@ -1483,6 +1485,7 @@ class PickDlg(QDialog): self._embedded = embedded self.station = station self.network = network + self.location = location self.rotate = rotate self.metadata = metadata self.wftype = wftype @@ -2127,22 +2130,21 @@ class PickDlg(QDialog): return self.components def getStation(self): - if self.network and self.station: - return self.network + '.' + self.station - return self.station + return self.network + '.' + self.station + '.' + self.location def getChannelID(self, key): if key < 0: key = 0 - return self.multicompfig.getPlotDict()[int(key)][1] + return self.multicompfig.getPlotDict()[int(key)].split('.')[-1] def getTraceID(self, channels): plotDict = self.multicompfig.getPlotDict() traceIDs = [] for channel in channels: channel = channel.upper() - for traceID, channelID in plotDict.items(): + for seed_id in plotDict.items(): + channelID = seed_id.split('.')[-1] if channelID[1].upper().endswith(channel): - traceIDs.append(traceID) + traceIDs.append(seed_id) return traceIDs def getUser(self): @@ -2845,10 +2847,9 @@ class PickDlg(QDialog): self.multicompfig.connectEvents() def setPlotLabels(self): - # get channel labels pos = self.multicompfig.getPlotDict().keys() - labels = [self.multicompfig.getPlotDict()[key][1] for key in pos] + labels = [self.multicompfig.getPlotDict()[key].split('.')[-1] for key in pos] ax = self.multicompfig.figure.axes[0] @@ -3300,10 +3301,7 @@ class TuneAutopicker(QWidget): print('Warning: Could not read file {} as a stream object: {}'.format(filename, e)) continue for trace in st: - network = trace.stats.network - station = trace.stats.station - location = trace.stats.location - station_id = '{}.{}.{}'.format(network, station, location) + station_id = trace.get_id() if not station_id in self.station_ids: self.station_ids[station_id] = [] self.station_ids[station_id].append(filename) @@ -3417,14 +3415,15 @@ class TuneAutopicker(QWidget): self.pdlg_widget = None return self.load_wf_data() - station = self.get_current_station() + network, station, location, channel = self.get_current_station_id() wfdata = self.data.getWFData() metadata = self.parent().metadata event = self.get_current_event() filteroptions = self.parent().filteroptions wftype = self.wftype if self.obspy_dmt else '' self.pickDlg = PickDlg(self.parent(), data=wfdata.select(station=station).copy(), - station=station, parameter=self.parameter, + station=station, network=network, + location=location, parameter=self.parameter, picks=self.get_current_event_picks(station), autopicks=self.get_current_event_autopicks(station), metadata=metadata, event=event, filteroptions=filteroptions, @@ -3441,6 +3440,7 @@ class TuneAutopicker(QWidget): hl.addWidget(self.pickDlg) def picks_from_pickdlg(self, picks=None): + seed_id = self.get_current_station_id() station = self.get_current_station() replot = self.parent().addPicks(station, picks) self.get_current_event().setPick(station, picks) @@ -3449,7 +3449,7 @@ class TuneAutopicker(QWidget): self.parent().plotWaveformDataThread() self.parent().drawPicks() else: - self.parent().drawPicks(station) + self.parent().drawPicks(seed_id) self.parent().draw() def clear_plotitem(self, plotitem): From a0f9561bcfd881725e33f7e757ccc556193d2ef1 Mon Sep 17 00:00:00 2001 From: Marcel Date: Thu, 9 Aug 2018 11:16:20 +0200 Subject: [PATCH 169/169] [new] hybrid selection for array_map (plot automatic and manual picks, prefer manuals) --- pylot/core/util/array_map.py | 34 ++++++++++++++++++++++--------- pylot/core/util/dataprocessing.py | 6 +++--- pylot/core/util/widgets.py | 2 +- 3 files changed, 28 insertions(+), 14 deletions(-) diff --git a/pylot/core/util/array_map.py b/pylot/core/util/array_map.py index 7a428006..262bbd7f 100644 --- a/pylot/core/util/array_map.py +++ b/pylot/core/util/array_map.py @@ -1,6 +1,7 @@ #!/usr/bin/env python # -*- coding: utf-8 -*- +import traceback import matplotlib.pyplot as plt import numpy as np import obspy @@ -36,6 +37,15 @@ class Array_map(QtGui.QWidget): self._style = parent._style # self.show() + @property + def hybrids_dict(self): + hybrids_dict = self.picks_dict.copy() + for station, pick in self.autopicks_dict.items(): + if not station in hybrids_dict.keys(): + hybrids_dict[station] = pick + return hybrids_dict + + def init_map(self): self.init_lat_lon_dimensions() self.init_lat_lon_grid() @@ -51,15 +61,14 @@ class Array_map(QtGui.QWidget): return data = self._parent.get_data().getWFData() for index in ind: - station = str(self._station_onpick_ids[index].split('.')[-1]) + network, station = self._station_onpick_ids[index].split('.')[:2] try: data = data.select(station=station) if not data: self._warn('No data for station {}'.format(station)) return pickDlg = PickDlg(self._parent, parameter=self._parent._inputs, - data=data, - station=station, + data=data, network=network, station=station, picks=self._parent.get_current_event().getPick(station), autopicks=self._parent.get_current_event().getAutopick(station), filteroptions=self._parent.filteroptions) @@ -67,6 +76,7 @@ class Array_map(QtGui.QWidget): message = 'Could not generate Plot for station {st}.\n {er}'.format(st=station, er=e) self._warn(message) print(message, e) + print(traceback.format_exc()) return pyl_mw = self._parent try: @@ -115,9 +125,10 @@ class Array_map(QtGui.QWidget): self.status_label.setText('Latitude: {}, Longitude: {}'.format(lat, lon)) def current_picks_dict(self): - picktype = self.comboBox_am.currentText() + picktype = self.comboBox_am.currentText().split(' ')[0] auto_manu = {'auto': self.autopicks_dict, - 'manual': self.picks_dict} + 'manual': self.picks_dict, + 'hybrid': self.hybrids_dict} return auto_manu[picktype] def init_graphics(self): @@ -141,8 +152,9 @@ class Array_map(QtGui.QWidget): self.comboBox_phase.insertItem(1, 'S') self.comboBox_am = QtGui.QComboBox() - self.comboBox_am.insertItem(0, 'auto') + self.comboBox_am.insertItem(0, 'hybrid (prefer manual)') self.comboBox_am.insertItem(1, 'manual') + self.comboBox_am.insertItem(2, 'auto') self.top_row.addWidget(QtGui.QLabel('Select a phase: ')) self.top_row.addWidget(self.comboBox_phase) @@ -349,15 +361,17 @@ class Array_map(QtGui.QWidget): def draw_everything(self): picktype = self.comboBox_am.currentText() - if (self.picks_dict and picktype == 'manual') \ - or (self.autopicks_dict and picktype == 'auto'): + picks_available = (self.picks_dict and picktype == 'manual') \ + or (self.autopicks_dict and picktype == 'auto') \ + or ((self.autopicks_dict or self.picks_dict) and picktype.startswith('hybrid')) + + if picks_available: self.init_picks() if len(self.picks) >= 3: self.init_picksgrid() self.draw_contour_filled() self.scatter_all_stations() - if (self.picks_dict and picktype == 'manual') \ - or (self.autopicks_dict and picktype == 'auto'): + if picks_available: self.scatter_picked_stations() self.cbar = self.add_cbar(label='Time relative to first onset ({}) [s]'.format(self._earliest_picktime)) self.comboBox_phase.setEnabled(True) diff --git a/pylot/core/util/dataprocessing.py b/pylot/core/util/dataprocessing.py index 756486e0..18a99a57 100644 --- a/pylot/core/util/dataprocessing.py +++ b/pylot/core/util/dataprocessing.py @@ -182,7 +182,7 @@ class Metadata(object): station_name = station[0].station_call_letters network_name = station[0].network_code if not station_name in self.stations_dict.keys(): - st_id = network_name + '.' + station_name + st_id = '{}.{}'.format(network_name, station_name) self.stations_dict[st_id] = {'latitude': station[0].latitude, 'longitude': station[0].longitude} @@ -192,9 +192,9 @@ class Metadata(object): station_name = station.code network_name = network_name.code if not station_name in self.stations_dict.keys(): - st_id = network_name + '.' + station_name + st_id = '{}.{}'.format(network_name, station_name) self.stations_dict[st_id] = {'latitude': station[0].latitude, - 'longitude': station[0].longitude} + 'longitude': station[0].longitude} read_stat = {'xml': stat_info_from_inventory, 'dless': stat_info_from_parser} diff --git a/pylot/core/util/widgets.py b/pylot/core/util/widgets.py index 29644904..23f65826 100644 --- a/pylot/core/util/widgets.py +++ b/pylot/core/util/widgets.py @@ -2130,7 +2130,7 @@ class PickDlg(QDialog): return self.components def getStation(self): - return self.network + '.' + self.station + '.' + self.location + return '{}.{}.{}'.format(self.network, self.station, self.location) def getChannelID(self, key): if key < 0: key = 0