Exemplo n.º 1
0
    dirname = 'sac'

    if not os.path.exists(dirname):
        os.mkdir(dirname)

    suffix = 'BH' + fname.split('_')[2][0].upper()

    for i, sta_name in enumerate(header[1:len(header)]):

        trace = Trace()
        # trace.id = sta_name.replace('_','.')+'.'+suffix
        print('Processing ' + trace.id)
        trace.data = array[:, i + 1]
        trace.stats.sampling_rate = 100
        trace.stats.delta = 1.0 / trace.stats.sampling_rate
        trace.stats.network = sta_name.split('_')[0]
        trace.stats.station = sta_name.split('_')[1]
        trace.stats.location = '00'  # TODO
        trace.stats.channel = suffix
        trace.id = trace.stats.network + '.' + trace.stats.station + '.' + trace.stats.location + '.' + trace.stats.channel
        trace.stats.starttime = UTCDateTime(array[0, 0])
        trace.stats._format = 'SAC'
        trace.write(dirname + '/' + trace.id + '.SAC', format='SAC')

        st = read(dirname + '/' + trace.id + '.SAC')
        st[0].stats.sac.b = array[0, 0]
        st[0].stats.sac.e = array[len(stdata) - 1, 0]

        st.write(dirname + '/' + trace.id + '.SAC', format='SAC')
def correlate_traces(tr1, tr2, shift, abuse_seedid=False,
                     use_headers=set(), use_seedid_headers=True,
                     calc_header=None, phase=False,
                     **kwargs):
    """
    Return trace of cross-correlation of two input traces

    :param tr1,tr2: two |Trace| objects
    :param shift: maximal shift in correlation in seconds
    """
    if use_seedid_headers:
        seedid_headers = {'network', 'station', 'location', 'channel'}
        use_headers = set(use_headers) | seedid_headers
    sr = tr1.stats.sampling_rate
    assert sr == tr2.stats.sampling_rate
    header = {k: v for k, v in tr1.stats.items() if tr2.stats.get(k) == v and k != 'npts'}
    for k in use_headers:
        if k in tr1.stats:
            header[k + '1'] = tr1.stats[k]
        if k in tr2.stats:
            header[k + '2'] = tr2.stats[k]
    if 'channel' not in header:
        c1 = tr1.stats.channel
        c2 = tr2.stats.channel
        if c1 != '' and c2 != '' and c1[:-1] == c2[:-1]:
            header['channel'] = c1[:-1] + '?'
            header['channel'] = c1[:-1] + c1[-1] + c2[-1]
    st1 = tr1.stats.starttime
    st2 = tr2.stats.starttime
    len1 = tr1.stats.endtime - st1
    len2 = tr2.stats.endtime - st2
    if (st1 + len1 / 2) - (st2 + len2 / 2) < 0.1:
        header['starttime'] = st1 + len1 / 2
    corrf = correlate_phase if phase else correlate
    xdata = corrf(tr1.data, tr2.data, int(round(shift * sr)), **kwargs)
    tr = Trace(data=xdata, header=header)
    if abuse_seedid:
        n1, s1, l1, c1 = tr1.id.split('.')
        n2, s2, l2, c2 = tr2.id.split('.')
        tr.id = '.'.join(s1, c1, s2, c2)
    if calc_header == 'event' and 'elon' in tr1.stats:
        s1 = tr1.stats
        s2 = tr2.stats
        args = (s1.elat, s1.elon, s2.elat, s2.elon)
        dist, azi, baz = gps2dist_azimuth(*args)
        dpdif = (s2.edep - s1.edep) * 1000
        tr.stats.dist = (dist ** 2 + dpdif**2) ** 0.5  # dist in meter
        tr.stats.azi = azi
        tr.stats.baz = baz
        tr.stats.inc = np.rad2deg(np.arctan2(dist, dpdif))
        # only valid if event 1 is above event 2
        assert tr.stats.inc <= 90.
        if 'slat' in s1:
            a = s1.elat, s1.elon, s1.edep * 1000
            b = s2.elat, s2.elon, s2.edep * 1000
            c = s1.slat, s1.slon, 0
            tr.stats.angle12s = calc_angle(a, b, c)
            tr.stats.angle21s = calc_angle(b, a, c)
    elif calc_header == 'station' and 'slon' in tr1.stats:
        args = (tr1.stats.slat, tr1.stats.slon, tr2.stats.slat, tr2.stats.slon)
        dist, azi, baz = gps2dist_azimuth(*args)
        tr.stats.dist = dist / 1000  # dist in km
        tr.stats.azi = azi
        tr.stats.baz = baz
    return tr