Ejemplo n.º 1
0
def obtain_timeshifts(st):
    '''function to compute time shift of overlapping files              '''
    '''st: obspy stream containing one station channel pair             '''

    # check if all traces are from same station/channel
    for tr in st:
        if tr.stats.station == st[0].stats.station:
            pass
        else:
            raise NameError("Traces in st recorded by different stations")
        if tr.stats.channel == st[0].stats.channel:
            pass
        else:
            raise NameError("Traces in st recorded on different channels")

    # empty stream for time corrected traces; add first trace
    cor = Stream()
    # "take_previous" determines if first trace is subject to syncronization to previous mseed file
    take_previous = False
    # check if previous mseed file is available
    try:
        stn = st[0].stats.station
        chn = st[0].stats.channel
        stime = st[0].stats.starttime
        prev = read("/scratch/flindner/G7Jul01/MSEED/4D.%s..%s.%04d%02d%02d%02d*" \
                % (stn, chn, stime.year, stime.month, stime.day, stime.hour), starttime=stime - 5)
        cor += prev[0]
        # available -> synchronize
        take_previous = True
    except:
        pass
    # in case of no sync to previous file, start with timeshift between first and second trace
    if take_previous == False:
        cor += st[0]
        st = st[1:]
        warnings.warn("Synchronization to previous MSEED file failed!")
    # empty list for dts
    dts = []
    
    # add next trace
    for i, tr in enumerate(st):
        cor += tr
        # helper stream - overlap
        helper = cor.copy()
        t1 = helper[1].stats.starttime
        t2 = helper[0].stats.endtime
        helper.trim(t1, t2)
        delta = helper[0].stats.delta
        npts = helper[0].stats.npts
        # even number of samples
        if (npts % 2) != 0: 
            helper.trim(t1, t2-delta)
            delta = helper[0].stats.delta
        
        # cross-correlation in order to obtain timeshift
        xcorr = np.correlate(helper[0].data, helper[1].data, "same")
        xcorr = Trace(data=xcorr)
        xcorr.stats.delta = delta
        xcorr.resample(1000)
        ndelta = xcorr.stats.delta
        nnpts = xcorr.stats.npts
        dt = (np.argmax(xcorr.data) - nnpts/2.) * ndelta
        dt = round(dt, 3)
        # add estimated time shift to second trace
        cor[1].stats.starttime += dt
    
        # test if time series are perfectly aligned
        check = True
        count = 0
        while check:
            start = cor[1].stats.starttime
            end = cor[0].stats.endtime
            test = cor.slice(start, end)
            eq_st = False
            if round(test[0].stats.starttime.timestamp, 4) == round(test[1].stats.starttime.timestamp, 4):
                eq_st = True
            eq_ar = np.array_equal(test[0].data, test[1].data)
            if eq_ar == True and eq_st == True:
                # if perfectly aligned, quit testing loop
                check = False  
                if count == 0:
                    dts.append(dt) 
            # if not perfectly aligned, undo time shift obtained by xcorr and shift manually
            else:
                if count == 0:
                    # undo time shift obtained from xcorr
                    cor[1].stats.starttime -= dt
                    mshift = int((end - start) / delta) + 1000
                    cor[1].stats.starttime -= mshift*delta
                elif count > 0:
                    cor[1].stats.starttime += delta
                cor[1].stats.starttime.microsecond = np.round(cor[1].stats.starttime.microsecond, 3)
            count += 1
        # in case of take_previous == True, remove previous file from stream (was just needed for time sync)
        if i==0 and take_previous:
            for tr in cor.select(network="4D"):
                cor.remove(tr)
        # time shift obtained from shifting
        if count > 1:
            dt = (-mshift + count - 2) * delta
            dts.append(dt) 

        cor.merge(method=1)
    # check number of written times shifts
    dts = np.asarray(dts)
    if len(dts) != len(st):
        raise ValueError("Number of time shifts is not correct")
    return dts, take_previous