Merge branch 'develop' of ariadne.geophysik.ruhr-uni-bochum.de:/data/git/pylot into develop
This commit is contained in:
commit
b140dd4f53
858
QtPyLoT.py
858
QtPyLoT.py
File diff suppressed because it is too large
Load Diff
133
autoPyLoT.py
133
autoPyLoT.py
@ -16,9 +16,9 @@ import pylot.core.loc.focmec as focmec
|
|||||||
import pylot.core.loc.hash as hash
|
import pylot.core.loc.hash as hash
|
||||||
import pylot.core.loc.nll as nll
|
import pylot.core.loc.nll as nll
|
||||||
#from PySide.QtGui import QWidget, QInputDialog
|
#from PySide.QtGui import QWidget, QInputDialog
|
||||||
from pylot.core.analysis.magnitude import MomentMagnitude, RichterMagnitude
|
from pylot.core.analysis.magnitude import MomentMagnitude, LocalMagnitude
|
||||||
from pylot.core.io.data import Data
|
from pylot.core.io.data import Data
|
||||||
from pylot.core.io.inputs import AutoPickParameter
|
from pylot.core.io.inputs import PylotParameter
|
||||||
from pylot.core.pick.autopick import autopickevent, iteratepicker
|
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, \
|
||||||
remove_underscores
|
remove_underscores
|
||||||
@ -35,7 +35,7 @@ def autoPyLoT(input_dict=None, parameter=None, inputfile=None, fnames=None, even
|
|||||||
|
|
||||||
:param inputfile: path to the input file containing all parameter
|
:param inputfile: path to the input file containing all parameter
|
||||||
information for automatic picking (for formatting details, see.
|
information for automatic picking (for formatting details, see.
|
||||||
`~pylot.core.io.inputs.AutoPickParameter`
|
`~pylot.core.io.inputs.PylotParameter`
|
||||||
:type inputfile: str
|
:type inputfile: str
|
||||||
:return:
|
:return:
|
||||||
|
|
||||||
@ -71,13 +71,13 @@ def autoPyLoT(input_dict=None, parameter=None, inputfile=None, fnames=None, even
|
|||||||
|
|
||||||
if not parameter:
|
if not parameter:
|
||||||
if inputfile:
|
if inputfile:
|
||||||
parameter = AutoPickParameter(inputfile)
|
parameter = PylotParameter(inputfile)
|
||||||
iplot = parameter['iplot']
|
iplot = parameter['iplot']
|
||||||
else:
|
else:
|
||||||
print('No parameters set and no input file given. Choose either of both.')
|
print('No parameters set and no input file given. Choose either of both.')
|
||||||
return
|
return
|
||||||
else:
|
else:
|
||||||
if not type(parameter) == AutoPickParameter:
|
if not type(parameter) == PylotParameter:
|
||||||
print('Wrong input type for parameter: {}'.format(type(parameter)))
|
print('Wrong input type for parameter: {}'.format(type(parameter)))
|
||||||
return
|
return
|
||||||
if inputfile:
|
if inputfile:
|
||||||
@ -98,8 +98,8 @@ def autoPyLoT(input_dict=None, parameter=None, inputfile=None, fnames=None, even
|
|||||||
|
|
||||||
exf = ['root', 'dpath', 'dbase']
|
exf = ['root', 'dpath', 'dbase']
|
||||||
|
|
||||||
if parameter.hasParam('eventID') and fnames == 'None':
|
if parameter['eventID'] is not '*' and fnames == 'None':
|
||||||
dsfields['eventID'] = parameter.get('eventID')
|
dsfields['eventID'] = parameter['eventID']
|
||||||
exf.append('eventID')
|
exf.append('eventID')
|
||||||
|
|
||||||
datastructure.modifyFields(**dsfields)
|
datastructure.modifyFields(**dsfields)
|
||||||
@ -130,21 +130,35 @@ def autoPyLoT(input_dict=None, parameter=None, inputfile=None, fnames=None, even
|
|||||||
print("!!No source parameter estimation possible!!")
|
print("!!No source parameter estimation possible!!")
|
||||||
print(" !!! ")
|
print(" !!! ")
|
||||||
|
|
||||||
datapath = datastructure.expandDataPath()
|
if not input_dict:
|
||||||
if fnames == 'None' and not parameter.hasParam('eventID'):
|
# started in production mode
|
||||||
# multiple event processing
|
datapath = datastructure.expandDataPath()
|
||||||
# read each event in database
|
if fnames == 'None' and parameter['eventID'] is '*':
|
||||||
events = [events for events in glob.glob(os.path.join(datapath, '*')) if os.path.isdir(events)]
|
# multiple event processing
|
||||||
elif fnames == 'None' and parameter.hasParam('eventID'):
|
# read each event in database
|
||||||
# single event processing
|
events = [events for events in glob.glob(os.path.join(datapath, '*')) if os.path.isdir(events)]
|
||||||
events = glob.glob(os.path.join(datapath, parameter.get('eventID')))
|
elif fnames == 'None' and parameter['eventID'] is not '*':
|
||||||
|
# single event processing
|
||||||
|
events = glob.glob(os.path.join(datapath, parameter['eventID']))
|
||||||
|
else:
|
||||||
|
# autoPyLoT was initialized from GUI
|
||||||
|
events = []
|
||||||
|
events.append(eventid)
|
||||||
|
evID = os.path.split(eventid)[-1]
|
||||||
|
locflag = 2
|
||||||
else:
|
else:
|
||||||
# autoPyLoT was initialized from GUI
|
# started in tune mode
|
||||||
|
datapath = os.path.join(parameter['rootpath'],
|
||||||
|
parameter['datapath'])
|
||||||
events = []
|
events = []
|
||||||
events.append(eventid)
|
events.append(os.path.join(datapath,
|
||||||
evID = os.path.split(eventid)[-1]
|
parameter['database'],
|
||||||
locflag = 2
|
parameter['eventID']))
|
||||||
|
|
||||||
|
if not events:
|
||||||
|
print('autoPyLoT: No events given. Return!')
|
||||||
|
return
|
||||||
|
|
||||||
for event in events:
|
for event in events:
|
||||||
if fnames == 'None':
|
if fnames == 'None':
|
||||||
data.setWFData(glob.glob(os.path.join(datapath, event, '*')))
|
data.setWFData(glob.glob(os.path.join(datapath, event, '*')))
|
||||||
@ -229,7 +243,7 @@ def autoPyLoT(input_dict=None, parameter=None, inputfile=None, fnames=None, even
|
|||||||
# get latest NLLoc-location file if several are available
|
# get latest NLLoc-location file if several are available
|
||||||
nllocfile = max(glob.glob(locsearch), key=os.path.getctime)
|
nllocfile = max(glob.glob(locsearch), key=os.path.getctime)
|
||||||
evt = read_events(nllocfile)[0]
|
evt = read_events(nllocfile)[0]
|
||||||
# calculating seismic moment Mo and moment magnitude Mw
|
# calculate seismic moment Mo and moment magnitude Mw
|
||||||
moment_mag = MomentMagnitude(corr_dat, evt, parameter.get('vp'),
|
moment_mag = MomentMagnitude(corr_dat, evt, parameter.get('vp'),
|
||||||
parameter.get('Qp'),
|
parameter.get('Qp'),
|
||||||
parameter.get('rho'), True, \
|
parameter.get('rho'), True, \
|
||||||
@ -238,15 +252,29 @@ def autoPyLoT(input_dict=None, parameter=None, inputfile=None, fnames=None, even
|
|||||||
for station, props in moment_mag.moment_props.items():
|
for station, props in moment_mag.moment_props.items():
|
||||||
picks[station]['P'].update(props)
|
picks[station]['P'].update(props)
|
||||||
evt = moment_mag.updated_event()
|
evt = moment_mag.updated_event()
|
||||||
local_mag = RichterMagnitude(corr_dat, evt,
|
net_mw = moment_mag.net_magnitude()
|
||||||
parameter.get('sstop'), True,\
|
print("Network moment magnitude: %4.1f" % net_mw.mag)
|
||||||
iplot)
|
# calculate local (Richter) magntiude
|
||||||
|
WAscaling = parameter.get('WAscaling')
|
||||||
|
magscaling = parameter.get('magscaling')
|
||||||
|
local_mag = LocalMagnitude(corr_dat, evt,
|
||||||
|
parameter.get('sstop'),
|
||||||
|
WAscaling, True, iplot)
|
||||||
for station, amplitude in local_mag.amplitudes.items():
|
for station, amplitude in local_mag.amplitudes.items():
|
||||||
picks[station]['S']['Ao'] = amplitude.generic_amplitude
|
picks[station]['S']['Ao'] = amplitude.generic_amplitude
|
||||||
evt = local_mag.updated_event()
|
print("Local station magnitudes scaled with:")
|
||||||
|
print("log(Ao) + %f * log(r) + %f * r + %f" % (WAscaling[0],
|
||||||
|
WAscaling[1],
|
||||||
|
WAscaling[2]))
|
||||||
|
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]))
|
||||||
else:
|
else:
|
||||||
print("autoPyLoT: No NLLoc-location file available!")
|
print("autoPyLoT: No NLLoc-location file available!")
|
||||||
print("No source parameter estimation possible!")
|
print("No source parameter estimation possible!")
|
||||||
|
locflag = 9
|
||||||
else:
|
else:
|
||||||
# get theoretical P-onset times from NLLoc-location file
|
# get theoretical P-onset times from NLLoc-location file
|
||||||
locsearch = '%s/loc/%s.????????.??????.grid?.loc.hyp' % (nllocroot, nllocout)
|
locsearch = '%s/loc/%s.????????.??????.grid?.loc.hyp' % (nllocroot, nllocout)
|
||||||
@ -287,7 +315,7 @@ def autoPyLoT(input_dict=None, parameter=None, inputfile=None, fnames=None, even
|
|||||||
nlloccounter = maxnumit
|
nlloccounter = maxnumit
|
||||||
evt = read_events(nllocfile)[0]
|
evt = read_events(nllocfile)[0]
|
||||||
if locflag < 2:
|
if locflag < 2:
|
||||||
# calculating seismic moment Mo and moment magnitude Mw
|
# calculate seismic moment Mo and moment magnitude Mw
|
||||||
moment_mag = MomentMagnitude(corr_dat, evt, parameter.get('vp'),
|
moment_mag = MomentMagnitude(corr_dat, evt, parameter.get('vp'),
|
||||||
parameter.get('Qp'),
|
parameter.get('Qp'),
|
||||||
parameter.get('rho'), True, \
|
parameter.get('rho'), True, \
|
||||||
@ -296,14 +324,25 @@ def autoPyLoT(input_dict=None, parameter=None, inputfile=None, fnames=None, even
|
|||||||
for station, props in moment_mag.moment_props.items():
|
for station, props in moment_mag.moment_props.items():
|
||||||
picks[station]['P'].update(props)
|
picks[station]['P'].update(props)
|
||||||
evt = moment_mag.updated_event()
|
evt = moment_mag.updated_event()
|
||||||
local_mag = RichterMagnitude(corr_dat, evt,
|
|
||||||
parameter.get('sstop'), True, \
|
|
||||||
iplot)
|
|
||||||
for station, amplitude in local_mag.amplitudes.items():
|
|
||||||
picks[station]['S']['Ao'] = amplitude.generic_amplitude
|
|
||||||
evt = local_mag.updated_event()
|
|
||||||
net_mw = moment_mag.net_magnitude()
|
net_mw = moment_mag.net_magnitude()
|
||||||
print("Network moment magnitude: %4.1f" % net_mw.mag)
|
print("Network moment magnitude: %4.1f" % net_mw.mag)
|
||||||
|
# calculate local (Richter) magntiude
|
||||||
|
WAscaling = parameter.get('WAscaling')
|
||||||
|
magscaling = parameter.get('magscaling')
|
||||||
|
local_mag = LocalMagnitude(corr_dat, evt,
|
||||||
|
parameter.get('sstop'),
|
||||||
|
WAscaling, True, iplot)
|
||||||
|
for station, amplitude in local_mag.amplitudes.items():
|
||||||
|
picks[station]['S']['Ao'] = amplitude.generic_amplitude
|
||||||
|
print("Local station magnitudes scaled with:")
|
||||||
|
print("log(Ao) + %f * log(r) + %f * r + %f" % (WAscaling[0],
|
||||||
|
WAscaling[1],
|
||||||
|
WAscaling[2]))
|
||||||
|
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]))
|
||||||
else:
|
else:
|
||||||
print("autoPyLoT: No NLLoc-location file available! Stop iteration!")
|
print("autoPyLoT: No NLLoc-location file available! Stop iteration!")
|
||||||
locflag = 9
|
locflag = 9
|
||||||
@ -314,26 +353,26 @@ def autoPyLoT(input_dict=None, parameter=None, inputfile=None, fnames=None, even
|
|||||||
data.applyEVTData(picks)
|
data.applyEVTData(picks)
|
||||||
if evt is not None:
|
if evt is not None:
|
||||||
data.applyEVTData(evt, 'event')
|
data.applyEVTData(evt, 'event')
|
||||||
fnqml = '%s/autoPyLoT' % event
|
fnqml = '%s/PyLoT_%s' % (event, evID)
|
||||||
data.exportEvent(fnqml)
|
data.exportEvent(fnqml, fnext='.xml', fcheck='manual')
|
||||||
# HYPO71
|
|
||||||
hypo71file = '%s/autoPyLoT_HYPO71_phases' % event
|
|
||||||
hypo71.export(picks, hypo71file, parameter)
|
|
||||||
# HYPOSAT
|
|
||||||
hyposatfile = '%s/autoPyLoT_HYPOSAT_phases' % event
|
|
||||||
hyposat.export(picks, hyposatfile, parameter)
|
|
||||||
if locflag == 1:
|
if locflag == 1:
|
||||||
|
# HYPO71
|
||||||
|
hypo71file = '%s/PyLoT_%s_HYPO71_phases' % (event, evID)
|
||||||
|
hypo71.export(picks, hypo71file, parameter)
|
||||||
|
# HYPOSAT
|
||||||
|
hyposatfile = '%s/PyLoT_%s_HYPOSAT_phases' % (event, evID)
|
||||||
|
hyposat.export(picks, hyposatfile, parameter)
|
||||||
# VELEST
|
# VELEST
|
||||||
velestfile = '%s/autoPyLoT_VELEST_phases.cnv' % event
|
velestfile = '%s/PyLoT_%s_VELEST_phases.cnv' % (event, evID)
|
||||||
velest.export(picks, velestfile, parameter, evt)
|
velest.export(picks, velestfile, parameter, evt)
|
||||||
# hypoDD
|
# hypoDD
|
||||||
hypoddfile = '%s/autoPyLoT_hypoDD_phases.pha' % event
|
hypoddfile = '%s/PyLoT_%s_hypoDD_phases.pha' % (event, evID)
|
||||||
hypodd.export(picks, hypoddfile, parameter, evt)
|
hypodd.export(picks, hypoddfile, parameter, evt)
|
||||||
# FOCMEC
|
# FOCMEC
|
||||||
focmecfile = '%s/autoPyLoT_FOCMEC.in' % event
|
focmecfile = '%s/PyLoT_%s_FOCMEC.in' % (event, evID)
|
||||||
focmec.export(picks, focmecfile, parameter, evt)
|
focmec.export(picks, focmecfile, parameter, evt)
|
||||||
# HASH
|
# HASH
|
||||||
hashfile = '%s/autoPyLoT_HASH' % event
|
hashfile = '%s/PyLoT_%s_HASH' % (event, evID)
|
||||||
hash.export(picks, hashfile, parameter, evt)
|
hash.export(picks, hashfile, parameter, evt)
|
||||||
|
|
||||||
endsplash = '''------------------------------------------\n'
|
endsplash = '''------------------------------------------\n'
|
||||||
@ -385,9 +424,5 @@ if __name__ == "__main__":
|
|||||||
|
|
||||||
cla = parser.parse_args()
|
cla = parser.parse_args()
|
||||||
|
|
||||||
try:
|
picks = autoPyLoT(inputfile=str(cla.inputfile), fnames=str(cla.fnames),
|
||||||
picks, mainFig = autoPyLoT(inputfile=str(cla.inputfile), fnames=str(cla.fnames),
|
eventid=str(cla.eventid), savepath=str(cla.spath))
|
||||||
eventid=str(cla.eventid), savepath=str(cla.spath))
|
|
||||||
except ValueError:
|
|
||||||
print("autoPyLoT was running in production mode.")
|
|
||||||
|
|
||||||
|
@ -1 +0,0 @@
|
|||||||
0af79-dirty
|
|
@ -2,6 +2,7 @@
|
|||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
"""
|
"""
|
||||||
Created autumn/winter 2015.
|
Created autumn/winter 2015.
|
||||||
|
Revised/extended summer 2017.
|
||||||
|
|
||||||
:author: Ludger Küperkoch / MAGS2 EP3 working group
|
:author: Ludger Küperkoch / MAGS2 EP3 working group
|
||||||
"""
|
"""
|
||||||
@ -17,10 +18,17 @@ from pylot.core.pick.utils import getsignalwin, crossings_nonzero_all, \
|
|||||||
from pylot.core.util.utils import common_range, fit_curve
|
from pylot.core.util.utils import common_range, fit_curve
|
||||||
|
|
||||||
def richter_magnitude_scaling(delta):
|
def richter_magnitude_scaling(delta):
|
||||||
relation = np.loadtxt(os.path.join(os.path.expanduser('~'),
|
distance = np.array([0, 10, 20, 25, 30, 35,40, 45, 50, 60, 70, 75, 85, 90, 100, 110,
|
||||||
'.pylot', 'richter_scaling.data'))
|
120, 130, 140, 150, 160, 170, 180, 190, 200, 210, 230, 240, 250,
|
||||||
|
260, 270, 280, 290, 300, 310, 320, 330, 340, 350, 360, 370, 380,
|
||||||
|
390, 400, 430, 470, 510, 560, 600, 700, 800, 900, 1000])
|
||||||
|
richter_scaling = np.array([1.4, 1.5, 1.7, 1.9, 2.1, 2.3, 2.4, 2.5, 2.6, 2.8, 2.8, 2.9,
|
||||||
|
2.9, 3.0, 3.1, 3.1, 3.2, 3.2, 3.3, 3.3, 3.4, 3.4, 3.5, 3.5,
|
||||||
|
3.6, 3.7, 3.7, 3.8, 3.8, 3.9, 3.9, 4.0, 4.0, 4.1, 4.2, 4.2,
|
||||||
|
4.2, 4.2, 4.3, 4.3, 4.3, 4.4, 4.4, 4.5, 4.6, 4.7, 4.8, 4.9,
|
||||||
|
5.1, 5.2, 5.4, 5.5, 5.7])
|
||||||
# prepare spline interpolation to calculate return value
|
# prepare spline interpolation to calculate return value
|
||||||
func, params = fit_curve(relation[:, 0], relation[:, 1])
|
func, params = fit_curve(distance, richter_scaling)
|
||||||
return func(delta, params)
|
return func(delta, params)
|
||||||
|
|
||||||
|
|
||||||
@ -31,10 +39,10 @@ class Magnitude(object):
|
|||||||
|
|
||||||
def __init__(self, stream, event, verbosity=False, iplot=0):
|
def __init__(self, stream, event, verbosity=False, iplot=0):
|
||||||
self._type = "M"
|
self._type = "M"
|
||||||
|
self._stream = stream
|
||||||
self._plot_flag = iplot
|
self._plot_flag = iplot
|
||||||
self._verbosity = verbosity
|
self._verbosity = verbosity
|
||||||
self._event = event
|
self._event = event
|
||||||
self._stream = stream
|
|
||||||
self._magnitudes = dict()
|
self._magnitudes = dict()
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
@ -108,28 +116,35 @@ class Magnitude(object):
|
|||||||
def calc(self):
|
def calc(self):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def updated_event(self):
|
def updated_event(self, magscaling=None):
|
||||||
self.event.magnitudes.append(self.net_magnitude())
|
self.event.magnitudes.append(self.net_magnitude(magscaling))
|
||||||
return self.event
|
return self.event
|
||||||
|
|
||||||
def net_magnitude(self):
|
def net_magnitude(self, magscaling=None):
|
||||||
if self:
|
if self:
|
||||||
# TODO if an average Magnitude instead of the median is calculated
|
if magscaling is not None and str(magscaling) is not '[0.0, 0.0]':
|
||||||
# StationMagnitudeContributions should be added to the returned
|
# scaling necessary
|
||||||
# Magnitude object
|
print("Scaling network magnitude ...")
|
||||||
# mag_error => weights (magnitude error estimate from peak_to_peak, calcsourcespec?)
|
mag = ope.Magnitude(
|
||||||
# weights => StationMagnitdeContribution
|
mag=np.median([M.mag for M in self.magnitudes.values()]) *\
|
||||||
mag = ope.Magnitude(
|
magscaling[0] + magscaling[1],
|
||||||
mag=np.median([M.mag for M in self.magnitudes.values()]),
|
magnitude_type=self.type,
|
||||||
magnitude_type=self.type,
|
origin_id=self.origin_id,
|
||||||
origin_id=self.origin_id,
|
station_count=len(self.magnitudes),
|
||||||
station_count=len(self.magnitudes),
|
azimuthal_gap=self.origin_id.get_referred_object().quality.azimuthal_gap)
|
||||||
azimuthal_gap=self.origin_id.get_referred_object().quality.azimuthal_gap)
|
else:
|
||||||
|
# no saling necessary
|
||||||
|
mag = ope.Magnitude(
|
||||||
|
mag=np.median([M.mag for M in self.magnitudes.values()]),
|
||||||
|
magnitude_type=self.type,
|
||||||
|
origin_id=self.origin_id,
|
||||||
|
station_count=len(self.magnitudes),
|
||||||
|
azimuthal_gap=self.origin_id.get_referred_object().quality.azimuthal_gap)
|
||||||
return mag
|
return mag
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
|
||||||
class RichterMagnitude(Magnitude):
|
class LocalMagnitude(Magnitude):
|
||||||
"""
|
"""
|
||||||
Method to derive peak-to-peak amplitude as seen on a Wood-Anderson-
|
Method to derive peak-to-peak amplitude as seen on a Wood-Anderson-
|
||||||
seismograph. Has to be derived from instrument corrected traces!
|
seismograph. Has to be derived from instrument corrected traces!
|
||||||
@ -146,10 +161,11 @@ class RichterMagnitude(Magnitude):
|
|||||||
|
|
||||||
_amplitudes = dict()
|
_amplitudes = dict()
|
||||||
|
|
||||||
def __init__(self, stream, event, calc_win, verbosity=False, iplot=0):
|
def __init__(self, stream, event, calc_win, wascaling, verbosity=False, iplot=0):
|
||||||
super(RichterMagnitude, self).__init__(stream, event, verbosity, iplot)
|
super(LocalMagnitude, self).__init__(stream, event, verbosity, iplot)
|
||||||
|
|
||||||
self._calc_win = calc_win
|
self._calc_win = calc_win
|
||||||
|
self._wascaling = wascaling
|
||||||
self._type = 'ML'
|
self._type = 'ML'
|
||||||
self.calc()
|
self.calc()
|
||||||
|
|
||||||
@ -161,6 +177,10 @@ class RichterMagnitude(Magnitude):
|
|||||||
def calc_win(self, value):
|
def calc_win(self, value):
|
||||||
self._calc_win = value
|
self._calc_win = value
|
||||||
|
|
||||||
|
@property
|
||||||
|
def wascaling(self):
|
||||||
|
return self._wascaling
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def amplitudes(self):
|
def amplitudes(self):
|
||||||
return self._amplitudes
|
return self._amplitudes
|
||||||
@ -195,6 +215,8 @@ class RichterMagnitude(Magnitude):
|
|||||||
th = np.arange(0, len(sqH) * dt, dt)
|
th = np.arange(0, len(sqH) * dt, dt)
|
||||||
# get maximum peak within pick window
|
# get maximum peak within pick window
|
||||||
iwin = getsignalwin(th, t0 - stime, self.calc_win)
|
iwin = getsignalwin(th, t0 - stime, self.calc_win)
|
||||||
|
ii = min([iwin[len(iwin)-1], len(th)])
|
||||||
|
iwin = iwin[0:ii]
|
||||||
wapp = np.max(sqH[iwin])
|
wapp = np.max(sqH[iwin])
|
||||||
if self.verbose:
|
if self.verbose:
|
||||||
print("Determined Wood-Anderson peak-to-peak amplitude for station {0}: {1} "
|
print("Determined Wood-Anderson peak-to-peak amplitude for station {0}: {1} "
|
||||||
@ -244,10 +266,17 @@ class RichterMagnitude(Magnitude):
|
|||||||
self.event.amplitudes.append(amplitude)
|
self.event.amplitudes.append(amplitude)
|
||||||
self.amplitudes = (station, amplitude)
|
self.amplitudes = (station, amplitude)
|
||||||
# using standard Gutenberg-Richter relation
|
# using standard Gutenberg-Richter relation
|
||||||
# TODO make the ML calculation more flexible by allowing
|
# or scale WA amplitude with given scaling relation
|
||||||
# use of custom relation functions
|
if str(self.wascaling) == '[0.0, 0.0, 0.0]':
|
||||||
magnitude = ope.StationMagnitude(
|
print("Calculating original Richter magnitude ...")
|
||||||
mag=np.log10(a0) + richter_magnitude_scaling(delta))
|
magnitude = ope.StationMagnitude(mag=np.log10(a0) \
|
||||||
|
+ richter_magnitude_scaling(delta))
|
||||||
|
else:
|
||||||
|
print("Calculating scaled local 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[2])
|
||||||
magnitude.origin_id = self.origin_id
|
magnitude.origin_id = self.origin_id
|
||||||
magnitude.waveform_id = pick.waveform_id
|
magnitude.waveform_id = pick.waveform_id
|
||||||
magnitude.amplitude_id = amplitude.resource_id
|
magnitude.amplitude_id = amplitude.resource_id
|
||||||
|
@ -6,11 +6,12 @@ import os
|
|||||||
from obspy import read_events
|
from obspy import read_events
|
||||||
from obspy.core import read, Stream, UTCDateTime
|
from obspy.core import read, Stream, UTCDateTime
|
||||||
from obspy.io.sac import SacIOError
|
from obspy.io.sac import SacIOError
|
||||||
from obspy.core.event import Event
|
from obspy.core.event import Event as ObsPyEvent
|
||||||
from pylot.core.io.phases import readPILOTEvent, picks_from_picksdict, \
|
from pylot.core.io.phases import readPILOTEvent, picks_from_picksdict, \
|
||||||
picksdict_from_pilot, merge_picks
|
picksdict_from_pilot, merge_picks
|
||||||
from pylot.core.util.errors import FormatError, OverwriteError
|
from pylot.core.util.errors import FormatError, OverwriteError
|
||||||
from pylot.core.util.utils import fnConstructor, full_range
|
from pylot.core.util.utils import fnConstructor, full_range
|
||||||
|
from pylot.core.util.event import Event
|
||||||
|
|
||||||
class Data(object):
|
class Data(object):
|
||||||
"""
|
"""
|
||||||
@ -33,7 +34,7 @@ class Data(object):
|
|||||||
self.comp = 'Z'
|
self.comp = 'Z'
|
||||||
self.wfdata = Stream()
|
self.wfdata = Stream()
|
||||||
self._new = False
|
self._new = False
|
||||||
if isinstance(evtdata, Event):
|
if isinstance(evtdata, ObsPyEvent) or isinstance(evtdata, Event):
|
||||||
pass
|
pass
|
||||||
elif isinstance(evtdata, dict):
|
elif isinstance(evtdata, dict):
|
||||||
evt = readPILOTEvent(**evtdata)
|
evt = readPILOTEvent(**evtdata)
|
||||||
@ -49,7 +50,7 @@ class Data(object):
|
|||||||
if 'Unknown format for file' in e.message:
|
if 'Unknown format for file' in e.message:
|
||||||
if 'PHASES' in evtdata:
|
if 'PHASES' in evtdata:
|
||||||
picks = picksdict_from_pilot(evtdata)
|
picks = picksdict_from_pilot(evtdata)
|
||||||
evtdata = Event()
|
evtdata = ObsPyEvent()
|
||||||
evtdata.picks = picks_from_picksdict(picks)
|
evtdata.picks = picks_from_picksdict(picks)
|
||||||
elif 'LOC' in evtdata:
|
elif 'LOC' in evtdata:
|
||||||
raise NotImplementedError('PILOT location information '
|
raise NotImplementedError('PILOT location information '
|
||||||
@ -61,7 +62,7 @@ class Data(object):
|
|||||||
raise e
|
raise e
|
||||||
else: # create an empty Event object
|
else: # create an empty Event object
|
||||||
self.setNew()
|
self.setNew()
|
||||||
evtdata = Event()
|
evtdata = ObsPyEvent()
|
||||||
evtdata.picks = []
|
evtdata.picks = []
|
||||||
self.evtdata = evtdata
|
self.evtdata = evtdata
|
||||||
self.wforiginal = None
|
self.wforiginal = None
|
||||||
@ -73,6 +74,8 @@ class Data(object):
|
|||||||
|
|
||||||
def __add__(self, other):
|
def __add__(self, other):
|
||||||
assert isinstance(other, Data), "operands must be of same type 'Data'"
|
assert isinstance(other, Data), "operands must be of same type 'Data'"
|
||||||
|
rs_id = self.get_evt_data().get('resource_id')
|
||||||
|
rs_id_other = other.get_evt_data().get('resource_id')
|
||||||
if other.isNew() and not self.isNew():
|
if other.isNew() and not self.isNew():
|
||||||
picks_to_add = other.get_evt_data().picks
|
picks_to_add = other.get_evt_data().picks
|
||||||
old_picks = self.get_evt_data().picks
|
old_picks = self.get_evt_data().picks
|
||||||
@ -84,7 +87,7 @@ class Data(object):
|
|||||||
self.evtdata = new.get_evt_data()
|
self.evtdata = new.get_evt_data()
|
||||||
elif self.isNew() and other.isNew():
|
elif self.isNew() and other.isNew():
|
||||||
pass
|
pass
|
||||||
elif self.get_evt_data().get('id') == other.get_evt_data().get('id'):
|
elif rs_id == rs_id_other:
|
||||||
other.setNew()
|
other.setNew()
|
||||||
return self + other
|
return self + other
|
||||||
else:
|
else:
|
||||||
@ -95,7 +98,7 @@ class Data(object):
|
|||||||
def getPicksStr(self):
|
def getPicksStr(self):
|
||||||
picks_str = ''
|
picks_str = ''
|
||||||
for pick in self.get_evt_data().picks:
|
for pick in self.get_evt_data().picks:
|
||||||
picks_str += str(pick) + '\n'
|
picks_str += str(PyLoT) + '\n'
|
||||||
return picks_str
|
return picks_str
|
||||||
|
|
||||||
def getParent(self):
|
def getParent(self):
|
||||||
@ -144,12 +147,13 @@ class Data(object):
|
|||||||
# handle forbidden filenames especially on windows systems
|
# handle forbidden filenames especially on windows systems
|
||||||
return fnConstructor(str(ID))
|
return fnConstructor(str(ID))
|
||||||
|
|
||||||
def exportEvent(self, fnout, fnext='.xml'):
|
def exportEvent(self, fnout, fnext='.xml', fcheck='auto'):
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
:param fnout:
|
:param fnout:
|
||||||
:param fnext:
|
:param fnext:
|
||||||
|
:param fcheck:
|
||||||
:raise KeyError:
|
:raise KeyError:
|
||||||
"""
|
"""
|
||||||
from pylot.core.util.defaults import OUTPUTFORMATS
|
from pylot.core.util.defaults import OUTPUTFORMATS
|
||||||
@ -160,13 +164,35 @@ class Data(object):
|
|||||||
errmsg = '{0}; selected file extension {1} not ' \
|
errmsg = '{0}; selected file extension {1} not ' \
|
||||||
'supported'.format(e, fnext)
|
'supported'.format(e, fnext)
|
||||||
raise FormatError(errmsg)
|
raise FormatError(errmsg)
|
||||||
|
|
||||||
|
# check for already existing xml-file
|
||||||
|
if fnext == '.xml':
|
||||||
|
if os.path.isfile(fnout + fnext):
|
||||||
|
print("xml-file already exists! Check content ...")
|
||||||
|
cat_old = read_events(fnout + fnext)
|
||||||
|
checkflag = 0
|
||||||
|
for j in range(len(cat_old.events[0].picks)):
|
||||||
|
if cat_old.events[0].picks[j].method_id.id.split('/')[1] == fcheck:
|
||||||
|
print("Found %s pick(s), append to new catalog." % fcheck)
|
||||||
|
checkflag = 1
|
||||||
|
break
|
||||||
|
if checkflag == 1:
|
||||||
|
self.get_evt_data().write(fnout + fnext, format=evtformat)
|
||||||
|
cat_new = read_events(fnout + fnext)
|
||||||
|
cat_new.append(cat_old.events[0])
|
||||||
|
cat_new.write(fnout + fnext, format=evtformat)
|
||||||
|
else:
|
||||||
|
self.get_evt_data().write(fnout + fnext, format=evtformat)
|
||||||
|
else:
|
||||||
|
self.get_evt_data().write(fnout + fnext, format=evtformat)
|
||||||
|
|
||||||
# try exporting event via ObsPy
|
# try exporting event via ObsPy
|
||||||
try:
|
else:
|
||||||
self.get_evt_data().write(fnout + fnext, format=evtformat)
|
try:
|
||||||
except KeyError as e:
|
self.get_evt_data().write(fnout + fnext, format=evtformat)
|
||||||
raise KeyError('''{0} export format
|
except KeyError as e:
|
||||||
not implemented: {1}'''.format(evtformat, e))
|
raise KeyError('''{0} export format
|
||||||
|
not implemented: {1}'''.format(evtformat, e))
|
||||||
|
|
||||||
def getComp(self):
|
def getComp(self):
|
||||||
"""
|
"""
|
||||||
@ -279,12 +305,12 @@ class Data(object):
|
|||||||
def setEvtData(self, event):
|
def setEvtData(self, event):
|
||||||
self.evtdata = event
|
self.evtdata = event
|
||||||
|
|
||||||
def applyEVTData(self, data, type='pick', authority_id='rub'):
|
def applyEVTData(self, data, typ='pick', authority_id='rub'):
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
:param data:
|
:param data:
|
||||||
:param type:
|
:param typ:
|
||||||
:param authority_id:
|
:param authority_id:
|
||||||
:raise OverwriteError:
|
:raise OverwriteError:
|
||||||
"""
|
"""
|
||||||
@ -326,19 +352,27 @@ class Data(object):
|
|||||||
information on the event to the actual data
|
information on the event to the actual data
|
||||||
:param event:
|
:param event:
|
||||||
"""
|
"""
|
||||||
if not self.isNew():
|
if self.isNew():
|
||||||
self.setEvtData(event)
|
self.setEvtData(event)
|
||||||
else:
|
else:
|
||||||
# prevent overwriting original pick information
|
# prevent overwriting original pick information
|
||||||
picks = copy.deepcopy(self.get_evt_data().picks)
|
event_old = self.get_evt_data()
|
||||||
|
print(event_old.resource_id, event.resource_id)
|
||||||
|
if not event_old.resource_id == event.resource_id:
|
||||||
|
print("WARNING: Missmatch in event resource id's: {} and {}".format(
|
||||||
|
event_old.resource_id,
|
||||||
|
event.resource_id))
|
||||||
|
picks = copy.deepcopy(event_old.picks)
|
||||||
event = merge_picks(event, picks)
|
event = merge_picks(event, picks)
|
||||||
# apply event information from location
|
# apply event information from location
|
||||||
self.get_evt_data().update(event)
|
event_old.update(event)
|
||||||
|
|
||||||
applydata = {'pick': applyPicks,
|
applydata = {'pick': applyPicks,
|
||||||
'event': applyEvent}
|
'event': applyEvent}
|
||||||
|
|
||||||
applydata[type](data)
|
applydata[typ](data)
|
||||||
|
self._new = False
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class GenericDataStructure(object):
|
class GenericDataStructure(object):
|
||||||
|
@ -14,7 +14,7 @@ defaults = {'rootpath': {'type': str,
|
|||||||
'value': ''},
|
'value': ''},
|
||||||
|
|
||||||
'eventID': {'type': str,
|
'eventID': {'type': str,
|
||||||
'tooltip': 'event ID for single event processing',
|
'tooltip': 'event ID for single event processing (* for all events found in database)',
|
||||||
'value': ''},
|
'value': ''},
|
||||||
|
|
||||||
'extent': {'type': str,
|
'extent': {'type': str,
|
||||||
@ -275,7 +275,17 @@ defaults = {'rootpath': {'type': str,
|
|||||||
|
|
||||||
'wdttolerance': {'type': float,
|
'wdttolerance': {'type': float,
|
||||||
'tooltip': 'maximum allowed deviation from Wadati-diagram',
|
'tooltip': 'maximum allowed deviation from Wadati-diagram',
|
||||||
'value': 1.0}
|
'value': 1.0},
|
||||||
|
|
||||||
|
'WAscaling': {'type': (float, float, float),
|
||||||
|
'tooltip': 'Scaling relation (log(Ao)+Alog(r)+Br+C) of Wood-Anderson amplitude Ao [nm] \
|
||||||
|
If zeros are set, original Richter magnitude is calculated!',
|
||||||
|
'value': (0., 0., 0.)},
|
||||||
|
|
||||||
|
'magscaling': {'type': (float, float),
|
||||||
|
'tooltip': 'Scaling relation for derived local magnitude [a*Ml+b]. \
|
||||||
|
If zeros are set, no scaling of network magnitude is applied!',
|
||||||
|
'value': (0., 0.)}
|
||||||
}
|
}
|
||||||
|
|
||||||
settings_main={
|
settings_main={
|
||||||
@ -298,6 +308,9 @@ settings_main={
|
|||||||
'vp',
|
'vp',
|
||||||
'rho',
|
'rho',
|
||||||
'Qp'],
|
'Qp'],
|
||||||
|
'localmag':[
|
||||||
|
'WAscaling',
|
||||||
|
'magscaling'],
|
||||||
'pick':[
|
'pick':[
|
||||||
'extent',
|
'extent',
|
||||||
'pstart',
|
'pstart',
|
||||||
|
@ -4,9 +4,9 @@
|
|||||||
from pylot.core.util.errors import ParameterError
|
from pylot.core.util.errors import ParameterError
|
||||||
import default_parameters
|
import default_parameters
|
||||||
|
|
||||||
class AutoPickParameter(object):
|
class PylotParameter(object):
|
||||||
'''
|
'''
|
||||||
AutoPickParameters is a parameter type object capable to read and/or write
|
PylotParameter is a parameter type object capable to read and/or write
|
||||||
parameter ASCII.
|
parameter ASCII.
|
||||||
|
|
||||||
:param fn str: Filename of the input file
|
:param fn str: Filename of the input file
|
||||||
@ -78,7 +78,7 @@ class AutoPickParameter(object):
|
|||||||
|
|
||||||
# String representation of the object
|
# String representation of the object
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
return "AutoPickParameter('%s')" % self.__filename
|
return "PylotParameter('%s')" % self.__filename
|
||||||
|
|
||||||
# Boolean test
|
# Boolean test
|
||||||
def __nonzero__(self):
|
def __nonzero__(self):
|
||||||
@ -140,7 +140,8 @@ class AutoPickParameter(object):
|
|||||||
all_names += self.get_main_para_names()['dirs']
|
all_names += self.get_main_para_names()['dirs']
|
||||||
all_names += self.get_main_para_names()['nlloc']
|
all_names += self.get_main_para_names()['nlloc']
|
||||||
all_names += self.get_main_para_names()['smoment']
|
all_names += self.get_main_para_names()['smoment']
|
||||||
all_names += self.get_main_para_names()['pick']
|
all_names += self.get_main_para_names()['localmag']
|
||||||
|
all_names += self.get_main_para_names()['pick']
|
||||||
all_names += self.get_special_para_names()['z']
|
all_names += self.get_special_para_names()['z']
|
||||||
all_names += self.get_special_para_names()['h']
|
all_names += self.get_special_para_names()['h']
|
||||||
all_names += self.get_special_para_names()['fm']
|
all_names += self.get_special_para_names()['fm']
|
||||||
@ -220,22 +221,23 @@ class AutoPickParameter(object):
|
|||||||
# for key, value in self.iteritems():
|
# for key, value in self.iteritems():
|
||||||
# lines.append('{key}\t{value}\n'.format(key=key, value=value))
|
# lines.append('{key}\t{value}\n'.format(key=key, value=value))
|
||||||
# fid_out.writelines(lines)
|
# fid_out.writelines(lines)
|
||||||
|
|
||||||
header = ('%This is a parameter input file for PyLoT/autoPyLoT.\n'+
|
header = ('%This is a parameter input file for PyLoT/autoPyLoT.\n'+
|
||||||
'%All main and special settings regarding data handling\n'+
|
'%All main and special settings regarding data handling\n'+
|
||||||
'%and picking are to be set here!\n'+
|
'%and picking are to be set here!\n'+
|
||||||
'%Parameters are optimized for local data sets!\n')
|
'%Parameters are optimized for %{} data sets!\n'.format(self.get_main_para_names()['pick'][0]))
|
||||||
seperator = '%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n'
|
separator = '%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n'
|
||||||
|
|
||||||
fid_out.write(header)
|
fid_out.write(header)
|
||||||
self.write_section(fid_out, self.get_main_para_names()['dirs'],
|
self.write_section(fid_out, self.get_main_para_names()['dirs'],
|
||||||
'main settings', seperator)
|
'main settings', separator)
|
||||||
self.write_section(fid_out, self.get_main_para_names()['nlloc'],
|
self.write_section(fid_out, self.get_main_para_names()['nlloc'],
|
||||||
'NLLoc settings', seperator)
|
'NLLoc settings', separator)
|
||||||
self.write_section(fid_out, self.get_main_para_names()['smoment'],
|
self.write_section(fid_out, self.get_main_para_names()['smoment'],
|
||||||
'parameters for seismic moment estimation', seperator)
|
'parameters for seismic moment estimation', separator)
|
||||||
|
self.write_section(fid_out, self.get_main_para_names()['localmag'],
|
||||||
|
'settings local magnitude', separator)
|
||||||
self.write_section(fid_out, self.get_main_para_names()['pick'],
|
self.write_section(fid_out, self.get_main_para_names()['pick'],
|
||||||
'common settings picker', seperator)
|
'common settings picker', separator)
|
||||||
fid_out.write(('#special settings for calculating CF#\n'+
|
fid_out.write(('#special settings for calculating CF#\n'+
|
||||||
'%!!Edit the following only if you know what you are doing!!%\n'))
|
'%!!Edit the following only if you know what you are doing!!%\n'))
|
||||||
self.write_section(fid_out, self.get_special_para_names()['z'],
|
self.write_section(fid_out, self.get_special_para_names()['z'],
|
||||||
@ -247,9 +249,9 @@ class AutoPickParameter(object):
|
|||||||
self.write_section(fid_out, self.get_special_para_names()['quality'],
|
self.write_section(fid_out, self.get_special_para_names()['quality'],
|
||||||
'quality assessment', None)
|
'quality assessment', None)
|
||||||
|
|
||||||
def write_section(self, fid, names, title, seperator):
|
def write_section(self, fid, names, title, separator):
|
||||||
if seperator:
|
if separator:
|
||||||
fid.write(seperator)
|
fid.write(separator)
|
||||||
fid.write('#{}#\n'.format(title))
|
fid.write('#{}#\n'.format(title))
|
||||||
l_val = 50
|
l_val = 50
|
||||||
l_name = 15
|
l_name = 15
|
||||||
|
@ -7,8 +7,9 @@ import os
|
|||||||
import scipy.io as sio
|
import scipy.io as sio
|
||||||
import warnings
|
import warnings
|
||||||
from obspy.core import UTCDateTime
|
from obspy.core import UTCDateTime
|
||||||
|
from obspy.core.util import AttribDict
|
||||||
|
|
||||||
from pylot.core.io.inputs import AutoPickParameter
|
from pylot.core.io.inputs import PylotParameter
|
||||||
from pylot.core.io.location import create_arrival, create_event, \
|
from pylot.core.io.location import create_arrival, create_event, \
|
||||||
create_magnitude, create_origin, create_pick
|
create_magnitude, create_origin, create_pick
|
||||||
from pylot.core.pick.utils import select_for_phase
|
from pylot.core.pick.utils import select_for_phase
|
||||||
@ -116,7 +117,7 @@ def picksdict_from_pilot(fn):
|
|||||||
picks = dict()
|
picks = dict()
|
||||||
phases_pilot = sio.loadmat(fn)
|
phases_pilot = sio.loadmat(fn)
|
||||||
stations = stations_from_pilot(phases_pilot['stat'])
|
stations = stations_from_pilot(phases_pilot['stat'])
|
||||||
params = AutoPickParameter(TIMEERROR_DEFAULTS)
|
params = PylotParameter(TIMEERROR_DEFAULTS)
|
||||||
timeerrors = dict(P=params.get('timeerrorsP'),
|
timeerrors = dict(P=params.get('timeerrorsP'),
|
||||||
S=params.get('timeerrorsS'))
|
S=params.get('timeerrorsS'))
|
||||||
for n, station in enumerate(stations):
|
for n, station in enumerate(stations):
|
||||||
@ -195,6 +196,7 @@ def picksdict_from_picks(evt):
|
|||||||
phase = {}
|
phase = {}
|
||||||
station = pick.waveform_id.station_code
|
station = pick.waveform_id.station_code
|
||||||
channel = pick.waveform_id.channel_code
|
channel = pick.waveform_id.channel_code
|
||||||
|
network = pick.waveform_id.network_code
|
||||||
try:
|
try:
|
||||||
onsets = picks[station]
|
onsets = picks[station]
|
||||||
except KeyError as e:
|
except KeyError as e:
|
||||||
@ -215,6 +217,7 @@ def picksdict_from_picks(evt):
|
|||||||
phase['lpp'] = lpp
|
phase['lpp'] = lpp
|
||||||
phase['spe'] = spe
|
phase['spe'] = spe
|
||||||
phase['channel'] = channel
|
phase['channel'] = channel
|
||||||
|
phase['network'] = network
|
||||||
try:
|
try:
|
||||||
picker = str(pick.method_id)
|
picker = str(pick.method_id)
|
||||||
if picker.startswith('smi:local/'):
|
if picker.startswith('smi:local/'):
|
||||||
@ -231,7 +234,7 @@ def picks_from_picksdict(picks, creation_info=None):
|
|||||||
picks_list = list()
|
picks_list = list()
|
||||||
for station, onsets in picks.items():
|
for station, onsets in picks.items():
|
||||||
for label, phase in onsets.items():
|
for label, phase in onsets.items():
|
||||||
if not isinstance(phase, dict):
|
if not isinstance(phase, dict) and not isinstance(phase, AttribDict):
|
||||||
continue
|
continue
|
||||||
onset = phase['mpp']
|
onset = phase['mpp']
|
||||||
try:
|
try:
|
||||||
@ -295,14 +298,14 @@ def reassess_pilot_db(root_dir, db_dir, out_dir=None, fn_param=None, verbosity=0
|
|||||||
def reassess_pilot_event(root_dir, db_dir, event_id, out_dir=None, fn_param=None, verbosity=0):
|
def reassess_pilot_event(root_dir, db_dir, event_id, out_dir=None, fn_param=None, verbosity=0):
|
||||||
from obspy import read
|
from obspy import read
|
||||||
|
|
||||||
from pylot.core.io.inputs import AutoPickParameter
|
from pylot.core.io.inputs import PylotParameter
|
||||||
from pylot.core.pick.utils import earllatepicker
|
from pylot.core.pick.utils import earllatepicker
|
||||||
|
|
||||||
if fn_param is None:
|
if fn_param is None:
|
||||||
import pylot.core.util.defaults as defaults
|
import pylot.core.util.defaults as defaults
|
||||||
fn_param = defaults.AUTOMATIC_DEFAULTS
|
fn_param = defaults.AUTOMATIC_DEFAULTS
|
||||||
|
|
||||||
default = AutoPickParameter(fn_param, verbosity)
|
default = PylotParameter(fn_param, verbosity)
|
||||||
|
|
||||||
search_base = os.path.join(root_dir, db_dir, event_id)
|
search_base = os.path.join(root_dir, db_dir, event_id)
|
||||||
phases_file = glob.glob(os.path.join(search_base, 'PHASES.mat'))
|
phases_file = glob.glob(os.path.join(search_base, 'PHASES.mat'))
|
||||||
@ -382,12 +385,12 @@ def reassess_pilot_event(root_dir, db_dir, event_id, out_dir=None, fn_param=None
|
|||||||
evt.picks = picks_from_picksdict(picks_dict)
|
evt.picks = picks_from_picksdict(picks_dict)
|
||||||
# write phase information to file
|
# write phase information to file
|
||||||
if not out_dir:
|
if not out_dir:
|
||||||
fnout_prefix = os.path.join(root_dir, db_dir, event_id, '{0}.'.format(event_id))
|
fnout_prefix = os.path.join(root_dir, db_dir, event_id, 'PyLoT_{0}.'.format(event_id))
|
||||||
else:
|
else:
|
||||||
out_dir = os.path.join(out_dir, db_dir)
|
out_dir = os.path.join(out_dir, db_dir)
|
||||||
if not os.path.isdir(out_dir):
|
if not os.path.isdir(out_dir):
|
||||||
os.makedirs(out_dir)
|
os.makedirs(out_dir)
|
||||||
fnout_prefix = os.path.join(out_dir, '{0}.'.format(event_id))
|
fnout_prefix = os.path.join(out_dir, 'PyLoT_{0}.'.format(event_id))
|
||||||
evt.write(fnout_prefix + 'xml', format='QUAKEML')
|
evt.write(fnout_prefix + 'xml', format='QUAKEML')
|
||||||
#evt.write(fnout_prefix + 'cnv', format='VELEST')
|
#evt.write(fnout_prefix + 'cnv', format='VELEST')
|
||||||
|
|
||||||
@ -835,9 +838,10 @@ def merge_picks(event, picks):
|
|||||||
err = pick.time_errors
|
err = pick.time_errors
|
||||||
phase = pick.phase_hint
|
phase = pick.phase_hint
|
||||||
station = pick.waveform_id.station_code
|
station = pick.waveform_id.station_code
|
||||||
|
network = pick.waveform_id.network_code
|
||||||
method = pick.method_id
|
method = pick.method_id
|
||||||
for p in event.picks:
|
for p in event.picks:
|
||||||
if p.waveform_id.station_code == station and p.phase_hint == phase:
|
if p.waveform_id.station_code == station and p.phase_hint == phase:
|
||||||
p.time, p.time_errors, p.method_id = time, err, method
|
p.time, p.time_errors, p.waveform_id.network_code, p.method_id = time, err, network, method
|
||||||
del time, err, phase, station, method
|
del time, err, phase, station, network, method
|
||||||
return event
|
return event
|
||||||
|
@ -11,7 +11,7 @@ function conglomerate utils.
|
|||||||
|
|
||||||
import matplotlib.pyplot as plt
|
import matplotlib.pyplot as plt
|
||||||
import numpy as np
|
import numpy as np
|
||||||
from pylot.core.io.inputs import AutoPickParameter
|
from pylot.core.io.inputs import PylotParameter
|
||||||
from pylot.core.pick.picker import AICPicker, PragPicker
|
from pylot.core.pick.picker import AICPicker, PragPicker
|
||||||
from pylot.core.pick.charfuns import CharacteristicFunction
|
from pylot.core.pick.charfuns import CharacteristicFunction
|
||||||
from pylot.core.pick.charfuns import HOScf, AICcf, ARZcf, ARHcf, AR3Ccf
|
from pylot.core.pick.charfuns import HOScf, AICcf, ARZcf, ARHcf, AR3Ccf
|
||||||
@ -81,7 +81,7 @@ def autopickstation(wfstream, pickparam, verbose=False, iplot=0, fig_dict=None):
|
|||||||
|
|
||||||
:param pickparam: container of picking parameters from input file,
|
:param pickparam: container of picking parameters from input file,
|
||||||
usually autoPyLoT.in
|
usually autoPyLoT.in
|
||||||
:type pickparam: AutoPickParameter
|
:type pickparam: PylotParameter
|
||||||
:param verbose:
|
:param verbose:
|
||||||
:type verbose: bool
|
:type verbose: bool
|
||||||
|
|
||||||
|
@ -212,6 +212,14 @@ class AICPicker(AutoPicker):
|
|||||||
self.Data[0].data = self.Data[0].data * 1000000
|
self.Data[0].data = self.Data[0].data * 1000000
|
||||||
# get signal window
|
# get signal window
|
||||||
isignal = getsignalwin(self.Tcf, self.Pick, self.TSNR[2])
|
isignal = getsignalwin(self.Tcf, self.Pick, self.TSNR[2])
|
||||||
|
ii = min([isignal[len(isignal)-1], len(self.Tcf)])
|
||||||
|
isignal = isignal[0:ii]
|
||||||
|
try:
|
||||||
|
aic[isignal]
|
||||||
|
except IndexError as e:
|
||||||
|
msg = "Time series out of bounds! {}".format(e)
|
||||||
|
print(msg)
|
||||||
|
return
|
||||||
# calculate SNR from CF
|
# calculate SNR from CF
|
||||||
self.SNR = max(abs(aic[isignal] - np.mean(aic[isignal]))) / \
|
self.SNR = max(abs(aic[isignal] - np.mean(aic[isignal]))) / \
|
||||||
max(abs(aic[inoise] - np.mean(aic[inoise])))
|
max(abs(aic[inoise] - np.mean(aic[inoise])))
|
||||||
@ -223,28 +231,29 @@ class AICPicker(AutoPicker):
|
|||||||
# find maximum within slope determination window
|
# find maximum within slope determination window
|
||||||
# 'cause slope should be calculated up to first local minimum only!
|
# 'cause slope should be calculated up to first local minimum only!
|
||||||
imax = np.argmax(self.Data[0].data[islope])
|
imax = np.argmax(self.Data[0].data[islope])
|
||||||
if imax == 0:
|
|
||||||
print('AICPicker: Maximum for slope determination right at the beginning of the window!')
|
|
||||||
print('Choose longer slope determination window!')
|
|
||||||
if self.iplot > 1:
|
|
||||||
if not self.fig:
|
|
||||||
fig = plt.figure() #self.iplot) ### WHY? MP MP
|
|
||||||
else:
|
|
||||||
fig = self.fig
|
|
||||||
ax = fig.add_subplot(111)
|
|
||||||
x = self.Data[0].data
|
|
||||||
ax.plot(self.Tcf, x / max(x), 'k', legend='(HOS-/AR-) Data')
|
|
||||||
ax.plot(self.Tcf, aicsmooth / max(aicsmooth), 'r', legend='Smoothed AIC-CF')
|
|
||||||
ax.legend()
|
|
||||||
ax.set_xlabel('Time [s] since %s' % self.Data[0].stats.starttime)
|
|
||||||
ax.set_yticks([])
|
|
||||||
ax.set_title(self.Data[0].stats.station)
|
|
||||||
return
|
|
||||||
|
|
||||||
iislope = islope[0][0:imax]
|
iislope = islope[0][0:imax]
|
||||||
if len(iislope) <= 3:
|
if len(iislope) <= 2:
|
||||||
# calculate slope from initial onset to maximum of AIC function
|
# calculate slope from initial onset to maximum of AIC function
|
||||||
|
print("AICPicker: Not enough data samples left for slope calculation!")
|
||||||
|
print("Calculating slope from initial onset to maximum of AIC function ...")
|
||||||
imax = np.argmax(aicsmooth[islope])
|
imax = np.argmax(aicsmooth[islope])
|
||||||
|
if imax == 0:
|
||||||
|
print("AICPicker: Maximum for slope determination right at the beginning of the window!")
|
||||||
|
print("Choose longer slope determination window!")
|
||||||
|
if self.iplot > 1:
|
||||||
|
if not self.fig:
|
||||||
|
fig = plt.figure() #self.iplot) ### WHY? MP MP
|
||||||
|
else:
|
||||||
|
fig = self.fig
|
||||||
|
ax = fig.add_subplot(111)
|
||||||
|
x = self.Data[0].data
|
||||||
|
ax.plot(self.Tcf, x / max(x), 'k', label='(HOS-/AR-) Data')
|
||||||
|
ax.plot(self.Tcf, aicsmooth / max(aicsmooth), 'r', label='Smoothed AIC-CF')
|
||||||
|
ax.legend()
|
||||||
|
ax.set_xlabel('Time [s] since %s' % self.Data[0].stats.starttime)
|
||||||
|
ax.set_yticks([])
|
||||||
|
ax.set_title(self.Data[0].stats.station)
|
||||||
|
return
|
||||||
iislope = islope[0][0:imax]
|
iislope = islope[0][0:imax]
|
||||||
dataslope = self.Data[0].data[iislope]
|
dataslope = self.Data[0].data[iislope]
|
||||||
# calculate slope as polynomal fit of order 1
|
# calculate slope as polynomal fit of order 1
|
||||||
|
144
pylot/core/util/event.py
Normal file
144
pylot/core/util/event.py
Normal file
@ -0,0 +1,144 @@
|
|||||||
|
#!/usr/bin/env python
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
import os
|
||||||
|
|
||||||
|
from obspy import UTCDateTime
|
||||||
|
from obspy.core.event import Event as ObsPyEvent
|
||||||
|
from obspy.core.event import Origin, Magnitude, ResourceIdentifier
|
||||||
|
|
||||||
|
from pylot.core.io.phases import picks_from_picksdict
|
||||||
|
|
||||||
|
|
||||||
|
class Event(ObsPyEvent):
|
||||||
|
'''
|
||||||
|
Pickable class derived from ~obspy.core.event.Event containing information on a single event.
|
||||||
|
'''
|
||||||
|
def __init__(self, path):
|
||||||
|
self.pylot_id = path.split('/')[-1]
|
||||||
|
# initialize super class
|
||||||
|
super(Event, self).__init__(resource_id=ResourceIdentifier('smi:local/'+self.pylot_id))
|
||||||
|
self.path = path
|
||||||
|
self.database = path.split('/')[-2]
|
||||||
|
self.datapath = path.split('/')[-3]
|
||||||
|
self.rootpath = '/' + os.path.join(*path.split('/')[:-3])
|
||||||
|
self.pylot_autopicks = {}
|
||||||
|
self.pylot_picks = {}
|
||||||
|
self.notes = ''
|
||||||
|
self._testEvent = False
|
||||||
|
self._refEvent = False
|
||||||
|
self.get_notes()
|
||||||
|
|
||||||
|
def get_notes_path(self):
|
||||||
|
notesfile = os.path.join(self.path, 'notes.txt')
|
||||||
|
return notesfile
|
||||||
|
|
||||||
|
def get_notes(self):
|
||||||
|
notesfile = self.get_notes_path()
|
||||||
|
if os.path.isfile(notesfile):
|
||||||
|
with open(notesfile) as infile:
|
||||||
|
path = str(infile.readlines()[0].split('\n')[0])
|
||||||
|
text = '[eventInfo: '+path+']'
|
||||||
|
self.addNotes(text)
|
||||||
|
try:
|
||||||
|
datetime = UTCDateTime(path.split('/')[-1])
|
||||||
|
origin = Origin(resource_id=self.resource_id, time=datetime, latitude=0, longitude=0, depth=0)
|
||||||
|
self.origins.append(origin)
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
|
||||||
|
def addNotes(self, notes):
|
||||||
|
self.notes = str(notes)
|
||||||
|
|
||||||
|
def clearNotes(self):
|
||||||
|
self.notes = None
|
||||||
|
|
||||||
|
def isRefEvent(self):
|
||||||
|
return self._refEvent
|
||||||
|
|
||||||
|
def isTestEvent(self):
|
||||||
|
return self._testEvent
|
||||||
|
|
||||||
|
def setRefEvent(self, bool):
|
||||||
|
self._refEvent = bool
|
||||||
|
if bool: self._testEvent = False
|
||||||
|
|
||||||
|
def setTestEvent(self, bool):
|
||||||
|
self._testEvent = bool
|
||||||
|
if bool: self._refEvent = False
|
||||||
|
|
||||||
|
def addPicks(self, picks):
|
||||||
|
'''
|
||||||
|
add pylot picks and overwrite existing
|
||||||
|
'''
|
||||||
|
for station in picks:
|
||||||
|
self.pylot_picks[station] = picks[station]
|
||||||
|
#add ObsPy picks
|
||||||
|
self.picks = picks_from_picksdict(self.pylot_picks)
|
||||||
|
|
||||||
|
def addAutopicks(self, autopicks):
|
||||||
|
for station in autopicks:
|
||||||
|
self.pylot_autopicks[station] = autopicks[station]
|
||||||
|
|
||||||
|
def setPick(self, station, pick):
|
||||||
|
if pick:
|
||||||
|
self.pylot_picks[station] = pick
|
||||||
|
self.picks = picks_from_picksdict(self.pylot_picks)
|
||||||
|
|
||||||
|
def setPicks(self, picks):
|
||||||
|
'''
|
||||||
|
set pylot picks and delete and overwrite all existing
|
||||||
|
'''
|
||||||
|
self.pylot_picks = picks
|
||||||
|
self.picks = picks_from_picksdict(self.pylot_picks)
|
||||||
|
|
||||||
|
def getPick(self, station):
|
||||||
|
if station in self.pylot_picks.keys():
|
||||||
|
return self.pylot_picks[station]
|
||||||
|
|
||||||
|
def getPicks(self):
|
||||||
|
return self.pylot_picks
|
||||||
|
|
||||||
|
def setAutopick(self, station, autopick):
|
||||||
|
if autopick:
|
||||||
|
self.pylot_autopicks[station] = autopick
|
||||||
|
|
||||||
|
def setAutopicks(self, autopicks):
|
||||||
|
self.pylot_autopicks = autopicks
|
||||||
|
|
||||||
|
def getAutopick(self, station):
|
||||||
|
if station in self.pylot_autopicks.keys():
|
||||||
|
return self.pylot_autopicks[station]
|
||||||
|
|
||||||
|
def getAutopicks(self):
|
||||||
|
return self.pylot_autopicks
|
||||||
|
|
||||||
|
def save(self, filename):
|
||||||
|
'''
|
||||||
|
Save PyLoT Event to a file.
|
||||||
|
Can be loaded by using event.load(filename).
|
||||||
|
'''
|
||||||
|
try:
|
||||||
|
import cPickle
|
||||||
|
except ImportError:
|
||||||
|
import _pickle as cPickle
|
||||||
|
|
||||||
|
try:
|
||||||
|
outfile = open(filename, 'wb')
|
||||||
|
cPickle.dump(self, outfile, -1)
|
||||||
|
except Exception as e:
|
||||||
|
print('Could not pickle PyLoT event. Reason: {}'.format(e))
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def load(filename):
|
||||||
|
'''
|
||||||
|
Load project from filename.
|
||||||
|
'''
|
||||||
|
try:
|
||||||
|
import cPickle
|
||||||
|
except ImportError:
|
||||||
|
import _pickle as cPickle
|
||||||
|
infile = open(filename, 'rb')
|
||||||
|
event = cPickle.load(infile)
|
||||||
|
print('Loaded %s' % filename)
|
||||||
|
return event
|
@ -22,6 +22,7 @@ class map_projection(QtGui.QWidget):
|
|||||||
self.parser = parent.metadata[1]
|
self.parser = parent.metadata[1]
|
||||||
self.picks = None
|
self.picks = None
|
||||||
self.picks_dict = None
|
self.picks_dict = None
|
||||||
|
self.eventLoc = None
|
||||||
self.figure = figure
|
self.figure = figure
|
||||||
self.init_graphics()
|
self.init_graphics()
|
||||||
self.init_stations()
|
self.init_stations()
|
||||||
@ -244,6 +245,10 @@ class map_projection(QtGui.QWidget):
|
|||||||
self.sc = self.basemap.scatter(self.lon, self.lat, s=50, facecolor='none', latlon=True,
|
self.sc = self.basemap.scatter(self.lon, self.lat, s=50, facecolor='none', latlon=True,
|
||||||
zorder=10, picker=True, edgecolor='m', label='Not Picked')
|
zorder=10, picker=True, edgecolor='m', label='Not Picked')
|
||||||
self.cid = self.canvas.mpl_connect('pick_event', self.onpick)
|
self.cid = self.canvas.mpl_connect('pick_event', self.onpick)
|
||||||
|
if self.eventLoc:
|
||||||
|
lat, lon = self.eventLoc
|
||||||
|
self.sc_event = self.basemap.scatter(lon, lat, s=100, facecolor='red',
|
||||||
|
latlon=True, zorder=11, label='Event (might be outside map region)')
|
||||||
|
|
||||||
def scatter_picked_stations(self):
|
def scatter_picked_stations(self):
|
||||||
lon = self.lon_no_nan
|
lon = self.lon_no_nan
|
||||||
@ -274,8 +279,7 @@ class map_projection(QtGui.QWidget):
|
|||||||
|
|
||||||
def refresh_drawings(self, picks=None):
|
def refresh_drawings(self, picks=None):
|
||||||
self.picks_dict = picks
|
self.picks_dict = picks
|
||||||
self.remove_drawings()
|
self._refresh_drawings()
|
||||||
self.draw_everything()
|
|
||||||
|
|
||||||
def _refresh_drawings(self):
|
def _refresh_drawings(self):
|
||||||
self.remove_drawings()
|
self.remove_drawings()
|
||||||
@ -303,6 +307,9 @@ class map_projection(QtGui.QWidget):
|
|||||||
if hasattr(self, 'sc_picked'):
|
if hasattr(self, 'sc_picked'):
|
||||||
self.sc_picked.remove()
|
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)
|
||||||
if hasattr(self, 'cbar'):
|
if hasattr(self, 'cbar'):
|
||||||
self.cbar.remove()
|
self.cbar.remove()
|
||||||
del(self.cbar)
|
del(self.cbar)
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
import sys
|
import sys, os
|
||||||
from PySide.QtCore import QThread, Signal, Qt
|
from PySide.QtCore import QThread, Signal, Qt
|
||||||
from PySide.QtGui import QDialog, QProgressBar, QLabel, QHBoxLayout
|
from PySide.QtGui import QDialog, QProgressBar, QLabel, QHBoxLayout
|
||||||
|
|
||||||
@ -64,7 +64,9 @@ class Thread(QThread):
|
|||||||
except Exception as e:
|
except Exception as e:
|
||||||
self._executed = False
|
self._executed = False
|
||||||
self._executedError = e
|
self._executedError = e
|
||||||
print(e)
|
exc_type, exc_obj, exc_tb = sys.exc_info()
|
||||||
|
fname = os.path.split(exc_tb.tb_frame.f_code.co_filename)[1]
|
||||||
|
print('Exception: {}, file: {}, line: {}'.format(exc_type, fname, exc_tb.tb_lineno))
|
||||||
sys.stdout = sys.__stdout__
|
sys.stdout = sys.__stdout__
|
||||||
|
|
||||||
def __del__(self):
|
def __del__(self):
|
||||||
|
@ -10,9 +10,9 @@ import re
|
|||||||
import warnings
|
import warnings
|
||||||
import subprocess
|
import subprocess
|
||||||
from obspy import UTCDateTime, read
|
from obspy import UTCDateTime, read
|
||||||
from pylot.core.io.inputs import AutoPickParameter
|
from pylot.core.io.inputs import PylotParameter
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def _pickle_method(m):
|
def _pickle_method(m):
|
||||||
if m.im_self is None:
|
if m.im_self is None:
|
||||||
return getattr, (m.im_class, m.im_func.func_name)
|
return getattr, (m.im_class, m.im_func.func_name)
|
||||||
@ -497,7 +497,7 @@ def which(program, infile=None):
|
|||||||
bpath = os.path.join(os.path.expanduser('~'), '.pylot', infile)
|
bpath = os.path.join(os.path.expanduser('~'), '.pylot', infile)
|
||||||
|
|
||||||
if os.path.exists(bpath):
|
if os.path.exists(bpath):
|
||||||
nllocpath = ":" + AutoPickParameter(bpath).get('nllocbin')
|
nllocpath = ":" + PylotParameter(bpath).get('nllocbin')
|
||||||
os.environ['PATH'] += nllocpath
|
os.environ['PATH'] += nllocpath
|
||||||
except ImportError as e:
|
except ImportError as e:
|
||||||
print(e.message)
|
print(e.message)
|
||||||
|
@ -12,6 +12,11 @@ import copy
|
|||||||
import datetime
|
import datetime
|
||||||
import numpy as np
|
import numpy as np
|
||||||
|
|
||||||
|
try:
|
||||||
|
import pyqtgraph as pg
|
||||||
|
except:
|
||||||
|
pg = None
|
||||||
|
|
||||||
from matplotlib.figure import Figure
|
from matplotlib.figure import Figure
|
||||||
from pylot.core.util.utils import find_horizontals
|
from pylot.core.util.utils import find_horizontals
|
||||||
|
|
||||||
@ -31,7 +36,7 @@ from PySide.QtCore import QSettings, Qt, QUrl, Signal, Slot
|
|||||||
from PySide.QtWebKit import QWebView
|
from PySide.QtWebKit import QWebView
|
||||||
from obspy import Stream, UTCDateTime
|
from obspy import Stream, UTCDateTime
|
||||||
from pylot.core.io.data import Data
|
from pylot.core.io.data import Data
|
||||||
from pylot.core.io.inputs import FilterOptions, AutoPickParameter
|
from pylot.core.io.inputs import FilterOptions, PylotParameter
|
||||||
from pylot.core.pick.utils import getSNR, earllatepicker, getnoisewin, \
|
from pylot.core.pick.utils import getSNR, earllatepicker, getnoisewin, \
|
||||||
getResolutionWindow
|
getResolutionWindow
|
||||||
from pylot.core.pick.compare import Comparison
|
from pylot.core.pick.compare import Comparison
|
||||||
@ -42,6 +47,12 @@ from autoPyLoT import autoPyLoT
|
|||||||
from pylot.core.util.thread import Thread
|
from pylot.core.util.thread import Thread
|
||||||
import icons_rc
|
import icons_rc
|
||||||
|
|
||||||
|
if pg:
|
||||||
|
pg.setConfigOption('background', 'w')
|
||||||
|
pg.setConfigOption('foreground', 'k')
|
||||||
|
pg.setConfigOptions(antialias=True)
|
||||||
|
#pg.setConfigOption('leftButtonPan', False)
|
||||||
|
|
||||||
def getDataType(parent):
|
def getDataType(parent):
|
||||||
type = QInputDialog().getItem(parent, "Select phases type", "Type:",
|
type = QInputDialog().getItem(parent, "Select phases type", "Type:",
|
||||||
["manual", "automatic"])
|
["manual", "automatic"])
|
||||||
@ -393,6 +404,174 @@ class PlotWidget(FigureCanvas):
|
|||||||
return self._parent
|
return self._parent
|
||||||
|
|
||||||
|
|
||||||
|
class WaveformWidgetPG(QtGui.QWidget):
|
||||||
|
def __init__(self, parent=None, xlabel='x', ylabel='y', title='Title'):
|
||||||
|
QtGui.QWidget.__init__(self, parent)#, 1)
|
||||||
|
self.setParent(parent)
|
||||||
|
self._parent = parent
|
||||||
|
# attribute plotdict is a dictionary connecting position and a name
|
||||||
|
self.plotdict = dict()
|
||||||
|
# create plot
|
||||||
|
self.main_layout = QtGui.QVBoxLayout()
|
||||||
|
self.label = QtGui.QLabel()
|
||||||
|
self.setLayout(self.main_layout)
|
||||||
|
self.plotWidget = pg.PlotWidget(title=title, autoDownsample=True)
|
||||||
|
self.main_layout.addWidget(self.plotWidget)
|
||||||
|
self.main_layout.addWidget(self.label)
|
||||||
|
self.plotWidget.showGrid(x=False, y=True, alpha=0.2)
|
||||||
|
self.plotWidget.hideAxis('bottom')
|
||||||
|
self.plotWidget.hideAxis('left')
|
||||||
|
self.reinitMoveProxy()
|
||||||
|
self._proxy = pg.SignalProxy(self.plotWidget.scene().sigMouseMoved, rateLimit=60, slot=self.mouseMoved)
|
||||||
|
|
||||||
|
def reinitMoveProxy(self):
|
||||||
|
self.vLine = pg.InfiniteLine(angle=90, movable=False)
|
||||||
|
self.hLine = pg.InfiniteLine(angle=0, movable=False)
|
||||||
|
self.plotWidget.addItem(self.vLine, ignoreBounds=True)
|
||||||
|
self.plotWidget.addItem(self.hLine, ignoreBounds=True)
|
||||||
|
|
||||||
|
def mouseMoved(self, evt):
|
||||||
|
pos = evt[0] ## using signal proxy turns original arguments into a tuple
|
||||||
|
if self.plotWidget.sceneBoundingRect().contains(pos):
|
||||||
|
mousePoint = self.plotWidget.getPlotItem().vb.mapSceneToView(pos)
|
||||||
|
x, y, = (mousePoint.x(), mousePoint.y())
|
||||||
|
#if x > 0:# and index < len(data1):
|
||||||
|
wfID = self._parent.getWFID(y)
|
||||||
|
station = self._parent.getStationName(wfID)
|
||||||
|
if self._parent.get_current_event():
|
||||||
|
self.label.setText("station = {}, t = {} [s]".format(station, x))
|
||||||
|
self.vLine.setPos(mousePoint.x())
|
||||||
|
self.hLine.setPos(mousePoint.y())
|
||||||
|
|
||||||
|
def getPlotDict(self):
|
||||||
|
return self.plotdict
|
||||||
|
|
||||||
|
def setPlotDict(self, key, value):
|
||||||
|
self.plotdict[key] = value
|
||||||
|
|
||||||
|
def clearPlotDict(self):
|
||||||
|
self.plotdict = dict()
|
||||||
|
|
||||||
|
def getParent(self):
|
||||||
|
return self._parent
|
||||||
|
|
||||||
|
def setParent(self, parent):
|
||||||
|
self._parent = parent
|
||||||
|
|
||||||
|
def plotWFData(self, wfdata, title=None, zoomx=None, zoomy=None,
|
||||||
|
noiselevel=None, scaleddata=False, mapping=True,
|
||||||
|
component='*', nth_sample=1, iniPick=None):
|
||||||
|
self.title = title
|
||||||
|
self.clearPlotDict()
|
||||||
|
wfstart, wfend = full_range(wfdata)
|
||||||
|
nmax = 0
|
||||||
|
|
||||||
|
settings = QSettings()
|
||||||
|
compclass = settings.value('compclass')
|
||||||
|
if not compclass:
|
||||||
|
print('Warning: No settings for channel components found. Using default')
|
||||||
|
compclass = SetChannelComponents()
|
||||||
|
|
||||||
|
if not component == '*':
|
||||||
|
alter_comp = compclass.getCompPosition(component)
|
||||||
|
#alter_comp = str(alter_comp[0])
|
||||||
|
|
||||||
|
st_select = wfdata.select(component=component)
|
||||||
|
st_select += wfdata.select(component=alter_comp)
|
||||||
|
else:
|
||||||
|
st_select = wfdata
|
||||||
|
|
||||||
|
# list containing tuples of network, station, channel (for sorting)
|
||||||
|
nsc = []
|
||||||
|
for trace in st_select:
|
||||||
|
nsc.append((trace.stats.network, trace.stats.station, trace.stats.channel))
|
||||||
|
nsc.sort()
|
||||||
|
nsc.reverse()
|
||||||
|
plots = []
|
||||||
|
|
||||||
|
try:
|
||||||
|
self.plotWidget.getPlotItem().vb.setLimits(xMin=float(0),
|
||||||
|
xMax=float(wfend-wfstart),
|
||||||
|
yMin=-0.5,
|
||||||
|
yMax=len(nsc)+0.5)
|
||||||
|
except:
|
||||||
|
print('Warning: Could not set zoom limits')
|
||||||
|
|
||||||
|
for n, (network, station, channel) in enumerate(nsc):
|
||||||
|
st = st_select.select(network=network, station=station, channel=channel)
|
||||||
|
trace = st[0]
|
||||||
|
if mapping:
|
||||||
|
comp = channel[-1]
|
||||||
|
n = compclass.getPlotPosition(str(comp))
|
||||||
|
#n = n[0]
|
||||||
|
if n > nmax:
|
||||||
|
nmax = n
|
||||||
|
msg = 'plotting %s channel of station %s' % (channel, station)
|
||||||
|
print(msg)
|
||||||
|
stime = trace.stats.starttime - wfstart
|
||||||
|
time_ax = prepTimeAxis(stime, trace)
|
||||||
|
if time_ax is not None:
|
||||||
|
if not scaleddata:
|
||||||
|
trace.detrend('constant')
|
||||||
|
trace.normalize(np.max(np.abs(trace.data)) * 2)
|
||||||
|
times = [time for index, time in enumerate(time_ax) if not index%nth_sample]
|
||||||
|
data = [datum + n for index, datum in enumerate(trace.data) if not index%nth_sample]
|
||||||
|
plots.append((times, data))
|
||||||
|
self.setPlotDict(n, (station, channel, network))
|
||||||
|
self.xlabel = 'seconds since {0}'.format(wfstart)
|
||||||
|
self.ylabel = ''
|
||||||
|
self.setXLims([0, wfend - wfstart])
|
||||||
|
self.setYLims([-0.5, nmax + 0.5])
|
||||||
|
return plots
|
||||||
|
|
||||||
|
# def getAxes(self):
|
||||||
|
# return self.axes
|
||||||
|
|
||||||
|
# def getXLims(self):
|
||||||
|
# return self.getAxes().get_xlim()
|
||||||
|
|
||||||
|
# def getYLims(self):
|
||||||
|
# return self.getAxes().get_ylim()
|
||||||
|
|
||||||
|
def setXLims(self, lims):
|
||||||
|
vb = self.plotWidget.getPlotItem().getViewBox()
|
||||||
|
vb.setXRange(float(lims[0]), float(lims[1]), padding=0)
|
||||||
|
|
||||||
|
def setYLims(self, lims):
|
||||||
|
vb = self.plotWidget.getPlotItem().getViewBox()
|
||||||
|
vb.setYRange(float(lims[0]), float(lims[1]), padding=0)
|
||||||
|
|
||||||
|
def setYTickLabels(self, pos, labels):
|
||||||
|
ticks = zip(pos, labels)
|
||||||
|
minorTicks = [(0, 0) for item in labels]
|
||||||
|
# leftAx.tickLength = 5
|
||||||
|
# leftAx.orientation = 'right'
|
||||||
|
self.getAxItem('left').setTicks([ticks, minorTicks])
|
||||||
|
|
||||||
|
def updateXLabel(self, text):
|
||||||
|
self.getAxItem('bottom').setLabel(text)
|
||||||
|
self.draw()
|
||||||
|
|
||||||
|
def updateYLabel(self, text):
|
||||||
|
self.getAxItem('left').setLabel(text)
|
||||||
|
self.draw()
|
||||||
|
|
||||||
|
def getAxItem(self, position):
|
||||||
|
return self.plotWidget.getPlotItem().axes[position]['item']
|
||||||
|
|
||||||
|
def updateTitle(self, text):
|
||||||
|
self.plotWidget.getPlotItem().setTitle(text)
|
||||||
|
self.draw()
|
||||||
|
|
||||||
|
def updateWidget(self):#, xlabel, ylabel, title):
|
||||||
|
self.updateXLabel(self.xlabel)
|
||||||
|
self.updateYLabel(self.ylabel)
|
||||||
|
self.updateTitle(self.title)
|
||||||
|
|
||||||
|
def draw(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
class WaveformWidget(FigureCanvas):
|
class WaveformWidget(FigureCanvas):
|
||||||
def __init__(self, parent=None, xlabel='x', ylabel='y', title='Title'):
|
def __init__(self, parent=None, xlabel='x', ylabel='y', title='Title'):
|
||||||
|
|
||||||
@ -446,18 +625,20 @@ class WaveformWidget(FigureCanvas):
|
|||||||
alter_comp = compclass.getCompPosition(component)
|
alter_comp = compclass.getCompPosition(component)
|
||||||
#alter_comp = str(alter_comp[0])
|
#alter_comp = str(alter_comp[0])
|
||||||
|
|
||||||
wfdata = wfdata.select(component=component)
|
st_select = wfdata.select(component=component)
|
||||||
wfdata += wfdata.select(component=alter_comp)
|
st_select += wfdata.select(component=alter_comp)
|
||||||
|
else:
|
||||||
|
st_select = wfdata
|
||||||
|
|
||||||
# list containing tuples of network, station, channel (for sorting)
|
# list containing tuples of network, station, channel (for sorting)
|
||||||
nsc = []
|
nsc = []
|
||||||
for trace in wfdata:
|
for trace in st_select:
|
||||||
nsc.append((trace.stats.network, trace.stats.station, trace.stats.channel))
|
nsc.append((trace.stats.network, trace.stats.station, trace.stats.channel))
|
||||||
nsc.sort()
|
nsc.sort()
|
||||||
nsc.reverse()
|
nsc.reverse()
|
||||||
|
|
||||||
for n, (network, station, channel) in enumerate(nsc):
|
for n, (network, station, channel) in enumerate(nsc):
|
||||||
st = wfdata.select(network=network, station=station, channel=channel)
|
st = st_select.select(network=network, station=station, channel=channel)
|
||||||
trace = st[0]
|
trace = st[0]
|
||||||
if mapping:
|
if mapping:
|
||||||
comp = channel[-1]
|
comp = channel[-1]
|
||||||
@ -571,6 +752,7 @@ class PickDlg(QDialog):
|
|||||||
self._init_autopicks = {}
|
self._init_autopicks = {}
|
||||||
self.filteroptions = FILTERDEFAULTS
|
self.filteroptions = FILTERDEFAULTS
|
||||||
self.pick_block = False
|
self.pick_block = False
|
||||||
|
self.nextStation = QtGui.QCheckBox('Continue with next station.')
|
||||||
|
|
||||||
# initialize panning attributes
|
# initialize panning attributes
|
||||||
self.press = None
|
self.press = None
|
||||||
@ -664,17 +846,21 @@ class PickDlg(QDialog):
|
|||||||
self.s_button = QPushButton('S', self)
|
self.s_button = QPushButton('S', self)
|
||||||
self.p_button.setCheckable(True)
|
self.p_button.setCheckable(True)
|
||||||
self.s_button.setCheckable(True)
|
self.s_button.setCheckable(True)
|
||||||
# button shortcuts (1 for P-button, 2 for S-button)
|
|
||||||
self.p_button.setShortcut(QKeySequence('1'))
|
|
||||||
self.s_button.setShortcut(QKeySequence('2'))
|
|
||||||
# set button tooltips
|
# set button tooltips
|
||||||
self.p_button.setToolTip('Hotkey: "1"')
|
self.p_button.setToolTip('Hotkey: "1"')
|
||||||
self.s_button.setToolTip('Hotkey: "2"')
|
self.s_button.setToolTip('Hotkey: "2"')
|
||||||
|
|
||||||
# create accept/reject button
|
# create accept/reject button
|
||||||
self.accept_button = QPushButton('&Accept Picks')
|
self.accept_button = QPushButton('&Accept Picks')
|
||||||
self.reject_button = QPushButton('&Reject Picks')
|
self.reject_button = QPushButton('&Reject Picks')
|
||||||
self.disable_ar_buttons()
|
self.disable_ar_buttons()
|
||||||
|
|
||||||
|
# add hotkeys
|
||||||
|
self._shortcut_space = QtGui.QShortcut(QtGui.QKeySequence(' '), self)
|
||||||
|
self._shortcut_space.activated.connect(self.accept_button.clicked)
|
||||||
|
# button shortcuts (1 for P-button, 2 for S-button)
|
||||||
|
self.p_button.setShortcut(QKeySequence('1'))
|
||||||
|
self.s_button.setShortcut(QKeySequence('2'))
|
||||||
|
|
||||||
# layout the outermost appearance of the Pick Dialog
|
# layout the outermost appearance of the Pick Dialog
|
||||||
_outerlayout = QVBoxLayout()
|
_outerlayout = QVBoxLayout()
|
||||||
@ -691,7 +877,9 @@ class PickDlg(QDialog):
|
|||||||
_dialtoolbar.addAction(self.resetPicksAction)
|
_dialtoolbar.addAction(self.resetPicksAction)
|
||||||
if self._embedded:
|
if self._embedded:
|
||||||
_dialtoolbar.addWidget(self.accept_button)
|
_dialtoolbar.addWidget(self.accept_button)
|
||||||
_dialtoolbar.addWidget(self.reject_button)
|
_dialtoolbar.addWidget(self.reject_button)
|
||||||
|
else:
|
||||||
|
_dialtoolbar.addWidget(self.nextStation)
|
||||||
|
|
||||||
# layout the innermost widget
|
# layout the innermost widget
|
||||||
_innerlayout = QVBoxLayout()
|
_innerlayout = QVBoxLayout()
|
||||||
@ -1429,7 +1617,6 @@ class TuneAutopicker(QWidget):
|
|||||||
self.eventBox = self.parent.createEventBox()
|
self.eventBox = self.parent.createEventBox()
|
||||||
self.eventBox.setMaxVisibleItems(20)
|
self.eventBox.setMaxVisibleItems(20)
|
||||||
self.fill_eventbox()
|
self.fill_eventbox()
|
||||||
self.eventBox.setCurrentIndex(0)
|
|
||||||
self.trace_layout.addWidget(self.eventBox)
|
self.trace_layout.addWidget(self.eventBox)
|
||||||
|
|
||||||
def init_stationlist(self):
|
def init_stationlist(self):
|
||||||
@ -1459,7 +1646,7 @@ class TuneAutopicker(QWidget):
|
|||||||
model = self.stationBox.model()
|
model = self.stationBox.model()
|
||||||
for network, station in stations:
|
for network, station in stations:
|
||||||
item = QtGui.QStandardItem(network+'.'+station)
|
item = QtGui.QStandardItem(network+'.'+station)
|
||||||
if station in self.get_current_event().picks:
|
if station in self.get_current_event().pylot_picks:
|
||||||
item.setBackground(self.parent._colors['ref'])
|
item.setBackground(self.parent._colors['ref'])
|
||||||
model.appendRow(item)
|
model.appendRow(item)
|
||||||
|
|
||||||
@ -1475,7 +1662,7 @@ class TuneAutopicker(QWidget):
|
|||||||
self.stb_names = ['aicARHfig', 'refSpick', 'el_S1pick', 'el_S2pick']
|
self.stb_names = ['aicARHfig', 'refSpick', 'el_S1pick', 'el_S2pick']
|
||||||
|
|
||||||
def add_parameters(self):
|
def add_parameters(self):
|
||||||
self.paraBox = AutoPickParaBox(self.parameter)
|
self.paraBox = PylotParaBox(self.parameter)
|
||||||
self.paraBox.set_tune_mode(True)
|
self.paraBox.set_tune_mode(True)
|
||||||
self.update_eventID()
|
self.update_eventID()
|
||||||
self.parameter_layout.addWidget(self.paraBox)
|
self.parameter_layout.addWidget(self.paraBox)
|
||||||
@ -1500,8 +1687,8 @@ class TuneAutopicker(QWidget):
|
|||||||
self.listWidget.scrollToBottom()
|
self.listWidget.scrollToBottom()
|
||||||
|
|
||||||
def get_current_event(self):
|
def get_current_event(self):
|
||||||
index = self.eventBox.currentIndex()
|
path = self.eventBox.currentText()
|
||||||
return self.eventBox.itemData(index)
|
return self.parent.project.getEventFromPath(path)
|
||||||
|
|
||||||
def get_current_event_name(self):
|
def get_current_event_name(self):
|
||||||
return self.eventBox.currentText().split('/')[-1]
|
return self.eventBox.currentText().split('/')[-1]
|
||||||
@ -1511,13 +1698,13 @@ class TuneAutopicker(QWidget):
|
|||||||
|
|
||||||
def get_current_event_picks(self, station):
|
def get_current_event_picks(self, station):
|
||||||
event = self.get_current_event()
|
event = self.get_current_event()
|
||||||
if station in event.picks.keys():
|
if station in event.pylot_picks.keys():
|
||||||
return event.picks[station]
|
return event.pylot_picks[station]
|
||||||
|
|
||||||
def get_current_event_autopicks(self, station):
|
def get_current_event_autopicks(self, station):
|
||||||
event = self.get_current_event()
|
event = self.get_current_event()
|
||||||
if event.autopicks:
|
if event.pylot_autopicks:
|
||||||
return event.autopicks[station]
|
return event.pylot_autopicks[station]
|
||||||
|
|
||||||
def get_current_station(self):
|
def get_current_station(self):
|
||||||
return str(self.stationBox.currentText()).split('.')[-1]
|
return str(self.stationBox.currentText()).split('.')[-1]
|
||||||
@ -1531,6 +1718,9 @@ class TuneAutopicker(QWidget):
|
|||||||
return widget
|
return widget
|
||||||
|
|
||||||
def gen_pick_dlg(self):
|
def gen_pick_dlg(self):
|
||||||
|
if not self.get_current_event():
|
||||||
|
self.pickDlg = None
|
||||||
|
return
|
||||||
station = self.get_current_station()
|
station = self.get_current_station()
|
||||||
data = self.data.getWFData()
|
data = self.data.getWFData()
|
||||||
pickDlg = PickDlg(self, data=data.select(station=station),
|
pickDlg = PickDlg(self, data=data.select(station=station),
|
||||||
@ -1541,7 +1731,6 @@ class TuneAutopicker(QWidget):
|
|||||||
pickDlg.update_picks.connect(self.picks_from_pickdlg)
|
pickDlg.update_picks.connect(self.picks_from_pickdlg)
|
||||||
pickDlg.update_picks.connect(self.fill_eventbox)
|
pickDlg.update_picks.connect(self.fill_eventbox)
|
||||||
pickDlg.update_picks.connect(self.fill_stationbox)
|
pickDlg.update_picks.connect(self.fill_stationbox)
|
||||||
pickDlg.update_picks.connect(self.parent.drawPicks)
|
|
||||||
pickDlg.update_picks.connect(lambda: self.parent.setDirty(True))
|
pickDlg.update_picks.connect(lambda: self.parent.setDirty(True))
|
||||||
pickDlg.update_picks.connect(self.parent.enableSaveManualPicksAction)
|
pickDlg.update_picks.connect(self.parent.enableSaveManualPicksAction)
|
||||||
self.pickDlg = QtGui.QWidget()
|
self.pickDlg = QtGui.QWidget()
|
||||||
@ -1551,7 +1740,15 @@ class TuneAutopicker(QWidget):
|
|||||||
|
|
||||||
def picks_from_pickdlg(self, picks=None):
|
def picks_from_pickdlg(self, picks=None):
|
||||||
station = self.get_current_station()
|
station = self.get_current_station()
|
||||||
|
replot = self.parent.addPicks(station, picks)
|
||||||
self.get_current_event().setPick(station, picks)
|
self.get_current_event().setPick(station, picks)
|
||||||
|
if self.get_current_event() == self.parent.get_current_event():
|
||||||
|
if replot:
|
||||||
|
self.parent.plotWaveformDataThread()
|
||||||
|
self.parent.drawPicks()
|
||||||
|
else:
|
||||||
|
self.parent.drawPicks(station)
|
||||||
|
self.parent.draw()
|
||||||
|
|
||||||
def plot_manual_picks_to_figs(self):
|
def plot_manual_picks_to_figs(self):
|
||||||
picks = self.get_current_event_picks(self.get_current_station())
|
picks = self.get_current_event_picks(self.get_current_station())
|
||||||
@ -1619,7 +1816,7 @@ class TuneAutopicker(QWidget):
|
|||||||
id1 = self.figure_tabs.insertTab(1, self.overview, 'Overview')
|
id1 = self.figure_tabs.insertTab(1, self.overview, 'Overview')
|
||||||
id2 = self.figure_tabs.insertTab(2, self.p_tabs, 'P')
|
id2 = self.figure_tabs.insertTab(2, self.p_tabs, 'P')
|
||||||
id3 = self.figure_tabs.insertTab(3, self.s_tabs, 'S')
|
id3 = self.figure_tabs.insertTab(3, self.s_tabs, 'S')
|
||||||
if picked:
|
if picked and self.get_current_event():
|
||||||
self.fill_p_tabs(canvas_dict)
|
self.fill_p_tabs(canvas_dict)
|
||||||
self.fill_s_tabs(canvas_dict)
|
self.fill_s_tabs(canvas_dict)
|
||||||
self.toggle_autopickTabs(bool(self.fig_dict['mainFig'].axes))
|
self.toggle_autopickTabs(bool(self.fig_dict['mainFig'].axes))
|
||||||
@ -1658,7 +1855,30 @@ class TuneAutopicker(QWidget):
|
|||||||
self.init_tab_names()
|
self.init_tab_names()
|
||||||
|
|
||||||
def fill_eventbox(self):
|
def fill_eventbox(self):
|
||||||
|
project = self.parent.project
|
||||||
|
if not project:
|
||||||
|
return
|
||||||
|
# update own list
|
||||||
self.parent.fill_eventbox(eventBox=self.eventBox, select_events='ref')
|
self.parent.fill_eventbox(eventBox=self.eventBox, select_events='ref')
|
||||||
|
index_start = self.parent.eventBox.currentIndex()
|
||||||
|
index = index_start
|
||||||
|
if index == -1:
|
||||||
|
index += 1
|
||||||
|
nevents = self.eventBox.model().rowCount()
|
||||||
|
path = self.eventBox.itemText(index)
|
||||||
|
if project.getEventFromPath(path).isTestEvent():
|
||||||
|
for index in range(nevents):
|
||||||
|
path = self.eventBox.itemText(index)
|
||||||
|
if project.getEventFromPath(index):
|
||||||
|
if not project.getEventFromPath(index).isTestEvent():
|
||||||
|
break
|
||||||
|
#in case all events are marked as test events and last event is reached
|
||||||
|
if index == nevents - 1:
|
||||||
|
index = -1
|
||||||
|
self.eventBox.setCurrentIndex(index)
|
||||||
|
if not index == index_start:
|
||||||
|
self.eventBox.activated.emit(index)
|
||||||
|
# update parent
|
||||||
self.parent.fill_eventbox()
|
self.parent.fill_eventbox()
|
||||||
|
|
||||||
def update_eventID(self):
|
def update_eventID(self):
|
||||||
@ -1698,8 +1918,8 @@ class TuneAutopicker(QWidget):
|
|||||||
self._warn('Could not execute picker:\n{}'.format(
|
self._warn('Could not execute picker:\n{}'.format(
|
||||||
self.ap_thread._executedError))
|
self.ap_thread._executedError))
|
||||||
return
|
return
|
||||||
self.picks = self.ap_thread.data
|
self.pylot_picks = self.ap_thread.data
|
||||||
if not self.picks:
|
if not self.pylot_picks:
|
||||||
self._warn('No picks found. See terminal output.')
|
self._warn('No picks found. See terminal output.')
|
||||||
return
|
return
|
||||||
#renew tabs
|
#renew tabs
|
||||||
@ -1729,7 +1949,8 @@ class TuneAutopicker(QWidget):
|
|||||||
|
|
||||||
def clear_all(self):
|
def clear_all(self):
|
||||||
if hasattr(self, 'pickDlg'):
|
if hasattr(self, 'pickDlg'):
|
||||||
self.pickDlg.setParent(None)
|
if self.pickDlg:
|
||||||
|
self.pickDlg.setParent(None)
|
||||||
del(self.pickDlg)
|
del(self.pickDlg)
|
||||||
if hasattr(self, 'overview'):
|
if hasattr(self, 'overview'):
|
||||||
self.overview.setParent(None)
|
self.overview.setParent(None)
|
||||||
@ -1754,13 +1975,13 @@ class TuneAutopicker(QWidget):
|
|||||||
self.qmb.show()
|
self.qmb.show()
|
||||||
|
|
||||||
|
|
||||||
class AutoPickParaBox(QtGui.QWidget):
|
class PylotParaBox(QtGui.QWidget):
|
||||||
def __init__(self, parameter, parent=None):
|
def __init__(self, parameter, parent=None):
|
||||||
'''
|
'''
|
||||||
Generate Widget containing parameters for automatic picking algorithm.
|
Generate Widget containing parameters for automatic picking algorithm.
|
||||||
|
|
||||||
:param: parameter
|
:param: parameter
|
||||||
:type: AutoPickParameter (object)
|
:type: PylotParameter (object)
|
||||||
|
|
||||||
'''
|
'''
|
||||||
QtGui.QWidget.__init__(self, parent)
|
QtGui.QWidget.__init__(self, parent)
|
||||||
@ -1773,13 +1994,15 @@ class AutoPickParaBox(QtGui.QWidget):
|
|||||||
self.labels = {}
|
self.labels = {}
|
||||||
self.boxes = {}
|
self.boxes = {}
|
||||||
self.groupboxes = {}
|
self.groupboxes = {}
|
||||||
|
self._exclusive_widgets = []
|
||||||
self._init_sublayouts()
|
self._init_sublayouts()
|
||||||
self.setLayout(self.layout)
|
self.setLayout(self.layout)
|
||||||
self.add_main_parameters_tab()
|
self.add_main_parameters_tab()
|
||||||
self.add_special_pick_parameters_tab()
|
self.add_special_pick_parameters_tab()
|
||||||
self.params_to_gui()
|
self.params_to_gui()
|
||||||
self._toggle_advanced_settings()
|
self._toggle_advanced_settings()
|
||||||
self.resize(720, 1280)
|
self.resize(720, 1280)
|
||||||
|
self.setWindowModality(QtCore.Qt.WindowModality.ApplicationModal)
|
||||||
|
|
||||||
def _init_sublayouts(self):
|
def _init_sublayouts(self):
|
||||||
self._main_layout = QtGui.QVBoxLayout()
|
self._main_layout = QtGui.QVBoxLayout()
|
||||||
@ -1819,7 +2042,7 @@ class AutoPickParaBox(QtGui.QWidget):
|
|||||||
|
|
||||||
def _create_advanced_cb(self):
|
def _create_advanced_cb(self):
|
||||||
self._advanced_cb = QtGui.QCheckBox('Enable Advanced Settings')
|
self._advanced_cb = QtGui.QCheckBox('Enable Advanced Settings')
|
||||||
self._advanced_layout.addWidget(self._advanced_cb)
|
self._advanced_layout.insertWidget(0, self._advanced_cb)
|
||||||
self._advanced_cb.toggled.connect(self._toggle_advanced_settings)
|
self._advanced_cb.toggled.connect(self._toggle_advanced_settings)
|
||||||
|
|
||||||
def _toggle_advanced_settings(self):
|
def _toggle_advanced_settings(self):
|
||||||
@ -1907,31 +2130,31 @@ class AutoPickParaBox(QtGui.QWidget):
|
|||||||
scrollA = QtGui.QScrollArea()
|
scrollA = QtGui.QScrollArea()
|
||||||
scrollA.setWidgetResizable(True)
|
scrollA.setWidgetResizable(True)
|
||||||
scrollA.setWidget(widget)
|
scrollA.setWidget(widget)
|
||||||
|
|
||||||
widget.setLayout(layout)
|
widget.setLayout(layout)
|
||||||
|
|
||||||
self.tabs.addTab(scrollA, name)
|
self.tabs.addTab(scrollA, name)
|
||||||
|
|
||||||
def add_main_parameters_tab(self):
|
def add_main_parameters_tab(self):
|
||||||
self.add_to_layout(self._main_layout, 'Directories',
|
self.add_to_layout(self._main_layout, 'Directories',
|
||||||
self.parameter.get_main_para_names()['dirs'])
|
self.parameter.get_main_para_names()['dirs'], 0)
|
||||||
self.add_to_layout(self._main_layout, 'NLLoc',
|
self.add_to_layout(self._main_layout, 'NLLoc',
|
||||||
self.parameter.get_main_para_names()['nlloc'])
|
self.parameter.get_main_para_names()['nlloc'], 1)
|
||||||
self.add_to_layout(self._main_layout, 'Seismic Moment',
|
self.add_to_layout(self._main_layout, 'Seismic Moment',
|
||||||
self.parameter.get_main_para_names()['smoment'])
|
self.parameter.get_main_para_names()['smoment'], 2)
|
||||||
|
self.add_to_layout(self._main_layout, 'Local Magnitude',
|
||||||
|
self.parameter.get_main_para_names()['localmag'], 3)
|
||||||
self.add_to_layout(self._main_layout, 'Common Settings Characteristic Function',
|
self.add_to_layout(self._main_layout, 'Common Settings Characteristic Function',
|
||||||
self.parameter.get_main_para_names()['pick'])
|
self.parameter.get_main_para_names()['pick'], 4)
|
||||||
self.add_tab(self._main_layout, 'Main Settings')
|
self.add_tab(self._main_layout, 'Main Settings')
|
||||||
|
|
||||||
def add_special_pick_parameters_tab(self):
|
def add_special_pick_parameters_tab(self):
|
||||||
self.add_to_layout(self._advanced_layout, 'Z-component',
|
self.add_to_layout(self._advanced_layout, 'Z-component',
|
||||||
self.parameter.get_special_para_names()['z'])
|
self.parameter.get_special_para_names()['z'], 1)
|
||||||
self.add_to_layout(self._advanced_layout, 'H-components',
|
self.add_to_layout(self._advanced_layout, 'H-components',
|
||||||
self.parameter.get_special_para_names()['h'])
|
self.parameter.get_special_para_names()['h'], 2)
|
||||||
self.add_to_layout(self._advanced_layout, 'First-motion picker',
|
self.add_to_layout(self._advanced_layout, 'First-motion picker',
|
||||||
self.parameter.get_special_para_names()['fm'])
|
self.parameter.get_special_para_names()['fm'], 3)
|
||||||
self.add_to_layout(self._advanced_layout, 'Quality assessment',
|
self.add_to_layout(self._advanced_layout, 'Quality assessment',
|
||||||
self.parameter.get_special_para_names()['quality'])
|
self.parameter.get_special_para_names()['quality'], 4)
|
||||||
self.add_tab(self._advanced_layout, 'Advanced Settings')
|
self.add_tab(self._advanced_layout, 'Advanced Settings')
|
||||||
|
|
||||||
# def gen_h_seperator(self):
|
# def gen_h_seperator(self):
|
||||||
@ -1945,12 +2168,46 @@ class AutoPickParaBox(QtGui.QWidget):
|
|||||||
# font.setBold(True)
|
# font.setBold(True)
|
||||||
# label.setFont(font)
|
# label.setFont(font)
|
||||||
# return label
|
# return label
|
||||||
|
|
||||||
|
def refresh(self):
|
||||||
|
for groupbox in self.groupboxes.values():
|
||||||
|
layout = groupbox._parentLayout
|
||||||
|
position = groupbox._position
|
||||||
|
layout.insertWidget(position, groupbox)
|
||||||
|
|
||||||
|
def get_groupbox_exclusive(self, name):
|
||||||
|
widget = QtGui.QWidget(self, 1)
|
||||||
|
layout = QtGui.QVBoxLayout()
|
||||||
|
widget.setLayout(layout)
|
||||||
|
layout.addWidget(self.groupboxes[name])
|
||||||
|
self._exclusive_widgets.append(widget)
|
||||||
|
return widget
|
||||||
|
|
||||||
|
def get_groupbox_dialog(self, name):
|
||||||
|
widget = self.get_groupbox_exclusive(name)
|
||||||
|
dialog = QtGui.QDialog(self.parent())
|
||||||
|
layout = QtGui.QVBoxLayout()
|
||||||
|
dialog.setLayout(layout)
|
||||||
|
buttonbox = QtGui.QDialogButtonBox(QDialogButtonBox.Ok |
|
||||||
|
QDialogButtonBox.Cancel)
|
||||||
|
buttonbox.accepted.connect(dialog.accept)
|
||||||
|
buttonbox.accepted.connect(self.refresh)
|
||||||
|
buttonbox.accepted.connect(self.params_from_gui)
|
||||||
|
buttonbox.rejected.connect(dialog.reject)
|
||||||
|
buttonbox.rejected.connect(self.refresh)
|
||||||
|
buttonbox.rejected.connect(self.params_to_gui)
|
||||||
|
layout.addWidget(widget)
|
||||||
|
layout.addWidget(buttonbox)
|
||||||
|
self._exclusive_dialog = dialog
|
||||||
|
return dialog
|
||||||
|
|
||||||
def add_to_layout(self, layout, name, items):
|
def add_to_layout(self, layout, name, items, position):
|
||||||
groupbox = QtGui.QGroupBox(name)
|
groupbox = QtGui.QGroupBox(name)
|
||||||
|
groupbox._position = position
|
||||||
|
groupbox._parentLayout = layout
|
||||||
self.groupboxes[name] = groupbox
|
self.groupboxes[name] = groupbox
|
||||||
groupbox.setLayout(self.init_boxes(items))
|
groupbox.setLayout(self.init_boxes(items))
|
||||||
layout.addWidget(groupbox)
|
layout.insertWidget(position, groupbox)
|
||||||
|
|
||||||
def show_groupboxes(self):
|
def show_groupboxes(self):
|
||||||
for name in self.groupboxes.keys():
|
for name in self.groupboxes.keys():
|
||||||
@ -1974,6 +2231,16 @@ class AutoPickParaBox(QtGui.QWidget):
|
|||||||
else:
|
else:
|
||||||
print('Groupbox {} not part of object.'.format(name))
|
print('Groupbox {} not part of object.'.format(name))
|
||||||
|
|
||||||
|
def show_file_buttons(self):
|
||||||
|
self.saveButton.show()
|
||||||
|
self.loadButton.show()
|
||||||
|
self.defaultsButton.show()
|
||||||
|
|
||||||
|
def hide_file_buttons(self):
|
||||||
|
self.saveButton.hide()
|
||||||
|
self.loadButton.hide()
|
||||||
|
self.defaultsButton.hide()
|
||||||
|
|
||||||
def show_parameter(self, name=None):
|
def show_parameter(self, name=None):
|
||||||
if not name:
|
if not name:
|
||||||
for name in self.boxes.keys():
|
for name in self.boxes.keys():
|
||||||
@ -2028,6 +2295,8 @@ class AutoPickParaBox(QtGui.QWidget):
|
|||||||
if type(box) == QtGui.QLineEdit:
|
if type(box) == QtGui.QLineEdit:
|
||||||
box.setText(str(value))
|
box.setText(str(value))
|
||||||
elif type(box) == QtGui.QSpinBox or type(box) == QtGui.QDoubleSpinBox:
|
elif type(box) == QtGui.QSpinBox or type(box) == QtGui.QDoubleSpinBox:
|
||||||
|
if not value:
|
||||||
|
value = 0.
|
||||||
box.setValue(value)
|
box.setValue(value)
|
||||||
elif type(box) == QtGui.QCheckBox:
|
elif type(box) == QtGui.QCheckBox:
|
||||||
if value == 'True':
|
if value == 'True':
|
||||||
@ -2084,6 +2353,14 @@ class AutoPickParaBox(QtGui.QWidget):
|
|||||||
except Exception as e:
|
except Exception as e:
|
||||||
self._warn('Could not restore defaults:\n{}'.format(e))
|
self._warn('Could not restore defaults:\n{}'.format(e))
|
||||||
return
|
return
|
||||||
|
|
||||||
|
def show(self):
|
||||||
|
self.refresh()
|
||||||
|
self.show_parameter()
|
||||||
|
if hasattr(self, '_exclusive_dialog'):
|
||||||
|
self._exclusive_dialog.close()
|
||||||
|
self._exclusive_widgets = []
|
||||||
|
QtGui.QWidget.show(self)
|
||||||
|
|
||||||
def _warn(self, message):
|
def _warn(self, message):
|
||||||
self.qmb = QtGui.QMessageBox(QtGui.QMessageBox.Icon.Warning,
|
self.qmb = QtGui.QMessageBox(QtGui.QMessageBox.Icon.Warning,
|
||||||
@ -2196,6 +2473,7 @@ class PropTab(QWidget):
|
|||||||
|
|
||||||
def resetValues(self, infile=None):
|
def resetValues(self, infile=None):
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
|
||||||
class InputsTab(PropTab):
|
class InputsTab(PropTab):
|
||||||
def __init__(self, parent, infile=None):
|
def __init__(self, parent, infile=None):
|
||||||
@ -2250,7 +2528,7 @@ class InputsTab(PropTab):
|
|||||||
return values
|
return values
|
||||||
|
|
||||||
def resetValues(self, infile):
|
def resetValues(self, infile):
|
||||||
para = AutoPickParameter(infile)
|
para = PylotParameter(infile)
|
||||||
datstruct = para.get('datastructure')
|
datstruct = para.get('datastructure')
|
||||||
if datstruct == 'SeisComp':
|
if datstruct == 'SeisComp':
|
||||||
index = 0
|
index = 0
|
||||||
@ -2307,6 +2585,7 @@ class GraphicsTab(PropTab):
|
|||||||
def __init__(self, parent=None):
|
def __init__(self, parent=None):
|
||||||
super(GraphicsTab, self).__init__(parent)
|
super(GraphicsTab, self).__init__(parent)
|
||||||
self.init_layout()
|
self.init_layout()
|
||||||
|
self.add_pg_cb()
|
||||||
self.add_nth_sample()
|
self.add_nth_sample()
|
||||||
self.setLayout(self.main_layout)
|
self.setLayout(self.main_layout)
|
||||||
|
|
||||||
@ -2321,15 +2600,28 @@ class GraphicsTab(PropTab):
|
|||||||
|
|
||||||
self.spinbox_nth_sample = QtGui.QSpinBox()
|
self.spinbox_nth_sample = QtGui.QSpinBox()
|
||||||
label = QLabel('nth sample')
|
label = QLabel('nth sample')
|
||||||
|
label.setToolTip('Plot every nth sample (to speed up plotting)')
|
||||||
self.spinbox_nth_sample.setMinimum(1)
|
self.spinbox_nth_sample.setMinimum(1)
|
||||||
self.spinbox_nth_sample.setMaximum(10e3)
|
self.spinbox_nth_sample.setMaximum(10e3)
|
||||||
self.spinbox_nth_sample.setValue(int(nth_sample))
|
self.spinbox_nth_sample.setValue(int(nth_sample))
|
||||||
label.setToolTip('Plot every nth sample (to speed up plotting)')
|
self.main_layout.addWidget(label, 1, 0)
|
||||||
self.main_layout.addWidget(label, 0, 0)
|
self.main_layout.addWidget(self.spinbox_nth_sample, 1, 1)
|
||||||
self.main_layout.addWidget(self.spinbox_nth_sample, 0, 1)
|
|
||||||
|
|
||||||
|
def add_pg_cb(self):
|
||||||
|
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 getValues(self):
|
def getValues(self):
|
||||||
values = {'nth_sample': self.spinbox_nth_sample.value()}
|
values = {'nth_sample': self.spinbox_nth_sample.value(),
|
||||||
|
'pyqtgraphic': self.checkbox_pg.isChecked()}
|
||||||
return values
|
return values
|
||||||
|
|
||||||
|
|
||||||
@ -2492,7 +2784,7 @@ class LocalisationTab(PropTab):
|
|||||||
return values
|
return values
|
||||||
|
|
||||||
def resetValues(self, infile):
|
def resetValues(self, infile):
|
||||||
para = AutoPickParameter(infile)
|
para = PylotParameter(infile)
|
||||||
nllocroot = para.get('nllocroot')
|
nllocroot = para.get('nllocroot')
|
||||||
nllocbin = para.get('nllocbin')
|
nllocbin = para.get('nllocbin')
|
||||||
loctool = self.locToolComboBox.setCurrentIndex(3)
|
loctool = self.locToolComboBox.setCurrentIndex(3)
|
||||||
|
Loading…
Reference in New Issue
Block a user