From 158da885239c90944acafeef4cf67a071dfa39b9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ludger=20K=C3=BCperkoch?= Date: Mon, 26 Oct 2015 09:40:07 +0100 Subject: [PATCH 01/21] Marginal changes only. --- pylot/core/analysis/magnitude.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/pylot/core/analysis/magnitude.py b/pylot/core/analysis/magnitude.py index 9d24392e..ab49bf86 100644 --- a/pylot/core/analysis/magnitude.py +++ b/pylot/core/analysis/magnitude.py @@ -188,7 +188,9 @@ class DCfc(Magnitude): "Determined corner frequency: %f Hz" % (self.w0, self.fc)) - if self.getiplot() > 1: + #if self.getiplot() > 1: + iplot=2 + if iplot > 1: f1 = plt.figure() plt.subplot(2,1,1) # show displacement in mm From 69a023e04842a6d331799c01e6ee2b6a4c23383a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ludger=20K=C3=BCperkoch?= Date: Mon, 26 Oct 2015 09:41:02 +0100 Subject: [PATCH 02/21] Introduced new function for writing phases files for various kinds of location tools. --- pylot/core/pick/utils.py | 46 ++++++++++++++++++++++++++++++++++++++-- 1 file changed, 44 insertions(+), 2 deletions(-) diff --git a/pylot/core/pick/utils.py b/pylot/core/pick/utils.py index 16fd2cec..233bb70d 100644 --- a/pylot/core/pick/utils.py +++ b/pylot/core/pick/utils.py @@ -7,7 +7,7 @@ :author: Ludger Kueperkoch / MAGS2 EP3 working group """ - +import pdb import numpy as np import matplotlib.pyplot as plt from obspy.core import Stream, UTCDateTime @@ -74,7 +74,7 @@ def earllatepicker(X, nfac, TSNR, Pick1, iplot=None): # if EPick stays NaN the signal window size will be doubled while np.isnan(EPick): if count > 0: - print("\nearllatepicker: Doubled signal window size %s time(s) " + print("earllatepicker: Doubled signal window size %s time(s) " "because of NaN for earliest pick." %count) isigDoubleWinStart = pis[-1] + 1 isignalDoubleWin = np.arange(isigDoubleWinStart, @@ -928,6 +928,48 @@ def checkZ4S(X, pick, zfac, checkwin, iplot): return returnflag + +def writephases(arrivals, fformat, filename): + ''' + Function of methods to write phases to the following standard file + formats used for locating earthquakes: + + HYPO71, NLLoc, VELEST, HYPOSAT, HYPOINVERSE and hypoDD + + :param: arrivals + :type: dictionary containing all phase information including + station ID, phase, first motion, weight (uncertainty), + .... + + :param: fformat + :type: string, chosen file format (location routine), + choose between NLLoc, HYPO71, HYPOSAT, VELEST, + HYPOINVERSE, and hypoDD + + :param: filename, full path and name of phase file + :type: string + ''' + + + if fformat == 'NLLoc': + print ("Writing phases to %s for NLLoc" % filename) + fid = open("%s" % filename, 'w') + # write header + fid.write('# EQEVENT: Label: EQ001 Loc: X 0.00 Y 0.00 Z 10.00 OT 0.00 \n') + for key in arrivals: + if arrivals[key]['P']['weight'] < 4: + # NLLoc only knows weight 0 (do not use pick) + # and weight 1 (use pick) + NLLocweight = 1 + # write phase information to file + fid.write('%s \n' % key) + + fid.close() + + + + + if __name__ == '__main__': import doctest doctest.testmod() From b96f81553d49ba0e935b72e9b8263fdcef7e621b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ludger=20K=C3=BCperkoch?= Date: Mon, 26 Oct 2015 09:42:25 +0100 Subject: [PATCH 03/21] Implemented new function for writing phase files for various kinds of location tools. --- autoPyLoT.py | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/autoPyLoT.py b/autoPyLoT.py index 3084f1ad..767881af 100755 --- a/autoPyLoT.py +++ b/autoPyLoT.py @@ -13,6 +13,7 @@ from pylot.core.read.data import Data from pylot.core.read.inputs import AutoPickParameter from pylot.core.util.structure import DATASTRUCTURE from pylot.core.pick.autopick import autopickevent +from pylot.core.pick.utils import writephases __version__ = _getVersionString() @@ -85,6 +86,9 @@ def autoPyLoT(inputfile): # !automated picking starts here! picks = autopickevent(wfdat, parameter) + # write phases to NLLoc-phase file + writephases(wd_checked_onsets, 'NLLoc', phasefile) + print '------------------------------------------' print '-----Finished event %s!-----' % event print '------------------------------------------' @@ -100,6 +104,9 @@ def autoPyLoT(inputfile): # !automated picking starts here! picks = autopickevent(wfdat, parameter) + # write phases to NLLoc-phase file + writephases(wd_checked_onsets, 'NLLoc', phasefile) + print '------------------------------------------' print '-------Finished event %s!-------' % parameter.getParam('eventID') print '------------------------------------------' From 7029c0b5761acafba3230c14bfacf8431c7bab56 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ludger=20K=C3=BCperkoch?= Date: Tue, 27 Oct 2015 10:00:16 +0100 Subject: [PATCH 04/21] Implemted writephases.py. --- autoPyLoT.py | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/autoPyLoT.py b/autoPyLoT.py index af61bcb1..3fd83257 100755 --- a/autoPyLoT.py +++ b/autoPyLoT.py @@ -12,6 +12,7 @@ from pylot.core.read.data import Data from pylot.core.read.inputs import AutoPickParameter from pylot.core.util.structure import DATASTRUCTURE from pylot.core.pick.autopick import autopickevent +from pylot.core.pick.utils import writephases from pylot.core.util.version import get_git_version as _getVersionString __version__ = _getVersionString() @@ -70,6 +71,13 @@ def autoPyLoT(inputfile): # get path to inventory or dataless-seed file with station meta data invdir = parameter.getParam('invdir') + # get path and name of phase file + phasefile = parameter.getParam('phasefile') + # get path and name of NLLoc-control file + locfile = parameter.getparam('locfile') + # path and pattern of NLLoc ttimes from location grid + ttpattern = parameter.getparam('ttpattern') + # multiple event processing # read each event in database @@ -85,6 +93,9 @@ def autoPyLoT(inputfile): # !automated picking starts here! picks = autopickevent(wfdat, parameter) + # write phases to NLLoc-phase file + writephases(picks, 'NLLoc', phasefile) + print '------------------------------------------' print '-----Finished event %s!-----' % event print '------------------------------------------' @@ -99,6 +110,13 @@ def autoPyLoT(inputfile): ########################################################## # !automated picking starts here! picks = autopickevent(wfdat, parameter) + + # write phases to NLLoc-phase file + writephases(picks, 'NLLoc', phasefile) + + # create comment line for NLLoc-control file + locfiles = printf('LOCFILES %s NLLOC_OBS %s %s 0' % (phasefile, ttpattern, NLLocoutfile)) + print '------------------------------------------' print '-------Finished event %s!-------' % parameter.getParam('eventID') From a3153844174184b386f216be8bea7a0d3344c047 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ludger=20K=C3=BCperkoch?= Date: Tue, 27 Oct 2015 10:01:07 +0100 Subject: [PATCH 05/21] New function writephases.py for writing phases files for various kinds of location routines. Started with NLLoc-phase file. --- pylot/core/pick/utils.py | 43 +++++++++++++++++++++++++++++++++++----- 1 file changed, 38 insertions(+), 5 deletions(-) diff --git a/pylot/core/pick/utils.py b/pylot/core/pick/utils.py index 9feabbb8..34b0c207 100644 --- a/pylot/core/pick/utils.py +++ b/pylot/core/pick/utils.py @@ -961,11 +961,44 @@ def writephases(arrivals, fformat, filename): fid.write('# EQEVENT: Label: EQ001 Loc: X 0.00 Y 0.00 Z 10.00 OT 0.00 \n') for key in arrivals: if arrivals[key]['P']['weight'] < 4: - # NLLoc only knows weight 0 (do not use pick) - # and weight 1 (use pick) - NLLocweight = 1 - # write phase information to file - fid.write('%s \n' % key) + fm = arrivals[key]['P']['fm'] + onset = arrivals[key]['P']['mpp'] + year = onset.year + month = onset.month + day = onset.day + hh = onset.hour + mm = onset.minute + ss = onset.second + ms = onset.microsecond + ss_ms = ss + ms / 1000000.0 + fid.write('%s ? ? ? P %s %d%02d%02d %02d%02d %7.4f GAU 0 0 0 0 1 \n' % (key, + fm, + year, + month, + day, + hh, + mm, + ss_ms)) + if arrivals[key]['S']['weight'] < 4: + fm = '?' + onset = arrivals[key]['S']['mpp'] + year = onset.year + month = onset.month + day = onset.day + hh = onset.hour + mm = onset.minute + ss = onset.second + ms = onset.microsecond + ss_ms = ss + ms / 1000000.0 + fid.write('%s ? ? ? S %s %d%02d%02d %02d%02d %7.4f GAU 0 0 0 0 1 \n' % (key, + fm, + year, + month, + day, + hh, + mm, + ss_ms)) + fid.close() From 55d3692f33e83b729e90fea82832bc3d824aadb3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ludger=20K=C3=BCperkoch?= Date: Tue, 27 Oct 2015 10:03:40 +0100 Subject: [PATCH 06/21] New parameters phasefile, locfile and ttpattern for auomatic modifying NLLoc-control file. --- autoPyLoT_local.in | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/autoPyLoT_local.in b/autoPyLoT_local.in index 84ae2137..a6fad4f8 100644 --- a/autoPyLoT_local.in +++ b/autoPyLoT_local.in @@ -3,7 +3,6 @@ %and picking are to be set here! %Parameters are optimized for local data sets! %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - #main settings# /DATA/Insheim #rootpath# %project path EVENT_DATA/LOCAL #datapath# %data path @@ -12,10 +11,15 @@ e0019.048.13 #eventID# %event ID for single event pr /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 -AUTOPHASES_AIC_HOS4_ARH #phasefile# %name of autoPILOT output phase file -AUTOLOC_AIC_HOS4_ARH #locfile# %name of autoPILOT output location file +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +#NLLoc settings +/home/ludger/NLLOC/Insheim/obs/AUTOPHASES.obs #phasefile# %name and full path of autoPyLoT-output + %phase file for NLLoc +/home/ludger/NLLOC/Insheim/run/Insheim_min1d2015.in #locfile# %name and full path of autoPyLoT-output + %control file for NLLoc +/home/ludger/NLLOC/Insheim/time/ttime #ttpattern# %path and pattern of NLLOC ttimes from grid +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% AUTOFOCMEC_AIC_HOS4_ARH.in #focmecin# %name of focmec input file containing polarities -HYPOSAT #locrt# %location routine used ("HYPOINVERSE" or "HYPOSAT") 6 #pmin# %minimum required P picks for location 4 #p0min# %minimum required P picks for location if at least %3 excellent P picks are found From f8cbdf7ff03be99a094c6d26a6cc377519ec96d9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ludger=20K=C3=BCperkoch?= Date: Tue, 27 Oct 2015 15:26:25 +0100 Subject: [PATCH 07/21] Implemented location routine NLLoc. --- autoPyLoT.py | 69 +++++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 60 insertions(+), 9 deletions(-) diff --git a/autoPyLoT.py b/autoPyLoT.py index 3fd83257..3d84de3b 100755 --- a/autoPyLoT.py +++ b/autoPyLoT.py @@ -5,8 +5,9 @@ import os import argparse import glob - +import subprocess import matplotlib.pyplot as plt + from obspy.core import read from pylot.core.read.data import Data from pylot.core.read.inputs import AutoPickParameter @@ -71,12 +72,23 @@ def autoPyLoT(inputfile): # get path to inventory or dataless-seed file with station meta data invdir = parameter.getParam('invdir') - # get path and name of phase file - phasefile = parameter.getParam('phasefile') - # get path and name of NLLoc-control file - locfile = parameter.getparam('locfile') - # path and pattern of NLLoc ttimes from location grid - ttpattern = parameter.getparam('ttpattern') + + # get NLLoc-root path + nllocroot = parameter.getParam('nllocroot') + # get path to NLLoc executable + nllocbin = parameter.getParam('nllocbin') + nlloccall = '%s/NLLoc' % nllocbin + # get name of phase file + phasef = parameter.getParam('phasefile') + phasefile = '%s/%s' % (nllocroot, phasef) + # get name of NLLoc-control file + locf = parameter.getParam('locfile') + locfile = '%s/run/%s' % (nllocroot, locf) + # patter of NLLoc ttimes from location grid + ttpat = parameter.getParam('ttpatter') + ttpatter = '%s/time/%s' % (nllocroot, ttpat) + # patter of NLLoc-output file + nllocoutpatter = parameter.getParam('outpatter') # multiple event processing @@ -96,6 +108,27 @@ def autoPyLoT(inputfile): # write phases to NLLoc-phase file writephases(picks, 'NLLoc', phasefile) + ########################################################## + # For locating the events we have to modify the NLLoc-control file! + # create comment line for NLLoc-control file + # NLLoc-output file + nllocout = '%s/loc/%s_%s' % (nllocroot, event, nllocoutpatter) + locfiles = 'LOCFILES %s NLLOC_OBS %s %s 0' % (phasefile, ttpatter, nllocout) + print ("Modifying NLLoc-control file %s ..." % locfile) + # modification of NLLoc-control file + filedata = None + nllfile = open(locfile, 'r') + filedata = nllfile.read() + # replace old command + filedata = filedata.replace('LOCFILES', locfiles) + nllfile = open(locfile, 'w') + nllfile.write(filedata) + nllfile.close() + + # locate the event + subprocess.call([nlloccall, locfile]) + ########################################################## + print '------------------------------------------' print '-----Finished event %s!-----' % event print '------------------------------------------' @@ -114,8 +147,26 @@ def autoPyLoT(inputfile): # write phases to NLLoc-phase file writephases(picks, 'NLLoc', phasefile) - # create comment line for NLLoc-control file - locfiles = printf('LOCFILES %s NLLOC_OBS %s %s 0' % (phasefile, ttpattern, NLLocoutfile)) + ########################################################## + # For locating the events we have to modify the NLLoc-control file! + # create comment line for NLLoc-control file NLLoc-output file + nllocout = '%s/loc/%s_%s' % (nllocroot, parameter.getParam('eventID'), nllocoutpatter) + locfiles = 'LOCFILES %s NLLOC_OBS %s %s 0' % (phasefile, ttpatter, nllocout) + print ("Modifying NLLoc-control file %s ..." % locfile) + # modification of NLLoc-control file + filedata = None + nllfile = open(locfile, 'r') + filedata = nllfile.read() + # replace old command + filedata = filedata.replace('LOCFILES', locfiles) + nllfile = open(locfile, 'w') + nllfile.write(filedata) + nllfile.close() + + # locate the event + subprocess.call([nlloccall, locfile]) + ########################################################## + print '------------------------------------------' From fbaaac843523512379037a6bcdef5c61635ad9aa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ludger=20K=C3=BCperkoch?= Date: Tue, 27 Oct 2015 15:26:55 +0100 Subject: [PATCH 08/21] New parameters for default location routine NLLoc. --- autoPyLoT_local.in | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/autoPyLoT_local.in b/autoPyLoT_local.in index a6fad4f8..0ec8e105 100644 --- a/autoPyLoT_local.in +++ b/autoPyLoT_local.in @@ -13,11 +13,16 @@ PILOT #datastructure# %choose data structure 0 #iplot# %flag for plotting: 0 none, 1, partly, >1 everything %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% #NLLoc settings -/home/ludger/NLLOC/Insheim/obs/AUTOPHASES.obs #phasefile# %name and full path of autoPyLoT-output - %phase file for NLLoc -/home/ludger/NLLOC/Insheim/run/Insheim_min1d2015.in #locfile# %name and full path of autoPyLoT-output - %control file for NLLoc -/home/ludger/NLLOC/Insheim/time/ttime #ttpattern# %path and pattern of NLLOC ttimes from grid +/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 + %(in nllocroot/obs) +Insheim_min1d2015.in #locfile# %name of autoPyLoT-output control file for NLLoc + %(in nllocroot/run) +ttime #ttpatter# %patter of NLLoc ttimes from grid + %(in nllocroot/times) +AUTOLOC_nlloc #outpatter# %patter of NLLoc-output file + %(returns e.g. 'eventID_outpatter') %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% AUTOFOCMEC_AIC_HOS4_ARH.in #focmecin# %name of focmec input file containing polarities 6 #pmin# %minimum required P picks for location From f13dda9a0f41aab607b76881b3b5ae2d45d50c4a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ludger=20K=C3=BCperkoch?= Date: Tue, 27 Oct 2015 15:50:37 +0100 Subject: [PATCH 09/21] Cosmetics. --- autoPyLoT_local.in | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/autoPyLoT_local.in b/autoPyLoT_local.in index 0ec8e105..ae4556c0 100644 --- a/autoPyLoT_local.in +++ b/autoPyLoT_local.in @@ -19,10 +19,10 @@ AUTOPHASES.obs #phasefile# %name of autoPyLoT-output pha %(in nllocroot/obs) Insheim_min1d2015.in #locfile# %name of autoPyLoT-output control file for NLLoc %(in nllocroot/run) -ttime #ttpatter# %patter of NLLoc ttimes from grid +ttime #ttpatter# %pattern of NLLoc ttimes from grid %(in nllocroot/times) -AUTOLOC_nlloc #outpatter# %patter of NLLoc-output file - %(returns e.g. 'eventID_outpatter') +AUTOLOC_nlloc #outpatter# %pattern of NLLoc-output file + %(returns 'eventID_outpatter') %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% AUTOFOCMEC_AIC_HOS4_ARH.in #focmecin# %name of focmec input file containing polarities 6 #pmin# %minimum required P picks for location From d5b3a7d40f7699cd337f741eb954e4cc5ea3021b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ludger=20K=C3=BCperkoch?= Date: Tue, 27 Oct 2015 16:26:40 +0100 Subject: [PATCH 10/21] Marginal changes. --- autoPyLoT.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/autoPyLoT.py b/autoPyLoT.py index 3d84de3b..d073f4ea 100755 --- a/autoPyLoT.py +++ b/autoPyLoT.py @@ -80,7 +80,7 @@ def autoPyLoT(inputfile): nlloccall = '%s/NLLoc' % nllocbin # get name of phase file phasef = parameter.getParam('phasefile') - phasefile = '%s/%s' % (nllocroot, phasef) + phasefile = '%s/obs/%s' % (nllocroot, phasef) # get name of NLLoc-control file locf = parameter.getParam('locfile') locfile = '%s/run/%s' % (nllocroot, locf) @@ -148,7 +148,7 @@ def autoPyLoT(inputfile): writephases(picks, 'NLLoc', phasefile) ########################################################## - # For locating the events we have to modify the NLLoc-control file! + # For locating the event we have to modify the NLLoc-control file! # create comment line for NLLoc-control file NLLoc-output file nllocout = '%s/loc/%s_%s' % (nllocroot, parameter.getParam('eventID'), nllocoutpatter) locfiles = 'LOCFILES %s NLLOC_OBS %s %s 0' % (phasefile, ttpatter, nllocout) From 6676484a6142e891e270395505c5a696a93e5251 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ludger=20K=C3=BCperkoch?= Date: Tue, 27 Oct 2015 16:51:42 +0100 Subject: [PATCH 11/21] Debuged: Avoids writing multiple LOCFILES-command lines if same event is processed several times. --- autoPyLoT.py | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/autoPyLoT.py b/autoPyLoT.py index d073f4ea..9ae760f7 100755 --- a/autoPyLoT.py +++ b/autoPyLoT.py @@ -7,7 +7,7 @@ import argparse import glob import subprocess import matplotlib.pyplot as plt - +import pdb from obspy.core import read from pylot.core.read.data import Data from pylot.core.read.inputs import AutoPickParameter @@ -157,11 +157,12 @@ def autoPyLoT(inputfile): filedata = None nllfile = open(locfile, 'r') filedata = nllfile.read() - # replace old command - filedata = filedata.replace('LOCFILES', locfiles) - nllfile = open(locfile, 'w') - nllfile.write(filedata) - nllfile.close() + if filedata.find(locfiles) < 0: + # replace old command + filedata = filedata.replace('LOCFILES', locfiles) + nllfile = open(locfile, 'w') + nllfile.write(filedata) + nllfile.close() # locate the event subprocess.call([nlloccall, locfile]) From 43d243e0a1a1123802bd0b8dd7eda28c4e9eafdd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ludger=20K=C3=BCperkoch?= Date: Tue, 27 Oct 2015 16:53:11 +0100 Subject: [PATCH 12/21] Same for multiple event processing. --- autoPyLoT.py | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/autoPyLoT.py b/autoPyLoT.py index 9ae760f7..77436b66 100755 --- a/autoPyLoT.py +++ b/autoPyLoT.py @@ -119,11 +119,12 @@ def autoPyLoT(inputfile): filedata = None nllfile = open(locfile, 'r') filedata = nllfile.read() - # replace old command - filedata = filedata.replace('LOCFILES', locfiles) - nllfile = open(locfile, 'w') - nllfile.write(filedata) - nllfile.close() + if filedata.find(locfiles) < 0: + # replace old command + filedata = filedata.replace('LOCFILES', locfiles) + nllfile = open(locfile, 'w') + nllfile.write(filedata) + nllfile.close() # locate the event subprocess.call([nlloccall, locfile]) From fc319f7162a6c41a568f252cad8100e60fcc4c30 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ludger=20K=C3=BCperkoch?= Date: Wed, 28 Oct 2015 09:13:13 +0100 Subject: [PATCH 13/21] Introduced option for running autoPyLoT without location routine, if parameter nllocbin in autoPyLoT.in is not set. --- autoPyLoT.py | 146 +++++++++++++++++++++++++++------------------------ 1 file changed, 76 insertions(+), 70 deletions(-) diff --git a/autoPyLoT.py b/autoPyLoT.py index 77436b66..1e60e54d 100755 --- a/autoPyLoT.py +++ b/autoPyLoT.py @@ -6,8 +6,7 @@ import os import argparse import glob import subprocess -import matplotlib.pyplot as plt -import pdb + from obspy.core import read from pylot.core.read.data import Data from pylot.core.read.inputs import AutoPickParameter @@ -20,7 +19,7 @@ __version__ = _getVersionString() def autoPyLoT(inputfile): - ''' + """ Determine phase onsets automatically utilizing the automatic picking algorithms by Kueperkoch et al. 2010/2012. @@ -32,7 +31,7 @@ def autoPyLoT(inputfile): .. rubric:: Example - ''' + """ print '************************************' print '*********autoPyLoT starting*********' print 'The Python picking and Location Tool' @@ -57,9 +56,9 @@ def autoPyLoT(inputfile): if parameter.hasParam('datastructure'): datastructure = DATASTRUCTURE[parameter.getParam('datastructure')]() - dsfields = {'root':parameter.getParam('rootpath'), - 'dpath':parameter.getParam('datapath'), - 'dbase':parameter.getParam('database')} + dsfields = {'root' :parameter.getParam('rootpath'), + 'dpath' :parameter.getParam('datapath'), + 'dbase' :parameter.getParam('database')} exf = ['root', 'dpath', 'dbase'] @@ -70,25 +69,28 @@ def autoPyLoT(inputfile): datastructure.modifyFields(**dsfields) datastructure.setExpandFields(exf) - # get path to inventory or dataless-seed file with station meta data - invdir = parameter.getParam('invdir') - - # get NLLoc-root path - nllocroot = parameter.getParam('nllocroot') - # get path to NLLoc executable - nllocbin = parameter.getParam('nllocbin') - nlloccall = '%s/NLLoc' % nllocbin - # get name of phase file - phasef = parameter.getParam('phasefile') - phasefile = '%s/obs/%s' % (nllocroot, phasef) - # get name of NLLoc-control file - locf = parameter.getParam('locfile') - locfile = '%s/run/%s' % (nllocroot, locf) - # patter of NLLoc ttimes from location grid - ttpat = parameter.getParam('ttpatter') - ttpatter = '%s/time/%s' % (nllocroot, ttpat) - # patter of NLLoc-output file - nllocoutpatter = parameter.getParam('outpatter') + # check if default location routine NLLoc is available + if parameter.hasParam('nllocbin'): + locflag = 1 + # get NLLoc-root path + nllocroot = parameter.getParam('nllocroot') + # get path to NLLoc executable + nllocbin = parameter.getParam('nllocbin') + nlloccall = '%s/NLLoc' % nllocbin + # get name of phase file + phasef = parameter.getParam('phasefile') + phasefile = '%s/obs/%s' % (nllocroot, phasef) + # get name of NLLoc-control file + locf = parameter.getParam('locfile') + locfile = '%s/run/%s' % (nllocroot, locf) + # patter of NLLoc ttimes from location grid + ttpat = parameter.getParam('ttpatter') + ttpatter = '%s/time/%s' % (nllocroot, ttpat) + # patter of NLLoc-output file + nllocoutpatter = parameter.getParam('outpatter') + else: + locflag = 0 + print ("!!No location routine available, autoPyLoT just picks the events without locating them!!") # multiple event processing @@ -97,37 +99,39 @@ def autoPyLoT(inputfile): if not parameter.hasParam('eventID'): for event in [events for events in glob.glob(os.path.join(datapath, '*')) if os.path.isdir(events)]: data.setWFData(glob.glob(os.path.join(datapath, event, '*'))) - print 'Working on event %s' %event + print 'Working on event %s' % event print data - wfdat = data.getWFData() # all available streams + wfdat = data.getWFData() # all available streams ########################################################## # !automated picking starts here! picks = autopickevent(wfdat, parameter) - # write phases to NLLoc-phase file - writephases(picks, 'NLLoc', phasefile) - ########################################################## - # For locating the events we have to modify the NLLoc-control file! - # create comment line for NLLoc-control file - # NLLoc-output file - nllocout = '%s/loc/%s_%s' % (nllocroot, event, nllocoutpatter) - locfiles = 'LOCFILES %s NLLOC_OBS %s %s 0' % (phasefile, ttpatter, nllocout) - print ("Modifying NLLoc-control file %s ..." % locfile) - # modification of NLLoc-control file - filedata = None - nllfile = open(locfile, 'r') - filedata = nllfile.read() - if filedata.find(locfiles) < 0: - # replace old command - filedata = filedata.replace('LOCFILES', locfiles) - nllfile = open(locfile, 'w') - nllfile.write(filedata) - nllfile.close() + # locating + if locflag == 1: + # write phases to NLLoc-phase file + writephases(picks, 'NLLoc', phasefile) - # locate the event - subprocess.call([nlloccall, locfile]) + # For locating the events we have to modify the NLLoc-control file! + # create comment line for NLLoc-control file + # NLLoc-output file + nllocout = '%s/loc/%s_%s' % (nllocroot, event, nllocoutpatter) + locfiles = 'LOCFILES %s NLLOC_OBS %s %s 0' % (phasefile, ttpatter, nllocout) + print ("Modifying NLLoc-control file %s ..." % locfile) + # modification of NLLoc-control file + filedata = None + nllfile = open(locfile, 'r') + filedata = nllfile.read() + if filedata.find(locfiles) < 0: + # replace old command + filedata = filedata.replace('LOCFILES', locfiles) + nllfile = open(locfile, 'w') + nllfile.write(filedata) + nllfile.close() + + # locate the event + subprocess.call([nlloccall, locfile]) ########################################################## print '------------------------------------------' @@ -140,33 +144,35 @@ def autoPyLoT(inputfile): print 'Working on event ', parameter.getParam('eventID') print data - wfdat = data.getWFData() # all available streams + wfdat = data.getWFData() # all available streams ########################################################## # !automated picking starts here! picks = autopickevent(wfdat, parameter) - # write phases to NLLoc-phase file - writephases(picks, 'NLLoc', phasefile) - ########################################################## - # For locating the event we have to modify the NLLoc-control file! - # create comment line for NLLoc-control file NLLoc-output file - nllocout = '%s/loc/%s_%s' % (nllocroot, parameter.getParam('eventID'), nllocoutpatter) - locfiles = 'LOCFILES %s NLLOC_OBS %s %s 0' % (phasefile, ttpatter, nllocout) - print ("Modifying NLLoc-control file %s ..." % locfile) - # modification of NLLoc-control file - filedata = None - nllfile = open(locfile, 'r') - filedata = nllfile.read() - if filedata.find(locfiles) < 0: - # replace old command - filedata = filedata.replace('LOCFILES', locfiles) - nllfile = open(locfile, 'w') - nllfile.write(filedata) - nllfile.close() + # locating + if locflag == 1: + # write phases to NLLoc-phase file + writephases(picks, 'NLLoc', phasefile) - # locate the event - subprocess.call([nlloccall, locfile]) + # For locating the event we have to modify the NLLoc-control file! + # create comment line for NLLoc-control file NLLoc-output file + nllocout = '%s/loc/%s_%s' % (nllocroot, parameter.getParam('eventID'), nllocoutpatter) + locfiles = 'LOCFILES %s NLLOC_OBS %s %s 0' % (phasefile, ttpatter, nllocout) + print ("Modifying NLLoc-control file %s ..." % locfile) + # modification of NLLoc-control file + filedata = None + nllfile = open(locfile, 'r') + filedata = nllfile.read() + if filedata.find(locfiles) < 0: + # replace old command + filedata = filedata.replace('LOCFILES', locfiles) + nllfile = open(locfile, 'w') + nllfile.write(filedata) + nllfile.close() + + # locate the event + subprocess.call([nlloccall, locfile]) ########################################################## From 94448297bbc08b093ada5519c47149e1a751af36 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ludger=20K=C3=BCperkoch?= Date: Wed, 28 Oct 2015 09:13:30 +0100 Subject: [PATCH 14/21] Marginal changes. --- pylot/core/pick/utils.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pylot/core/pick/utils.py b/pylot/core/pick/utils.py index 34b0c207..28de1716 100644 --- a/pylot/core/pick/utils.py +++ b/pylot/core/pick/utils.py @@ -8,7 +8,7 @@ :author: Ludger Kueperkoch / MAGS2 EP3 working group """ -import pdb + import numpy as np import matplotlib.pyplot as plt from obspy.core import Stream, UTCDateTime From 43f9e6fe0dd02b0988d63f900a98ce2cb224e168 Mon Sep 17 00:00:00 2001 From: Sebastian Wehling-Benatelli Date: Fri, 30 Oct 2015 06:11:15 +0100 Subject: [PATCH 15/21] [added] __nonzero__ method for boolean tests on FilterOptions object --- pylot/core/read/inputs.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/pylot/core/read/inputs.py b/pylot/core/read/inputs.py index 01e7cd3b..76b9bae9 100644 --- a/pylot/core/read/inputs.py +++ b/pylot/core/read/inputs.py @@ -206,6 +206,9 @@ class FilterOptions(object): order=self.getOrder()) return hrs + def __nonzero__(self): + return bool(self.getFilterType()) + def parseFilterOptions(self): if self.getFilterType(): robject = {'type': self.getFilterType(), 'corners': self.getOrder()} From 9b1f7541fd2abf91517b92ad477c363c90ff5ecd Mon Sep 17 00:00:00 2001 From: Sebastian Wehling-Benatelli Date: Fri, 30 Oct 2015 06:12:23 +0100 Subject: [PATCH 16/21] [added] isSorted function for iterables --- 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 f5c9b5fd..bbfe4d4d 100644 --- a/pylot/core/util/utils.py +++ b/pylot/core/util/utils.py @@ -32,7 +32,8 @@ def runProgram(cmd, parameter=None): output = subprocess.check_output('{} | tee /dev/stderr'.format(cmd), shell = True) - +def isSorted(iterable): + return sorted(iterable) == iterable def fnConstructor(s): if type(s) is str: From 0cd427486c6c2dc40cd6d0bda2e5dfe4a8b18117 Mon Sep 17 00:00:00 2001 From: Sebastian Wehling-Benatelli Date: Fri, 30 Oct 2015 06:16:00 +0100 Subject: [PATCH 17/21] [modified] updateUi method for the FilterOptionsDlg has been restructured and simplified --- pylot/core/util/widgets.py | 37 ++++++++++++++++++------------------- 1 file changed, 18 insertions(+), 19 deletions(-) diff --git a/pylot/core/util/widgets.py b/pylot/core/util/widgets.py index 1a8ef94c..2fece9da 100644 --- a/pylot/core/util/widgets.py +++ b/pylot/core/util/widgets.py @@ -27,7 +27,7 @@ from pylot.core.pick.utils import getSNR, earllatepicker, getnoisewin,\ getResolutionWindow from pylot.core.util.defaults import OUTPUTFORMATS, FILTERDEFAULTS from pylot.core.util.utils import prepTimeAxis, getGlobalTimes, scaleWFData, \ - demeanTrace + demeanTrace, isSorted def createAction(parent, text, slot=None, shortcut=None, icon=None, @@ -985,7 +985,7 @@ class FilterOptionsDialog(QDialog): """ super(FilterOptionsDialog, self).__init__() - if parent is not None: + if parent is not None and parent.getFilterOptions(): self.filterOptions = parent.getFilterOptions() elif filterOptions is not None: self.filterOptions = FilterOptions(filterOptions) @@ -1021,8 +1021,8 @@ class FilterOptionsDialog(QDialog): try: self.freqmaxSpinBox.setValue(self.getFilterOptions().getFreq()) self.freqminSpinBox.setValue(self.getFilterOptions().getFreq()) - except TypeError, e: - print e + except TypeError as e: + print(e) self.freqmaxSpinBox.setValue(1.) self.freqminSpinBox.setValue(.1) @@ -1037,6 +1037,7 @@ class FilterOptionsDialog(QDialog): self.selectTypeLabel.setText("Select filter type:") self.selectTypeCombo = QComboBox() self.selectTypeCombo.addItems(typeOptions) + self.selectTypeCombo.setCurrentIndex(typeOptions.index(self.getFilterOptions().getFilterType())) self.selectTypeLayout = QVBoxLayout() self.selectTypeLayout.addWidget(self.orderLabel) self.selectTypeLayout.addWidget(self.orderSpinBox) @@ -1071,30 +1072,28 @@ class FilterOptionsDialog(QDialog): self.buttonBox.rejected.connect(self.reject) def updateUi(self): - _enable = False - if self.selectTypeCombo.currentText() not in ['bandpass', 'bandstop']: - self.freqminLabel.setText("cutoff:") - self.freqmaxSpinBox.setValue(self.freqminSpinBox.value()) - else: - _enable = True - self.freqminLabel.setText("minimum:") - + type = self.selectTypeCombo.currentText() + _enable = type in ['bandpass', 'bandstop'] + freq = [self.freqminSpinBox.value(), self.freqmaxSpinBox.value()] self.freqmaxLabel.setEnabled(_enable) self.freqmaxSpinBox.setEnabled(_enable) - self.getFilterOptions().setFilterType( - self.selectTypeCombo.currentText()) - freq = [self.freqminSpinBox.value()] - if _enable: - if self.freqminSpinBox.value() > self.freqmaxSpinBox.value(): + if not _enable: + self.freqminLabel.setText("cutoff:") + self.freqmaxSpinBox.setValue(freq[0]) + freq.remove(freq[1]) + else: + self.freqminLabel.setText("minimum:") + if not isSorted(freq): QMessageBox.warning(self, "Value error", "Maximum frequency must be at least the " "same value as minimum frequency (notch)!") - self.freqmaxSpinBox.setValue(self.freqminSpinBox.value()) + self.freqmaxSpinBox.setValue(freq[0]) self.freqmaxSpinBox.selectAll() self.freqmaxSpinBox.setFocus() return - freq.append(self.freqmaxSpinBox.value()) + + self.getFilterOptions().setFilterType(type) self.getFilterOptions().setFreq(freq) self.getFilterOptions().setOrder(self.orderSpinBox.value()) From 809b6bea61fc241d4a4da6f8582a5861897348a4 Mon Sep 17 00:00:00 2001 From: Sebastian Wehling-Benatelli Date: Fri, 30 Oct 2015 08:33:05 +0100 Subject: [PATCH 18/21] make use of the new __nonzero__ method --- pylot/core/read/inputs.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pylot/core/read/inputs.py b/pylot/core/read/inputs.py index 76b9bae9..e6d609e3 100644 --- a/pylot/core/read/inputs.py +++ b/pylot/core/read/inputs.py @@ -210,7 +210,7 @@ class FilterOptions(object): return bool(self.getFilterType()) def parseFilterOptions(self): - if self.getFilterType(): + if self: robject = {'type': self.getFilterType(), 'corners': self.getOrder()} if len(self.getFreq()) > 1: robject['freqmin'] = self.getFreq()[0] From a2047aa37b876c50e59139d85d2bbeeaea18311e Mon Sep 17 00:00:00 2001 From: Sebastian Wehling-Benatelli Date: Fri, 30 Oct 2015 08:37:00 +0100 Subject: [PATCH 19/21] [disabled] P and S buttons preliminary removed due to unclear functionality --- QtPyLoT.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/QtPyLoT.py b/QtPyLoT.py index 2ba21c67..e6dabc5b 100755 --- a/QtPyLoT.py +++ b/QtPyLoT.py @@ -235,10 +235,10 @@ class MainWindow(QMainWindow): fileToolBar.setObjectName("FileTools") self.addActions(fileToolBar, fileToolActions) - phaseToolBar = self.addToolBar("PhaseTools") - phaseToolActions = (self.selectPAction, self.selectSAction) - phaseToolBar.setObjectName("PhaseTools") - self.addActions(phaseToolBar, phaseToolActions) + # phaseToolBar = self.addToolBar("PhaseTools") + # phaseToolActions = (self.selectPAction, self.selectSAction) + # phaseToolBar.setObjectName("PhaseTools") + # self.addActions(phaseToolBar, phaseToolActions) # create button group for component selection From 2201c3ea4d28472540c9c7ebb383d72c7c8e42ee Mon Sep 17 00:00:00 2001 From: Sebastian Wehling-Benatelli Date: Fri, 30 Oct 2015 08:39:51 +0100 Subject: [PATCH 20/21] [modified] restructured filterWaveformData method in order to make the GUI more intuitive --- QtPyLoT.py | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/QtPyLoT.py b/QtPyLoT.py index e6dabc5b..5c2cd677 100755 --- a/QtPyLoT.py +++ b/QtPyLoT.py @@ -544,18 +544,17 @@ class MainWindow(QMainWindow): return True return False - if self.filterAction.isChecked(): - kwargs = {} - freq = self.getFilterOptions().getFreq() - if freq is not None and len(freq) > 1: - kwargs['freqmin'] = freq[0] - kwargs['freqmax'] = freq[1] - elif freq is not None and len(freq) == 1: - kwargs['freq'] = freq + def pushFilterWF(kwdict): if hasfreq(kwargs): - kwargs['type'] = self.getFilterOptions().getFilterType() - kwargs['corners'] = self.getFilterOptions().getOrder() self.getData().filterWFData(kwargs) + + if self.getFilterOptions() and self.filterAction.isChecked(): + kwargs = self.getFilterOptions().parseFilterOptions() + pushFilterWF(kwargs) + elif self.filterAction.isChecked(): + self.adjustFilterOptions() + kwargs = self.getFilterOptions().parseFilterOptions() + pushFilterWF(kwargs) else: self.getData().resetWFData() self.plotWaveformData() From a31e1a21f0a70eb09b52d3cf7fbc22fb326f1fb3 Mon Sep 17 00:00:00 2001 From: Sebastian Wehling-Benatelli Date: Sat, 31 Oct 2015 00:07:24 +0100 Subject: [PATCH 21/21] [bugfix] now filtering in the main window works; filter parameters are not stored -> has to be checked again --- QtPyLoT.py | 25 +++++++++---------------- 1 file changed, 9 insertions(+), 16 deletions(-) diff --git a/QtPyLoT.py b/QtPyLoT.py index 5c2cd677..92aa76ea 100755 --- a/QtPyLoT.py +++ b/QtPyLoT.py @@ -536,38 +536,31 @@ class MainWindow(QMainWindow): self.plotWaveformData() self.drawPicks() + def pushFilterWF(self, param_args): + self.getData().filterWFData(param_args) + def filterWaveformData(self): if self.getData(): - def hasfreq(kwdict): - for key in kwdict.keys(): - if not key.startswith('freq'): - return True - return False - - def pushFilterWF(kwdict): - if hasfreq(kwargs): - self.getData().filterWFData(kwargs) - if self.getFilterOptions() and self.filterAction.isChecked(): kwargs = self.getFilterOptions().parseFilterOptions() - pushFilterWF(kwargs) + self.pushFilterWF(kwargs) elif self.filterAction.isChecked(): self.adjustFilterOptions() - kwargs = self.getFilterOptions().parseFilterOptions() - pushFilterWF(kwargs) else: self.getData().resetWFData() self.plotWaveformData() def adjustFilterOptions(self): - filteroptions = self.getFilterOptions() fstring = "Filter Options ({0})".format(self.getSeismicPhase()) filterDlg = FilterOptionsDialog(titleString=fstring, - parent=self, - filterOptions=filteroptions) + parent=self) if filterDlg.exec_(): filteroptions = filterDlg.getFilterOptions() self.setFilterOptions(filteroptions) + if self.filterAction.isChecked(): + kwargs = self.getFilterOptions().parseFilterOptions() + self.pushFilterWF(kwargs) + self.plotWaveformData() def getFilterOptions(self): try: