From e53dd99d756e7e127aebcca8a7ba98ddfb959ad2 Mon Sep 17 00:00:00 2001 From: Sebastianw Wehling-Benatelli Date: Thu, 25 Aug 2016 13:31:51 +0200 Subject: [PATCH 1/6] [refs #137] implementation of GUI driven NonLinLoc location started --- QtPyLoT.py | 14 ++++++++----- autoPyLoT.py | 37 ++++++++++++++++++--------------- pylot/core/loc/hsat.py | 19 +++++++++++++++++ pylot/core/loc/nll.py | 45 +++++++++++++++++++++------------------- pylot/core/util/utils.py | 40 +++++++++++++++++++++++++++++++++-- 5 files changed, 110 insertions(+), 45 deletions(-) diff --git a/QtPyLoT.py b/QtPyLoT.py index 8209d464..9584061b 100755 --- a/QtPyLoT.py +++ b/QtPyLoT.py @@ -44,7 +44,7 @@ from pylot.core.io.inputs import FilterOptions, AutoPickParameter from pylot.core.pick.autopick import autopickevent from pylot.core.pick.compare import Comparison from pylot.core.io.phases import picksdict_from_picks -from pylot.core.loc.nll import locate as locateNll +import pylot.core.loc.nll as nll from pylot.core.util.defaults import FILTERDEFAULTS, COMPNAME_MAP, \ AUTOMATIC_DEFAULTS from pylot.core.util.errors import FormatError, DatastructureError, \ @@ -61,7 +61,7 @@ from pylot.core.util.thread import AutoPickThread from pylot.core.util.version import get_git_version as _getVersionString import icons_rc -locateTool = dict(nll=locateNll) +locateTool = dict(nll=nll) class MainWindow(QMainWindow): @@ -890,10 +890,14 @@ class MainWindow(QMainWindow): def locateEvent(self): settings = QSettings() + # get location tool hook loctool = settings.value("loc/tool", "nll") - extlocpath = settings.value("%s/binPath".format(loctool), None) - locroot = settings.value("%s/rootPath".format(loctool), None) - if extlocpath is None or locroot is None: + lt = locateTool[loctool] + # get working directory + locroot = settings.value("{0}/rootPath".format(loctool), None) + infile = settings.value("{0}/inputFile".format(loctool), None) + lt.locate(infile) + if locroot is None: self.PyLoTprefs() def check4Loc(self): diff --git a/autoPyLoT.py b/autoPyLoT.py index 89898ec9..70bc5156 100755 --- a/autoPyLoT.py +++ b/autoPyLoT.py @@ -6,13 +6,15 @@ from __future__ import print_function import argparse import glob import string +import os import numpy as np from pylot.core.analysis.magnitude import M0Mw from pylot.core.io.data import Data from pylot.core.io.inputs import AutoPickParameter -from pylot.core.loc.nll import * +import pylot.core.loc.nll as nll +import pylot.core.loc.hsat as hsat from pylot.core.pick.autopick import autopickevent, iteratepicker from pylot.core.util.structure import DATASTRUCTURE from pylot.core.util.version import get_git_version as _getVersionString @@ -112,16 +114,17 @@ def autoPyLoT(inputfile): # locating if locflag == 1: # write phases to NLLoc-phase file - picksExport(picks, 'NLLoc', phasefile) + nll.export(picks, phasefile) # For locating the event the NLLoc-control file has to be modified! evID = event[string.rfind(event, "/") + 1: len(events) - 1] nllocout = '%s_%s' % (evID, nllocoutpatter) # create comment line for NLLoc-control file - modifyInputFile(ctrf, nllocroot, nllocout, phasef, ttpat) + nll.modifyInputFile(ctrf, nllocroot, nllocout, phasef, + ttpat) # locate the event - locate(nlloccall, ctrfile) + nll.locate(ctrfile) # !iterative picking if traces remained unpicked or occupied with bad picks! # get theoretical onset times for picks with weights >= 4 @@ -162,11 +165,11 @@ def autoPyLoT(inputfile): print("autoPyLoT: Starting with iteration No. %d ..." % nlloccounter) picks = iteratepicker(wfdat, nllocfile, picks, badpicks, parameter) # write phases to NLLoc-phase file - picksExport(picks, 'NLLoc', phasefile) + nll.export(picks, phasefile) # remove actual NLLoc-location file to keep only the last os.remove(nllocfile) # locate the event - locate(nlloccall, ctrfile) + nll.locate(ctrfile) print("autoPyLoT: Iteration No. %d finished." % nlloccounter) # get updated NLLoc-location file nllocfile = max(glob.glob(locsearch), key=os.path.getctime) @@ -201,13 +204,13 @@ def autoPyLoT(inputfile): hypo71file = '%s/autoPyLoT_HYPO71.pha' % event if hasattr(finalpicks, 'getpicdic'): if finalpicks.getpicdic() is not None: - writephases(finalpicks.getpicdic(), 'HYPO71', hypo71file) + hsat.export(finalpicks.getpicdic(), hypo71file) data.applyEVTData(finalpicks.getpicdic()) else: - writephases(picks, 'HYPO71', hypo71file) + hsat.export(picks, hypo71file) data.applyEVTData(picks) else: - writephases(picks, 'HYPO71', hypo71file) + hsat.export(picks, hypo71file) data.applyEVTData(picks) fnqml = '%s/autoPyLoT' % event data.exportEvent(fnqml) @@ -235,15 +238,15 @@ def autoPyLoT(inputfile): # locating if locflag == 1: # write phases to NLLoc-phase file - picksExport(picks, 'NLLoc', phasefile) + nll.export(picks, phasefile) # For locating the event the NLLoc-control file has to be modified! nllocout = '%s_%s' % (parameter.get('eventID'), nllocoutpatter) # create comment line for NLLoc-control file - modifyInputFile(ctrf, nllocroot, nllocout, phasef, ttpat) + nll.modifyInputFile(ctrf, nllocroot, nllocout, phasef, ttpat) # locate the event - locate(nlloccall, ctrfile) + nll.locate(ctrfile) # !iterative picking if traces remained unpicked or occupied with bad picks! # get theoretical onset times for picks with weights >= 4 # in order to reprocess them using smaller time windows around theoretical onset @@ -283,11 +286,11 @@ def autoPyLoT(inputfile): print("autoPyLoT: Starting with iteration No. %d ..." % nlloccounter) picks = iteratepicker(wfdat, nllocfile, picks, badpicks, parameter) # write phases to NLLoc-phase file - picksExport(picks, 'NLLoc', phasefile) + nll.export(picks, phasefile) # remove actual NLLoc-location file to keep only the last os.remove(nllocfile) # locate the event - locate(nlloccall, ctrfile) + nll.locate(ctrfile) print("autoPyLoT: Iteration No. %d finished." % nlloccounter) # get updated NLLoc-location file nllocfile = max(glob.glob(locsearch), key=os.path.getctime) @@ -322,13 +325,13 @@ def autoPyLoT(inputfile): hypo71file = '%s/%s/autoPyLoT_HYPO71.pha' % (datapath, parameter.get('eventID')) if hasattr(finalpicks, 'getpicdic'): if finalpicks.getpicdic() is not None: - writephases(finalpicks.getpicdic(), 'HYPO71', hypo71file) + hsat.export(finalpicks.getpicdic(), hypo71file) data.applyEVTData(finalpicks.getpicdic()) else: - writephases(picks, 'HYPO71', hypo71file) + hsat.export(picks, hypo71file) data.applyEVTData(picks) else: - writephases(picks, 'HYPO71', hypo71file) + hsat.export(picks, hypo71file) data.applyEVTData(picks) fnqml = '%s/%s/autoPyLoT' % (datapath, parameter.get('eventID')) data.exportEvent(fnqml) diff --git a/pylot/core/loc/hsat.py b/pylot/core/loc/hsat.py index faa18be5..b191f21b 100644 --- a/pylot/core/loc/hsat.py +++ b/pylot/core/loc/hsat.py @@ -1,2 +1,21 @@ #!/usr/bin/env python # -*- coding: utf-8 -*- + +from pylot.core.io.phases import writephases +from pylot.core.util.version import get_git_version as _getVersionString + +__version__ = _getVersionString() + +def export(picks, fnout): + ''' + Take dictionary and exports picking data to a NLLOC-obs + without creating an ObsPy event object. + + :param picks: picking data dictionary + :type picks: dict + + :param fnout: complete path to the exporting obs file + :type fnout: str + ''' + # write phases to NLLoc-phase file + writephases(picks, 'HYPO71', fnout) diff --git a/pylot/core/loc/nll.py b/pylot/core/loc/nll.py index b5a5522a..96a2b007 100644 --- a/pylot/core/loc/nll.py +++ b/pylot/core/loc/nll.py @@ -3,14 +3,17 @@ import subprocess import os +from obspy import read_events from pylot.core.io.phases import writephases -from pylot.core.util.utils import getPatternLine, runProgram +from pylot.core.util.utils import getPatternLine, runProgram, which from pylot.core.util.version import get_git_version as _getVersionString __version__ = _getVersionString() +class NLLocError(EnvironmentError): + pass -def picksExport(picks, locrt, phasefile): +def export(picks, fnout): ''' Take dictionary and exports picking data to a NLLOC-obs without creating an ObsPy event object. @@ -18,14 +21,11 @@ def picksExport(picks, locrt, phasefile): :param picks: picking data dictionary :type picks: dict - :param locrt: choose location routine - :type locrt: str - - :param phasefile: complete path to the exporting obs file - :type phasefile: str + :param fnout: complete path to the exporting obs file + :type fnout: str ''' # write phases to NLLoc-phase file - writephases(picks, locrt, phasefile) + writephases(picks, 'NLLoc', fnout) def modifyInputFile(ctrfn, root, nllocoutn, phasefn, tttn): @@ -66,24 +66,27 @@ def modifyInputFile(ctrfn, root, nllocoutn, phasefn, tttn): nllfile.close() -def locate(call, fnin): - ''' - Takes paths to NLLoc executable and input parameter file - and starts the location calculation. +def locate(fnin): + """ + takes an external program name + :param fnin: + :return: + """ - :param call: full path to NLLoc executable - :type call: str + exe_path = which('NLLoc') + if exe_path is None: + raise NLLocError('NonLinLoc executable not found; check your ' + 'environment variables') - :param fnin: full path to input parameter file - :type fnin: str - ''' - - # locate the event - runProgram(call, fnin) + # locate the event utilizing external NonLinLoc installation + try: + runProgram(exe_path, fnin) + except subprocess.CalledProcessError as e: + print(e.output) def readLocation(fn): - pass + return read_events(fn) if __name__ == '__main__': diff --git a/pylot/core/util/utils.py b/pylot/core/util/utils.py index 9f7697dc..1eb2a6d6 100644 --- a/pylot/core/util/utils.py +++ b/pylot/core/util/utils.py @@ -277,6 +277,15 @@ def getPatternLine(fn, pattern): return None +def is_executable(fn): + """ + takes a filename and returns True if the file is executable on the system + and False otherwise + :param fn: path to the file to be tested + :return: True or False + """ + return os.path.isfile(fn) and os.access(fn, os.X_OK) + def isSorted(iterable): ''' @@ -393,9 +402,36 @@ def runProgram(cmd, parameter=None): cmd.strip() cmd += ' %s 2>&1' % parameter - output = subprocess.check_output('{} | tee /dev/stderr'.format(cmd), - shell=True) + subprocess.check_output('{} | tee /dev/stderr'.format(cmd), shell=True) +def which(program): + """ + takes a program name and returns the full path to the executable or None + found on: http://stackoverflow.com/questions/377017/test-if-executable-exists-in-python + :param program: name of the desired external program + :return: full path of the executable file + """ + + def is_exe(fpath): + return os.path.exists(fpath) and os.access(fpath, os.X_OK) + + def ext_candidates(fpath): + yield fpath + for ext in os.environ.get("PATHEXT", "").split(os.pathsep): + yield fpath + ext + + fpath, fname = os.path.split(program) + if fpath: + if is_exe(program): + return program + else: + for path in os.environ["PATH"].split(os.pathsep): + exe_file = os.path.join(path, program) + for candidate in ext_candidates(exe_file): + if is_exe(candidate): + return candidate + + return None if __name__ == "__main__": import doctest From b29c7068e316f52786992c2142b0dea7abc2b39d Mon Sep 17 00:00:00 2001 From: Sebastian Wehling-Benatelli Date: Thu, 25 Aug 2016 21:32:41 +0200 Subject: [PATCH 2/6] [refs #137] some improvements in autoPyLoT and ongoing work in the QtPyLoT NLL implementation --- QtPyLoT.py | 24 +++++++++++++++++++++++- autoPyLoT.py | 26 +++++++++----------------- pylot/core/loc/nll.py | 4 ++-- 3 files changed, 34 insertions(+), 20 deletions(-) diff --git a/QtPyLoT.py b/QtPyLoT.py index 9584061b..cd375089 100755 --- a/QtPyLoT.py +++ b/QtPyLoT.py @@ -37,6 +37,7 @@ from PySide.QtGui import QMainWindow, QInputDialog, QIcon, QFileDialog, \ QDialog, QErrorMessage, QApplication, QPixmap, QMessageBox, QSplashScreen, \ QActionGroup, QListWidget, QDockWidget import numpy as np +import subprocess from obspy import UTCDateTime from pylot.core.io.data import Data @@ -630,6 +631,8 @@ class MainWindow(QMainWindow): ans = self.data.setWFData(self.fnames) elif self.fnames is None and self.okToContinue(): ans = self.data.setWFData(self.getWFFnames()) + else: + ans = False self._stime = getGlobalTimes(self.getData().getWFData())[0] if ans: self.plotWaveformData() @@ -889,6 +892,12 @@ class MainWindow(QMainWindow): raise TypeError('Unknow picktype {0}'.format(picktype)) def locateEvent(self): + """ + locate event using the manually picked phases + :return: + """ + if not self.okToContinue(): + return settings = QSettings() # get location tool hook loctool = settings.value("loc/tool", "nll") @@ -896,9 +905,22 @@ class MainWindow(QMainWindow): # get working directory locroot = settings.value("{0}/rootPath".format(loctool), None) infile = settings.value("{0}/inputFile".format(loctool), None) - lt.locate(infile) + outfile = settings.value("{0}/outputFile".format(loctool), None) + phasepath = os.tempnam(os.path.join(locroot, 'obs'), loctool) + locpath = os.path.join(locroot, 'loc', outfile) + lt.export(self.getPicks(), phasepath) + phasefile = os.path.split(phasepath)[-1] + args = lt.modify_inputs(infile, locroot, outfile, phasefile, ) if locroot is None: self.PyLoTprefs() + try: + lt.locate(infile) + except RuntimeError as e: + print(e.message) + finally: + os.remove(phasepath) + + self.getData().applyEVTData(lt.read_location(locpath), type='event') def check4Loc(self): return self.picksNum() > 4 diff --git a/autoPyLoT.py b/autoPyLoT.py index 70bc5156..01b430ab 100755 --- a/autoPyLoT.py +++ b/autoPyLoT.py @@ -120,8 +120,8 @@ def autoPyLoT(inputfile): evID = event[string.rfind(event, "/") + 1: len(events) - 1] nllocout = '%s_%s' % (evID, nllocoutpatter) # create comment line for NLLoc-control file - nll.modifyInputFile(ctrf, nllocroot, nllocout, phasef, - ttpat) + nll.modify_inputs(ctrf, nllocroot, nllocout, phasef, + ttpat) # locate the event nll.locate(ctrfile) @@ -202,13 +202,9 @@ def autoPyLoT(inputfile): # write phase files for various location routines # HYPO71 hypo71file = '%s/autoPyLoT_HYPO71.pha' % event - if hasattr(finalpicks, 'getpicdic'): - if finalpicks.getpicdic() is not None: - hsat.export(finalpicks.getpicdic(), hypo71file) - data.applyEVTData(finalpicks.getpicdic()) - else: - hsat.export(picks, hypo71file) - data.applyEVTData(picks) + if hasattr(finalpicks, 'getpicdic') and finalpicks.getpicdic() is not None: + hsat.export(finalpicks.getpicdic(), hypo71file) + data.applyEVTData(finalpicks.getpicdic()) else: hsat.export(picks, hypo71file) data.applyEVTData(picks) @@ -243,7 +239,7 @@ def autoPyLoT(inputfile): # For locating the event the NLLoc-control file has to be modified! nllocout = '%s_%s' % (parameter.get('eventID'), nllocoutpatter) # create comment line for NLLoc-control file - nll.modifyInputFile(ctrf, nllocroot, nllocout, phasef, ttpat) + nll.modify_inputs(ctrf, nllocroot, nllocout, phasef, ttpat) # locate the event nll.locate(ctrfile) @@ -323,13 +319,9 @@ def autoPyLoT(inputfile): # write phase files for various location routines # HYPO71 hypo71file = '%s/%s/autoPyLoT_HYPO71.pha' % (datapath, parameter.get('eventID')) - if hasattr(finalpicks, 'getpicdic'): - if finalpicks.getpicdic() is not None: - hsat.export(finalpicks.getpicdic(), hypo71file) - data.applyEVTData(finalpicks.getpicdic()) - else: - hsat.export(picks, hypo71file) - data.applyEVTData(picks) + if hasattr(finalpicks, 'getpicdic') and finalpicks.getpicdic() is not None: + hsat.export(finalpicks.getpicdic(), hypo71file) + data.applyEVTData(finalpicks.getpicdic()) else: hsat.export(picks, hypo71file) data.applyEVTData(picks) diff --git a/pylot/core/loc/nll.py b/pylot/core/loc/nll.py index 96a2b007..0ff8e2da 100644 --- a/pylot/core/loc/nll.py +++ b/pylot/core/loc/nll.py @@ -28,7 +28,7 @@ def export(picks, fnout): writephases(picks, 'NLLoc', fnout) -def modifyInputFile(ctrfn, root, nllocoutn, phasefn, tttn): +def modify_inputs(ctrfn, root, nllocoutn, phasefn, tttn): ''' :param ctrfn: name of NLLoc-control file :type: str @@ -82,7 +82,7 @@ def locate(fnin): try: runProgram(exe_path, fnin) except subprocess.CalledProcessError as e: - print(e.output) + raise RuntimeError(e.output) def readLocation(fn): From 30ccd331d48846a3396a93d687756556a5c4c146 Mon Sep 17 00:00:00 2001 From: Sebastian Wehling-Benatelli Date: Fri, 26 Aug 2016 10:48:16 +0200 Subject: [PATCH 3/6] [refs #137] bugfix in widgets.py badly formatted string corrupted load of settings; added a functionality to utils' which function to also look for NLLoc installation in the settings' binary path --- QtPyLoT.py | 9 +++++---- pylot/core/util/utils.py | 10 +++++++++- pylot/core/util/widgets.py | 8 ++++---- 3 files changed, 18 insertions(+), 9 deletions(-) diff --git a/QtPyLoT.py b/QtPyLoT.py index cd375089..9e04d8e4 100755 --- a/QtPyLoT.py +++ b/QtPyLoT.py @@ -904,15 +904,16 @@ class MainWindow(QMainWindow): lt = locateTool[loctool] # get working directory locroot = settings.value("{0}/rootPath".format(loctool), None) + if locroot is None: + self.PyLoTprefs() + self.locateEvent() infile = settings.value("{0}/inputFile".format(loctool), None) outfile = settings.value("{0}/outputFile".format(loctool), None) phasepath = os.tempnam(os.path.join(locroot, 'obs'), loctool) + phasefile = os.path.split(phasepath)[-1] locpath = os.path.join(locroot, 'loc', outfile) lt.export(self.getPicks(), phasepath) - phasefile = os.path.split(phasepath)[-1] - args = lt.modify_inputs(infile, locroot, outfile, phasefile, ) - if locroot is None: - self.PyLoTprefs() + lt.modify_inputs(infile, locroot, outfile, phasefile, ) try: lt.locate(infile) except RuntimeError as e: diff --git a/pylot/core/util/utils.py b/pylot/core/util/utils.py index 1eb2a6d6..8aafbd9b 100644 --- a/pylot/core/util/utils.py +++ b/pylot/core/util/utils.py @@ -407,10 +407,18 @@ def runProgram(cmd, parameter=None): def which(program): """ takes a program name and returns the full path to the executable or None - found on: http://stackoverflow.com/questions/377017/test-if-executable-exists-in-python + modified after: http://stackoverflow.com/questions/377017/test-if-executable-exists-in-python :param program: name of the desired external program :return: full path of the executable file """ + try: + from PySide.QtCore import QSettings + settings = QSettings() + for key in settings.allKeys(): + if 'binPath' in key: + os.environ['PATH'] += ':{0}'.format(settings.value(key)) + except ImportError as e: + print(e.message) def is_exe(fpath): return os.path.exists(fpath) and os.access(fpath, os.X_OK) diff --git a/pylot/core/util/widgets.py b/pylot/core/util/widgets.py index 28cc1e85..a1e7f8c4 100644 --- a/pylot/core/util/widgets.py +++ b/pylot/core/util/widgets.py @@ -1337,8 +1337,8 @@ class LocalisationTab(PropTab): self.locToolComboBox.setCurrentIndex(toolind) - curroot = settings.value("%s/rootPath".format(curtool), None) - curbin = settings.value("%s/binPath".format(curtool), None) + curroot = settings.value("{0}/rootPath".format(curtool), None) + curbin = settings.value("{0}/binPath".format(curtool), None) self.rootlabel = QLabel("root directory") self.binlabel = QLabel("bin directory") @@ -1385,8 +1385,8 @@ class LocalisationTab(PropTab): def getValues(self): loctool = self.locToolComboBox.currentText() - values = {"%s/rootPath".format(loctool): self.rootedit.text(), - "%s/binPath".format(loctool): self.binedit.text(), + values = {"{0}/rootPath".format(loctool): self.rootedit.text(), + "{0}/binPath".format(loctool): self.binedit.text(), "loc/tool": loctool} return values From 060bc1d0c8636fe303fbb68d39c6fa07f8e0b8c5 Mon Sep 17 00:00:00 2001 From: Sebastianw Wehling-Benatelli Date: Fri, 26 Aug 2016 14:36:33 +0200 Subject: [PATCH 4/6] [refs #137] bugfix value now is specified by user on demand --- QtPyLoT.py | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/QtPyLoT.py b/QtPyLoT.py index 9e04d8e4..41fdf523 100755 --- a/QtPyLoT.py +++ b/QtPyLoT.py @@ -907,10 +907,21 @@ class MainWindow(QMainWindow): if locroot is None: self.PyLoTprefs() self.locateEvent() + infile = settings.value("{0}/inputFile".format(loctool), None) + + 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) + infile = ans[0] + settings.setValue("{0}/inputFile".format(loctool), infile) + settings.sync() outfile = settings.value("{0}/outputFile".format(loctool), None) - phasepath = os.tempnam(os.path.join(locroot, 'obs'), loctool) - phasefile = os.path.split(phasepath)[-1] + phasefile = os.path.split(os.tempnam())[-1] + phasepath = os.path.join(locroot, 'obs', phasefile) locpath = os.path.join(locroot, 'loc', outfile) lt.export(self.getPicks(), phasepath) lt.modify_inputs(infile, locroot, outfile, phasefile, ) From ad91504211480b4ec6a057ccc8e6f264f34bea1e Mon Sep 17 00:00:00 2001 From: Sebastianw Wehling-Benatelli Date: Mon, 29 Aug 2016 15:52:58 +0200 Subject: [PATCH 5/6] [ref #137] removing last bugs before closing feature --- QtPyLoT.py | 18 +++++++++++++++--- pylot/core/io/phases.py | 30 +++++++++++++++++++----------- pylot/core/loc/nll.py | 8 +++++++- 3 files changed, 41 insertions(+), 15 deletions(-) diff --git a/QtPyLoT.py b/QtPyLoT.py index 41fdf523..689e6988 100755 --- a/QtPyLoT.py +++ b/QtPyLoT.py @@ -35,7 +35,7 @@ from PySide.QtCore import QCoreApplication, QSettings, Signal, QFile, \ from PySide.QtGui import QMainWindow, QInputDialog, QIcon, QFileDialog, \ QWidget, QHBoxLayout, QStyle, QKeySequence, QLabel, QFrame, QAction, \ QDialog, QErrorMessage, QApplication, QPixmap, QMessageBox, QSplashScreen, \ - QActionGroup, QListWidget, QDockWidget + QActionGroup, QListWidget, QDockWidget, QLineEdit import numpy as np import subprocess from obspy import UTCDateTime @@ -919,12 +919,24 @@ class MainWindow(QMainWindow): infile = ans[0] settings.setValue("{0}/inputFile".format(loctool), infile) settings.sync() - outfile = settings.value("{0}/outputFile".format(loctool), None) + 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]) phasefile = os.path.split(os.tempnam())[-1] phasepath = os.path.join(locroot, 'obs', phasefile) locpath = os.path.join(locroot, 'loc', outfile) lt.export(self.getPicks(), phasepath) - lt.modify_inputs(infile, locroot, outfile, phasefile, ) + lt.modify_inputs(infile, locroot, outfile, phasefile, ttt) try: lt.locate(infile) except RuntimeError as e: diff --git a/pylot/core/io/phases.py b/pylot/core/io/phases.py index 60d4d180..0de1d40a 100644 --- a/pylot/core/io/phases.py +++ b/pylot/core/io/phases.py @@ -117,7 +117,7 @@ def picksdict_from_pilot(fn): except IndexError as e: print(e.message + '\ntake two times the largest default error value') spe = timeerrors[onset_name][-1] * 2 - phases[onset_name] = dict(mpp=pick, spe=spe) + phases[onset_name] = dict(mpp=pick, spe=spe, weight=ierror) picks[station] = phases return picks @@ -395,7 +395,11 @@ def writephases(arrivals, fformat, filename): for key in arrivals: # P onsets if arrivals[key]['P']: - fm = arrivals[key]['P']['fm'] + try: + fm = arrivals[key]['P']['fm'] + except KeyError as e: + print(e) + fm = None if fm == None: fm = '?' onset = arrivals[key]['P']['mpp'] @@ -407,10 +411,12 @@ def writephases(arrivals, fformat, filename): ss = onset.second ms = onset.microsecond ss_ms = ss + ms / 1000000.0 - if arrivals[key]['P']['weight'] < 4: - pweight = 1 # use pick - else: - pweight = 0 # do not use pick + pweight = 1 # use pick + try: + if arrivals[key]['P']['weight'] >= 4: + pweight = 0 # do not use pick + except KeyError as e: + print(e.message + '; no weight set during processing') fid.write('%s ? ? ? P %s %d%02d%02d %02d%02d %7.4f GAU 0 0 0 0 %d \n' % (key, fm, year, @@ -421,7 +427,7 @@ def writephases(arrivals, fformat, filename): ss_ms, pweight)) # S onsets - if arrivals[key]['S']: + if arrivals[key].has_key('S') and arrivals[key]['S']: fm = '?' onset = arrivals[key]['S']['mpp'] year = onset.year @@ -432,10 +438,12 @@ def writephases(arrivals, fformat, filename): ss = onset.second ms = onset.microsecond ss_ms = ss + ms / 1000000.0 - if arrivals[key]['S']['weight'] < 4: - sweight = 1 # use pick - else: - sweight = 0 # do not use pick + sweight = 1 # use pick + try: + if arrivals[key]['S']['weight'] >= 4: + sweight = 0 # do not use pick + except KeyError as e: + print(str(e) + '; no weight set during processing') fid.write('%s ? ? ? S %s %d%02d%02d %02d%02d %7.4f GAU 0 0 0 0 %d \n' % (key, fm, year, diff --git a/pylot/core/loc/nll.py b/pylot/core/loc/nll.py index 0ff8e2da..5cc0c647 100644 --- a/pylot/core/loc/nll.py +++ b/pylot/core/loc/nll.py @@ -3,6 +3,7 @@ import subprocess import os +import glob from obspy import read_events from pylot.core.io.phases import writephases from pylot.core.util.utils import getPatternLine, runProgram, which @@ -85,7 +86,12 @@ def locate(fnin): raise RuntimeError(e.output) -def readLocation(fn): +def read_location(fn): + path, file = os.path.split(fn) + file = glob.glob1(path, file + '.[0-9]*.grid0.loc.hyp') + if len(file) > 1: + raise IOError('ambiguous location name {0}'.format(file)) + fn = os.path.join(path, file[0]) return read_events(fn) From 280e954cac0919c77aa348ead2af588071a4a15c Mon Sep 17 00:00:00 2001 From: Sebastianw Wehling-Benatelli Date: Tue, 30 Aug 2016 14:53:58 +0200 Subject: [PATCH 6/6] [closes #137] location out of QtPyLoT now possible --- pylot/core/io/data.py | 21 ++++++++++----------- pylot/core/loc/nll.py | 2 +- 2 files changed, 11 insertions(+), 12 deletions(-) diff --git a/pylot/core/io/data.py b/pylot/core/io/data.py index 71c6371e..1f4a6008 100644 --- a/pylot/core/io/data.py +++ b/pylot/core/io/data.py @@ -1,6 +1,7 @@ #!/usr/bin/env python # -*- coding: utf-8 -*- +import copy import glob import os from obspy import read_events, read_inventory @@ -434,7 +435,8 @@ class Data(object): #firstonset = find_firstonset(picks) if self.getEvtData().picks: raise OverwriteError('Actual picks would be overwritten!') - picks = picks_from_picksdict(picks) + else: + picks = picks_from_picksdict(picks) self.getEvtData().picks = picks # if 'smi:local' in self.getID() and firstonset: # fonset_str = firstonset.strftime('%Y_%m_%d_%H_%M_%S') @@ -443,25 +445,22 @@ class Data(object): # self.getEvtData().resource_id = ID - def applyArrivals(arrivals): - """ - - :param arrivals: - """ - pass - def applyEvent(event): """ - + takes an `obspy.core.event.Event` object and applies all new + information on the event to the actual data :param event: """ if not self.isNew(): self.setEvtData(event) else: - raise OverwriteError('Acutal event would be overwritten!') + # prevent overwriting uncertainty information + picks = copy.deepcopy(self.getEvtData().picks) + event.picks = picks + # apply event information from location + self.getEvtData().update(event) applydata = {'pick': applyPicks, - 'arrival': applyArrivals, 'event': applyEvent} applydata[type](data) diff --git a/pylot/core/loc/nll.py b/pylot/core/loc/nll.py index 5cc0c647..f9b36e76 100644 --- a/pylot/core/loc/nll.py +++ b/pylot/core/loc/nll.py @@ -92,7 +92,7 @@ def read_location(fn): if len(file) > 1: raise IOError('ambiguous location name {0}'.format(file)) fn = os.path.join(path, file[0]) - return read_events(fn) + return read_events(fn)[0] if __name__ == '__main__':