Esempio n. 1
0
 def remove_resp(self, trace, paz=None):
     
     # removing response...
     if paz:
         # ...using paz:
         if trace.stats.sampling_rate > 10.0:
             # decimating large trace, else fft crashes
             factor = int(np.ceil(trace.stats.sampling_rate / 10))
             trace.decimate(factor=factor, no_filter=True)
         trace.simulate(paz_remove=paz,
                        paz_simulate=obspy.signal.cornFreq2Paz(0.01),
                        remove_sensitivity=True,
                        simulate_sensitivity=True,
                        nfft_pow2=True)
     else:
         # ...using StationXML:
         # first band-pass to downsample data before removing response
         # (else remove_response() method is slow or even hangs)
         trace.filter(type="bandpass",
                      freqmin=self.freqmin,
                      freqmax=self.freqmax,
                      corners=self.corners,
                      zerophase=self.zerophase)
         psutils.resample(trace, dt_resample=self.period_resample)
         trace.remove_response(output="VEL", zero_mean=True)
     return trace
Esempio n. 2
0
    def remove_resp(self, trace, paz=None):

        # removing response...
        if paz:
            # ...using paz:
            if trace.stats.sampling_rate > 10.0:
                # decimating large trace, else fft crashes
                factor = int(np.ceil(trace.stats.sampling_rate / 10))
                trace.decimate(factor=factor, no_filter=True)
            trace.simulate(paz_remove=paz,
                           paz_simulate=obspy.signal.cornFreq2Paz(0.01),
                           remove_sensitivity=True,
                           simulate_sensitivity=True,
                           nfft_pow2=True)
        else:
            # ...using StationXML:
            # first band-pass to downsample data before removing response
            # (else remove_response() method is slow or even hangs)
            trace.filter(type="bandpass",
                         freqmin=self.freqmin,
                         freqmax=self.freqmax,
                         corners=self.corners,
                         zerophase=self.zerophase)
            psutils.resample(trace, dt_resample=self.period_resample)
            trace.remove_response(output="VEL", zero_mean=True)
        return trace
Esempio n. 3
0
    def time_norm(self, trace, trcopy):

        if self.onebit_norm:
            # one-bit normalization
            trace.data = np.sign(trace.data)
        else:
            # normalization of the signal by the running mean
            # in the earthquake frequency band
            trcopy.filter(type="bandpass",
                          freqmin=self.freqmin_earthquake,
                          freqmax=self.freqmax_earthquake,
                          corners=self.corners,
                          zerophase=self.zerophase)
        # decimating trace
        psutils.resample(trcopy, self.period_resample)

        # Time-normalization weights from smoothed abs(data)
        # Note that trace's data can be a masked array
        halfwindow = int(
            round(self.window_time * trcopy.stats.sampling_rate / 2))
        mask = ~trcopy.data.mask if np.ma.isMA(trcopy.data) else None
        tnorm_w = psutils.moving_avg(np.abs(trcopy.data),
                                     halfwindow=halfwindow,
                                     mask=mask)
        if np.ma.isMA(trcopy.data):
            # turning time-normalization weights into a masked array
            s = "[warning: {}.{} trace's data is a masked array]"
            print s.format(trace.stats.network, trace.stats.station),
            tnorm_w = np.ma.masked_array(tnorm_w, trcopy.data.mask)

        if np.any((tnorm_w == 0.0) | np.isnan(tnorm_w)):
            # illegal normalizing value -> skipping trace
            raise pserrors.CannotPreprocess("Zero or NaN normalization weight")

        # time-normalization
        trace.data /= tnorm_w

        return trace
Esempio n. 4
0
    def time_norm(self, trace, trcopy):
        
        if self.onebit_norm:
            # one-bit normalization
            trace.data = np.sign(trace.data)
        else:
            # normalization of the signal by the running mean
            # in the earthquake frequency band
            trcopy.filter(type="bandpass",
                      freqmin=self.freqmin_earthquake,
                      freqmax=self.freqmax_earthquake,
                      corners=self.corners,
                      zerophase=self.zerophase)
        # decimating trace
        psutils.resample(trcopy, self.period_resample)

        # Time-normalization weights from smoothed abs(data)
        # Note that trace's data can be a masked array
        halfwindow = int(round(self.window_time*trcopy.stats.sampling_rate/2))
        mask = ~trcopy.data.mask if np.ma.isMA(trcopy.data) else None
        tnorm_w = psutils.moving_avg(np.abs(trcopy.data),
                                     halfwindow=halfwindow,
                                     mask=mask)
        if np.ma.isMA(trcopy.data):
            # turning time-normalization weights into a masked array
            s = "[warning: {}.{} trace's data is a masked array]"
            print s.format(trace.stats.network, trace.stats.station),
            tnorm_w = np.ma.masked_array(tnorm_w, trcopy.data.mask)

        if np.any((tnorm_w == 0.0) | np.isnan(tnorm_w)):
            # illegal normalizing value -> skipping trace
            raise pserrors.CannotPreprocess("Zero or NaN normalization weight")

        # time-normalization
        trace.data /= tnorm_w
        
        return trace
Esempio n. 5
0
    def preprocess_trace(self, trace, paz=None, verbose=False):
        """
        Preprocesses a trace (so that it is ready to be cross-correlated),
        by applying the following steps:
            - removal of instrument response, mean and trend
            - band-pass filtering between *freqmin*-*freqmax*
            - downsampling to *period_resample* secs
            - time-normalization (one-bit normalization or normalization
              by the running mean in the earthquake frequency band)
            - spectral whitening (if running mean normalization)

        Raises CannotPreprocess exception if:
            - trace only contains 0 (happens sometimes...)
            - a normalization weight is 0 or NaN
            - a Nan appeared in trace data
            
        Note that the processing steps are performed in-place.

        @type trace: L{Trace}
        @param paz: poles and zeros of instrumental response
                    (set None if response is directly attached to trace)

        """
        
        # =======================================
        # Check if any data to work with to begin
        # =======================================
        if np.all(trace.data == 0.0):
            # no data -> skipping trace
            raise pserrors.CannotPreprocess("Only zeros")
        
        # ==========================
        # Remove instrument response
        # ==========================
        if RESP_REMOVE:
            t1 = dt.datetime.now()
            trace = self.remove_resp(trace, paz=paz)
            delta = (dt.datetime.now() - t1).total_seconds()
            if verbose:
                print "\nRemoved response in {:.1f} seconds".format(delta)
        
        
        #Initialise the AutoTrigger class for the current trace
        if HIGHAMP_REMOVE:
            # this check finds high amplitude noise creates a list of where it is located in the signal
            TRIGGER = AutoTrigger(trace, freqmin=FREQMIN, freqmax=FREQMAX)
            UTC_events = TRIGGER.trigger_times(check=True)
            if UTC_events is not None:
                # set the application to remove these parts from the trace!
                trace_new = None
                for event in UTC_events:
                    # event is a list of length 2, start and end times
                    # use trace.trim(starttime=x, endtime=y)
                    # trace 1 is from trace start until the event starttime                        
                    trace1 = trace.trim(starttime=trace.stats.starttime,
                                        endtime=event[0])
                    trace2 = trace.trim(starttime=event[1],
                                        endtime=trace.stats.endtime)
                    if trace_new is None:
                        trace_new = trace1 + trace2
                    else:
                        trace_new += (trace1 + trace2)
                
                # trace_new has removed all high amp. noise from trace original
                trace = trace_new
                print trace.data
                
        # ==============================================
        # Check trace data completeness is above MINFILL
        # ==============================================        
        if COMPLETENESS:
            # Data fill for current TIME INTERVAL!
            # CHECK THAT THE get_fill_trace function works! 
            fill = psutils.get_fill_trace(trace)
            
            if fill < MINFILL:
                # not enough data
                raise pserrors.CannotPreprocess("{:.0f}% fill"\
                .format(fill*100))
                
        # ========================
        # Trim, demean and detrend
        # ========================        
        if TDD:
            t1 = dt.datetime.now()
            midt = trace.stats.starttime + (trace.stats.endtime -
            trace.stats.starttime) / 2.0
            
            t0 = UTCDateTime(midt.date)# date of trace, at time 00h00m00s
            trace.trim(starttime=t0, endtime=t0 + dt.timedelta(days=1))
            trace.detrend(type='constant')
            trace.detrend(type='linear')
            delta = (dt.datetime.now() - t1).total_seconds()
            if verbose:
                print "\nProcessed trim in {:.1f} seconds".format(delta)

        
        # =========
        # Band-pass
        # =========
        if BANDPASS:
            t0 = dt.datetime.now()
            trace.filter(type="bandpass",
                         freqmin=self.freqmin,
                         freqmax=self.freqmax,
                         corners=self.corners,
                         zerophase=self.zerophase)
            delta = (dt.datetime.now() - t0).total_seconds()
            if verbose:
                print "\nProcessed filters in {:.1f} seconds".format(delta)
                
        # ============
        # Downsampling
        # ============
        if DOWNSAMPLE:
            if abs(1.0 / trace.stats.sampling_rate - self.period_resample)>EPS:
                psutils.resample(trace, dt_resample=self.period_resample)

        # ==================
        # Time normalization
        # ==================
        if TIME_NOMALISATION:
            t0 = dt.datetime.now()
            # keeping a copy of the trace for weights of time-normalization
            trcopy = trace.copy()
            trace = self.time_norm(trace, trcopy)        
            delta = (dt.datetime.now() - t0).total_seconds()
            if verbose:
                print "\nProcessed time-normalisation in {:.1f} seconds"\
                .format(delta)

        # ==================
        # Spectral whitening
        # ==================
        if SPEC_WHITENING:
            t0 = dt.datetime.now()
            trace = self.spectral_whitening(trace)
            delta = (dt.datetime.now() - t0).total_seconds()
            if verbose:
                print "\nProcessed spectral whitening in {:.1f} seconds".\
                format(delta)

        # ==============================================
        # Verifying that we don't have nan in trace data
        # ==============================================
        if np.any(np.isnan(trace.data)):
            raise pserrors.CannotPreprocess("Got NaN in trace data")
Esempio n. 6
0
    def preprocess_trace(self, trace, paz=None, verbose=False):
        """
        Preprocesses a trace (so that it is ready to be cross-correlated),
        by applying the following steps:
            - removal of instrument response, mean and trend
            - band-pass filtering between *freqmin*-*freqmax*
            - downsampling to *period_resample* secs
            - time-normalization (one-bit normalization or normalization
              by the running mean in the earthquake frequency band)
            - spectral whitening (if running mean normalization)

        Raises CannotPreprocess exception if:
            - trace only contains 0 (happens sometimes...)
            - a normalization weight is 0 or NaN
            - a Nan appeared in trace data
            
        Note that the processing steps are performed in-place.

        @type trace: L{Trace}
        @param paz: poles and zeros of instrumental response
                    (set None if response is directly attached to trace)

        """

        # =======================================
        # Check if any data to work with to begin
        # =======================================
        #print type(trace)
        #print "trace: ", trace
        if np.all(trace.data == 0.0):
            # no data -> skipping trace
            raise pserrors.CannotPreprocess("Only zeros")

        # ==========================
        # Remove instrument response
        # ==========================
        if RESP_REMOVE:
            t1 = dt.datetime.now()
            trace = self.remove_resp(trace, paz=paz)
            delta = (dt.datetime.now() - t1).total_seconds()
            if verbose:
                print "\nRemoved response in {:.1f} seconds".format(delta)

        #Initialise the AutoTrigger class for the current trace
        if HIGHAMP_REMOVE:
            # this check finds high amplitude noise creates a list of where it is located in the signal
            TRIGGER = AutoTrigger(trace, freqmin=FREQMIN, freqmax=FREQMAX)
            UTC_events = TRIGGER.trigger_times(check=True)
            if UTC_events is not None:
                # set the application to remove these parts from the trace!
                trace_new = None
                for event in UTC_events:
                    # event is a list of length 2, start and end times
                    # use trace.trim(starttime=x, endtime=y)
                    # trace 1 is from trace start until the event starttime
                    trace1 = trace.trim(starttime=trace.stats.starttime,
                                        endtime=event[0])
                    trace2 = trace.trim(starttime=event[1],
                                        endtime=trace.stats.endtime)
                    if trace_new is None:
                        trace_new = trace1 + trace2
                    else:
                        trace_new += (trace1 + trace2)

                # trace_new has removed all high amp. noise from trace original
                trace = trace_new
                print trace.data

        # ==============================================
        # Check trace data completeness is above MINFILL
        # ==============================================
        if COMPLETENESS:
            # Data fill for current TIME INTERVAL!
            # CHECK THAT THE get_fill_trace function works!
            fill = psutils.get_fill_trace(trace)

            if fill < MINFILL:
                # not enough data
                raise pserrors.CannotPreprocess("{:.0f}% fill"\
                .format(fill*100))

        # ========================
        # Trim, demean and detrend
        # ========================
        if TDD:
            t1 = dt.datetime.now()
            midt = trace.stats.starttime + (trace.stats.endtime -
                                            trace.stats.starttime) / 2.0

            t0 = UTCDateTime(midt.date)  # date of trace, at time 00h00m00s
            trace.trim(starttime=t0, endtime=t0 + dt.timedelta(days=1))
            trace.detrend(type='constant')
            trace.detrend(type='linear')
            delta = (dt.datetime.now() - t1).total_seconds()
            if verbose:
                print "Processed trim in {:.1f} seconds".format(delta)

        #plt.figure()
        #plt.title("TDD")
        #plt.plot(trace.data)
        #plt.show()
        #plt.clf()
        # =========
        # Band-pass
        # =========
        if BANDPASS:
            t0 = dt.datetime.now()
            trace.filter(type="bandpass",
                         freqmin=self.freqmin,
                         freqmax=self.freqmax,
                         corners=self.corners,
                         zerophase=self.zerophase)
            delta = (dt.datetime.now() - t0).total_seconds()

            if verbose:
                print "Processed filters in {:.1f} seconds".format(delta)

        #plt.figure()
        #plt.title("Bandpass")
        #plt.plot(trace.data)
        #plt.show()
        #plt.clf()
        # ============
        # Downsampling
        # ============
        if DOWNSAMPLE:
            if abs(1.0 / trace.stats.sampling_rate -
                   self.period_resample) > EPS:
                psutils.resample(trace, dt_resample=self.period_resample)
        #plt.figure()
        #plt.title("DOWNSAMPLE")
        #plt.plot(trace.data)
        #plt.show()
        #plt.clf()
        # ==================
        # Time normalization
        # ==================
        if TIME_NOMALISATION:
            t0 = dt.datetime.now()
            # keeping a copy of the trace for weights of time-normalization
            trcopy = trace.copy()
            trace = self.time_norm(trace, trcopy)
            delta = (dt.datetime.now() - t0).total_seconds()
            if verbose:
                print "Processed time-normalisation in {:.1f} seconds"\
                .format(delta)
        #plt.figure()
        #plt.title("NORMALISATION")
        #plt.plot(trace.data)
        #plt.show()
        #plt.clf()
        # ==================
        # Spectral whitening
        # ==================
        if SPEC_WHITENING:
            t0 = dt.datetime.now()
            trace = self.spectral_whitening(trace)
            delta = (dt.datetime.now() - t0).total_seconds()
            if verbose:
                print "Processed spectral whitening in {:.1f} seconds".\
                format(delta)
        #plt.figure()
        #plt.title("SPECTRAL WHITENING")
        #plt.plot(trace.data)
        #plt.show()
        #plt.clf()
        # ==============================================
        # Verifying that we don't have nan in trace data
        # ==============================================
        if np.any(np.isnan(trace.data)):
            raise pserrors.CannotPreprocess("Got NaN in trace data")