Merge remote-tracking branch 'origin/develop' into develop

This commit is contained in:
ann-christin 2022-11-14 10:30:38 +01:00
commit 3b3bbc29d1
9 changed files with 110047 additions and 109103 deletions

View File

@ -60,7 +60,7 @@ except ImportError:
from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas
from matplotlib.figure import Figure
from pylot.core.analysis.magnitude import LocalMagnitude, MomentMagnitude
from pylot.core.analysis.magnitude import LocalMagnitude, MomentMagnitude, calcsourcespec
from pylot.core.io.data import Data
from pylot.core.io.inputs import FilterOptions, PylotParameter
from autoPyLoT import autoPyLoT
@ -83,7 +83,8 @@ from pylot.core.io.location import create_creation_info, create_event
from pylot.core.util.widgets import FilterOptionsDialog, NewEventDlg, \
PylotCanvas, WaveformWidgetPG, PropertiesDlg, HelpForm, createAction, PickDlg, \
ComparisonWidget, TuneAutopicker, PylotParaBox, AutoPickDlg, CanvasWidget, AutoPickWidget, \
CompareEventsWidget, ProgressBarWidget, AddMetadataWidget, SingleTextLineDialog, LogWidget
CompareEventsWidget, ProgressBarWidget, AddMetadataWidget, SingleTextLineDialog, LogWidget, PickQualitiesFromXml, \
SourceSpecWindow, ChooseWaveFormWindow
from pylot.core.util.array_map import Array_map
from pylot.core.util.structure import DATASTRUCTURE
from pylot.core.util.thread import Thread, Worker
@ -734,12 +735,22 @@ class MainWindow(QMainWindow):
if use_logwidget:
self.logwidget = LogWidget(parent=None)
self.logwidget.show()
self.stdout = self.logwidget.stdout
self.stderr = self.logwidget.stderr
sys.stdout = self.logwidget.stdout
sys.stderr = self.logwidget.stderr
sys.stdout = self.stdout
sys.stderr = self.stderr
# Not sure why but the lines above kept messing with the Ouput even with use_logwidget disabled
sys.stdout = self.stdout
sys.stderr = self.stderr
self.setCentralWidget(_widget)
# Need to store PickQualities Window somewhere so it doesnt disappear
self.pickQualitiesWindow = None
def init_wfWidget(self):
xlab = self.startTime.strftime('seconds since %Y/%m/%d %H:%M:%S (%Z)')
plottitle = None # "Overview: {0} components ".format(self.getComponent())
@ -1668,15 +1679,41 @@ class MainWindow(QMainWindow):
def pickQualities(self):
path = self.get_current_event_path()
getQualitiesfromxml(path, self._inputs.get('timeerrorsP'), self._inputs.get('timeerrorsS'), plotflag=1)
return
(_, _, plot) = getQualitiesfromxml(path, self._inputs.get('timeerrorsP'), self._inputs.get('timeerrorsS'),plotflag=1)
self.pickQualitiesWindow = PickQualitiesFromXml(figure=plot, path=self.get_current_event_path(),inputVar=self._inputs)
self.pickQualitiesWindow.showUI()
return
def eventlistXml(self):
# WIP JG
def eventlistXml2(self):
path = self._inputs['rootpath'] + '/' + self._inputs['datapath'] + '/' + self._inputs['database']
outpath = self.project.location[:self.project.location.rfind('/')]
geteventlistfromxml(path, outpath)
return
# WIP JG
def eventlistXml(self):
global test
stations = []
names = []
traces = {}
for tr in self.get_data().wfdata.traces:
if not tr.stats.station in stations:
stations.append(tr.stats.station)
names.append(tr.stats.network + '.' + tr.stats.station)
for station in stations:
traces[station] = {}
for ch in ['Z', 'N', 'E']:
for tr in self.get_data().wfdata.select(component=ch).traces:
traces[tr.stats.station][ch] = tr
names.sort()
a = self.get_current_event()
test = ChooseWaveFormWindow(WaveForms=names, traces=traces, stream=self.get_data())
#self.get_data().wfdata.spectrogram()
test.show()
def compareMulti(self):
if not self.compareoptions:
return
@ -3075,11 +3112,13 @@ class MainWindow(QMainWindow):
lt = locateTool[loctool]
# get working directory
locroot = parameter['nllocroot']
#locroot = 'E:/NLL/src/Insheim'
if locroot is None:
self.PyLoTprefs()
self.locate_event()
ctrfile = os.path.join(locroot, 'run', parameter['ctrfile'])
#ctrfile = 'E:/NLL/src/Insheim/run/Insheim_min1d032016.in'
ttt = parameter['ttpatter']
outfile = parameter['outpatter']
eventname = self.get_current_event_name()
@ -3090,7 +3129,7 @@ class MainWindow(QMainWindow):
phasefile = os.path.join(obsdir, filename + '.obs')
lt.modify_inputs(ctrfile, locroot, filename, phasefile, ttt)
try:
lt.locate(ctrfile)
lt.locate(ctrfile, self.obspy_dmt)
except RuntimeError as e:
print(e.message)
# finally:
@ -3495,7 +3534,7 @@ class MainWindow(QMainWindow):
wf_select = Stream()
# restitute only picked traces
for station in np.unique(self.getPicks('manual').keys() + self.getPicks('auto').keys()):
for station in np.unique(list(self.getPicks('manual').keys()) + list(self.getPicks('auto').keys())):
wf_select += wf_copy.select(station=station)
corr_wf = restitute_data(wf_select, self.metadata)

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.2 KiB

218853
icons_rc_3.py

File diff suppressed because it is too large Load Diff

View File

@ -144,6 +144,10 @@ class Magnitude(object):
azimuthal_gap=self.origin_id.get_referred_object().quality.azimuthal_gap)
else:
# no scaling necessary
# Temporary fix needs rework
if (len(self.magnitudes.keys()) == 0):
print("Error in local magnitude calculation ")
return None
mag = ope.Magnitude(
mag=np.median([M.mag for M in self.magnitudes.values()]),
magnitude_type=self.type,
@ -432,6 +436,40 @@ class MomentMagnitude(Magnitude):
self.event.station_magnitudes.append(magnitude)
self.magnitudes = (station, magnitude)
# WIP JG
def getSourceSpec(self):
for a in self.arrivals:
if a.phase not in 'pP':
continue
# make sure calculating Mo only from reliable onsets
# NLLoc: time_weight = 0 => do not use onset!
if a.time_weight == 0:
continue
pick = a.pick_id.get_referred_object()
station = pick.waveform_id.station_code
if len(self.stream) <= 2:
print("Station:" '{0}'.format(station))
print("WARNING: No instrument corrected data available,"
" no magnitude calculation possible! Go on.")
continue
wf = self.stream.select(station=station)
if not wf:
continue
try:
scopy = wf.copy()
except AssertionError:
print("WARNING: Something's wrong with the data,"
"station {},"
"no calculation of moment magnitude possible! Go on.".format(station))
continue
onset = pick.time
distance = degrees2kilometers(a.distance)
azimuth = a.azimuth
incidence = a.takeoff_angle
w0, fc, plt = calcsourcespec(scopy, onset, self.p_velocity, distance,
azimuth, incidence, self.p_attenuation,
3, self.verbose)
return w0, fc, plt
def calcMoMw(wfstream, w0, rho, vp, delta, verbosity=False):
'''
@ -602,7 +640,7 @@ def calcsourcespec(wfstream, onset, vp, delta, azimuth, incidence,
N = min(int(np.power(m, 2)), 16384)
# N = int(np.power(m, 2))
y = dt * np.fft.fft(xdat, N)
Y = abs(y[: N / 2])
Y = abs(y[: int(N / 2)])
L = (N - 1) / freq
f = np.arange(0, fny, 1 / L)
@ -679,6 +717,8 @@ def calcsourcespec(wfstream, onset, vp, delta, azimuth, incidence,
plt.xlabel('Frequency [Hz]')
plt.ylabel('Amplitude [m/Hz]')
plt.grid()
if iplot == 3:
return w0, Fc, plt
plt.show()
try:
input()

View File

@ -82,7 +82,7 @@ def locate(fnin, parameter=None):
:param fnin: external program name
:return: None
"""
exe_path = which('NLLoc', parameter)
exe_path = parameter['nllocbin'] + '/bin/NLLoc'
if exe_path is None:
raise NLLocError('NonLinLoc executable not found; check your '
'environment variables')

View File

@ -16,10 +16,9 @@ autoregressive prediction: application ot local and regional distances, Geophys.
:author: MAGS2 EP3 working group
"""
import numpy as np
from obspy.core import Stream
from scipy import signal
from obspy.core import Stream
class CharacteristicFunction(object):
@ -259,7 +258,7 @@ class HOScf(CharacteristicFunction):
"""
Function to calculate skewness (statistics of order 3) or kurtosis
(statistics of order 4), using one long moving window, as published
in Kueperkoch et al. (2010).
in Kueperkoch et al. (2010), or order 2, i.e. STA/LTA.
:param data: data, time series (whether seismogram or CF)
:type data: tuple
:return: HOS cf
@ -276,28 +275,47 @@ class HOScf(CharacteristicFunction):
elif self.getOrder() == 4: # this is kurtosis
y = np.power(xnp, 4)
y1 = np.power(xnp, 2)
elif self.getOrder() == 2: # this is variance, used for STA/LTA processing
y = np.power(xnp, 2)
y1 = np.power(xnp, 2)
# Initialisation
# t2: long term moving window
ilta = int(round(self.getTime2() / self.getIncrement()))
ista = int(round((self.getTime2() / 10) / self.getIncrement())) # TODO: still hard coded!!
lta = y[0]
lta1 = y1[0]
sta = y[0]
# moving windows
LTA = np.zeros(len(xnp))
STA = np.zeros(len(xnp))
for j in range(0, len(xnp)):
if j < 4:
LTA[j] = 0
STA[j] = 0
elif j <= ista:
lta = (y[j] + lta * (j - 1)) / j
if self.getOrder() == 2:
sta = (y[j] + sta * (j - 1)) / j
# elif j < 4:
elif j <= ilta:
lta = (y[j] + lta * (j - 1)) / j
lta1 = (y1[j] + lta1 * (j - 1)) / j
if self.getOrder() == 2:
sta = (y[j] - y[j - ista]) / ista + sta
else:
lta = (y[j] - y[j - ilta]) / ilta + lta
lta1 = (y1[j] - y1[j - ilta]) / ilta + lta1
if self.getOrder() == 2:
sta = (y[j] - y[j - ista]) / ista + sta
# define LTA
if self.getOrder() == 3:
LTA[j] = lta / np.power(lta1, 1.5)
elif self.getOrder() == 4:
LTA[j] = lta / np.power(lta1, 2)
else:
LTA[j] = lta
STA[j] = sta
# remove NaN's with first not-NaN-value,
# so autopicker doesnt pick discontinuity at start of the trace
@ -306,7 +324,10 @@ class HOScf(CharacteristicFunction):
first = ind[0]
LTA[:first] = LTA[first]
self.cf = LTA
if self.getOrder() > 2:
self.cf = LTA
else: # order 2 means STA/LTA!
self.cf = STA / LTA
self.xcf = x

View File

@ -56,7 +56,7 @@ def which(program, parameter):
nllocpath = ":" + parameter.get('nllocbin')
os.environ['PATH'] += nllocpath
except Exception as e:
print(e.message)
print(e)
def is_exe(fpath):
return os.path.exists(fpath) and os.access(fpath, os.X_OK)

View File

@ -1,7 +1,6 @@
# -*- coding: utf-8 -*-
"""
Created on Wed Mar 19 11:27:35 2014
@author: sebastianw
"""
@ -3161,7 +3160,6 @@ class CanvasWidget(QWidget):
class MultiEventWidget(QWidget):
start = Signal()
'''
'''
def __init__(self, options=None, parent=None, windowflag=Qt.Window):
@ -3438,7 +3436,6 @@ class TuneAutopicker(QWidget):
update = QtCore.Signal(str)
'''
QWidget used to modifiy and test picking parameters for autopicking algorithm.
:param: parent
:type: PyLoT Mainwindow
'''
@ -3959,10 +3956,8 @@ class PylotParaBox(QtWidgets.QWidget):
def __init__(self, parameter, parent=None, windowflag=Qt.Window):
'''
Generate Widget containing parameters for PyLoT.
:param: parameter
:type: PylotParameter (object)
'''
QtWidgets.QWidget.__init__(self, parent, windowflag)
self.parameter = parameter
@ -5561,7 +5556,165 @@ class HelpForm(QDialog):
self.pageLabel.setText(self.webBrowser.title())
class PickQualitiesFromXml(QWidget):
"""
PyLoT widget PickQualitiesFromXml is a QWidget object. It is an UI that enables the user
to create a plot showing the pick qualities in the event selected inside the QComboBox created
by this Widget. The user can also choose to select all Events.
The plot is being shown by a FigureCanvas from matlplotlib.
"""
def __init__(self, parent=None, figure=Figure(), path="", inputVar=None):
super(PickQualitiesFromXml, self).__init__(parent)
self.fig = figure
self.chooseBox = QComboBox()
self.path = path
self.inputs = inputVar
self.setupUi()
def setupUi(self):
self.setWindowTitle("Get pick qualities from xml files")
self.main_layout = QtWidgets.QVBoxLayout()
self.figureC = FigureCanvas(self.fig)
self.chooseBox = self.createComboBox()
if self.chooseBox:
self.main_layout.addWidget(self.chooseBox)
self.main_layout.addWidget(self.figureC)
self.setLayout(self.main_layout)
def showUI(self):
self.show()
# Creates a QComboBox and adds all events in the current folder as options. Also gives the option to choose all events
def createComboBox(self):
self.chooseBox.addItems(glob.glob(os.path.join(os.path.dirname(self.path) + "/*/", '*.xml')))
self.chooseBox.addItem("All")
self.chooseBox.currentIndexChanged.connect(self.selectionChanged)
self.chooseBox.setCurrentIndex(self.chooseBox.count() - 1)
return self.chooseBox
# Function that gets called when the user changes the current selection in the QComboBox. Redraws the plot with the new data
def selectionChanged(self):
self.figureC.setParent(None)
if self.chooseBox.currentIndex() == self.chooseBox.count() - 1:
(_, _, plot) = getQualitiesfromxml(self.path, self.inputs.get('timeerrorsP'),
self.inputs.get('timeerrorsS'), plotflag=1)
self.figureC = FigureCanvas(plot)
else:
(_, _, plot) = getQualitiesfromxml(self.path, self.inputs.get('timeerrorsP'),
self.inputs.get('timeerrorsS'), plotflag=1,
xmlnames=[self.chooseBox.currentText()])
self.figureC = FigureCanvas(plot)
self.figureC.draw()
self.main_layout.addWidget(self.figureC)
self.setLayout(self.main_layout)
class SourceSpecWindow(QWidget):
def __init__(self, parent=None, figure=Figure()):
super(SourceSpecWindow, self).__init__(parent)
self.main_layout = QVBoxLayout()
self.setWindowTitle("Display source spectrum from selected trace")
self.fig = figure
def setupUi(self):
self.figureC = FigureCanvas(self.fig)
self.main_layout.addWidget(self.figureC)
self.setLayout(self.main_layout)
class ChooseWaveFormWindow(QWidget):
def __init__(self, parent=None, WaveForms=[], traces=[], stream=None, chooseB=False):
super(ChooseWaveFormWindow, self).__init__(parent)
self.main_layout = QVBoxLayout()
self.setWindowTitle("Choose trace to display source spectrum")
self.wFs = WaveForms
self.chooseBoxTraces = QComboBox()
self.chooseBoxComponent = QComboBox()
self.submitButton = QPushButton(text='test')
self.chooseB = chooseB
self.verticalButton = QPushButton(text='Z')
self.northButton = QPushButton(text='N')
self.eastButton = QPushButton(text='E')
self.component = ''
self.traces = traces
self.stream = stream
self.setupUI()
self.currentSpectro = Figure()
def setupUI(self):
self.submitButton.clicked.connect(self.submit)
self.createComboBoxTraces()
self.main_layout.addWidget(self.chooseBoxTraces)
if self.chooseB:
self.createComboBoxComponent()
self.main_layout.addWidget(self.submitButton)
self.main_layout.addWidget(self.chooseBoxComponent)
else:
self.createButtonsComponent()
self.setLayout(self.main_layout)
def submit(self):
matplotlib.pyplot.close(self.currentSpectro)
t = self.chooseBoxTraces.currentText() + " " + self.chooseBoxComponent.currentText()
self.currentSpectro = self.traces[
self.chooseBoxTraces.currentText()[3:]][self.chooseBoxComponent.currentText()].spectrogram(show=False, title=t)
self.currentSpectro.show()
def submitN(self):
matplotlib.pyplot.close(self.currentSpectro)
t = self.chooseBoxTraces.currentText() + " " + self.chooseBoxComponent.currentText()
self.currentSpectro = self.traces[
self.chooseBoxTraces.currentText()[3:]]['N'].spectrogram(show=False, title=t)
self.currentSpectro.show()
def submitE(self):
matplotlib.pyplot.close(self.currentSpectro)
t = self.chooseBoxTraces.currentText() + " " + self.chooseBoxComponent.currentText()
self.currentSpectro = self.traces[
self.chooseBoxTraces.currentText()[3:]]['E'].spectrogram(show=False, title=t)
self.currentSpectro.show()
def submitZ(self):
matplotlib.pyplot.close(self.currentSpectro)
t = self.chooseBoxTraces.currentText() + " " + self.chooseBoxComponent.currentText()
self.currentSpectro = self.traces[
self.chooseBoxTraces.currentText()[3:]]['Z'].spectrogram(show=False, title=t)
self.currentSpectro.show()
# Creates a QComboBox and adds all traces provided
def createComboBoxTraces(self):
if len(self.wFs) <= 0:
raise 'No traces provided'
self.chooseBoxTraces.addItems(self.wFs)
self.chooseBoxTraces.currentIndexChanged.connect(self.selectionChanged)
self.chooseBoxTraces.setCurrentIndex(0)
return self.chooseBoxTraces
def createButtonsComponent(self):
self.northButton.clicked.connect(self.submitN)
self.eastButton.clicked.connect(self.submitE)
self.verticalButton.clicked.connect(self.submitZ)
self.main_layout.addWidget(self.verticalButton)
self.main_layout.addWidget(self.northButton)
self.main_layout.addWidget(self.eastButton)
def createComboBoxComponent(self):
self.chooseBoxComponent.addItems(['Z', 'N', 'E'])
# Function that gets called when the user changes the current selection in the QComboBox.
def selectionChanged(self):
pass
if __name__ == '__main__':
import doctest
doctest.testmod()
doctest.testmod()