Exemplo n.º 1
0
def chirp_signal(time, fmin, fmax, dt):
    """
	Chirp signal
	"""

    w1 = chirp(time,
               f0=fmax,
               f1=fmin,
               t1=time[-1],
               method='quadratic',
               vertex_zero=False)

    f_w1 = fmin - (fmin - fmax) * (time[-1] - time)**2 / time[-1]**2

    fmin = fmin
    fmax = fmax + 5
    w2 = chirp(time,
               f0=fmax,
               f1=fmin,
               t1=time[-1],
               method='quadratic',
               vertex_zero=False)

    f_w2 = fmin - (fmin - fmax) * (time[-1] - time)**2 / time[-1]**2

    sig = w1 + w2[::-1]
    tr = Trace()
    tr.data = sig
    tr.stats.delta = dt
    tr.stats.starttime = 0
    tr.normalize()

    return tr
Exemplo n.º 2
0
def continuous_signal(time, low, high, dt):
    """
    Continuous source-signal
    """

    sig = (np.random.rand(time.size) * 2 - 1)

    tr = Trace()
    tr.data = sig
    tr.stats.delta = dt
    tr.stats.starttime = 0
    tr.filter('bandpass', freqmin=low, freqmax=high, corners=4)

    tr.normalize()

    return tr
Exemplo n.º 3
0
def sine_sum_signal(time, fmin, n, dt):
    """
    Continuous source-signal
    """
    n = n + 1
    sig = np.sin(2 * pi * fmin * (time))
    for i in range(2, n):
        sig += np.sin(2 * pi * fmin * (i * 0.8) * (time))

    # sig = sig + (np.random.rand(time.size) * 2 - 1)*1 #*np.exp(-0.05*time) + (np.random.rand(time.size) * 2 - 1)*1e-2

    tr = Trace()
    tr.data = sig
    tr.stats.delta = dt
    tr.stats.starttime = 0
    tr.normalize()

    return tr
Exemplo n.º 4
0
def pro5stack2d(eq_num,
                slow_delta=0.0005,
                slowR_lo=-0.1,
                slowR_hi=0.1,
                slowT_lo=-0.1,
                slowT_hi=0.1,
                start_buff=-50,
                end_buff=50,
                norm=1,
                ARRAY=0,
                NS=False,
                decimate_fac=0,
                ref_loc=0,
                ref_lat=36.3,
                ref_lon=138.5,
                stack_option=1):

    from obspy import UTCDateTime
    from obspy import Stream, Trace
    from obspy import read
    from obspy.geodetics import gps2dist_azimuth
    import numpy as np
    import os
    from scipy.signal import hilbert
    import math
    import time

    import sys  # don't show any warnings
    import warnings
    from termcolor import colored
    print(colored('Running pro5b_stack2d', 'cyan'))

    env_stack = 0  # flag to stack envelopes instead of oscillating seismograms
    start_time_wc = time.time()

    fname = '/Users/vidale/Documents/Research/IC/EvLocs/event' + str(
        eq_num) + '.txt'
    file = open(fname, 'r')

    lines = file.readlines()
    split_line = lines[0].split()
    #            ids.append(split_line[0])  ignore label for now
    t = UTCDateTime(split_line[1])
    date_label = split_line[1][0:10]
    ev_lat = float(split_line[2])
    ev_lon = float(split_line[3])
    #    ev_depth    = float(      split_line[4])

    if not sys.warnoptions:
        warnings.simplefilter("ignore")

#%% Get location file
    if ARRAY == 0:  # Hinet set
        sta_file = '/Users/vidale/Documents/GitHub/Array_codes/Files/sta_hinet.txt'
        if ref_loc == 0:
            ref_lat = 36.3
            ref_lon = 138.5
    elif ARRAY == 1:  # LASA set
        sta_file = '/Users/vidale/Documents/GitHub/Array_codes/Files/sta_LASA.txt'
        if ref_loc == 0:
            ref_lat = 46.69
            ref_lon = -106.22
    elif ARRAY == 2:  # China set and center
        sta_file = '/Users/vidale/Documents/GitHub/Array_codes/Files/sta_ch.txt'
        if ref_loc == 0:
            ref_lat = 38  # °N
            ref_lon = 104.5  # °E
    with open(sta_file, 'r') as file:
        lines = file.readlines()
    print(str(len(lines)) + ' stations read from ' + sta_file)
    # Load station coords into arrays
    station_index = range(len(lines))
    st_names = []
    st_lats = []
    st_lons = []
    for ii in station_index:
        line = lines[ii]
        split_line = line.split()
        st_names.append(split_line[0])
        st_lats.append(split_line[1])
        st_lons.append(split_line[2])
    if ARRAY == 0:  # shorten and make upper case Hi-net station names to match station list
        for ii in station_index:
            this_name = st_names[ii]
            this_name_truc = this_name[0:5]
            st_names[ii] = this_name_truc.upper()

#%% Input parameters
# date_label = '2018-04-02' # date for filename
    fname = 'HD' + date_label + 'sel.mseed'
    goto = '/Users/vidale/Documents/Research/IC/Pro_Files'
    os.chdir(goto)

    st = Stream()
    st = read(fname)
    print('Read in: ' + str(len(st)) + ' traces')
    nt = len(st[0].data)
    dt = st[0].stats.delta
    print('First trace has : ' + str(nt) + ' time pts, time sampling of ' +
          str(dt) + ' and thus duration of ' + str((nt - 1) * dt))

    #%% Make grid of slownesses
    slowR_n = int(
        round(1 + (slowR_hi - slowR_lo) / slow_delta))  # number of slownesses
    slowT_n = int(
        round(1 + (slowT_hi - slowT_lo) / slow_delta))  # number of slownesses
    stack_nt = int(
        round(1 + ((end_buff - start_buff) / dt)))  # number of time points

    # In English, stack_slows = range(slow_n) * slow_delta - slow_lo
    a1R = range(slowR_n)
    a1T = range(slowT_n)
    stack_Rslows = [(x * slow_delta + slowR_lo) for x in a1R]
    stack_Tslows = [(x * slow_delta + slowT_lo) for x in a1T]

    # testing slownesses in indexing
    print(
        str(slowR_n) + ' radial slownesses, ' + str(slowT_n) +
        ' trans slownesses, ')
    print('Radial     slownesses 0' + ' ' + str(stack_Rslows[0]) + '   '
          'end' + ' ' + str(stack_Rslows[-1]))
    print('Transverse slownesses 1' + ' ' + str(stack_Tslows[0]) + '   '
          'end' + ' ' + str(stack_Tslows[-1]))

    #%% Build empty Stack array
    stack = Stream()
    tr = Trace()
    tr.stats.delta = dt
    tr.stats.starttime = t + start_buff
    tr.stats.npts = stack_nt
    tr.stats.network = 'stack'
    tr.stats.channel = 'BHZ'
    tr.data = np.zeros(stack_nt)
    done = 0
    for stackR_one in stack_Rslows:
        for stackT_one in stack_Tslows:
            tr1 = tr.copy()
            tr1.stats.station = str(int(round(done)))
            stack.extend([tr1])
            done += 1

    #  Only need to compute ref location to event distance once
    ref_dist_az = gps2dist_azimuth(ev_lat, ev_lon, ref_lat, ref_lon)
    ref_back_az = ref_dist_az[2]

    #%% select by distance, window and adjust start time to align picked times
    done = 0
    if env_stack == 1:
        for tr in st:  #  #convert oscillating seismograms to envelopes
            tr.data = np.abs(hilbert(tr.data))

    for tr in st:  # traces one by one, find lat-lon by searching entire inventory.  Inefficient but cheap
        if tr.stats.station in st_names:  # find station in station list
            ii = st_names.index(tr.stats.station)
            if norm == 1:
                tr.normalize()  # trace divided abs(max of trace)
            stalat = float(st_lats[ii])
            stalon = float(
                st_lons[ii])  # use lat & lon to find distance and back-az
            rel_dist_az = gps2dist_azimuth(stalat, stalon, ref_lat, ref_lon)
            rel_dist = rel_dist_az[0] / 1000  # km
            rel_back_az = rel_dist_az[1]  # radians

            if NS == False:
                del_distR = rel_dist * math.cos(
                    (rel_back_az - ref_back_az) * math.pi / 180)
                del_distT = rel_dist * math.sin(
                    (rel_back_az - ref_back_az) * math.pi / 180)
            # North and east
            else:
                del_distR = rel_dist * math.cos(rel_back_az * math.pi / 180)
                del_distT = rel_dist * math.sin(rel_back_az * math.pi / 180)
            for slowR_i in range(
                    slowR_n):  # for this station, loop over radial slownesses
                for slowT_i in range(
                        slowT_n):  # loop over transverse slownesses
                    time_lag = del_distR * stack_Rslows[
                        slowR_i]  # time shift due to radial slowness
                    time_lag += del_distT * stack_Tslows[
                        slowT_i]  # time shift due to transverse slowness
                    time_correction = ((t - tr.stats.starttime) +
                                       (time_lag + start_buff)) / dt
                    indx = int(round(slowR_i * slowT_n + slowT_i))
                    # could do a little better by sampling finer, 20 sps?, before applying statics in pro3

                    if stack_option == 0:  # my old inefficient method
                        for it in range(
                                stack_nt):  # check points one at a time
                            it_in = int(round(it + time_correction))
                            if it_in >= 0 and it_in < nt - 1:  # does data lie within seismogram?
                                stack[indx].data[it] += tr[it_in]

                    if stack_option == 1:  #  Wei's much faster method
                        arr = tr.data
                        nshift = round(time_correction)
                        if time_correction < 0:
                            nshift = nshift - 1
                        if nshift <= 0:
                            nbeg1 = -nshift
                            nend1 = stack_nt
                            nbeg2 = 0
                            nend2 = stack_nt + nshift
                        elif nshift > 0:
                            nbeg1 = 0
                            nend1 = stack_nt - nshift
                            nbeg2 = nshift
                            nend2 = stack_nt
                        if nend1 >= 0 and nbeg1 <= stack_nt:
                            stack[indx].data[nbeg1:nend1] += arr[nbeg2:nend2]
            done += 1
            if done % 100 == 0:
                print('Done stacking ' + str(done) + ' out of ' +
                      str(len(st)) + ' stations.')
        else:
            print(tr.stats.station + ' not found in station list')

#%% take envelope, decimate envelope
    stack_raw = stack.copy()
    for slowR_i in range(slowR_n):  # loop over radial slownesses
        for slowT_i in range(slowT_n):  # loop over transverse slownesses
            indx = slowR_i * slowT_n + slowT_i
            stack[indx].data = np.abs(hilbert(stack[indx].data))
            if decimate_fac != 0:
                stack[indx].decimate(decimate_fac, no_filter=True)

#%%  Save processed files
    fname = 'HD' + date_label + '_2dstack_env.mseed'
    stack.write(fname, format='MSEED')

    fname = 'HD' + date_label + '_2dstack.mseed'
    stack_raw.write(fname, format='MSEED')

    elapsed_time_wc = time.time() - start_time_wc
    print(f'This job took   {elapsed_time_wc:.1f}   seconds')
    os.system('say "Done"')
Exemplo n.º 5
0
def pro5stack(eq_file,
              plot_scale_fac=0.05,
              slowR_lo=-0.1,
              slowR_hi=0.1,
              slow_delta=0.0005,
              start_buff=-50,
              end_buff=50,
              ref_lat=36.3,
              ref_lon=138.5,
              envelope=1,
              plot_dyn_range=1000,
              log_plot=1,
              norm=1,
              global_norm_plot=1,
              color_plot=1,
              fig_index=401,
              ARRAY=0):

    #%% Import functions
    import obspy
    import obspy.signal
    from obspy import UTCDateTime
    from obspy import Stream, Trace
    from obspy import read
    from obspy.geodetics import gps2dist_azimuth
    import numpy as np
    import os
    from obspy.taup import TauPyModel
    import obspy.signal as sign
    import matplotlib.pyplot as plt
    from matplotlib.colors import LogNorm
    model = TauPyModel(model='iasp91')
    from scipy.signal import hilbert
    import math
    import time

    #	import sys # don't show any warnings
    #	import warnings

    print('Running pro5a_stack')

    #%% Get saved event info, also used to name files
    start_time_wc = time.time()

    if ARRAY == 0:
        file = open(eq_file, 'r')
    elif ARRAY == 1:
        file = open('EvLocs/' + eq_file, 'r')
    lines = file.readlines()
    split_line = lines[0].split()
    #			ids.append(split_line[0])  ignore label for now
    t = UTCDateTime(split_line[1])
    date_label = split_line[1][0:10]
    ev_lat = float(split_line[2])
    ev_lon = float(split_line[3])
    ev_depth = float(split_line[4])

    #if not sys.warnoptions:
    #    warnings.simplefilter("ignore")

    #%% Get station location file
    if ARRAY == 0:  # Hinet set and center
        sta_file = '/Users/vidale/Documents/GitHub/Array_codes/Files/hinet_sta.txt'
        ref_lat = 36.3
        ref_lon = 138.5
    elif ARRAY == 1:  # LASA set and center
        sta_file = '/Users/vidale/Documents/GitHub/Array_codes/Files/LASA_sta.txt'
        ref_lat = 46.69
        ref_lon = -106.22
    else:  # NORSAR set and center if 2
        sta_file = '/Users/vidale/Documents/GitHub/Array_codes/Files/NORSAR_sta.txt'
        ref_lat = 61
        ref_lon = 11
    with open(sta_file, 'r') as file:
        lines = file.readlines()
    print(str(len(lines)) + ' stations read from ' + sta_file)
    # Load station coords into arrays
    station_index = range(len(lines))
    st_names = []
    st_lats = []
    st_lons = []
    for ii in station_index:
        line = lines[ii]
        split_line = line.split()
        st_names.append(split_line[0])
        st_lats.append(split_line[1])
        st_lons.append(split_line[2])

#%% Name file, read data
# date_label = '2018-04-02' # date for filename
    if ARRAY == 0:
        fname = 'HD' + date_label + 'sel.mseed'
    elif ARRAY == 1:
        fname = 'Pro_Files/HD' + date_label + 'sel.mseed'
    st = Stream()
    print('reading ' + fname)
    st = read(fname)
    print('Read in: ' + str(len(st)) + ' traces')
    nt = len(st[0].data)
    dt = st[0].stats.delta
    print('First trace has : ' + str(nt) + ' time pts, time sampling of ' +
          str(dt) + ' and thus duration of ' + str((nt - 1) * dt))

    #%% Build Stack arrays
    stack = Stream()
    tr = Trace()
    tr.stats.delta = dt
    tr.stats.network = 'stack'
    tr.stats.channel = 'BHZ'
    slow_n = int(1 +
                 (slowR_hi - slowR_lo) / slow_delta)  # number of slownesses
    stack_nt = int(1 + ((end_buff - start_buff) / dt))  # number of time points
    # In English, stack_slows = range(slow_n) * slow_delta - slowR_lo
    a1 = range(slow_n)
    stack_slows = [(x * slow_delta + slowR_lo) for x in a1]
    print(str(slow_n) + ' slownesses.')
    tr.stats.starttime = t + start_buff
    tr.data = np.zeros(stack_nt)
    done = 0
    for stack_one in stack_slows:
        tr1 = tr.copy()
        tr1.stats.station = str(int(done))
        stack.extend([tr1])
        done += 1
    #	stack.append([tr])
    #	stack += tr

    #  Only need to compute ref location to event distance once
    ref_distance = gps2dist_azimuth(ev_lat, ev_lon, ref_lat, ref_lon)

    #%% Select traces by distance, window and adjust start time to align picked times
    done = 0
    for tr in st:  # traces one by one, find lat-lon by searching entire inventory.  Inefficient but cheap
        for ii in station_index:
            if ARRAY == 0:  # for hi-net, have to chop off last letter, always 'h'
                this_name = st_names[ii]
                this_name_truc = this_name[0:5]
                name_truc_cap = this_name_truc.upper()
            elif ARRAY == 1:
                name_truc_cap = st_names[ii]
            if (tr.stats.station == name_truc_cap
                ):  # find station in inventory
                if norm == 1:
                    tr.normalize()
#					tr.normalize(norm= -len(st)) # mystery command or error
                stalat = float(st_lats[ii])
                stalon = float(
                    st_lons[ii])  # look up lat & lon again to find distance
                distance = gps2dist_azimuth(
                    stalat, stalon, ev_lat,
                    ev_lon)  # Get traveltimes again, hard to store
                tr.stats.distance = distance[0]  # distance in m
                del_dist = (ref_distance[0] - distance[0]) / (1000)  # in km
                # ALSO NEEDS distance station - hypocenter calculation
                #isolate components of distance in radial and transverse directions, ref_distR & ref_distT
                # FIX ref_distR = distance*cos(azi-backazi)
                # FIX ref_distT = distance*sin(azi-backazi)
                #			for(k=0;k<nslow;k++){
                #				slow = 110.*(LOWSLOW + k*DELTASLOW);
                for slow_i in range(
                        slow_n):  # for this station, loop over slownesses
                    time_lag = -del_dist * stack_slows[
                        slow_i]  # time shift due to slowness, flipped to match 2D
                    #					start_offset = tr.stats.starttime - t
                    #					time_correction = (start_buff - (start_offset + time_lag))/dt
                    time_correction = ((t - tr.stats.starttime) +
                                       (time_lag + start_buff)) / dt
                    #				print('Time lag ' + str(time_lag) + ' for slowness ' + str(stack_slows[slow_i]) + ' and distance ' + str(del_dist) + ' time sample correction is ' + str(time_correction))
                    for it in range(stack_nt):  # check points one at a time
                        it_in = int(it + time_correction)
                        if it_in >= 0 and it_in < nt - 1:  # does data lie within seismogram?
                            stack[slow_i].data[it] += tr[it_in]
                done += 1
                if done % 50 == 0:
                    print('Done stacking ' + str(done) + ' out of ' +
                          str(len(st)) + ' stations.')
#%% Plot traces
    global_max = 0
    for slow_i in range(
            slow_n):  # find global max, and if requested, take envelope
        if len(stack[slow_i].data) == 0:
            print('%d data has zero length ' % (slow_i))
        if envelope == 1 or color_plot == 1:
            stack[slow_i].data = np.abs(hilbert(stack[slow_i].data))
        local_max = max(abs(stack[slow_i].data))
        if local_max > global_max:
            global_max = local_max
    if global_max <= 0:
        print('global_max ' + str(global_max) + ' slow_n ' + str(slow_n))

    # create time axis (x-axis), use of slow_i here is arbitrary, oops
    ttt = (np.arange(len(stack[slow_i].data)) * stack[slow_i].stats.delta +
           (stack[slow_i].stats.starttime - t))  # in units of seconds

    # Plotting
    if color_plot == 1:  # 2D color plot
        stack_array = np.zeros((slow_n, stack_nt))

        #	stack_array = np.random.rand(int(slow_n),int(stack_nt))  # test with random numbers
        min_allowed = global_max / plot_dyn_range
        if log_plot == 1:
            for it in range(stack_nt):  # check points one at a time
                for slow_i in range(
                        slow_n):  # for this station, loop over slownesses
                    num_val = stack[slow_i].data[it]
                    if num_val < min_allowed:
                        num_val = min_allowed
                    stack_array[
                        slow_i,
                        it] = math.log10(num_val) - math.log10(min_allowed)
        else:
            for it in range(stack_nt):  # check points one at a time
                for slow_i in range(
                        slow_n):  # for this station, loop over slownesses
                    stack_array[slow_i,
                                it] = stack[slow_i].data[it] / global_max
        y, x = np.mgrid[slice(stack_slows[0], stack_slows[-1] + slow_delta,
                              slow_delta),
                        slice(ttt[0], ttt[-1] + dt,
                              dt)]  # make underlying x-y grid for plot
        #	y, x = np.mgrid[ stack_slows , time ]  # make underlying x-y grid for plot
        plt.close(fig_index)

        fig, ax = plt.subplots(1, figsize=(9, 2))
        fig.subplots_adjust(bottom=0.3)
        #		c = ax.pcolormesh(x, y, stack_array, cmap=plt.cm.gist_yarg)
        #		c = ax.pcolormesh(x, y, stack_array, cmap=plt.cm.gist_rainbow_r)
        c = ax.pcolormesh(x, y, stack_array, cmap=plt.cm.binary)
        ax.axis([x.min(), x.max(), y.min(), y.max()])
        fig.colorbar(c, ax=ax)
        plt.figure(fig_index, figsize=(6, 8))
        plt.close(fig_index)
    else:  # line plot
        for slow_i in range(slow_n):
            dist_offset = stack_slows[slow_i]  # in units of slowness
            if global_norm_plot != 1:
                plt.plot(
                    ttt,
                    stack[slow_i].data * plot_scale_fac /
                    (stack[slow_i].data.max() - stack[slow_i].data.min()) +
                    dist_offset,
                    color='black')
            else:
                plt.plot(ttt,
                         stack[slow_i].data * plot_scale_fac /
                         (global_max - stack[slow_i].data.min()) + dist_offset,
                         color='black')
        plt.ylim(slowR_lo, slowR_hi)
        plt.xlim(start_buff, end_buff)
    plt.xlabel('Time (s)')
    plt.ylabel('Slowness (s/km)')
    plt.title(date_label)
    plt.show()

    #%% Save processed files
    print('Stack has ' + str(len(stack)) + ' traces')
    if ARRAY == 0:
        fname = 'HD' + date_label + '_1dstack.mseed'
    elif ARRAY == 1:
        fname = 'Pro_Files/HD' + date_label + '_1dstack.mseed'
    stack.write(fname, format='MSEED')

    elapsed_time_wc = time.time() - start_time_wc
    print('This job took ' + str(elapsed_time_wc) + ' seconds')
    os.system('say "Done"')
Exemplo n.º 6
0
def pro5stack2d(eq_file,
                plot_scale_fac=0.05,
                slow_delta=0.0005,
                slowR_lo=-0.1,
                slowR_hi=0.1,
                slowT_lo=-0.1,
                slowT_hi=0.1,
                start_buff=-50,
                end_buff=50,
                norm=1,
                global_norm_plot=1,
                ARRAY=0,
                NS=0,
                decimate_fac=0):

    from obspy import UTCDateTime
    from obspy import Stream, Trace
    from obspy import read
    from obspy.geodetics import gps2dist_azimuth
    import numpy as np
    import os
    from scipy.signal import hilbert
    import math
    import time

    import sys  # don't show any warnings
    import warnings

    print('Running pro5b_stack2d')
    start_time_wc = time.time()

    if ARRAY == 0:
        file = open(eq_file, 'r')
    elif ARRAY == 1:
        goto = '/Users/vidale/Documents/PyCode/LASA/EvLocs'
        os.chdir(goto)
        file = open(eq_file, 'r')

    lines = file.readlines()
    split_line = lines[0].split()
    #			ids.append(split_line[0])  ignore label for now
    t = UTCDateTime(split_line[1])
    date_label = split_line[1][0:10]
    ev_lat = float(split_line[2])
    ev_lon = float(split_line[3])
    #	ev_depth    = float(      split_line[4])

    if not sys.warnoptions:
        warnings.simplefilter("ignore")

#%% Get location file
    if ARRAY == 0:  # Hinet set
        sta_file = '/Users/vidale/Documents/GitHub/Array_codes/Files/hinet_sta.txt'
        ref_lat = 36.3
        ref_lon = 138.5
    else:  # LASA set
        sta_file = '/Users/vidale/Documents/GitHub/Array_codes/Files/LASA_sta.txt'
        ref_lat = 46.69
        ref_lon = -106.22
    with open(sta_file, 'r') as file:
        lines = file.readlines()
    print(str(len(lines)) + ' stations read from ' + sta_file)
    # Load station coords into arrays
    station_index = range(len(lines))
    st_names = []
    st_lats = []
    st_lons = []
    for ii in station_index:
        line = lines[ii]
        split_line = line.split()
        st_names.append(split_line[0])
        st_lats.append(split_line[1])
        st_lons.append(split_line[2])

#%% Input parameters
# date_label = '2018-04-02' # date for filename
    fname = 'HD' + date_label + 'sel.mseed'
    if ARRAY == 1:
        goto = '/Users/vidale/Documents/PyCode/LASA/Pro_Files'
        os.chdir(goto)

    st = Stream()
    st = read(fname)
    print('Read in: ' + str(len(st)) + ' traces')
    nt = len(st[0].data)
    dt = st[0].stats.delta
    print('First trace has : ' + str(nt) + ' time pts, time sampling of ' +
          str(dt) + ' and thus duration of ' + str((nt - 1) * dt))

    #%% Make grid of slownesses
    slowR_n = int(1 +
                  (slowR_hi - slowR_lo) / slow_delta)  # number of slownesses
    slowT_n = int(1 +
                  (slowT_hi - slowT_lo) / slow_delta)  # number of slownesses
    stack_nt = int(1 + ((end_buff - start_buff) / dt))  # number of time points
    # In English, stack_slows = range(slow_n) * slow_delta - slow_lo
    a1R = range(slowR_n)
    a1T = range(slowT_n)
    stack_Rslows = [(x * slow_delta + slowR_lo) for x in a1R]
    stack_Tslows = [(x * slow_delta + slowT_lo) for x in a1T]
    print(
        str(slowR_n) + ' radial slownesses, ' + str(slowT_n) +
        ' trans slownesses, ')

    #%% Build empty Stack array
    stack = Stream()
    tr = Trace()
    tr.stats.delta = dt
    tr.stats.starttime = t + start_buff
    tr.stats.npts = stack_nt
    tr.stats.network = 'stack'
    tr.stats.channel = 'BHZ'
    tr.data = np.zeros(stack_nt)
    done = 0
    for stackR_one in stack_Rslows:
        for stackT_one in stack_Tslows:
            tr1 = tr.copy()
            tr1.stats.station = str(int(done))
            stack.extend([tr1])
            done += 1

    #  Only need to compute ref location to event distance once
    ref_dist_az = gps2dist_azimuth(ev_lat, ev_lon, ref_lat, ref_lon)
    #	ref_dist    = ref_dist_az[0]/1000  # km
    ref_back_az = ref_dist_az[2]
    #	print(f'Ref location {ref_lat:.4f} , {ref_lon:.4f}, event location {ev_lat:.4f}  {ev_lon:.4f} ref_back_az  {ref_back_az:.1f}°')

    #%% select by distance, window and adjust start time to align picked times
    done = 0
    for tr in st:  # traces one by one, find lat-lon by searching entire inventory.  Inefficient but cheap
        for ii in station_index:
            if ARRAY == 0:  # have to chop off last letter, always 'h'
                this_name = st_names[ii]
                this_name_truc = this_name[0:5]
                name_truc_cap = this_name_truc.upper()
            elif ARRAY == 1:
                name_truc_cap = st_names[ii]
            if (tr.stats.station == name_truc_cap
                ):  # find station in inventory
                #			if (tr.stats.station == st_names[ii]): # found station in inventory
                if norm == 1:
                    tr.normalize()  # trace divided abs(max of trace)
                stalat = float(st_lats[ii])
                stalon = float(
                    st_lons[ii])  # use lat & lon to find distance and back-az
                rel_dist_az = gps2dist_azimuth(stalat, stalon, ref_lat,
                                               ref_lon)
                rel_dist = rel_dist_az[0] / 1000  # km
                rel_back_az = rel_dist_az[1]  # radians

                #				print(f'Sta lat-lon {stalat:.4f}  {stalon:.4f}')
                if NS == 0:
                    del_distR = rel_dist * math.cos(
                        (rel_back_az - ref_back_az) * math.pi / 180)
                    del_distT = rel_dist * math.sin(
                        (rel_back_az - ref_back_az) * math.pi / 180)
                # North and east
                else:
                    del_distR = rel_dist * math.cos(
                        rel_back_az * math.pi / 180)
                    del_distT = rel_dist * math.sin(
                        rel_back_az * math.pi / 180)
                for slowR_i in range(
                        slowR_n
                ):  # for this station, loop over radial slownesses
                    for slowT_i in range(
                            slowT_n):  # loop over transverse slownesses
                        time_lag = del_distR * stack_Rslows[
                            slowR_i]  # time shift due to radial slowness
                        time_lag += del_distT * stack_Tslows[
                            slowT_i]  # time shift due to transverse slowness
                        time_correction = ((t - tr.stats.starttime) +
                                           (time_lag + start_buff)) / dt
                        indx = int(slowR_i * slowT_n + slowT_i)
                        for it in range(
                                stack_nt):  # check points one at a time
                            it_in = int(it + time_correction)
                            if it_in >= 0 and it_in < nt - 2:  # does data lie within seismogram?
                                # should be 1, not 2, but 2 prevents the problem "index XX is out of bounds for axis 0 with size XX"
                                stack[indx].data[it] += tr[it_in]
                done += 1
                if done % 20 == 0:
                    print('Done stacking ' + str(done) + ' out of ' +
                          str(len(st)) + ' stations.')
#%% take envelope, decimate envelope
    stack_raw = stack.copy()
    for slowR_i in range(slowR_n):  # loop over radial slownesses
        for slowT_i in range(slowT_n):  # loop over transverse slownesses
            indx = slowR_i * slowT_n + slowT_i
            stack[indx].data = np.abs(hilbert(stack[indx].data))
            if decimate_fac != 0:
                stack[indx].decimate(decimate_fac)

#%%  Save processed files
    fname = 'HD' + date_label + '_2dstack_env.mseed'
    stack.write(fname, format='MSEED')

    fname = 'HD' + date_label + '_2dstack.mseed'
    stack_raw.write(fname, format='MSEED')

    elapsed_time_wc = time.time() - start_time_wc
    print('This job took ' + str(elapsed_time_wc) + ' seconds')
    os.system('say "Done"')
Exemplo n.º 7
0
def pro2_test(conv_file1, conv_file2):

    from obspy import UTCDateTime
    from obspy import Stream, Trace
    from obspy import read
    #    from obspy.signal import correlate_template
    import obspy
    import os
    import time
    import numpy as np
    import matplotlib.pyplot as plt
    from termcolor import colored

    print(colored('Running pro2_test', 'cyan'))

    #    import sys # don't show any warnings
    #    import warnings
    #
    #    if not sys.warnoptions:
    #        warnings.simplefilter('ignore')
    #
    start_time_wc = time.time()

    taper_frac = .5  #Fraction of window tapered on both ends

    #%% Load waveforms and convolution trace
    #    con_trace1 = Stream()
    #    fname1     = conv_file1
    #    con_trace1 = read(fname1)
    #
    #    con_trace2 = Stream()
    #    fname2     = conv_file2
    #    con_trace2 = read(fname2)
    #
    #    con_trace2.append(con_trace1[0])
    #    con_trace2.plot(typ = 'relative')

    con_trace1 = Stream()
    con_trace2 = Stream()
    tr = Trace()
    con_trace1 = read(conv_file1)
    con_trace2 = read(conv_file2)
    con_trace1.taper(taper_frac)
    con_trace2.taper(taper_frac)
    con_trace1.normalize()
    con_trace2.normalize()
    tr.data = np.convolve(con_trace2[0].data, con_trace1[0].data)
    tr.normalize()

    tr.stats.delta = 0.1
    tr.trim(starttime=tr.stats.starttime + 10, endtime=tr.stats.endtime - 10)
    con_trace1[0].stats.starttime = tr.stats.starttime
    con_trace2[0].stats.starttime = tr.stats.starttime
    print(
        str(tr.stats.delta) + ' ' + str(tr.stats.starttime) + ' ' +
        str(tr.stats.endtime))
    print(
        str(con_trace1[0].stats.delta) + ' ' +
        str(con_trace1[0].stats.starttime) + ' ' +
        str(con_trace1[0].stats.endtime))
    print(
        str(con_trace2[0].stats.delta) + ' ' +
        str(con_trace2[0].stats.starttime) + ' ' +
        str(con_trace2[0].stats.endtime))
    con_trace1[0].stats.channel = 'trace1'
    con_trace2[0].stats.channel = 'trace2'
    tr.stats.channel = 'convolved'
    con_trace1.append(con_trace2[0])
    con_trace1.append(tr)
    print('length of con_trace1 is ' + str(len(con_trace1)))

    sgrams = Stream()
    sgrams += con_trace1[0]
    sgrams += con_trace1[1]
    sgrams += con_trace1[2]
    #    con_trace1 += tr
    #    con_trace1.plot(type = 'relative')
    #    con_trace2.plot(type = 'relative')
    sgrams[0].stats.station = ''
    sgrams[1].stats.station = ''
    sgrams[2].stats.station = ''
    sgrams[0].stats.channel = '1971'
    sgrams[1].stats.channel = '1969'
    sgrams[2].stats.channel = 'convolved'
    sgrams.filter('bandpass', freqmin=1, freqmax=2, corners=4, zerophase=True)
    sgrams.normalize()

    print('made it, before')
    sgrams.plot(
        size=(800, 600)
    )  # program l=plots but hangs up here with obscure deprecating np.float message
    print('made it, after')

    elapsed_time_wc = time.time() - start_time_wc
    print('This job took ' + str(elapsed_time_wc) + ' seconds')
    os.system('say "Done"')
Exemplo n.º 8
0
def pro4statics(eq_file,
                use_ref_trace=0,
                ref_trace='nothing',
                event_no=0,
                dphase='PcP',
                dphase2='PKiKP',
                dphase3='P',
                dphase4='PP',
                start_beam=-1,
                end_beam=3,
                plot_scale_fac=0.05,
                start_buff=-10,
                end_buff=30,
                qual_threshold=0,
                corr_threshold=0,
                max_time_shift=2,
                min_dist=17,
                max_dist=21,
                ARRAY=0,
                auto_dist=1):

    from obspy import UTCDateTime
    from obspy.signal.cross_correlation import xcorr_pick_correction
    from obspy import Stream
    from obspy import Trace
    from obspy import read
    from obspy.geodetics import gps2dist_azimuth
    import numpy as np
    import os
    import sys
    from obspy.taup import TauPyModel
    import matplotlib.pyplot as plt
    model = TauPyModel(model='iasp91')

    import warnings  # don't show any warnings
    if not sys.warnoptions:
        warnings.simplefilter("ignore")

    print('pro4_get_shifts is starting')

    #%% Get station location file
    if ARRAY == 0:  # Hinet set
        sta_file = '/Users/vidale/Documents/GitHub/Array_codes/Files/sta_hinet.txt'
    elif ARRAY == 1:  # LASA set
        sta_file = '/Users/vidale/Documents/GitHub/Array_codes/Files/sta_LASA.txt'
    elif ARRAY == 2:  # China set
        sta_file = '/Users/vidale/Documents/GitHub/Array_codes/Files/sta_ch.txt'
    with open(sta_file, 'r') as file:
        lines = file.readlines()
    print('    ' + str(len(lines)) + ' stations read from ' + sta_file)
    # Load station coords into arrays
    # old line: station_index = range(343)
    station_index = range(len(lines))
    st_lats = []
    st_lons = []
    st_deps = []
    st_names = []
    for ii in station_index:
        line = lines[ii]
        split_line = line.split()
        st_names.append(split_line[0])
        st_lats.append(split_line[1])
        st_lons.append(split_line[2])
        st_deps.append(split_line[3])

    if ARRAY == 0:  # stupid kludge to reduce Hi-net names by one letter and equalize capitalization
        for ii in station_index:
            tested_name = st_names[ii]
            this_name_truc = tested_name[0:5]
            name_truc_cap = this_name_truc.upper()
            st_names[ii] = name_truc_cap

    # initialize lists of statics
    sta_names = []
    sta_dists = []
    sta_lats = []
    sta_lons = []
    sta_statics = []
    sta_corrs = []

    #%% Parameter list
    #dphase  = 'PKIKP'       # phase to be aligned
    #dphase2 = 'PKiKP'      # another phase to have traveltime plotted
    #dphase3 = 'PKP'        # another phase to have traveltime plotted
    #dphase4 = 'pP'        # another phase to have traveltime plotted
    #ref_trace = 'N.SZW'   # trace with reference waveform
    #start_beam = 2       # start of correlation window (more positive is earlier)
    start_beam = -start_beam
    #end_beam   = 7       # plots end Xs before PKiKP
    #max_time_shift = 2       # searches up to this time shift for alignment
    #corr_threshold = 0.  # threshold that correlation is good enough to keep trace
    #max_dist = 151
    #min_dist = 150.6
    #plot_scale_fac = 0.2    #  Bigger numbers make each trace amplitude bigger on plot
    #qual_threshold =  0 # minimum SNR
    plot_tt = True  # plot the traveltimes?
    plot_flag = False  # plot for each trace?  Watch out, can be lots, one for each station pair!!
    min_dist_auto = 180  # for use in auto-scaling y axis in trace gathers
    max_dist_auto = 0

    #%% Get saved event info, also used to name files
    #  event 2016-05-28T09:47:00.000 -56.241 -26.935 78
    file = open('/Users/vidale/Documents/PyCode/EvLocs/' + eq_file, 'r')
    lines = file.readlines()
    split_line = lines[0].split()
    #            ids.append(split_line[0])  ignore label, now "event"
    t = UTCDateTime(split_line[1])
    date_label = split_line[1][0:10]
    ev_lat = float(split_line[2])
    ev_lon = float(split_line[3])
    ev_depth = float(split_line[4])

    print('        Date label ' + date_label + ' lat ' + str(ev_lat) +
          ' lon ' + str(ev_lon))

    st = Stream()
    #    fname     = 'HD' + date_label + '.mseed'
    fname = 'HD' + date_label + 'sel.mseed'  # sel file has windowing, shift?, filtering

    print('        File ' + fname)

    os.chdir('/Users/vidale/Documents/PyCode/Pro_Files/')
    os.system('pwd')
    st = read(fname)
    print('    ' + str(len(st)) + '  traces read in')
    print('         First trace has : ' + str(len(st[0].data)) + ' time pts ')

    #%% Reference trace
    trim_start = t + start_buff
    trim_end = t + end_buff
    time_buff = end_buff - start_buff
    tr_ref = Trace()
    #%% Stack reference trace
    if use_ref_trace == 0:
        counter = 0
        for tr in st:  # loop over seismograms to find reference trace, put it in tr_ref
            if counter == 0:  # copy first trace to stack
                tr_ref = tr.copy()
                tr_ref.stats.station = 'STACK'
                tr_ref.trim(starttime=trim_start - time_buff,
                            endtime=trim_end + time_buff)
                nt_ref = len(tr_ref.data)
                tr_ref.normalize()
                counter = counter + 1
            else:  # add the rest of the traces to stack
                tr_add = tr.copy()
                tr_add.trim(starttime=trim_start - time_buff,
                            endtime=trim_end + time_buff)
                nt_add = len(tr_ref.data)
                tr_add.normalize()

                for it in range(nt_ref):  # add seismogram one point at a time
                    if nt_ref != nt_add:  # are seismograms the same length?
                        print(
                            'trying to stack seismograms of different lengths, debug!'
                        )
                    tr_ref.data[it] += tr_add[it]
                counter = counter + 1
        tr_ref.data = tr_ref.data / counter

    #%% Pick reference trace
    if use_ref_trace == 1:
        for tr in st:  # loop over seismograms to find reference trace, put it in tr_ref
            if (tr.stats.station == ref_trace):  # found it
                tr_ref = tr.copy()
                tr_ref.trim(starttime=trim_start - time_buff,
                            endtime=trim_end + time_buff)
                nt_ref = len(tr_ref.data)
                tr_ref.normalize()
                print('        found reference station ' + tr.stats.station)
    if len(tr_ref.data) == 0:
        sys.exit('Reference trace empty, will not work!')

    #%% Plot reference trace
    plt.close(4)
    plt.figure(4, figsize=(10, 10))
    plt.xlim(start_buff, end_buff)
    plt.ylim(min(tr_ref.data), max(tr_ref.data))

    time = np.arange(nt_ref) * tr_ref.stats.delta + start_buff
    plt.plot(time, tr_ref.data, color='black')
    plt.xlabel('Time (s)')
    if use_ref_trace == 1:
        plt.title('Reference trace ' + dphase + ' for ' + fname[2:12] + '  ' +
                  ref_trace)
        plt.ylabel('Normed amp')
    else:
        plt.title('Summed reference trace ' + dphase + ' for ' + fname[2:12] +
                  '   ' + str(event_no))
        plt.ylabel('Average amp, each trace normed to 1')
    plt.show()

    stgood = Stream()
    st2 = st.copy(
    )  # hard to measure timing of traces without adjusting entire thing
    # print('st2 has: ' + str(len(st)) + ' traces' + ' t (origin time) ' + str(t))
    print('        Ref time ' + str(t) +
          ' start_beam end_beam max_time_shift ' + str(start_beam) + '  ' +
          str(end_beam) + '  ' + str(max_time_shift) + '  ')

    #  get station lat-lon, compute distance for plot
    good_corr = 0
    bad_corr = 0
    for tr in st:  # do all seismograms
        if tr.stats.station in st_names:  # find station in inventory
            ii = st_names.index(tr.stats.station)
            #  print('found Station ' + this_name + '  ' + actual_trace)
            stalon = float(st_lons[ii])  # look up lat & lon to find distance
            stalat = float(st_lats[ii])
            distance = gps2dist_azimuth(stalat, stalon, ev_lat, ev_lon)
            tr.stats.distance = distance[0] / (
                1000. * 111)  # distance for phase time and plotting

            if tr.stats.distance < min_dist_auto:  # for auto-scaling y-axis in trace gather plots
                min_dist_auto = tr.stats.distance
            if tr.stats.distance > max_dist_auto:
                max_dist_auto = tr.stats.distance

            arrivals = model.get_travel_times(
                source_depth_in_km=ev_depth,
                distance_in_degree=tr.stats.distance,
                phase_list=[dphase])
            #                 print(tr.stats.station + '  ' + tr_ref.stats.station + ' start_corr ' +
            #                    str(start_beam) + ' end ' + str(end_beam))
            try:
                dt, coeff = xcorr_pick_correction(t,
                                                  tr_ref,
                                                  t,
                                                  tr,
                                                  start_beam,
                                                  end_beam,
                                                  max_time_shift,
                                                  plot=plot_flag)
                if dt > max_time_shift:
                    print('Hey!  Excess shift: %.3f' % dt)
                    print('Station ' + tr.stats.station + ' corr is ' +
                          str(coeff))
                if coeff > 1:
                    print('Hey!  Excess coeff: %.3f' % coeff)
                    print('Station ' + tr.stats.station + ' corr is ' +
                          str(coeff))
                if coeff > corr_threshold:
                    good_corr += 1
                    if plot_flag == True:
                        print('Time correction for pick 2: %.6f' % dt)
                        print('Correlation coefficient: %.2f' % coeff)
                    tr.stats.starttime -= dt
                    sta_names.extend([tr.stats.station])
                    sta_dists.extend([tr.stats.distance])
                    sta_lats.extend([stalat])
                    sta_lons.extend([stalon])
                    sta_statics.extend([dt])
                    sta_corrs.extend([coeff])
                    stgood += tr
                else:
                    bad_corr += 1
            except:
                print('        No time shift for ' + tr.stats.station +
                      ' at distance ' + str(tr.stats.distance))

    ##        # store shift to write out
    ##            if coeff > corr_threshold:
    #            # write out station_name, dt, coeff
    #            # record shifted waveform in stgood
    print('    ' + str(good_corr) + ' traces with good correlation')
    if (good_corr == 0):
        sys.exit('No traces is a failure')
    print('    ' + str(bad_corr) + '  traces with bad correlation')
    print('    ' + str(good_corr + bad_corr) + ' out of total')
    print('        corr threshhold is ' + str(corr_threshold))

    plt.close(5)
    plt.figure(5, figsize=(10, 10))
    plt.xlim(start_buff, end_buff)
    plt.ylim(min_dist, max_dist)

    if auto_dist == 1:
        dist_diff = max_dist_auto - min_dist_auto  # add space at extremes
        plt.ylim(min_dist_auto - 0.1 * dist_diff,
                 max_dist_auto + 0.1 * dist_diff)
    else:
        plt.ylim(min_dist, max_dist)

    for tr in stgood:
        dist_offset = tr.stats.distance  # trying for approx degrees
        time = np.arange(len(tr.data)) * tr.stats.delta + (tr.stats.starttime -
                                                           t)
        plt.plot(time, (tr.data - np.median(tr.data)) * plot_scale_fac /
                 (tr.data.max() - tr.data.min()) + dist_offset,
                 color='black')

    #%% Plot before shift
    if plot_tt:
        # first traveltime curve
        line_pts = 50
        dist_vec = np.arange(min_dist, max_dist,
                             (max_dist - min_dist) / line_pts)  # distance grid
        time_vec1 = np.arange(
            min_dist, max_dist, (max_dist - min_dist) /
            line_pts)  # empty time grid of same length (filled with -1000)
        for i in range(0, line_pts):
            arrivals = model.get_travel_times(source_depth_in_km=ev_depth,
                                              distance_in_degree=dist_vec[i],
                                              phase_list=[dphase])
            num_arrivals = len(arrivals)
            found_it = 0
            for j in range(0, num_arrivals):
                if arrivals[j].name == dphase:
                    time_vec1[i] = arrivals[j].time
                    found_it = 1
            if found_it == 0:
                time_vec1[i] = np.nan
    # second traveltime curve
        if dphase2 != 'no':
            time_vec2 = np.arange(
                min_dist, max_dist, (max_dist - min_dist) /
                line_pts)  # empty time grid of same length (filled with -1000)
            for i in range(0, line_pts):
                arrivals = model.get_travel_times(
                    source_depth_in_km=ev_depth,
                    distance_in_degree=dist_vec[i],
                    phase_list=[dphase2])
                num_arrivals = len(arrivals)
                found_it = 0
                for j in range(0, num_arrivals):
                    if arrivals[j].name == dphase2:
                        time_vec2[i] = arrivals[j].time
                        found_it = 1
                if found_it == 0:
                    time_vec2[i] = np.nan
            plt.plot(time_vec2, dist_vec, color='orange')
        # third traveltime curve
        if dphase3 != 'no':
            time_vec3 = np.arange(
                min_dist, max_dist, (max_dist - min_dist) /
                line_pts)  # empty time grid of same length (filled with -1000)
            for i in range(0, line_pts):
                arrivals = model.get_travel_times(
                    source_depth_in_km=ev_depth,
                    distance_in_degree=dist_vec[i],
                    phase_list=[dphase3])
                num_arrivals = len(arrivals)
                found_it = 0
                for j in range(0, num_arrivals):
                    if arrivals[j].name == dphase3:
                        time_vec3[i] = arrivals[j].time
                        found_it = 1
                if found_it == 0:
                    time_vec3[i] = np.nan
            plt.plot(time_vec3, dist_vec, color='yellow')
        # fourth traveltime curve
        if dphase4 != 'no':
            time_vec4 = np.arange(
                min_dist, max_dist, (max_dist - min_dist) /
                line_pts)  # empty time grid of same length (filled with -1000)
            for i in range(0, line_pts):
                arrivals = model.get_travel_times(
                    source_depth_in_km=ev_depth,
                    distance_in_degree=dist_vec[i],
                    phase_list=[dphase4])
                num_arrivals = len(arrivals)
                found_it = 0
                for j in range(0, num_arrivals):
                    if arrivals[j].name == dphase4:
                        time_vec4[i] = arrivals[j].time
                        found_it = 1
                if found_it == 0:
                    time_vec4[i] = np.nan
            plt.plot(time_vec4, dist_vec, color='purple')

        plt.plot(time_vec1, dist_vec, color='blue')
        plt.show()

    plt.xlabel('Time (s)')
    plt.ylabel('Epicentral distance from event (°)')
    plt.title('Post-alignment ' + dphase + ' for ' + fname[2:12] + '   ' +
              str(event_no))
    plt.show()

    # plot traces
    plt.close(6)
    plt.figure(6, figsize=(10, 10))
    plt.xlim(start_buff, end_buff)
    plt.ylim(min_dist, max_dist)

    if auto_dist == 1:
        dist_diff = max_dist_auto - min_dist_auto  # add space at extremes
        plt.ylim(min_dist_auto - 0.1 * dist_diff,
                 max_dist_auto + 0.1 * dist_diff)
        max_dist = max_dist_auto
        min_dist = min_dist_auto
    else:
        plt.ylim(min_dist, max_dist)

    for tr in st2:  # regenerate distances into st2 as they were loaded into st for plots
        if tr.stats.station in st_names:  # find station in station list
            ii = st_names.index(tr.stats.station)
            stalon = float(st_lons[ii])  # look up lat & lon to find distance
            stalat = float(st_lats[ii])
            distance = gps2dist_azimuth(stalat, stalon, ev_lat, ev_lon)
            tr.stats.distance = distance[0] / (
                1000. * 111)  # distance for phase time and plotting

    for tr in st2:  # generate plot
        dist_offset = tr.stats.distance  # trying for approx degrees
        time = np.arange(len(tr.data)) * tr.stats.delta + (tr.stats.starttime -
                                                           t)
        plt.plot(time, (tr.data - np.median(tr.data)) * plot_scale_fac /
                 (tr.data.max() - tr.data.min()) + dist_offset,
                 color='black')

    #%% Plot after shift
    if plot_tt:
        # first traveltime curve
        line_pts = 50
        dist_vec = np.arange(min_dist, max_dist,
                             (max_dist - min_dist) / line_pts)  # distance grid
        time_vec1 = np.arange(
            min_dist, max_dist, (max_dist - min_dist) /
            line_pts)  # empty time grid of same length (filled with -1000)
        for i in range(0, line_pts):
            arrivals = model.get_travel_times(source_depth_in_km=ev_depth,
                                              distance_in_degree=dist_vec[i],
                                              phase_list=[dphase])
            num_arrivals = len(arrivals)
            found_it = 0
            for j in range(0, num_arrivals):
                if arrivals[j].name == dphase:
                    time_vec1[i] = arrivals[j].time
                    found_it = 1
            if found_it == 0:
                time_vec1[i] = np.nan
    # second traveltime curve
        if dphase2 != 'no':
            time_vec2 = np.arange(
                min_dist, max_dist, (max_dist - min_dist) /
                line_pts)  # empty time grid of same length (filled with -1000)
            for i in range(0, line_pts):
                arrivals = model.get_travel_times(
                    source_depth_in_km=ev_depth,
                    distance_in_degree=dist_vec[i],
                    phase_list=[dphase2])
                num_arrivals = len(arrivals)
                found_it = 0
                for j in range(0, num_arrivals):
                    if arrivals[j].name == dphase2:
                        time_vec2[i] = arrivals[j].time
                        found_it = 1
                if found_it == 0:
                    time_vec2[i] = np.nan
            plt.plot(time_vec2, dist_vec, color='orange')
        # third traveltime curve
        if dphase3 != 'no':
            time_vec3 = np.arange(
                min_dist, max_dist, (max_dist - min_dist) /
                line_pts)  # empty time grid of same length (filled with -1000)
            for i in range(0, line_pts):
                arrivals = model.get_travel_times(
                    source_depth_in_km=ev_depth,
                    distance_in_degree=dist_vec[i],
                    phase_list=[dphase3])
                num_arrivals = len(arrivals)
                found_it = 0
                for j in range(0, num_arrivals):
                    if arrivals[j].name == dphase3:
                        time_vec3[i] = arrivals[j].time
                        found_it = 1
                if found_it == 0:
                    time_vec3[i] = np.nan
            plt.plot(time_vec3, dist_vec, color='yellow')
        # fourth traveltime curve
        if dphase4 != 'no':
            time_vec4 = np.arange(
                min_dist, max_dist, (max_dist - min_dist) /
                line_pts)  # empty time grid of same length (filled with -1000)
            for i in range(0, line_pts):
                arrivals = model.get_travel_times(
                    source_depth_in_km=ev_depth,
                    distance_in_degree=dist_vec[i],
                    phase_list=[dphase4])
                num_arrivals = len(arrivals)
                found_it = 0
                for j in range(0, num_arrivals):
                    if arrivals[j].name == dphase4:
                        time_vec4[i] = arrivals[j].time
                        found_it = 1
                if found_it == 0:
                    time_vec4[i] = np.nan
            plt.plot(time_vec4, dist_vec, color='purple')

        plt.plot(time_vec1, dist_vec, color='blue')
        plt.show()

    plt.xlabel('Time (s)')
    plt.ylabel('Epicentral distance from event (°)')
    plt.title('Pre-alignment ' + dphase + ' for ' + fname[2:12] + '   ' +
              str(event_no))
    plt.show()

    #  Save stats
    fname_stats = '/Users/vidale/Documents/PyCode/Mseed/fine_statics.txt'

    #  Save station static correction files
    #fname_stats = 'Statics' + etime[:10] + dphase + ref_trace + '.txt'
    stats_file = open(fname_stats, 'w')
    len_file1 = len(sta_names)
    for j in range(0, len_file1):
        dist_str = '{:.2f}'.format(
            sta_dists[j])  # 3 digits after decimal place
        lat_str = '{:.4f}'.format(sta_lats[j])  # 2 digits after decimal place
        lon_str = '{:.4f}'.format(sta_lons[j])
        stat_str = '{:.3f}'.format(sta_statics[j])
        corr_str = '{:.3f}'.format(sta_corrs[j])
        write_line = sta_names[
            j] + ' ' + dist_str + ' ' + lat_str + ' ' + lon_str + ' ' + stat_str + ' ' + corr_str + '\n'
        stats_file.write(write_line)
    file.close()
    # print('    ' + str(len_file1) + '  traces are in correlation file')


#     os.system('say "Done"')
Exemplo n.º 9
0
def slant_stack(eq_num, plot_scale_fac = 0.05, slowR_lo = -0.1, slowR_hi = 0.1, stack_option = 1,
            slow_delta = 0.0005, start_buff = -50, end_buff = 50,
            ref_lat = 36.3, ref_lon = 138.5, ref_loc = 0, envelope = 1, plot_dyn_range = 1000,
            log_plot = 1, norm = 1, global_norm_plot = 1, color_plot = 1, fig_index = 401, ARRAY = 0):

#%% Import functions
    import obspy
    import obspy.signal
    from obspy import UTCDateTime
    from obspy import Stream, Trace
    from obspy import read
    from obspy.geodetics import gps2dist_azimuth
    import numpy as np
    import os
    from obspy.taup import TauPyModel
    import obspy.signal as sign
    import matplotlib.pyplot as plt
    from matplotlib.colors import LogNorm
    model = TauPyModel(model='iasp91')
    from scipy.signal import hilbert
    import math
    import time
    from termcolor import colored

    env_stack = 0  # flag to stack envelopes instead of oscillating seismograms

#    import sys # don't show any warnings
#    import warnings

    print(colored('Running pro5a_stack', 'cyan'))

#%% Get saved event info, also used to name files
    start_time_wc = time.time()

    fname = '/Users/vidale/Documents/Research/IC/EvLocs/event' + str(eq_num) + '.txt'
    file = open(fname, 'r')
    lines=file.readlines()

    split_line = lines[0].split()
#            ids.append(split_line[0])  ignore label for now
    t           = UTCDateTime(split_line[1])
    date_label  = split_line[1][0:10]
    ev_lat      = float(      split_line[2])
    ev_lon      = float(      split_line[3])
    ev_depth    = float(      split_line[4])

    #if not sys.warnoptions:
    #    warnings.simplefilter("ignore")

#%% Get station location file
    if ARRAY == 0: # Hinet set and center
        sta_file = '/Users/vidale/Documents/GitHub/Array_codes/Files/sta_hinet.txt'
        if ref_loc == 0:
            ref_lat = 36.3
            ref_lon = 138.5
    elif ARRAY == 1: # LASA set and center
        sta_file = '/Users/vidale/Documents/GitHub/Array_codes/Files/sta_LASA.txt'
        if ref_loc == 0:
            ref_lat = 46.69
            ref_lon = -106.22
    elif ARRAY == 2: # China set and center
        sta_file = '/Users/vidale/Documents/GitHub/Array_codes/Files/sta_ch.txt'
        if ref_loc == 0:
            ref_lat = 38      # °N
            ref_lon = 104.5   # °E
    else:         # NORSAR set and center
        sta_file = '/Users/vidale/Documents/GitHub/Array_codes/Files/sta_NORSAR.txt'
        if ref_loc == 0:
            ref_lat = 61
            ref_lon = 11
    with open(sta_file, 'r') as file:
        lines = file.readlines()
    print('    ' + str(len(lines)) + ' stations of metadata read from ' + sta_file)
    # Load station coords into arrays
    station_index = range(len(lines))
    st_names = []
    st_lats  = []
    st_lons  = []
    for ii in station_index:
        line = lines[ii]
        split_line = line.split()
        st_names.append(split_line[0])
        st_lats.append( split_line[1])
        st_lons.append( split_line[2])
    if ARRAY == 0:  # shorten and make upper case Hi-net station names to match station list
        for ii in station_index:
            this_name = st_names[ii]
            this_name_truc = this_name[0:5]
            st_names[ii]  = this_name_truc.upper()

#%% Name file, read data
    # date_label = '2018-04-02' # date for filename
    fname = 'HD' + date_label + 'sel.mseed'
    goto = '/Users/vidale/Documents/Research/IC/Pro_Files'
    os.chdir(goto)

    # fname = '/Users/vidale/Documents/PyCode/Pro_Files/HD' + date_label + 'sel.mseed'

    st = Stream()
    print('        reading ' + fname)
    print('        Stack option is ' + str(stack_option))
    st = read(fname)
    print('    ' + str(len(st)) + ' traces read in')
    nt = len(st[0].data)
    dt = st[0].stats.delta
    print(f'        First trace has {nt} time pts, time sampling of {dt:.2f} and thus duration of {(nt-1)*dt:.0f} and max amp of {max(abs(st[0].data)):.1f}')
    print(f'st[0].stats.starttime-t {(st[0].stats.starttime-t):.2f} start_buff {start_buff:.2f}')

#%% Build Stack arrays
    stack = Stream()
    tr = Trace()
    tr.stats.delta = dt
    tr.stats.network = 'stack'
    tr.stats.channel = 'BHZ'
    slow_n = int(1 + (slowR_hi - slowR_lo)/slow_delta)  # number of slownesses
    stack_nt = int(1 + ((end_buff - start_buff)/dt))  # number of time points
    # In English, stack_slows = range(slow_n) * slow_delta - slowR_lo
    a1 = range(slow_n)
    stack_slows = [(x * slow_delta + slowR_lo) for x in a1]
    print('        ' + str(slow_n) + ' slownesses.')
    tr.stats.starttime = t + start_buff
    # print(f'tr.stats.starttime-t {(tr.stats.starttime-t):.2f} start_buff {start_buff:.2f}')
    tr.data = np.zeros(stack_nt)
    done = 0
    for stack_one in stack_slows:
        tr1 = tr.copy()
        tr1.stats.station = str(int(done))
        stack.extend([tr1])
        done += 1
    #    stack.append([tr])
    #    stack += tr

    #  Only need to compute ref location to event distance once
    ref_distance = gps2dist_azimuth(ev_lat,ev_lon,ref_lat,ref_lon)

#%% Select traces by distance, window and adjust start time to align picked times
    done = 0
    if env_stack == 1: #convert oscillating seismograms to envelopes
        for tr in st:
            tr.data = np.abs(hilbert(tr.data))

    for tr in st: # traces one by one
        if tr.stats.station in st_names:  # find station in station list
            ii = st_names.index(tr.stats.station)
            if norm == 1:
                tr.normalize()
            stalat = float(st_lats[ii])
            stalon = float(st_lons[ii]) # look up lat & lon again to find distance
            distance = gps2dist_azimuth(stalat,stalon,ev_lat,ev_lon) # Get traveltimes again, hard to store
            tr.stats.distance=distance[0] # distance in m
            del_dist = (ref_distance[0] - distance[0])/(1000) # in km
            rel_start_buff = tr.stats.starttime - (t + start_buff)
            print(f'{tr.stats.station} del_dist {del_dist:.2f} ref_dist {ref_distance[0]/1000.:.2f} distance {distance[0]/1000.:.2f} rel_start_buff {rel_start_buff:.2f} tr.stats.starttime-t {(tr.stats.starttime-t):.2f} start_buff {start_buff:.2f}')

            for slow_i in range(slow_n):  # for this station, loop over slownesses
                time_lag = -del_dist * stack_slows[slow_i]  # time shift due to slowness, flipped to match 2D
                time_correction = (rel_start_buff + time_lag)/dt
                # print(f'{slow_i} time_lag {time_lag:.1f} time correction {time_correction:.1f}')

                if stack_option == 0:
                    for it in range(stack_nt):  # check points one at a time
                        it_in = int(it + time_correction)
                        if it_in >= 0 and it_in < nt - 1: # does data lie within seismogram?
                            stack[slow_i].data[it] += tr[it_in]

                if stack_option == 1:
                    arr = tr.data
                    nshift = int(time_correction)
                    if time_correction < 0:
                        nshift = nshift-1
                    if nshift <= 0:
                        nbeg1 = -nshift
                        nend1 = stack_nt
                        nbeg2 = 0
                        nend2 = stack_nt + nshift;
                    elif nshift > 0:
                        nbeg1 = 0
                        nend1 = stack_nt - nshift
                        nbeg2 = nshift
                        nend2 = stack_nt
                    if nend1 >= 0 and nbeg1 <= stack_nt:
                        stack[slow_i].data[nbeg1:nend1] += arr[nbeg2:nend2]

            done += 1
            if done % 50 == 0:
                print('        Done stacking ' + str(done) + ' out of ' + str(len(st)) + ' stations.')
        else:
            print(tr.stats.station + ' not found in station list')

#%% Plot traces
    global_max = 0
    for slow_i in range(slow_n): # find global max, and if requested, take envelope
        if len(stack[slow_i].data) == 0:
                print('%d data has zero length ' % (slow_i))
        if envelope == 1 or color_plot == 1:
            stack[slow_i].data = np.abs(hilbert(stack[slow_i].data))
        local_max = max(abs(stack[slow_i].data))
        if local_max > global_max:
            global_max = local_max
    if global_max <= 0:
        print('        global_max ' + str(global_max) + ' slow_n ' + str(slow_n))

    # create time axis (x-axis), use of slow_i here is arbitrary, oops
    ttt = (np.arange(len(stack[slow_i].data)) * stack[slow_i].stats.delta +
         (stack[slow_i].stats.starttime - t)) # in units of seconds

    # Plotting
    if color_plot == 1: # 2D color plot
        stack_array = np.zeros((slow_n,stack_nt))

    #    stack_array = np.random.rand(int(slow_n),int(stack_nt))  # test with random numbers
        min_allowed = global_max/plot_dyn_range
        if log_plot == 1:
            for it in range(stack_nt):  # check points one at a time
                for slow_i in range(slow_n):  # for this station, loop over slownesses
                    num_val = stack[slow_i].data[it]
                    if num_val < min_allowed:
                        num_val = min_allowed
                    stack_array[slow_i, it] = math.log10(num_val) - math.log10(min_allowed)
        else:
            for it in range(stack_nt):  # check points one at a time
                for slow_i in range(slow_n):  # for this station, loop over slownesses
                    stack_array[slow_i, it] = stack[slow_i].data[it]/global_max
        y, x = np.mgrid[slice(stack_slows[0], stack_slows[-1] + slow_delta, slow_delta),
                     slice(ttt[0], ttt[-1] + dt, dt)]  # make underlying x-y grid for plot
    #    y, x = np.mgrid[ stack_slows , time ]  # make underlying x-y grid for plot
        plt.close(fig_index)

        fig, ax = plt.subplots(1, figsize=(9,9))
        fig.subplots_adjust(bottom=0.3)
        c = ax.pcolormesh(x, y, stack_array, cmap=plt.cm.gist_rainbow_r)
        # c = ax.pcolormesh(x, y, stack_array, cmap=plt.cm.gist_yarg)
        # c = ax.pcolormesh(x, y, stack_array, cmap=plt.cm.binary)
        ax.axis([x.min(), x.max(), y.min(), y.max()])
        if log_plot == 1:
            fig.colorbar(c, ax=ax, label='log amplitude')
        else:
            fig.colorbar(c, ax=ax, label='linear amplitude')
        plt.figure(fig_index,figsize=(6,8))
        plt.close(fig_index)
    else: # line plot
        for slow_i in range(slow_n):
            dist_offset = stack_slows[slow_i] # in units of slowness
            if global_norm_plot != 1:
                plt.plot(ttt, stack[slow_i].data*plot_scale_fac / (stack[slow_i].data.max()
            - stack[slow_i].data.min()) + dist_offset, color = 'black')
            else:
                plt.plot(ttt, stack[slow_i].data*plot_scale_fac / (global_max
            - stack[slow_i].data.min()) + dist_offset, color = 'black')
        plt.ylim(slowR_lo,slowR_hi)
        plt.xlim(start_buff,end_buff)
    plt.xlabel('Time (s)')
    plt.ylabel('Slowness (s/km)')
    plt.title('1Dstack   ' + str(eq_num) + '  ' + date_label)
    # os.chdir('/Users/vidale/Documents/PyCode/Plots')
    # plt.savefig(date_label + '_' + str(start_buff) + '_' + str(end_buff) + '_1D.png')
    plt.show()

#%% Save processed files
    print('        Stack has ' + str(len(stack)) + ' slownesses')
#
#    if ARRAY == 0:
#        goto = '/Users/vidale/Documents/PyCode/Hinet'
#    if ARRAY == 1:
#        goto = '/Users/vidale/Documents/PyCode/LASA/Pro_Files'
#    os.chdir(goto)
#    fname = 'HD' + date_label + '_1dstack.mseed'
#    stack.write(fname,format = 'MSEED')

    elapsed_time_wc = time.time() - start_time_wc
    print(f'    This job took   {elapsed_time_wc:.1f}   seconds')
    os.system('say "Done"')