示例#1
0
文件: stats.py 项目: thelenwes/vespa
def semblance(st, s, baz, winlen):
    '''
    Returns the semblance for a seismic array, for a beam of given slowness and backazimuth.

    Parameters
    ----------
    st : ObsPy Stream object
        Stream of SAC format seismograms for the seismic array, length K = no. of stations in array
    s  : float
        Magnitude of slowness vector, in s / km
    baz : float
        Backazimuth of slowness vector, (i.e. angle from North back to epicentre of event)
    winlen : int
        Length of Hann window over which to calculate the semblance.

    Returns
    -------
    semblance : NumPy array
        The semblance at the given slowness and backazimuth, as a time series.

    '''

    # Check that each channel has the same number of samples, otherwise we can't construct the beam properly
    assert len(set([
        len(tr) for tr in st
    ])) == 1, "Traces in stream have different lengths, cannot stack."

    nsta = len(st)

    stack = linear_stack(st, s, baz)

    # Taper the linear stack
    stack_trace = Trace(stack)
    stack_trace.taper(type='cosine', max_percentage=0.05)
    stack = stack_trace.data

    shifts = get_shifts(st, s, baz)

    # Smooth data with sliding Hann window (i.e. convolution of signal and window function)
    window = np.hanning(winlen)

    shifted_st = st.copy()

    for i, tr in enumerate(shifted_st):
        tr.data = np.roll(tr.data,
                          shifts[i])  # Shift data in each trace by its offset
        tr.taper(type='cosine', max_percentage=0.05)  # Taper it

    # Calculate the power in the beam
    beampower = np.convolve(stack**2, window, mode='same')

    # Calculate the summed power of each trace
    tracepower = np.convolve(np.sum([tr.data**2 for tr in shifted_st], axis=0),
                             window,
                             mode='same')

    # Calculate semblance
    semblance = nsta * beampower / tracepower

    return semblance
示例#2
0
 def test_taper(self):
     """
     Test taper method of trace
     """
     data = np.ones(10)
     tr = Trace(data=data)
     tr.taper()
     for i in range(len(data)):
         self.assertLessEqual(tr.data[i], 1.)
         self.assertGreaterEqual(tr.data[i], 0.)
示例#3
0
 def test_taper(self):
     """
     Test taper method of trace
     """
     data = np.ones(10)
     tr = Trace(data=data)
     tr.taper()
     for i in range(len(data)):
         self.assertTrue(tr.data[i] <= 1.)
         self.assertTrue(tr.data[i] >= 0.)
示例#4
0
 def test_taper(self):
     """
     Test taper method of trace
     """
     data = np.ones(10)
     tr = Trace(data=data)
     tr.taper()
     for i in range(len(data)):
         self.assertTrue(tr.data[i] <= 1.)
         self.assertTrue(tr.data[i] >= 0.)
示例#5
0
def semblance(st, s, baz, winlen):
    """
    Returns the semblance for a seismic array, for a beam of given slowness and backazimuth.

    Parameters
    ----------
    st : ObsPy Stream object
        Stream of SAC format seismograms for the seismic array, length K = no. of stations in array
    s  : float
        Magnitude of slowness vector, in s / km
    baz : float
        Backazimuth of slowness vector, (i.e. angle from North back to epicentre of event)
    winlen : int
        Length of Hann window over which to calculate the semblance.

    Returns
    -------
    semblance : NumPy array
        The semblance at the given slowness and backazimuth, as a time series.

    """

    # Check that each channel has the same number of samples, otherwise we can't construct the beam properly
    assert len(set([len(tr) for tr in st])) == 1, "Traces in stream have different lengths, cannot stack."

    nsta = len(st)

    stack = linear_stack(st, s, baz)

    # Taper the linear stack
    stack_trace = Trace(stack)
    stack_trace.taper(type="cosine", max_percentage=0.05)
    stack = stack_trace.data

    shifts = get_shifts(st, s, baz)

    # Smooth data with sliding Hann window (i.e. convolution of signal and window function)
    window = np.hanning(winlen)

    shifted_st = st.copy()

    for i, tr in enumerate(shifted_st):
        tr.data = np.roll(tr.data, shifts[i])  # Shift data in each trace by its offset
        tr.taper(type="cosine", max_percentage=0.05)  # Taper it

    # Calculate the power in the beam
    beampower = np.convolve(stack ** 2, window, mode="same")

    # Calculate the summed power of each trace
    tracepower = np.convolve(np.sum([tr.data ** 2 for tr in shifted_st], axis=0), window, mode="same")

    # Calculate semblance
    semblance = nsta * beampower / tracepower

    return semblance
示例#6
0
def st(data,
       minfreq=0,
       maxfreq=None,
       samprate=None,
       freqsamprate=1,
       remove_edge=False,
       analytic_signal=False,
       factor=1):
    if data.shape[0] <= 1 or len(data.shape) > 1:
        raise TypeError('input data invalid ,please check!')
    if not maxfreq and not samprate:
        #regard signal as 1 second length
        maxfreq = len(data) // 2
        samprate = len(data)
    if maxfreq and not samprate:
        samprate = len(data)
    if not maxfreq and samprate:
        maxfreq = samprate // 2

    orig = copy.copy(data)
    st_res = np.zeros((int((maxfreq - minfreq) / freqsamprate) + 1, len(data)),
                      dtype='c8')

    if remove_edge:
        print(
            'remove_edge selected;  Remove trend with polynomial fit and taper!'
        )
        try:
            from obspy.core import Trace
        except ModuleNotFoundError:
            print('Obspy not found ,please install Obspy!')
            sys.exit()
        tmp = Trace(data=orig)
        tmp.detrend('polynomial', order=2)
        tmp.taper(0.04)
        orig = tmp.data
    if analytic_signal:
        print('analytic_signal selected;  Calculating analytic signal!')
        orig = signal.hilbert(orig)

    vec = np.hstack((np.fft.fft(orig), np.fft.fft(orig)))

    if minfreq == 0:
        st_res[0] = np.mean(orig) * np.ones(len(data))
    else:
        st_res[0] = np.fft.ifft(vec[minfreq:minfreq + len(data)] *
                                g_window(len(data), minfreq, factor))

    for i in range(freqsamprate, (maxfreq - minfreq) + 1, freqsamprate):
        st_res[int(i / freqsamprate)] = np.fft.ifft(
            vec[minfreq + i:minfreq + i + len(data)] *
            g_window(len(data), minfreq + i, factor))
    return st_res
示例#7
0
def create_kiknet_acc(recid, path_kiknet_folder, fminNS2, fmaxNS2, fminEW2,
                      fmaxEW2):
    """
    KiK-net acc are stored within Database_small.hdf5 file
    """

    # Import libraries
    import numpy as np
    from obspy.core import Trace, UTCDateTime
    import re
    from obspy.signal import filter

    # desc1 = ""
    # desc2 = ""
    time1 = []
    time2 = []
    inp_acc1 = []
    inp_acc2 = []
    npts1 = []
    npts2 = []
    for i in range(1, 3):
        if i == 1:
            comp = 'EW2'
            fmin = fminEW2
            fmax = fmaxEW2
        elif i == 2:
            comp = 'NS2'
            fmin = fminNS2
            fmax = fmaxNS2

        file_acc = path_kiknet_folder + '/' + str(recid) + '/' + str(
            recid) + '.' + comp
        hdrnames = [
            'Origin Time', 'Lat.', 'Long.', 'Depth. (km)', 'Mag.',
            'Station Code', 'Station Lat.', 'Station Long.',
            'Station Height(m)', 'Record Time', 'Sampling Freq(Hz)',
            'Duration Time(s)', 'Dir.', 'Scale Factor', 'Max. Acc. (gal)',
            'Last Correction', 'Memo.'
        ]
        acc_data = []
        time = []
        with open(file_acc, 'r') as f:
            content = f.readlines()
        counter = 0
        for line in content:
            if counter < 17:
                if not line.startswith(hdrnames[counter]):
                    sys.exit("Expected line to start with %s but got %s " %
                             (hdrnames[counter], line))
                else:
                    flds = line.split()

            if (counter == 0):
                origin_time = flds[2] + ' ' + flds[3]
                origin_time = UTCDateTime.strptime(origin_time,
                                                   '%Y/%m/%d %H:%M:%S')
                # All times are in Japanese standard time which is 9 hours ahead of UTC
                origin_time -= 9 * 3600.

            elif (counter == 1):
                lat = float(flds[1])

            elif (counter == 2):
                lon = float(flds[1])

            elif (counter == 3):
                dp = float(flds[2])

            elif (counter == 4):
                mag = float(flds[1])

            elif (counter == 5):
                stnm = flds[2]

            elif (counter == 6):
                stla = float(flds[2])

            elif (counter == 7):
                stlo = float(flds[2])

            elif (counter == 8):
                stel = float(flds[2])

            elif (counter == 9):
                record_time = flds[2] + ' ' + flds[3]
                # A 15 s delay is added to the record time by the
                # the K-NET and KiK-Net data logger
                record_time = UTCDateTime.strptime(record_time,
                                                   '%Y/%m/%d %H:%M:%S') - 15.0
                # All times are in Japanese standard time which is 9 hours ahead of UTC
                record_time -= 9 * 3600.

            elif (counter == 10):
                freqstr = flds[2]
                m = re.search('[0-9]*', freqstr)
                freq = int(m.group())

            elif (counter == 11):
                duration = float(flds[2])

            elif (counter == 12):
                channel = flds[1].replace('-', '')
                kiknetcomps = {
                    '1': 'NS1',
                    '2': 'EW1',
                    '3': 'UD1',
                    '4': 'NS2',
                    '5': 'EW2',
                    '6': 'UD2'
                }
                if channel.strip() in kiknetcomps.keys(
                ):  # kiknet directions are 1-6
                    channel = kiknetcomps[channel.strip()]

            elif (counter == 13):
                eqn = flds[2]
                num, denom = eqn.split('/')
                num = float(re.search('[0-9]*', num).group())
                denom = float(denom)
                # convert the calibration from gal to m/s^2
                calib = 0.01 * num / denom

            elif (counter == 14):
                accmax = float(flds[3])

            elif (counter == 15):
                last_correction = flds[2] + ' ' + flds[3]
                last_correction = UTCDateTime.strptime(last_correction,
                                                       '%Y/%m/%d %H:%M:%S')
                # All times are in Japanese standard time which is 9 hours ahead of UTC
                last_correction -= 9 * 3600.

            elif counter > 16:
                data = str(line).split()
                for value in data:
                    a = float(value)
                    acc_data.append(a)
            counter = counter + 1

        data = np.array(acc_data)
        tr = Trace(data)
        tr.detrend("linear")
        tr.taper(max_percentage=0.05, type='cosine', side='both')
        filter_order = 4
        pad = np.zeros(int(round(1.5 * filter_order / fmin * freq)))
        tr.data = np.concatenate([pad, tr.data, pad])
        fN = freq / 2
        if fmax < fN:
            tr.data = filter.bandpass(tr.data,
                                      freqmin=fmin,
                                      freqmax=fmax,
                                      df=freq,
                                      corners=4,
                                      zerophase=True)
        else:
            tr.data = filter.highpass(tr.data,
                                      freq=fmin,
                                      df=freq,
                                      corners=4,
                                      zerophase=True)
        tr.data = tr.data[len(pad):len(tr.data) - len(pad)]
        tr.data = tr.data * calib / 9.81  #in g

        npts = len(tr.data)

        time = []
        for j in range(0, npts):
            t = j * 1 / freq
            time.append(t)
        time = np.asarray(time)
        if i == 1:
            inp_acc1 = tr.data
            npts1 = npts
            time1 = time
        if i == 2:
            inp_acc2 = tr.data
            npts2 = npts
            time2 = time
    return time1, time2, inp_acc1, inp_acc2, npts1, npts2
示例#8
0
i_max = np.argmax(abs(filt_stf))
ind = nstep - 1
while (filt_stf[ind] < tol):
    ind -= 1

delay = ind - i_max
print 'Delay used : ' + str(delay)

# 2 : Apply delay and bandpass source time function
delayed_stf = np.zeros(nstep + delay)
delayed_stf[-nstep:] = np.array(stf)

resu = bandpass(delayed_stf, freqmin, freqmax, df, zerophase=True)
t = Trace()
t.data = resu
t.taper(0.005, type='hann')
resu = t.data

if resamp == 1:
    resu = resample(resu[:nstep], int(1.5 * nstep_resamp))[:nstep_resamp]

plt.figure(1)
plt.plot(resu)
#plt.figure(1)
#plt.plot(result)
plt.plot(delayed_stf)
plt.show()
stf = open("my_filtered_stf.txt", "w")

for i in range(0, nstep_resamp):  #nstep + delay):
    stf.write("%d " % i)