[move] moving functions for Richter and moment magnitude calculation to magnitude module for re-use in autoPyLoT

This commit is contained in:
Sebastian Wehling-Benatelli 2016-09-23 15:12:04 +02:00
parent 04ec43c699
commit bfa7ffc960
2 changed files with 86 additions and 93 deletions

View File

@ -23,10 +23,11 @@ https://www.iconfinder.com/iconsets/flavour
(http://www.gnu.org/copyleft/lesser.html) (http://www.gnu.org/copyleft/lesser.html)
""" """
import matplotlib
import os import os
import sys import sys
import matplotlib
matplotlib.use('Qt4Agg') matplotlib.use('Qt4Agg')
matplotlib.rcParams['backend.qt4'] = 'PySide' matplotlib.rcParams['backend.qt4'] = 'PySide'
@ -37,18 +38,14 @@ from PySide.QtGui import QMainWindow, QInputDialog, QIcon, QFileDialog, \
QDialog, QErrorMessage, QApplication, QPixmap, QMessageBox, QSplashScreen, \ QDialog, QErrorMessage, QApplication, QPixmap, QMessageBox, QSplashScreen, \
QActionGroup, QListWidget, QDockWidget, QLineEdit QActionGroup, QListWidget, QDockWidget, QLineEdit
import numpy as np import numpy as np
import subprocess
from obspy import UTCDateTime from obspy import UTCDateTime
from obspy.geodetics import degrees2kilometers
from obspy.core.event import Magnitude
from pylot.core.analysis.magnitude import calcsourcespec, calcMoMw, \ from pylot.core.analysis.magnitude import calc_richter_magnitude, calc_moment_magnitude
calc_woodanderson_pp, gutenberg_richter_relation
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, AutoPickParameter
from pylot.core.pick.autopick import autopickevent from pylot.core.pick.autopick import autopickevent
from pylot.core.pick.compare import Comparison from pylot.core.pick.compare import Comparison
from pylot.core.pick.utils import symmetrize_error, select_for_phase from pylot.core.pick.utils import symmetrize_error
from pylot.core.io.phases import picksdict_from_picks from pylot.core.io.phases import picksdict_from_picks
import pylot.core.loc.nll as nll import pylot.core.loc.nll as nll
from pylot.core.util.defaults import FILTERDEFAULTS, COMPNAME_MAP, \ from pylot.core.util.defaults import FILTERDEFAULTS, COMPNAME_MAP, \
@ -66,7 +63,6 @@ from pylot.core.util.widgets import FilterOptionsDialog, NewEventDlg, \
from pylot.core.util.structure import DATASTRUCTURE from pylot.core.util.structure import DATASTRUCTURE
from pylot.core.util.thread import AutoPickThread from pylot.core.util.thread import AutoPickThread
from pylot.core.util.version import get_git_version as _getVersionString from pylot.core.util.version import get_git_version as _getVersionString
import icons_rc
locateTool = dict(nll=nll) locateTool = dict(nll=nll)
@ -991,50 +987,7 @@ class MainWindow(QMainWindow):
def calc_magnitude(self, type='ML'): def calc_magnitude(self, type='ML'):
if type == 'ML':
return self.calc_richter_magnitude()
elif type == 'Mw':
return self.calc_moment_magnitude()
else:
return None
def calc_richter_magnitude(self):
e = self.get_data().get_evt_data()
if e.origins:
o = e.origins[0]
mags = dict()
for a in o.arrivals:
if a.phase not in 'sS':
continue
pick = a.pick_id.get_referred_object()
station = pick.waveform_id.station_code
wf = select_for_phase(self.get_data().getWFData().select(
station=station), a.phase)
delta = degrees2kilometers(a.distance)
wapp = calc_woodanderson_pp(wf, self.metadata, pick.time,
self.inputs.get('sstop'))
# using standard Gutenberg-Richter relation
# TODO make the ML calculation more flexible by allowing
# use of custom relation functions
mag = np.log10(wapp) + gutenberg_richter_relation(delta)
mags[station] = mag
mag = np.median([M for M in mags.values()])
# give some information on the processing
print('number of stations used: {0}\n'.format(len(mags.values())))
print('stations used:\n')
for s in mags.keys(): print('\t{0}'.format(s))
return Magnitude(mag=mag, magnitude_type='ML')
else:
return None
def calc_moment_magnitude(self):
e = self.get_data().get_evt_data()
settings = QSettings() settings = QSettings()
if e.origins:
o = e.origins[0]
mags = dict()
fninv = settings.value("inventoryFile", None) fninv = settings.value("inventoryFile", None)
if fninv is None and not self.metadata: if fninv is None and not self.metadata:
fninv, _ = QFileDialog.getOpenFileName(self, self.tr( fninv, _ = QFileDialog.getOpenFileName(self, self.tr(
@ -1049,31 +1002,10 @@ class MainWindow(QMainWindow):
settings.setValue("inventoryFile", fninv) settings.setValue("inventoryFile", fninv)
settings.sync() settings.sync()
self.metadata = read_metadata(fninv) self.metadata = read_metadata(fninv)
for a in o.arrivals: if type == 'ML':
if a.phase in 'sS': return calc_richter_magnitude(self.get_data().get_evt_data(), self.get_data().getWFData(), self.metadata, self.inputs.get('sstop'))
continue elif type == 'Mw':
pick = a.pick_id.get_referred_object() return calc_moment_magnitude(self.get_data().get_evt_data(), self.get_data().getWFData(), self.metadata, self.inputs.get('vp'), self.inputs.get('Qp'), self.inputs.get('rho'))
station = pick.waveform_id.station_code
wf = self.get_data().getWFData().select(station=station)
if not wf:
continue
onset = pick.time
dist = degrees2kilometers(a.distance)
w0, fc = calcsourcespec(wf, onset, metadata, self.inputs.get('vp'), dist,
a.azimuth, a.takeoff_angle,
self.inputs.get('Qp'), 0)
if w0 is None or fc is None:
continue
station_mag = calcMoMw(wf, w0, self.inputs.get('rho'),
self.inputs.get('vp'), dist)
mags[station] = station_mag
mag = np.median([M[1] for M in mags.values()])
# give some information on the processing
print('number of stations used: {0}\n'.format(len(mags.values())))
print('stations used:\n')
for s in mags.keys(): print('\t{0}'.format(s))
return Magnitude(mag=mag, magnitude_type='Mw')
else: else:
return None return None

View File

@ -9,11 +9,13 @@ import os
import matplotlib.pyplot as plt import matplotlib.pyplot as plt
import numpy as np import numpy as np
from obspy.core import Stream, UTCDateTime from obspy.core import Stream, UTCDateTime
from pylot.core.pick.utils import getsignalwin, crossings_nonzero_all from obspy.core.event import Magnitude
from obspy.geodetics import degrees2kilometers
from pylot.core.pick.utils import getsignalwin, crossings_nonzero_all, select_for_phase
from pylot.core.util.utils import getPatternLine from pylot.core.util.utils import getPatternLine
from scipy.optimize import curve_fit from scipy.optimize import curve_fit
from scipy import integrate, signal from scipy import integrate, signal
from pylot.core.io.data import Data
from pylot.core.util.dataprocessing import restitute_data, read_metadata from pylot.core.util.dataprocessing import restitute_data, read_metadata
from pylot.core.util.utils import common_range, fit_curve from pylot.core.util.utils import common_range, fit_curve
@ -667,3 +669,62 @@ def fitSourceModel(f, S, fc0, iplot):
plt.close() plt.close()
return w0, fc return w0, fc
def calc_richter_magnitude(e, wf, metadata, amp_win):
if e.origins:
o = e.origins[0]
mags = dict()
for a in o.arrivals:
if a.phase not in 'sS':
continue
pick = a.pick_id.get_referred_object()
station = pick.waveform_id.station_code
wf = select_for_phase(wf.select(
station=station), a.phase)
delta = degrees2kilometers(a.distance)
wapp = calc_woodanderson_pp(wf, metadata, pick.time,
amp_win)
# using standard Gutenberg-Richter relation
# TODO make the ML calculation more flexible by allowing
# use of custom relation functions
mag = np.log10(wapp) + gutenberg_richter_relation(delta)
mags[station] = mag
mag = np.median([M for M in mags.values()])
# give some information on the processing
print('number of stations used: {0}\n'.format(len(mags.values())))
print('stations used:\n')
for s in mags.keys(): print('\t{0}'.format(s))
return Magnitude(mag=mag, magnitude_type='ML')
else:
return None
def calc_moment_magnitude(e, wf, metadata, vp, Qp, rho):
if e.origins:
o = e.origins[0]
mags = dict()
for a in o.arrivals:
if a.phase in 'sS':
continue
pick = a.pick_id.get_referred_object()
station = pick.waveform_id.station_code
wf = wf.select(station=station)
if not wf:
continue
onset = pick.time
dist = degrees2kilometers(a.distance)
w0, fc = calcsourcespec(wf, onset, metadata, vp, dist, a.azimuth, a.takeoff_angle, Qp, 0)
if w0 is None or fc is None:
continue
station_mag = calcMoMw(wf, w0, rho, vp, dist)
mags[station] = station_mag
mag = np.median([M[1] for M in mags.values()])
# give some information on the processing
print('number of stations used: {0}\n'.format(len(mags.values())))
print('stations used:\n')
for s in mags.keys(): print('\t{0}'.format(s))
return Magnitude(mag=mag, magnitude_type='Mw')
else:
return None