def VCalc(response_trace, _paz, _disp, _coeff, **kwargs): """ Function for calculation of vertical absolute sensitivity of a velocimeter,\ using the trace of displacement calibration sequence on Lennartz CTEW1 \ shake table. :type response_trace: trace object from obspy.core.Trace :param response_trace: Response of the velocimeter of a suitable sequence. \ See ctew1_shaker for performing such a sequence. Its sample rate should be \ at least 20Hz. The recommended sample rate is 100Hz. :type _paz: dict :param _paz: Dictionary containing PAZ and overall sensitivity. The \ sensitivity must only contain the datalogger gain. The gain in the \ dictionary is the A0 normalization constant (see obspy for details). :type _disp: float :param _disp: Vertical displacement of table in meters (normally close to \ 9e-4) :type _coeff: float :param _coeff: Loss due to instruments impedance: \ coeff=(Zsismo+Zdatalogger)/Zdatalogger (1.00326 for STS2 and Q330). :type verbose: bool :param verbose: Boolean flag to output a result for each table step or not. :type plotting: bool :param plotting: Boolean flag to create a plot at each calc stage or not. :type saving: bool :param saving: Boolean flag to write data (in mseed) at each calc stage \ or not. :return: Tuple containing sensitivity, the standard deviation and the SNR. """ #Handling kwargs if 'verbose' in kwargs: verbose=kwargs['verbose'] else: verbose=True if 'saving' in kwargs: saving=kwargs['saving'] else: saving=False if 'plotting' in kwargs: plotting=kwargs['plotting'] else: plotting=True #Copy original trace r_trace=response_trace.copy() #Check if sampling rate is fast enough if (r_trace.stats.sampling_rate < 20): print("[pyCTEW1.VCalc]: Error, sampling rate too slow") exit() #Init plot stream st_plot=Stream() #Add raw trace in plot stream trace=r_trace.copy() trace.stats.location='aa' st_plot.append(trace) #Prepare deconvolution r_trace.detrend('linear') r_trace.detrend('demean') #Taking in account the loss in line due to impedances r_trace.data=r_trace.data/_coeff #Instrumental deconvolution r_trace.simulate(paz_remove=_paz) #Add vel trace in plot stream trace=r_trace.copy() trace.stats.location='bb' st_plot.append(trace) #Extract "motion-free" indices bp=extractNoise(r_trace) #Calculate a polynomial extrapolation of noise, based on data with indices #marked "motion-free" noise=bestFit(bp, r_trace) #Add extrapolated noise in plot stream trace=r_trace.copy() trace.data=noise trace.stats.location='cc' st_plot.append(trace) #Substract extrapolated noise from data r_trace.data=r_trace.data-noise #Calculate noise rms nz=rms(trace) #Calculate data rms sg=rms(r_trace) #Integrate clean trace, ie data in displacemnt r_trace.integrate() #Add displacement trace in plot stream trace=r_trace.copy() trace.stats.location='dd' st_plot.append(trace) #Calculate position between each step, using "motion-free" indices. pos=np.array([]) i_pre=0 for i in range(1, len(bp)): if ( (bp[i]-bp[i-1]) != 1 ): x=range(int(bp[i_pre]), int(bp[i-1])) pos=np.append(pos, np.mean(r_trace.data[x])) i_pre=i #Calcul displacement between each position dispV=np.array([]) for i in range(0, len(pos)-1): dispV=np.append(dispV, pos[i]-pos[i+1]) #Print result (in V/m) at each step, if flag verbose set to True if verbose: for i in range(0, len(dispV)): print('Step #'+str(i+1)+': '+str(dispV[i]/_disp)) #Calculate SNR snr=20*np.log10(sg/nz) #Calculate mean result resultat=np.mean(np.abs(dispV))/_disp #Calculate standard deviation st_deviation=np.std(np.abs(dispV)/_disp) #Plot each trace in plot stream, if flag plotting set to True if plotting: plt.subplot(411) plt.plot(st_plot[0].data) plt.ylabel("raw") plt.subplot(412) plt.plot(st_plot[1].data) plt.ylabel("velocity") plt.subplot(413) plt.plot(st_plot[2].data) plt.ylabel("noise") plt.subplot(414) plt.plot(st_plot[3].data) plt.ylabel("displacement") plt.suptitle(r_trace.id+" CTEW1 absolute calibration") plt.show() #Save plot stream in mseed format, if flag saving set to True if saving: st_plot.write(r_trace.id+".VCalc.mseed", format="MSEED") #Return results return((resultat, st_deviation, snr))
def HCalc(response_trace, _paz, _disp, _coeff, _lBridge, _g, **kwargs): """ Function for calculation of horizontal absolute sensitivity of a \ velocimeter, using the trace of tilt calibration sequence on Lennartz \ CTEW1 shake table. :type response_trace: trace object from obspy.core.trace :param response_trace: Response of the velocimeter. Its sample rate should \ be at least 20Hz. The recommended sample rate is 20Hz, as the function \ differentiates the trace, which amplifies the high frequencies noise. :type _paz: dict :param _paz: Dictionary containing PAZ and overall sensitivity. The \ sensitivity must only contain the datalogger gain. The gain in the \ dictionary is the A0 normalization constant (see obspy for details). :type _disp: float :param _disp: Vertical displacement of table in meters (normally close to \ 1.75e-4) :type _coeff: float :param _coeff: Loss due to instruments impedance: \ coeff=(Zsismo+Zdatalogger)/Zdatalogger (1.00326 for STS2 and Q330). :type _lBridge: float :param _lBridge: Bridge length in meter (normally at 0.396) :type _g: float :param _g: Gravitational constant (normally close to 9.81) :type verbose: bool :param verbose: Boolean flag to output a result for each table step or not. :type plotting: bool :param plotting: Boolean flag to create a plot at each calc stage or not. :type saving: bool :param saving: Boolean flag to write data (in mseed) at each calc stage \ or not. :return: Tuple containing sensitivity, the standard deviation and the SNR. """ #Handling kwargs if 'verbose' in kwargs: verbose=kwargs['verbose'] else: verbose=True if 'saving' in kwargs: saving=kwargs['saving'] else: saving=False if 'plotting' in kwargs: plotting=kwargs['plotting'] else: plotting=True #Copy original trace r_trace=response_trace.copy() #Check if sampling rate is fast enough if (r_trace.stats.sampling_rate < 20): print("[pyCTEW1.HCalc]: Error, sampling rate too slow") exit() #Init plot stream st_plot=Stream() #Add raw trace in plot stream trace=r_trace.copy() trace.stats.location='aa' st_plot.append(trace) #Prepare deconvolution r_trace.detrend('linear') r_trace.detrend('demean') #Taking in account the loss in line due to impedances r_trace.data=r_trace.data/_coeff #Instrumental deconvolution r_trace.simulate(paz_remove=_paz) #Add vel plot in plot stream trace=r_trace.copy() trace.stats.location='bb' st_plot.append(trace) #Differentiate data, ie data in acceleration r_trace.differentiate() #Add acc trace in plot stream trace=r_trace.copy() trace.stats.location='cc' st_plot.append(trace) #Extract "motion-free" indices bp=extractNoise(r_trace) #Select noise indices before sequence for i in range(0, bp.size-1): if bp[i+1]-bp[i]!=1: break; y=range(0, bp[i-1]) #Calculate noise rms. #_util.rms not used because only using a part of trace trace=r_trace.copy() noise=np.sqrt(np.mean(trace.data[y]**2)) #Calculate trace rms trace=r_trace.copy() sg=rms(trace) #Lowpass filter (1Hz), to remove high frequencies noise r_trace.filter('lowpass', freq=1, corners=2) #Add filtered trace in plot stream trace=r_trace.copy() trace.stats.location='dd' st_plot.append(trace) #Extract indices where acc is constant (ie extract "motion-free" from #derivative acc) trace=r_trace.copy() trace.differentiate() acc_indices=extractNoise(trace) #Calc acc at each step acc_const=np.array([]) ai_pre=0 for i in range(0, acc_indices.size-1): if acc_indices[i+1]-acc_indices[i]!=1: acc=np.mean(r_trace[ai_pre:acc_indices[i]]) acc_const=np.append(acc_const, acc) ai_pre=acc_indices[i+1] accV=acc_const[1:] #Print result (in V/(m*s**2)) at each step, if flag verbose set to True if verbose: for i in range(0, len(accV)): print('Step #'+str(i+1)+': '+ \ str(accV[i]*_lBridge*2/(_disp*_g))) #Calc result: AccSensor / AccGauge #with AccGauge=g*sin(alpha)=g*sin(_disp/(2*_lBridge))~=2*g*_lBridge/_disp resultat=np.mean(np.absolute(accV))*_lBridge*2/(_disp*_g) #Calc standard deviation st_deviation=np.std(np.absolute(accV)*_lBridge*2/(_disp*_g)) #Plot each trace in plot stream, if flag plotting set to True if plotting: plt.subplot(411) plt.plot(st_plot[0].data) plt.ylabel("raw") plt.subplot(412) plt.plot(st_plot[1].data) plt.ylabel("velocity") plt.subplot(413) plt.plot(st_plot[2].data) plt.ylabel("acceleration") plt.subplot(414) plt.plot(st_plot[3].data) plt.ylabel("acc.filtered") plt.suptitle(r_trace.id+" CTEW1 absolute calibration") plt.show() #Save plot stream in mseed format, if flag saving set to True if saving: st_plot.write(r_trace.id+".HCalc.mseed", format="MSEED") #Calc SNR snr=20*np.log10(sg/noise) #Return results return ((resultat, st_deviation, snr))