diff --git a/autoPyLoT.py b/autoPyLoT.py index 6a89a660..27e45841 100755 --- a/autoPyLoT.py +++ b/autoPyLoT.py @@ -133,14 +133,32 @@ def autoPyLoT(inputfile): else: # get theoretical P-onset times from NLLoc-location file locsearch = '%s/loc/%s.????????.??????.grid?.loc.hyp' % (nllocroot, nllocout) - # get latest file if several are available - nllocfile = max(glob.glob(locsearch), key=os.path.getctime) - if os.path.isfile(nllocfile): - picks = iteratepicker(wfdat, nllocfile, picks, badpicks, parameter) - # write phases to NLLoc-phase file - picksExport(picks, 'NLLoc', phasefile) - # locate the event - locate(nlloccall, ctrfile) + maxnumit = 3 # maximum number of iterations + if len(glob.glob(locsearch)) > 0: + # get latest file if several are available + nllocfile = max(glob.glob(locsearch), key=os.path.getctime) + nlloccounter = 0 + while len(badpicks) > 0 and nlloccounter <= maxnumit: + nlloccounter += 1 + if nlloccounter > maxnumit: + print("autoPyLoT: Number of maximum iterations reached, stop iterative picking!") + break + 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) + # locate the event + locate(nlloccall, ctrfile) + print("autoPyLoT: Iteration No. %d finished." % nlloccounter) + badpicks = [] + for key in picks: + if picks[key]['P']['weight'] >= 4 or picks[key]['S']['weight'] >= 4: + badpicks.append([key, picks[key]['P']['mpp']]) + print("autoPyLoT: After iteration No. %d: %d bad onsets found ..." % (nlloccounter, \ + len(badpicks))) + if len(badpicks) == 0: + print("autoPyLoT: No more bad onsets found, stop iterative picking!") + break else: print("autoPyLoT: No NLLoc-location file available! Stop iteration!") ########################################################## @@ -195,14 +213,33 @@ def autoPyLoT(inputfile): else: # get theoretical P-onset times from NLLoc-location file locsearch = '%s/loc/%s.????????.??????.grid?.loc.hyp' % (nllocroot, nllocout) - # get latest file if several are available nllocfile = max(glob.glob(locsearch), key=os.path.getctime) - if os.path.isfile(nllocfile): - picks = iteratepicker(wfdat, nllocfile, picks, badpicks, parameter) - # write phases to NLLoc-phase file - picksExport(picks, 'NLLoc', phasefile) - # locate the event - locate(nlloccall, ctrfile) + maxnumit = 3 # maximum number of iterations + if len(glob.glob(locsearch)) > 0: + # get latest file if several are available + nllocfile = max(glob.glob(locsearch), key=os.path.getctime) + nlloccounter = 0 + while len(badpicks) > 0 and nlloccounter <= maxnumit: + nlloccounter += 1 + if nlloccounter > maxnumit: + print("autoPyLoT: Number of maximum iterations reached, stop iterative picking!") + break + 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) + # locate the event + locate(nlloccall, ctrfile) + print("autoPyLoT: Iteration No. %d finished." % nlloccounter) + badpicks = [] + for key in picks: + if picks[key]['P']['weight'] >= 4 or picks[key]['S']['weight'] >= 4: + badpicks.append([key, picks[key]['P']['mpp']]) + print("autoPyLoT: After iteration No. %d: %d bad onsets found ..." % (nlloccounter, \ + len(badpicks))) + if len(badpicks) == 0: + print("autoPyLoT: No more bad onsets found, stop iterative picking!") + break else: print("autoPyLoT: No NLLoc-location file available! Stop iteration!") ########################################################## diff --git a/autoPyLoT_local.in b/autoPyLoT_local.in index 93e56f16..7206954d 100644 --- a/autoPyLoT_local.in +++ b/autoPyLoT_local.in @@ -6,8 +6,8 @@ #main settings# /DATA/Insheim #rootpath# %project path EVENT_DATA/LOCAL #datapath# %data path -2013.02_Insheim #database# %name of data base -e0019.048.13 #eventID# %event ID for single event processing +2015.10_Insheim #database# %name of data base +e0011.280.15 #eventID# %event ID for single event processing /DATA/Insheim/STAT_INFO #invdir# %full path to inventory or dataless-seed file PILOT #datastructure#%choose data structure 0 #iplot# %flag for plotting: 0 none, 1 partly, >1 everything @@ -39,10 +39,10 @@ AUTOFOCMEC_AIC_HOS4_ARH.in #focmecin# %name of focmec input file co 300 #Qp# %quality factor for P waves 100 #Qs# %quality factor for S waves #common settings picker# -15 #pstart# %start time [s] for calculating CF for P-picking -60 #pstop# %end time [s] for calculating CF for P-picking +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 #sstop# %end time [s] after P-onset for calculating CF for S-picking +12.0 #sstop# %end time [s] after P-onset for calculating CF for S-picking 2 20 #bpz1# %lower/upper corner freq. of first band pass filter Z-comp. [Hz] 2 30 #bpz2# %lower/upper corner freq. of second band pass filter Z-comp. [Hz] 2 15 #bph1# %lower/upper corner freq. of first band pass filter H-comp. [Hz] @@ -95,8 +95,8 @@ ARH #algoS# %choose algorithm for S-onset 3 #minAICSslope# %below this slope [counts/s] the initial S pick is rejected 1.5 #minAICSSNR# %below this SNR the initial S pick is rejected #check duration of signal using envelope function# -5 #minsiglength# %minimum required length of signal [s] -1.8 #noisefactor# %noiselevel*noisefactor=threshold +4 #minsiglength# %minimum required length of signal [s] +1.5 #noisefactor# %noiselevel*noisefactor=threshold 50 #minpercent# %required percentage of samples higher than threshold #check for spuriously picked S-onsets# 2.0 #zfac# %P-amplitude must exceed at least zfac times RMS-S amplitude diff --git a/pylot/core/pick/autopick.py b/pylot/core/pick/autopick.py index be31c183..4d693e3a 100755 --- a/pylot/core/pick/autopick.py +++ b/pylot/core/pick/autopick.py @@ -800,6 +800,7 @@ def autopickstation(wfstream, pickparam): return picks + def iteratepicker(wf, NLLocfile, picks, badpicks, pickparameter): ''' Repicking of bad onsets. Uses theoretical onset times from NLLoc-location file. @@ -816,8 +817,8 @@ def iteratepicker(wf, NLLocfile, picks, badpicks, pickparameter): ''' print("#######################################################") - print("autoPyLoT: Found bad onsets at station(s) %s, starting re-picking them ...") \ - % badpicks + print("autoPyLoT: Found %d bad onsets at station(s) %s, starting re-picking them ...") \ + % (len(badpicks), badpicks) newpicks = {} for i in range(0, len(badpicks)): @@ -838,32 +839,44 @@ def iteratepicker(wf, NLLocfile, picks, badpicks, pickparameter): # modify some picking parameters pstart_old = pickparameter.getParam('pstart') pstop_old = pickparameter.getParam('pstop') + sstop_old = pickparameter.getParam('sstop') pickwinP_old = pickparameter.getParam('pickwinP') Precalcwin_old = pickparameter.getParam('Precalcwin') + noisefactor_old = pickparameter.getParam('noisefactor') + zfac_old = pickparameter.getParam('zfac') pickparameter.setParam(pstart=badpicks[i][1] - wf2pick[0].stats.starttime \ - pickparameter.getParam('tlta')) pickparameter.setParam(pstop=pickparameter.getParam('pstart') + \ (3 * pickparameter.getParam('tlta'))) + pickparameter.setParam(sstop=pickparameter.getParam('sstop') / 2) pickparameter.setParam(pickwinP=pickparameter.getParam('pickwinP') / 2) pickparameter.setParam(Precalcwin=pickparameter.getParam('Precalcwin') / 2) + pickparameter.setParam(noisefactor=1.0) + pickparameter.setParam(zfac=1.0) print("iteratepicker: The following picking parameters have been modified for iterative picking:") print("pstart: %fs => %fs" % (pstart_old, pickparameter.getParam('pstart'))) print("pstop: %fs => %fs" % (pstop_old, pickparameter.getParam('pstop'))) + print("sstop: %fs => %fs" % (sstop_old, pickparameter.getParam('sstop'))) print("pickwinP: %fs => %fs" % (pickwinP_old, pickparameter.getParam('pickwinP'))) print("Precalcwin: %fs => %fs" % (Precalcwin_old, pickparameter.getParam('Precalcwin'))) - + print("noisefactor: %f => %f" % (noisefactor_old, pickparameter.getParam('noisefactor'))) + print("zfac: %f => %f" % (zfac_old, pickparameter.getParam('zfac'))) + # repick station newpicks = autopickstation(wf2pick, pickparameter) # replace old dictionary with new one picks[badpicks[i][0]] = newpicks - # reset temporary change of picking parameters - print("iteratepicker: Resetting picking parameters ...") - pickparameter.setParam(pstart=pstart_old) - pickparameter.setParam(pstop=pstop_old) - pickparameter.setParam(pickwinP=pickwinP_old) - pickparameter.setParam(Precalcwin=Precalcwin_old) + # reset temporary change of picking parameters + print("iteratepicker: Resetting picking parameters ...") + pickparameter.setParam(pstart=pstart_old) + pickparameter.setParam(pstop=pstop_old) + pickparameter.setParam(sstop=sstop_old) + pickparameter.setParam(pickwinP=pickwinP_old) + pickparameter.setParam(Precalcwin=Precalcwin_old) + pickparameter.setParam(noisefactor=noisefactor_old) + pickparameter.setParam(zfac=zfac_old) return picks diff --git a/pylot/core/util/widgets.py b/pylot/core/util/widgets.py index 307b7e39..16731ef3 100644 --- a/pylot/core/util/widgets.py +++ b/pylot/core/util/widgets.py @@ -18,7 +18,7 @@ from matplotlib.widgets import MultiCursor from PySide.QtGui import QAction, QApplication, QComboBox, QDateTimeEdit, \ QDialog, QDialogButtonBox, QDoubleSpinBox, QGroupBox, QGridLayout, \ QIcon, QKeySequence, QLabel, QLineEdit, QMessageBox, QPixmap, QSpinBox, \ - QTabWidget, QToolBar, QVBoxLayout, QWidget + QTabWidget, QToolBar, QVBoxLayout, QWidget, QPushButton, QFileDialog from PySide.QtCore import QSettings, Qt, QUrl, Signal, Slot from PySide.QtWebKit import QWebView from obspy import Stream, UTCDateTime @@ -789,6 +789,7 @@ class PropertiesDlg(QDialog): self.tabWidget.addTab(OutputsTab(self), "Outputs") self.tabWidget.addTab(PhasesTab(self), "Phases") self.tabWidget.addTab(GraphicsTab(self), "Graphics") + self.tabWidget.addTab(LocalisationTab(self), "Loc Tools") self.buttonBox = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Apply | QDialogButtonBox.Close) @@ -842,10 +843,14 @@ class InputsTab(PropTab): # get the full name of the actual user self.fullNameEdit = QLineEdit() - self.fullNameEdit.setText(fulluser) + try: + self.fullNameEdit.setText(fulluser) + except TypeError as e: + self.fullNameEdit.setText(fulluser[0]) # information about data structure dataroot = settings.value("data/dataRoot") + curstructure = settings.value("data/Structure") dataDirLabel = QLabel("data root directory: ") self.dataDirEdit = QLineEdit() self.dataDirEdit.setText(dataroot) @@ -857,6 +862,10 @@ class InputsTab(PropTab): self.structureSelect.addItems(DATASTRUCTURE.keys()) + dsind = findComboBoxIndex(self.structureSelect, curstructure) + + self.structureSelect.setCurrentIndex(dsind) + layout = QGridLayout() layout.addWidget(dataDirLabel, 0, 0) layout.addWidget(self.dataDirEdit, 0, 1) @@ -929,14 +938,60 @@ class LocalisationTab(PropTab): toolind = findComboBoxIndex(self.locToolComboBox, curtool) self.locToolComboBox.setCurrentIndex(toolind) - - curroot = settings.value("loc/tool", None) + curroot = settings.value("%s/rootPath".format(curtool), None) + curbin = settings.value("%s/binPath".format(curtool), None) + + self.rootlabel = QLabel("root directory") + self.binlabel = QLabel("bin directory") + + self.rootedit = QLineEdit('') + self.binedit = QLineEdit('') + + if curroot is not None: + self.rootedit.setText(curroot) + if curbin is not None: + self.binedit.setText(curbin) + + rootBrowse = QPushButton('...', self) + rootBrowse.clicked.connect(lambda: self.selectDirectory(self.rootedit)) + + binBrowse = QPushButton('...', self) + binBrowse.clicked.connect(lambda: self.selectDirectory(self.binedit)) + + self.locToolComboBox.currentIndexChanged.connect(self.updateUi) + + self.updateUi() + + layout = QGridLayout() + layout.addWidget(loctoollabel, 0, 0) + layout.addWidget(self.locToolComboBox, 0, 1) + layout.addWidget(self.rootlabel, 1, 0) + layout.addWidget(self.rootedit, 1, 1) + layout.addWidget(rootBrowse, 1, 2) + layout.addWidget(self.binlabel, 2, 0) + layout.addWidget(self.binedit, 2, 1) + layout.addWidget(binBrowse, 2, 2) + + self.setLayout(layout) + + def updateUi(self): + curtool = self.locToolComboBox.currentText() if curtool is not None: - rootlabel = QLabel("{0} root dircetory".format(curtool)) - else: - rootlabel = QLabel("root dircetory") - rootlabel.setDisabled() + self.rootlabel.setText("{0} root directory".format(curtool)) + self.binlabel.setText("{0} bin directory".format(curtool)) + + def selectDirectory(self, edit): + selected_directory = QFileDialog.getExistingDirectory() + edit.setText(selected_directory) + + def getValues(self): + loctool = self.locToolComboBox.currentText() + values = {"%s/rootPath".format(loctool): self.rootedit.text(), + "%s/binPath".format(loctool): self.binedit.text(), + "loc/tool": loctool} + return values + class NewEventDlg(QDialog):