Esempio n. 1
0
    def decimate(self,decimation_factor,outfile,taper_width=0.005):
        """
        Decimate the wavefield and save to a new file 
        """
        
        fs_old = self.stats['Fs']
        freq = self.stats['Fs'] * 0.4 / float(decimation_factor)

        # Get filter coeff
        sos = filter.cheby2_lowpass(fs_old,freq)

        # figure out new length
        temp_trace = integer_decimation(self.data[0,:], decimation_factor)
        n = len(temp_trace)
       

        # Get taper
        # The default taper is very narrow, because it is expected that the traces are very long.
        taper = cosine_taper(self.stats['nt'],p=taper_width)

       
        # Need a new file, because the length changes.
        with self.copy_setup(newfile=outfile,nt=n) as newfile:

            for i in range(self.stats['ntraces']):
                
                temp_trace = sosfilt(sos,taper*self.data[i,:])
                newfile.data[i,:] = integer_decimation(temp_trace, decimation_factor)
            
        
            newfile.stats['Fs'] = fs_old / float(decimation_factor)
Esempio n. 2
0
    def decimate(self, decimation_factor, outfile, taper_width=0.005):
        """
        Decimate the wavefield and save to a new file 
        """

        fs_old = self.stats['Fs']
        freq = self.stats['Fs'] * 0.4 / float(decimation_factor)

        # Get filter coeff
        sos = filter.cheby2_lowpass(fs_old, freq)

        # figure out new length
        temp_trace = integer_decimation(self.data[0, :], decimation_factor)
        n = len(temp_trace)

        # Get taper
        # The default taper is very narrow, because it is expected that the traces are very long.
        taper = cosine_taper(self.stats['nt'], p=taper_width)

        # Need a new file, because the length changes.
        with self.copy_setup(newfile=outfile, nt=n) as newfile:

            for i in range(self.stats['ntraces']):

                temp_trace = sosfilt(sos, taper * self.data[i, :])
                newfile.data[i, :] = integer_decimation(
                    temp_trace, decimation_factor)

            newfile.stats['Fs'] = fs_old / float(decimation_factor)
Esempio n. 3
0
def prep_beam(binfile, matfile, stations_model, ndays=1,  nhours=1, fsamp=10., threshold_std=0.5, onebit=False,
              tempfilter=False, specwhite=True, timenorm=False, fact=10, new=False,
              fftpower=7, freq_int=(0.02, 0.4)):
    """
    Prepare the raw data before the beamforming. This comprises bandpass
    filtering, cutting the data into smaller chunks, removing the mean and
    down-weighting strong transient signals from for example earthquakes. One
    can chose between several methods to remove transients: 1-bit normalization,
    time domain normalization, which computes a smoothed traces of the absolute
    amplitude and down-weights the original trace by this smoothed trace, and a
    threshold based method that clips the trace at a predefined factor of the
    traces standard deviation. Note that currently no instrument correction is
    applied so the input traces either have to be already corrected for the
    instrument response, they need to be filtered within a frequency band for
    which all instrument responses are flat or they need to be all from the
    same instruments.

    :param files: Day long vertical component SAC files.
    :param matfile: Name of the file to which the pre-processed traces are
                    written. This saves the time of repeatedly running the
                    pre-processing for beamformer runs with different parameters.
                    The output file is a *.mat file that can also be read with
                    Matlab.
    :param statons_model:   
    :param nhours: Input data is cut into chunks of length of nhours.
    :param fsamp:  Sampling frequency of the input data.
    :param threshold_std: Clipping factor; values greater than
                          treshold_std * std(trace) are set to threshold_std.
    :param onebit: Turn on/off 1-bit normalization
    :param tempfilter: Turn on/off threshold based clipping.
    :param specwhite: Turn on/off spectral whitening (only retain spectral phase
                      and set spectral amplitude to one.
    :param timenomr: Turn on/off time domain normalization.
    :param fact: Decimation factor.
    :param new: If set to false it will try to load all return values from
                matfile. If true it will compute all return values from scratch.
    :param fftpower: Length of data chunks cut before the FFT.
    :param freq_int: Frequency interval for the band-pass filter.

    :return fseis: Pre-processed traces in the frequency domain.
    :return freqs: Frequency array corresponding to fseis
    :return slats: Station latitudes.
    :return slons: Station longitudes.
    :return dt: Sampling interval after decimation.
    :return seissmall: Pre-processed traces in the time domain.
    """
    if new:
        print (' >> Prepare raw data before beamforming...')
        ntimes = int(ndays) * int(round(24 / nhours))
        step = int( nhours * 3600 * fsamp / fact )
        stations = []
        slons = array([])
        slats = array([])
        nfiles = np.shape(binfile)[0]
        seisband = zeros((nfiles, ntimes, step))
        freqs = fftfreq(2 ** fftpower, 1. / (fsamp / fact))
        for i, (t, s) in enumerate(zip(binfile,stations_model)):
            data = t
            print (i, s.station)
            slons = append(slons, s.lon)
            slats = append(slats, s.lat)
            stations.append(s.station)
            data -= data.mean()
            data = bandpass(data, freqmin=freq_int[0], freqmax=freq_int[1], df=fsamp,
                   corners=4, zerophase=True)
            if fact != 1:
                data = integer_decimation(data, fact)
            npts = len(data) 
            df = fsamp / fact  
            dt = 1./df 
            seis0 = zeros(ndays * 24 * 3600 * int(df))
            istart = int(round(((UTCDateTime(0).hour * 60 + UTCDateTime(0).minute) * 60\
                          + UTCDateTime(0).second) * df))
            if timenorm:
                smoothdata = smooth(abs(data), window_len=257, window='flat')
                data /= smoothdata
            if np.isnan(data).any():
                data = zeros(ndays * 24 * 3600 * int(df))
            try:
                seis0[istart:(istart + npts)] = data
            except (ValueError, e):
                print ('Problem with %s'%s.station )
                raise ValueError

            seis0 -= seis0.mean()
            # iterate over nhours
            for j in np.arange(ntimes):
                ilow = j * step
                iup = (j + 1) * step
                seisband[i, j, :] = seis0[ilow:iup]
                seisband[i, j, :] -= seisband[i, j, :].mean()
                if onebit:
                    seisband[i, j, :] = sign(seisband[i, j, :])
            if tempfilter:
                sigmas = seisband[i, :, :].std(axis=1, ddof=1)
                sgm = ma.masked_equal(array(sigmas), 0.).compressed()
                sigma = sqrt(sum(sgm ** 2) / sgm.size)
                threshold = threshold_std * sigma
                seisband[i] = where(abs(seisband[i]) > threshold, threshold * sign(seisband[i]), seisband[i])
                seisband[i] = apply_along_axis(lambda e: e - e.mean(), 1, seisband[i])

        ismall = 2 **fftpower
        ipick = arange(ismall)
        taper = cosine_taper(len(ipick))
        n = ndays * nhours * 3600 * df
        nsub = int(np.floor(n / ismall))  # Number of time pieces -20 mins long each
        seissmall = zeros((nfiles, ntimes, nsub, len(ipick)))
        for ii in np.arange(nfiles):
            for jj in np.arange(ntimes):
                for kk in np.arange(nsub):
                    seissmall[ii, jj, kk, :] = seisband[ii, jj, kk * ismall + ipick] * taper
        fseis = fft(seissmall, n=2**fftpower, axis=3)
        if np.isnan(fseis).any():
            print ("NaN found")
            return
        ind = np.where((freqs > freq_int[0]) & (freqs < freq_int[1]))[0]
        fseis = fseis[:, :, :, ind]
        if specwhite:
            fseis = exp(angle(fseis) * 1j)

        sio.savemat(matfile, {'fseis':fseis, 'slats':slats, 'slons':slons, 'dt':dt, 
                              'freqs':freqs[ind]})
        return fseis, freqs[ind], slats, slons, dt
    else:
        print (' >> Reading %s and passing preprocess...'%matfile)
        a = sio.loadmat(matfile)
        fseis = a['fseis']
        freqs = np.squeeze(a['freqs'])
        slats = np.squeeze(a['slats'])
        slons = np.squeeze(a['slons'])
        dt = a['dt'][0][0]
        return fseis, freqs, slats, slons, dt