Esempio n. 1
0
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))
Esempio n. 2
0
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))