Re-implemented second option for calculating fit to source spectrum, take median of both options; some bug fixes
This commit is contained in:
parent
570e47f2df
commit
5a2aeeb70d
@ -229,7 +229,7 @@ class LocalMagnitude(Magnitude):
|
|||||||
sqH = np.sqrt(power_sum)
|
sqH = np.sqrt(power_sum)
|
||||||
|
|
||||||
# get time array
|
# get time array
|
||||||
th = np.arange(0, st[0].stats.npts / st[0].stats.sampling_rate, st[0].stats.delta)
|
th = np.arange(0, st[0].stats.npts / st[0].stats.sampling_rate, 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)])
|
ii = min([iwin[len(iwin) - 1], len(th)])
|
||||||
@ -449,17 +449,18 @@ def calcMoMw(wfstream, w0, rho, vp, delta, verbosity=False):
|
|||||||
|
|
||||||
if verbosity:
|
if verbosity:
|
||||||
print(
|
print(
|
||||||
"calcMoMw: Calculating seismic moment Mo and moment magnitude Mw for station {0} ...".format(
|
"calcMoMw: Calculating seismic moment Mo and moment magnitude Mw \
|
||||||
tr.stats.station))
|
for station {0} ...".format(tr.stats.station))
|
||||||
|
|
||||||
# additional common parameters for calculating Mo
|
# additional common parameters for calculating Mo
|
||||||
rP = 2 / np.sqrt(
|
# average radiation pattern of P waves (Aki & Richards, 1980)
|
||||||
15) # average radiation pattern of P waves (Aki & Richards, 1980)
|
rP = 2 / np.sqrt(15)
|
||||||
freesurf = 2.0 # free surface correction, assuming vertical incidence
|
freesurf = 2.0 # free surface correction, assuming vertical incidence
|
||||||
|
|
||||||
Mo = w0 * 4 * np.pi * rho * np.power(vp, 3) * delta / (rP * freesurf)
|
Mo = w0 * 4 * np.pi * rho * np.power(vp, 3) * delta / (rP * freesurf)
|
||||||
|
|
||||||
# Mw = np.log10(Mo * 1e07) * 2 / 3 - 10.7 # after Hanks & Kanamori (1979), defined for [dyn*cm]!
|
# Mw = np.log10(Mo * 1e07) * 2 / 3 - 10.7 # after Hanks & Kanamori (1979),
|
||||||
|
# defined for [dyn*cm]!
|
||||||
Mw = np.log10(Mo) * 2 / 3 - 6.7 # for metric units
|
Mw = np.log10(Mo) * 2 / 3 - 6.7 # for metric units
|
||||||
|
|
||||||
if verbosity:
|
if verbosity:
|
||||||
@ -519,7 +520,7 @@ def calcsourcespec(wfstream, onset, vp, delta, azimuth, incidence,
|
|||||||
|
|
||||||
dist = delta * 1000 # hypocentral distance in [m]
|
dist = delta * 1000 # hypocentral distance in [m]
|
||||||
|
|
||||||
fc = None
|
Fc = None
|
||||||
w0 = None
|
w0 = None
|
||||||
|
|
||||||
zdat = select_for_phase(wfstream, "P")
|
zdat = select_for_phase(wfstream, "P")
|
||||||
@ -575,9 +576,7 @@ def calcsourcespec(wfstream, onset, vp, delta, azimuth, incidence,
|
|||||||
print("calcsourcespec: Something is wrong with the waveform, "
|
print("calcsourcespec: Something is wrong with the waveform, "
|
||||||
"no zero crossings derived!\n")
|
"no zero crossings derived!\n")
|
||||||
print("No calculation of source spectrum possible!")
|
print("No calculation of source spectrum possible!")
|
||||||
plotflag = 0
|
|
||||||
else:
|
else:
|
||||||
plotflag = 1
|
|
||||||
index = min([3, len(zc) - 1])
|
index = min([3, len(zc) - 1])
|
||||||
calcwin = (zc[index] - zc[0]) * dt
|
calcwin = (zc[index] - zc[0]) * dt
|
||||||
iwin = getsignalwin(t, rel_onset, calcwin)
|
iwin = getsignalwin(t, rel_onset, calcwin)
|
||||||
@ -585,9 +584,9 @@ def calcsourcespec(wfstream, onset, vp, delta, azimuth, incidence,
|
|||||||
|
|
||||||
# fft
|
# fft
|
||||||
fny = freq / 2
|
fny = freq / 2
|
||||||
l = len(xdat) / freq
|
#l = len(xdat) / freq
|
||||||
# number of fft bins after Bath
|
# number of fft bins after Bath
|
||||||
n = freq * l
|
#n = freq * l
|
||||||
# find next power of 2 of data length
|
# find next power of 2 of data length
|
||||||
m = pow(2, np.ceil(np.log(len(xdat)) / np.log(2)))
|
m = pow(2, np.ceil(np.log(len(xdat)) / np.log(2)))
|
||||||
N = int(np.power(m, 2))
|
N = int(np.power(m, 2))
|
||||||
@ -619,25 +618,23 @@ def calcsourcespec(wfstream, onset, vp, delta, azimuth, incidence,
|
|||||||
# use of implicit scipy otimization function
|
# use of implicit scipy otimization function
|
||||||
fit = synthsourcespec(F, w0in, Fcin)
|
fit = synthsourcespec(F, w0in, Fcin)
|
||||||
[optspecfit, _] = curve_fit(synthsourcespec, F, YYcor, [w0in, Fcin])
|
[optspecfit, _] = curve_fit(synthsourcespec, F, YYcor, [w0in, Fcin])
|
||||||
w0 = optspecfit[0]
|
w01 = optspecfit[0]
|
||||||
fc = optspecfit[1]
|
fc1 = optspecfit[1]
|
||||||
# w01 = optspecfit[0]
|
|
||||||
# fc1 = optspecfit[1]
|
|
||||||
if verbosity:
|
if verbosity:
|
||||||
print("calcsourcespec: Determined w0-value: %e m/Hz, \n"
|
print("calcsourcespec: Determined w0-value: %e m/Hz, \n"
|
||||||
"calcsourcespec: Determined corner frequency: %f Hz" % (w0, fc))
|
"calcsourcespec: Determined corner frequency: %f Hz" % (w01, fc1))
|
||||||
|
|
||||||
# use of conventional fitting
|
# use of conventional fitting
|
||||||
# [w02, fc2] = fitSourceModel(F, YYcor, Fcin, iplot, verbosity)
|
[w02, fc2] = fitSourceModel(F, YYcor, Fcin, 2, verbosity)
|
||||||
|
|
||||||
# get w0 and fc as median of both
|
# get w0 and fc as median of both
|
||||||
# source spectrum fits
|
# source spectrum fits
|
||||||
# w0 = np.median([w01, w02])
|
w0 = np.median([w01, w02])
|
||||||
# fc = np.median([fc1, fc2])
|
Fc = np.median([fc1, fc2])
|
||||||
# if verbosity:
|
if verbosity:
|
||||||
# print("calcsourcespec: Using w0-value = %e m/Hz and fc = %f Hz" % (
|
print("calcsourcespec: Using w0-value = %e m/Hz and fc = %f Hz" % (
|
||||||
# w0, fc))
|
w0, Fc))
|
||||||
if iplot > 1:
|
if iplot >= 1:
|
||||||
f1 = plt.figure()
|
f1 = plt.figure()
|
||||||
tLdat = np.arange(0, len(Ldat) * dt, dt)
|
tLdat = np.arange(0, len(Ldat) * dt, dt)
|
||||||
plt.subplot(2, 1, 1)
|
plt.subplot(2, 1, 1)
|
||||||
@ -645,7 +642,7 @@ def calcsourcespec(wfstream, onset, vp, delta, azimuth, incidence,
|
|||||||
p1, = plt.plot(t, np.multiply(inttrz, 1000), 'k')
|
p1, = plt.plot(t, np.multiply(inttrz, 1000), 'k')
|
||||||
p2, = plt.plot(tLdat, np.multiply(Ldat, 1000))
|
p2, = plt.plot(tLdat, np.multiply(Ldat, 1000))
|
||||||
plt.legend([p1, p2], ['Displacement', 'Rotated Displacement'])
|
plt.legend([p1, p2], ['Displacement', 'Rotated Displacement'])
|
||||||
if plotflag == 1:
|
if iplot == 1:
|
||||||
plt.plot(t[iwin], np.multiply(xdat, 1000), 'g')
|
plt.plot(t[iwin], np.multiply(xdat, 1000), 'g')
|
||||||
plt.title('Seismogram and P Pulse, Station %s-%s' \
|
plt.title('Seismogram and P Pulse, Station %s-%s' \
|
||||||
% (zdat[0].stats.station, zdat[0].stats.channel))
|
% (zdat[0].stats.station, zdat[0].stats.channel))
|
||||||
@ -655,19 +652,19 @@ def calcsourcespec(wfstream, onset, vp, delta, azimuth, incidence,
|
|||||||
plt.xlabel('Time since %s' % zdat[0].stats.starttime)
|
plt.xlabel('Time since %s' % zdat[0].stats.starttime)
|
||||||
plt.ylabel('Displacement [mm]')
|
plt.ylabel('Displacement [mm]')
|
||||||
|
|
||||||
if plotflag == 1:
|
if iplot >= 1:
|
||||||
plt.subplot(2, 1, 2)
|
plt.subplot(2, 1, 2)
|
||||||
p1, = plt.loglog(f, Y.real, 'k')
|
p1, = plt.loglog(f, Y.real, 'k')
|
||||||
p2, = plt.loglog(F, YY.real)
|
p2, = plt.loglog(F, YY.real)
|
||||||
p3, = plt.loglog(F, YYcor, 'r')
|
p3, = plt.loglog(F, YYcor, 'r')
|
||||||
p4, = plt.loglog(F, fit, 'g')
|
p4, = plt.loglog(F, fit, 'g')
|
||||||
plt.loglog([fc, fc], [w0 / 100, w0], 'g')
|
plt.loglog([Fc, Fc], [w0 / 100, w0], 'g')
|
||||||
plt.legend([p1, p2, p3, p4], ['Raw Spectrum',
|
plt.legend([p1, p2, p3, p4], ['Raw Spectrum',
|
||||||
'Used Raw Spectrum',
|
'Used Raw Spectrum',
|
||||||
'Q-Corrected Spectrum',
|
'Q-Corrected Spectrum',
|
||||||
'Fit to Spectrum'])
|
'Fit to Spectrum'])
|
||||||
plt.title('Source Spectrum from P Pulse, w0=%e m/Hz, fc=%6.2f Hz' \
|
plt.title('Source Spectrum from P Pulse, w0=%e m/Hz, fc=%6.2f Hz' \
|
||||||
% (w0, fc))
|
% (w0, Fc))
|
||||||
plt.xlabel('Frequency [Hz]')
|
plt.xlabel('Frequency [Hz]')
|
||||||
plt.ylabel('Amplitude [m/Hz]')
|
plt.ylabel('Amplitude [m/Hz]')
|
||||||
plt.grid()
|
plt.grid()
|
||||||
@ -678,7 +675,7 @@ def calcsourcespec(wfstream, onset, vp, delta, azimuth, incidence,
|
|||||||
pass
|
pass
|
||||||
plt.close(f1)
|
plt.close(f1)
|
||||||
|
|
||||||
return w0, fc
|
return w0, Fc
|
||||||
|
|
||||||
|
|
||||||
def synthsourcespec(f, omega0, fcorner):
|
def synthsourcespec(f, omega0, fcorner):
|
||||||
@ -776,35 +773,36 @@ def fitSourceModel(f, S, fc0, iplot, verbosity=False):
|
|||||||
|
|
||||||
# get best found w0 anf fc from minimum
|
# get best found w0 anf fc from minimum
|
||||||
if len(STD) > 0:
|
if len(STD) > 0:
|
||||||
fc = fc[np.argmin(STD)]
|
Fc = fc[np.argmin(STD)]
|
||||||
w0 = w0[np.argmin(STD)]
|
w0 = w0[np.argmin(STD)]
|
||||||
elif len(STD) == 0:
|
elif len(STD) == 0:
|
||||||
fc = fc0
|
Fc = fc0
|
||||||
w0 = max(S)
|
w0 = max(S)
|
||||||
if verbosity:
|
if verbosity:
|
||||||
print(
|
print(
|
||||||
"fitSourceModel: best fc: {0} Hz, best w0: {1} m/Hz".format(fc, w0))
|
"fitSourceModel: best fc: {0} Hz, best w0: {1} m/Hz".format(fc, w0))
|
||||||
if iplot > 1:
|
if iplot > 0:
|
||||||
plt.figure() # iplot)
|
plt.figure() # iplot)
|
||||||
plt.loglog(f, S, 'k')
|
plt.loglog(f, S, 'k')
|
||||||
plt.loglog([f[0], fc], [w0, w0], 'g')
|
plt.loglog([f[0], Fc], [w0, w0], 'g')
|
||||||
plt.loglog([fc, fc], [w0 / 100, w0], 'g')
|
plt.loglog([Fc, Fc], [w0 / 100, w0], 'g')
|
||||||
plt.title('Calculated Source Spectrum, Omega0=%e m/Hz, fc=%6.2f Hz' \
|
plt.title('Calculated Source Spectrum, Omega0=%e m/Hz, fc=%6.2f Hz' \
|
||||||
% (w0, fc))
|
% (w0, Fc))
|
||||||
plt.xlabel('Frequency [Hz]')
|
plt.xlabel('Frequency [Hz]')
|
||||||
plt.ylabel('Amplitude [m/Hz]')
|
plt.ylabel('Amplitude [m/Hz]')
|
||||||
plt.grid()
|
plt.grid()
|
||||||
|
if iplot == 2:
|
||||||
plt.figure() # iplot + 1)
|
plt.figure() # iplot + 1)
|
||||||
plt.subplot(311)
|
plt.subplot(311)
|
||||||
plt.plot(f[il:ir], STD, '*')
|
plt.plot(fc, STD, '*')
|
||||||
plt.title('Common Standard Deviations')
|
plt.title('Common Standard Deviations')
|
||||||
plt.xticks([])
|
plt.xticks([])
|
||||||
plt.subplot(312)
|
plt.subplot(312)
|
||||||
plt.plot(f[il:ir], stdw0, '*')
|
plt.plot(fc, stdw0, '*')
|
||||||
plt.title('Standard Deviations of w0-Values')
|
plt.title('Standard Deviations of w0-Values')
|
||||||
plt.xticks([])
|
plt.xticks([])
|
||||||
plt.subplot(313)
|
plt.subplot(313)
|
||||||
plt.plot(f[il:ir], stdfc, '*')
|
plt.plot(fc, stdfc, '*')
|
||||||
plt.title('Standard Deviations of Corner Frequencies')
|
plt.title('Standard Deviations of Corner Frequencies')
|
||||||
plt.xlabel('Corner Frequencies [Hz]')
|
plt.xlabel('Corner Frequencies [Hz]')
|
||||||
plt.show()
|
plt.show()
|
||||||
@ -814,4 +812,4 @@ def fitSourceModel(f, S, fc0, iplot, verbosity=False):
|
|||||||
pass
|
pass
|
||||||
plt.close()
|
plt.close()
|
||||||
|
|
||||||
return w0, fc
|
return w0, Fc
|
||||||
|
0
pylot/core/util/generate_array_maps.py
Normal file → Executable file
0
pylot/core/util/generate_array_maps.py
Normal file → Executable file
Loading…
Reference in New Issue
Block a user