New function to derive plateau and corner frequency of observed source spectrum. Additional to scipys implicit function curve_fit, as seismic moment is sensitive to estimated plateau of source spectrum, which in turn is sensitivec to estimated corner frequency.
This commit is contained in:
		
							parent
							
								
									d29c57ab4b
								
							
						
					
					
						commit
						957d2ccfe7
					
				| @ -135,10 +135,10 @@ class WApp(Magnitude): | |||||||
|             plt.close(f) |             plt.close(f) | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| class DCfc(Magnitude): | class w0fc(Magnitude): | ||||||
|     ''' |     ''' | ||||||
|     Method to calculate the source spectrum and to derive from that the plateau |     Method to calculate the source spectrum and to derive from that the plateau | ||||||
|     (so-called DC-value) and the corner frequency assuming Aki's omega-square |     (usually called omega0) and the corner frequency assuming Aki's omega-square | ||||||
|     source model. Has to be derived from instrument corrected displacement traces! |     source model. Has to be derived from instrument corrected displacement traces! | ||||||
|     ''' |     ''' | ||||||
| 
 | 
 | ||||||
| @ -176,20 +176,23 @@ class DCfc(Magnitude): | |||||||
|         YY = Y[fi] |         YY = Y[fi] | ||||||
|         # get plateau (DC value) and corner frequency |         # get plateau (DC value) and corner frequency | ||||||
|         # initial guess of plateau |         # initial guess of plateau | ||||||
|         DCin = np.mean(YY[0:100]) |         w0in = np.mean(YY[0:100]) | ||||||
|         # initial guess of corner frequency |         # initial guess of corner frequency | ||||||
|         # where spectral level reached 50% of flat level |         # where spectral level reached 50% of flat level | ||||||
|         iin = np.where(YY >= 0.5 * DCin) |         iin = np.where(YY >= 0.5 * w0in) | ||||||
|         Fcin = F[iin[0][np.size(iin) - 1]] |         Fcin = F[iin[0][np.size(iin) - 1]] | ||||||
|         fit = synthsourcespec(F, DCin, Fcin) |         # use of implicit scipy function | ||||||
|         [optspecfit, pcov] = curve_fit(synthsourcespec, F, YY.real, [DCin, Fcin]) |         fit = synthsourcespec(F, w0in, Fcin) | ||||||
|         self.w0 = optspecfit[0] |         [optspecfit, pcov] = curve_fit(synthsourcespec, F, YY.real, [w0in, Fcin]) | ||||||
|         self.fc = optspecfit[1] |         self.w01 = optspecfit[0] | ||||||
|         print ("DCfc: Determined DC-value: %e m/Hz, \n" |         self.fc1 = optspecfit[1] | ||||||
|                "Determined corner frequency: %f Hz" % (self.w0, self.fc)) |         print ("w0fc: Determined w0-value: %e m/Hz, \n" | ||||||
|  |                "Determined corner frequency: %f Hz" % (self.w01, self.fc1)) | ||||||
|  |          | ||||||
|  |         # use of conventional fitting  | ||||||
|  |         [self.w02, self.fc2] = fitSourceModel(F, YY.real, Fcin, self.getiplot()) | ||||||
| 
 | 
 | ||||||
| 
 | 	if self.getiplot() > 1: | ||||||
|         if self.getiplot() > 1: |  | ||||||
|             f1 = plt.figure() |             f1 = plt.figure() | ||||||
|             plt.subplot(2,1,1) |             plt.subplot(2,1,1) | ||||||
|             # show displacement in mm |             # show displacement in mm | ||||||
| @ -203,7 +206,8 @@ class DCfc(Magnitude): | |||||||
|             plt.loglog(f, Y.real, 'k') |             plt.loglog(f, Y.real, 'k') | ||||||
|             plt.loglog(F, YY.real) |             plt.loglog(F, YY.real) | ||||||
|             plt.loglog(F, fit, 'g') |             plt.loglog(F, fit, 'g') | ||||||
|             plt.title('Source Spectrum from P Pulse, DC=%e m/Hz, fc=%4.1f Hz' \ |             plt.loglog([self.fc, self.fc], [self.w0/100, self.w0], 'g')  | ||||||
|  |             plt.title('Source Spectrum from P Pulse, w0=%e m/Hz, fc=%6.2f Hz' \ | ||||||
|                        % (self.w0, self.fc)) |                        % (self.w0, self.fc)) | ||||||
|             plt.xlabel('Frequency [Hz]') |             plt.xlabel('Frequency [Hz]') | ||||||
|             plt.ylabel('Amplitude [m/Hz]') |             plt.ylabel('Amplitude [m/Hz]') | ||||||
| @ -233,3 +237,92 @@ def synthsourcespec(f, omega0, fcorner): | |||||||
| 
 | 
 | ||||||
|     return ssp |     return ssp | ||||||
| 
 | 
 | ||||||
|  | 
 | ||||||
|  | def fitSourceModel(f, S, fc0, iplot): | ||||||
|  |     ''' | ||||||
|  |     Calculates synthetic source spectrum by varying corner frequency fc. | ||||||
|  |     Returns best approximated plateau omega0 and corner frequency, i.e. with least  | ||||||
|  |     common standard deviations.  | ||||||
|  | 
 | ||||||
|  |     :param:  f, frequencies | ||||||
|  |     :type:   array | ||||||
|  | 
 | ||||||
|  |     :param:  S, observed source spectrum | ||||||
|  |     :type:   array | ||||||
|  | 
 | ||||||
|  |     :param:  fc0, initial corner frequency | ||||||
|  |     :type:   float | ||||||
|  |     ''' | ||||||
|  | 
 | ||||||
|  |     w0 =  [] | ||||||
|  |     stdw0 = [] | ||||||
|  |     fc = [] | ||||||
|  |     stdfc = [] | ||||||
|  |     STD = [] | ||||||
|  | 
 | ||||||
|  |     # get window around initial corner frequency for trials | ||||||
|  |     fcstopl = fc0 - max(1, len(f) / 10) | ||||||
|  |     il = np.argmin(abs(f-fcstopl)) | ||||||
|  |     fcstopl = f[il] | ||||||
|  |     fcstopr = fc0 + min(len(f), len(f) /10)  | ||||||
|  |     ir = np.argmin(abs(f-fcstopr)) | ||||||
|  |     fcstopr = f[ir] | ||||||
|  |     iF = np.where((f >= fcstopl) & (f <= fcstopr)) | ||||||
|  | 
 | ||||||
|  |     # vary corner frequency around initial point | ||||||
|  |     for i in range(il, ir):  | ||||||
|  |         FC = f[i] | ||||||
|  |         indexdc = np.where((f > 0 ) & (f <= FC)) | ||||||
|  |         dc = np.mean(S[indexdc]) | ||||||
|  |         stddc = np.std(dc - S[indexdc]) | ||||||
|  |         w0.append(dc) | ||||||
|  |         stdw0.append(stddc) | ||||||
|  |         fc.append(FC) | ||||||
|  |         # slope | ||||||
|  |         indexfc = np.where((f >= FC) & (f <= fcstopr)) | ||||||
|  |         yi = dc/(1+(f[indexfc]/FC)**2) | ||||||
|  |         stdFC = np.std(yi - S[indexfc]) | ||||||
|  |         stdfc.append(stdFC) | ||||||
|  |         STD.append(stddc + stdFC) | ||||||
|  | 
 | ||||||
|  |     # get best found w0 anf fc from minimum | ||||||
|  |     fc = fc[np.argmin(STD)] | ||||||
|  |     w0 = w0[np.argmin(STD)] | ||||||
|  |     print("fitSourceModel: best fc: %fHz, best w0: %e m/Hz" \ | ||||||
|  |            % (fc, w0)) | ||||||
|  | 
 | ||||||
|  |     if iplot > 1: | ||||||
|  |         plt.figure(iplot) | ||||||
|  |         plt.loglog(f, S, 'k') | ||||||
|  |         plt.loglog([f[0], fc], [w0, w0], 'g') | ||||||
|  |         plt.loglog([fc, fc], [w0/100, w0], 'g')  | ||||||
|  |         plt.title('Calculated Source Spectrum, Omega0=%e m/Hz, fc=%6.2f Hz' \ | ||||||
|  |                    % (w0, fc))  | ||||||
|  |         plt.xlabel('Frequency [Hz]') | ||||||
|  |         plt.ylabel('Amplitude [m/Hz]') | ||||||
|  |         plt.grid() | ||||||
|  |         plt.figure(iplot+1) | ||||||
|  |         plt.subplot(311) | ||||||
|  |         plt.plot(f[il:ir], STD,'*') | ||||||
|  |         plt.title('Common Standard Deviations') | ||||||
|  |         plt.xticks([]) | ||||||
|  |         plt.subplot(312) | ||||||
|  |         plt.plot(f[il:ir], stdw0,'*') | ||||||
|  |         plt.title('Standard Deviations of w0-Values') | ||||||
|  |         plt.xticks([]) | ||||||
|  |         plt.subplot(313) | ||||||
|  |         plt.plot(f[il:ir],stdfc,'*') | ||||||
|  |         plt.title('Standard Deviations of Corner Frequencies') | ||||||
|  |         plt.xlabel('Corner Frequencies [Hz]') | ||||||
|  |         plt.show() | ||||||
|  |         raw_input() | ||||||
|  |         plt.close() | ||||||
|  | 
 | ||||||
|  |     return w0, fc | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user