Exemplo n.º 1
0
def create_trace(st, sta_code, sta_coordinate, channel, eve_coordinate, eve_ot,
                 freq4, ratio1, ratio2, freq_range, perc):
    tr = st.copy().select(station=sta_code, channel=channel)
    dist = locations2degrees(eve_coordinate[0], eve_coordinate[1],
                             sta_coordinate[0], sta_coordinate[1])
    if (len(tr) == 1):
        tr = tr[0]
        tr.stats.data_available = 1
        if (hasattr(tr.stats, 'response')):
            tr.stats.metadata_available = 1
            vel = tr.copy().detrend('demean').taper(0.05). \
                  remove_response(pre_filt=freq4,output="VEL")
            disp = tr.copy().detrend('demean').taper(0.05). \
                  remove_response(pre_filt=freq4,output="DISP")
            disp.resample(2.0)
            pdb.set_trace()
            sig_win_len = 0.36 * dist * 111.194929703 + 60
            noise_win_len = 3 * 60
            tr.stats.sn_test1 = sn_test(vel, noise_win_len, sig_win_len,
                                        ratio1)
            tr.stats.sn_test2 = sn_test(disp, noise_win_len, sig_win_len,
                                        ratio2)
            tr.stats.snr_test = snr_test(vel, noise_win_len, sig_win_len,
                                         freq_range, perc)
        else:
            tr.stats.metadata_available = 0
            tr.stats.sn_test1 = 0
            tr.stats.sn_test2 = 0
            tr.stats.snr_test = 0

    else:
        tr = Trace()
        tr.stats.data_available = 0
        tr.stats.metadata_available = 0
        tr.stats.sn_test1 = 0
        tr.stats.sn_test2 = 0
        tr.stats.snr_test = 0
        tr.trim(starttime=eve_ot - 7 * 60,
                endtime=eve_ot + 7 * 60,
                pad=True,
                fill_value=0.00001)
        tr.stats.station = sta_code
        tr.stats.channel = channel

    tr.stats.distance = dist
    tr.stats.eve_coord = eve_coordinate
    tr.stats.eve_ot = eve_ot
    tr.stats["coordinates"] = {}
    tr.stats["coordinates"]["latitude"] = sta_coordinate[0]
    tr.stats["coordinates"]["longitude"] = sta_coordinate[1]
    return tr
Exemplo n.º 2
0
    def test_trimAllDoesNotChangeDtype(self):
        """
        If a Trace is completely trimmed, e.g. no data samples are remaining,
        the dtype should remain unchanged.

        A trace with no data samples is not really senseful but the dtype
        should not be changed anyways.
        """
        # Choose non native dtype.
        tr = Trace(np.arange(100, dtype='int16'))
        tr.trim(UTCDateTime(10000), UTCDateTime(20000))
        # Assert the result.
        self.assertEqual(len(tr.data), 0)
        self.assertEqual(tr.data.dtype, 'int16')
Exemplo n.º 3
0
    def test_trimAllDoesNotChangeDtype(self):
        """
        If a Trace is completely trimmed, e.g. no data samples are remaining,
        the dtype should remain unchanged.

        A trace with no data samples is not really senseful but the dtype
        should not be changed anyways.
        """
        # Choose non native dtype.
        tr = Trace(np.arange(100, dtype='int16'))
        tr.trim(UTCDateTime(10000), UTCDateTime(20000))
        # Assert the result.
        self.assertEqual(len(tr.data), 0)
        self.assertEqual(tr.data.dtype, 'int16')
Exemplo n.º 4
0
 def test_trim(self):
     """
     Tests the trim method of the Trace class.
     """
     # set up
     trace = Trace(data=np.arange(1001))
     start = UTCDateTime(2000, 1, 1, 0, 0, 0, 0)
     trace.stats.starttime = start
     trace.stats.sampling_rate = 200.0
     end = UTCDateTime(2000, 1, 1, 0, 0, 5, 0)
     trace.verify()
     # rtrim 100 samples
     trace.trim(0.5, 0.5)
     trace.verify()
     np.testing.assert_array_equal(trace.data[-5:],
                                   np.array([896, 897, 898, 899, 900]))
     np.testing.assert_array_equal(trace.data[:5],
                                   np.array([100, 101, 102, 103, 104]))
     self.assertEqual(len(trace.data), 801)
     self.assertEqual(trace.stats.npts, 801)
     self.assertEqual(trace.stats.sampling_rate, 200.0)
     self.assertEqual(trace.stats.starttime, start + 0.5)
     self.assertEqual(trace.stats.endtime, end - 0.5)
Exemplo n.º 5
0
 def test_trim(self):
     """
     Tests the trim method of the Trace class.
     """
     # set up
     trace = Trace(data=np.arange(1001))
     start = UTCDateTime(2000, 1, 1, 0, 0, 0, 0)
     trace.stats.starttime = start
     trace.stats.sampling_rate = 200.0
     end = UTCDateTime(2000, 1, 1, 0, 0, 5, 0)
     trace.verify()
     # rtrim 100 samples
     trace.trim(0.5, 0.5)
     trace.verify()
     np.testing.assert_array_equal(trace.data[-5:],
                                   np.array([896, 897, 898, 899, 900]))
     np.testing.assert_array_equal(trace.data[:5],
                                   np.array([100, 101, 102, 103, 104]))
     self.assertEquals(len(trace.data), 801)
     self.assertEquals(trace.stats.npts, 801)
     self.assertEquals(trace.stats.sampling_rate, 200.0)
     self.assertEquals(trace.stats.starttime, start + 0.5)
     self.assertEquals(trace.stats.endtime, end - 0.5)
Exemplo n.º 6
0
        # ToDo: Think about whether zerophase would be better

        # taper first
        #ToDo: Discuss with Andreas whether this tapering makes sense!
        tr.taper(type='cosine', max_percentage=0.001)
        tr.data = sosfilt(sos, tr.data)
        tr.stats.sampling_rate = fs_old
        tr.interpolate(fs_new)

        # Differentiate
        if output_quantity == 'VEL' or output_quantity == 'ACC':
            tr.differentiate()
            if output_quantity == 'ACC':
                tr.differentiate()

        # Remove the extra time that specfem added
        tr.trim(starttime=tr.stats.starttime + offset_seconds)

        # Set data type
        tr.data = tr.data.astype(dtype_output)

        infnr[0] += tr.stats.npts
        infnr[1] += tr.stats.sampling_rate

        f_out.write(staname)
        infnr.tofile(f_out)
        tr.data.tofile(f_out)
        counter += 1
print 'New nr. of time steps after interpolation: ', tr.stats.npts
f_out.close()
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 main():
    usage = 'usage: %prog [options] sac_file(s)'

    parser = OptionParser(usage=usage)
    parser.add_option('-m', '--maxfreq', dest='maxfreq', action='store',
                      type='float', default=None,
                      help='Maximum frequency (hz) to calculate the '
                           'S-transform. If not specified, Nyquist '
                           'frequence is used')
    parser.add_option('-d', '--downsample', dest='downsample',
                      action='store_true', default=False,
                      help='Downsample data if the Nyquist is higher than '
                           'the max frequency')
    parser.add_option('-r', '--reffiled', dest='reffield', action='store',
                      default=None,
                      help='Reference (zero) field for plotting and/or '
                           'cutting traces')
    parser.add_option('-s', '--startcut', dest='startcut', action='store',
                      type='float', default=None,
                      help='Cut start time (in sec) respect to '
                           'reference field')
    parser.add_option('-e', '--endcut', dest='endcut', action='store',
                      type='float', default=None,
                      help='Cut end time (in sec) respect to reference field')
    parser.add_option('-f', '--factor', dest='decimation_factor',
                      action='store', type='int', default=1,
                      help='Factor for decimating the S-transform graph. '
                           '(Useful to speed-up plotting)')
    parser.add_option('-a', '--ascii', dest='ascii', action='store_true',
                      default=False,
                      help='Data file is in ascii format (two columns, '
                           'time/amplitude)')

    (options, args) = parser.parse_args()

    if len(args) < 1:
        parser.print_usage(file=sys.stderr)
        sys.stderr.write("\tUse '-h' for help\n\n")
        sys.exit(1)

    for sacfile in args:
        print(sacfile)

        if options.ascii:
            data = np.loadtxt(sacfile)
            time = data[:, 0]
            amplitude = data[:, 1]
            tr = Trace(amplitude)
            tr.stats.delta = time[1] - time[0]
        else:
            try:
                tr, = read(sacfile, format='SAC')
            except Exception as message:
                print(message)
                next

        # Calculate nyquist and do downsampling, if required
        stats = tr.stats
        delta = stats.delta
        fny = 1. / (2*delta)
        if options.maxfreq:
            if fny > options.maxfreq:
                if options.downsample:
                    newdelta = fny/options.maxfreq * delta
                    dsample = int(np.floor(newdelta/delta))
                    delta = delta * dsample
                    fny = 1./(2*delta)
                    tr.decimate(factor=dsample)
                else:
                    fny = options.maxfreq

        # Cut data, if required
        if options.startcut:
            if not options.reffield:
                sys.stderr.write('Error: you must specify a reference field '
                                 '(option -r)\n')
                sys.exit(1)
            if not options.endcut:
                sys.stderr.write('Error: you must specify a end cut time '
                                 '(option -e)\n')
                sys.exit(1)

            tstart = stats.starttime + stats.sac[options.reffield] -\
                stats.sac.b + options.startcut
            tend = tstart + options.endcut
            print(tstart, tend, stats.sac.b, stats.sac.a)
            tr.trim(tstart, tend)
            #stats.sac[options.reffield] = stats.sac.b - options.startcut
            #stats.sac.b = 0

        data = tr.data

        # remove mean
        data -= data.mean()
        # normalize trace
        norm = np.max((data.max(), -data.min()))
        data /= norm

        df = 1/(delta*len(data))  # frequency step
        low = 0  # lowest frequency for the S-Transform
        nfreq = int(np.ceil(fny/df))  # number of discrete frequencies

        # Stockwell file name
        basename = os.path.basename(sacfile)
        stock_file_name = basename + '.stock.npy'

        # If we have a transform saved to disk, we don't recalculate it
        try:
            stock = np.load(stock_file_name)
            print('File %s loaded' % stock_file_name)
        except Exception:
            #Stockwell transform
            stock = st.st(data, low, nfreq)
            stock = np.flipud(stock)
            #Save transform to disk
            if save_stockwell:
                np.save(stock_file_name, stock)

        #if stockwell_stack == None:
        #    stockwell_stack = stock
        #else:
        #    stockwell_stack += stock

        reftime = 0
        if options.reffield:
            try:
                reftime = stats.sac[options.reffield] - stats.sac.b
            except Exception as message:
                sys.stderr.write(message)

        plot_stockwell(data, delta, reftime, stock, df, sacfile,
                       options.decimation_factor)
Exemplo n.º 9
0
def upsample(trace, upfactor, starttime, endtime):
    """
    Upsample a data stream by a given factor, prior to decimation. The
    upsampling is carried out by linear interpolation.

    NOTE: assumes any data with off-sample timing has been corrected with
    :func:`~quakemigrate.util.shift_to_sample`. If not, the resulting traces
    may not all contain the correct number of samples (and desired start
    and end times).

    Parameters
    ----------
    trace : `obspy.Trace` object
        Trace to be upsampled.
    upfactor : int
        Factor by which to upsample the data in trace.

    Returns
    -------
    out : `obpsy.Trace` object
        Upsampled trace.

    """

    data = trace.data
    # Fenceposts
    dnew = np.zeros((len(data) - 1) * upfactor + 1)
    dnew[::upfactor] = data
    for i in range(1, upfactor):
        dnew[i::upfactor] = float(i)/upfactor*data[1:] \
                        + float(upfactor - i)/upfactor*data[:-1]

    # Check if start needs pad - if so pad with constant value (start value
    # of original trace). Use inequality here to only apply padding to data at
    # the start and end of the requested time window; not for other traces
    # floating in the middle (in the case that there are gaps).
    if 0. < trace.stats.starttime - starttime < trace.stats.delta:
        logging.debug(f"Mismatched starttimes: {trace.stats.starttime}, "
                      f"{starttime}")
        # Calculate how many additional samples are needed
        start_pad = np.round((trace.stats.starttime - starttime) \
            * trace.stats.sampling_rate * upfactor)
        logging.debug(f"Start pad = {start_pad}")
        # Add padding data (constant value)
        start_fill = np.full(np.int(start_pad), trace.data[0], dtype=int)
        dnew = np.append(start_fill, dnew)
        # Calculate new starttime of trace
        new_starttime = trace.stats.starttime - start_pad \
            / (trace.stats.sampling_rate * upfactor)
        logging.debug(f"New starttime = {new_starttime}")
    else:
        new_starttime = trace.stats.starttime

    # Ditto for end of trace
    if 0. < endtime - trace.stats.endtime < trace.stats.delta:
        logging.debug(f"Mismatched endtimes: {trace.stats.endtime}, {endtime}")
        # Calculate how many additional samples are needed
        end_pad = np.round((endtime - trace.stats.endtime) \
            * trace.stats.sampling_rate * upfactor)
        logging.debug(f"End pad = {end_pad}")
        # Add padding data (constant value)
        end_fill = np.full(np.int(end_pad), trace.data[-1], dtype=int)
        dnew = np.append(dnew, end_fill)

    out = Trace()
    out.data = dnew
    out.stats = trace.stats.copy()
    out.stats.npts = len(out.data)
    out.stats.starttime = new_starttime
    out.stats.sampling_rate = int(upfactor * trace.stats.sampling_rate)
    logging.debug(f"Raw upsampled trace:\n\t{out}")

    # Trim to remove additional padding left from reading with
    # nearest_sample=True at a variety of sampling rates.
    # NOTE: here we are using nearest_sample=False, as all data in the stream
    # should now be at a *multiple* of the desired sampling rate, and with any
    # off-sample data having had it's timing shifted.
    out.trim(starttime=starttime - 0.00001,
             endtime=endtime + 0.00001,
             nearest_sample=False)
    logging.debug(f"Trimmed upsampled trace:\n\t{out}")

    return out
Exemplo n.º 10
0
# + {"tags": ["exercise"]}


# + {"tags": ["solution"]}
tr.filter("lowpass", freq=1)
tr.plot()
# -

# - Use **`tr.trim(...)`** to remove some of the zeros at start and at the end
# - show the preview plot again

# + {"tags": ["exercise"]}


# + {"tags": ["solution"]}
tr.trim(tr.stats.starttime + 3, tr.stats.endtime - 5)
tr.plot()
# -

# - Scale up the amplitudes of the trace by a factor of 500
# - Add standard normal gaussian noise to the trace (use [**`np.random.randn()`**](http://docs.scipy.org/doc/numpy/reference/generated/numpy.random.randn.html))
# - Display the preview plot again

# + {"tags": ["exercise"]}


# + {"tags": ["solution"]}
tr.data = tr.data * 500
tr.data = tr.data + np.random.randn(len(tr))
tr.plot()
# -
Exemplo n.º 11
0
        # taper first
        #ToDo: Discuss with Andreas whether this tapering makes sense!
        tr.taper(type='cosine',max_percentage=0.001)
        tr.data = sosfilt(sos,tr.data)
        tr.stats.sampling_rate = fs_old
        tr.interpolate(fs_new)
        
        # Differentiate
        if output_quantity == 'VEL' or output_quantity == 'ACC':
            tr.differentiate()
            if output_quantity == 'ACC':
                tr.differentiate()
        
        
        # Remove the extra time that specfem added
        tr.trim(starttime = tr.stats.starttime+offset_seconds)
        
        # Set data type
        tr.data = tr.data.astype(dtype_output)
        

        infnr[0] += tr.stats.npts
        infnr[1] += tr.stats.sampling_rate
            
        f_out.write(staname)
        infnr.tofile(f_out)
        tr.data.tofile(f_out)
        counter +=1
print('New nr. of time steps after interpolation: '+ tr.stats.npts)
f_out.close()
        
Exemplo n.º 12
0
                        # get stream starttime
                        tstart[idx] = tc_cft.stats.starttime + tdif[idx]
                        # waveforms should have the same
                        # number of npts
                        # and should be synchronized to the
                        # S-wave travel time
                        secs = (h24 / nchunk) + 60
                        tend[idx] = tstart[idx] + secs
                        check_npts = (tend[idx] -
                                      tstart[idx]) / tc_cft.stats.delta
                        ts = UTCDateTime(tstart[idx], precision=utc_prec)
                        te = UTCDateTime(tend[idx], precision=utc_prec)
                        stall += tc_cft.trim(
                            starttime=ts,
                            endtime=te,
                            nearest_sample=True,
                            pad=True,
                            fill_value=0,
                        )
                    tstart = min([tr.stats.starttime for tr in stall])
                    df = stall[0].stats.sampling_rate
                    npts = stall[0].stats.npts

                    # compute mean cross correlation from the stack of
                    # CFTs (see stack function)

                    ccmad, tdifmin = stack(stall, df, tstart, npts, stdup,
                                           stddown, nch_min)
                    print("tdifmin == ", tdifmin)

                    if tdifmin is not None:
Exemplo n.º 13
0
        st = read(fichier)
        stz = read(fichier[:7] + 'UD' + fichier[9:])
        #vecteur de base pour creer le signal dirac
        vect = np.linspace(0, st[0].stats.npts/st[0].stats.sampling_rate, st[0].stats.npts)
        #position station et distance a l'hypocentre
        pos_sta = [R_Earth + 0.001*st[0].stats.sac.stel,
                   st[0].stats.sac.stla,
                   st[0].stats.sac.stlo]
        dst = dist(pos_hyp, pos_sta)
        dst1 = dist(pos_hyp1, pos_sta)
        dst2 = dist(pos_hyp2, pos_sta)
        if dst <= 100:
            #bruit blanc distribution normale
            nois = np.random.normal(0, 0.5, st[0].stats.npts)
            tr = [math.exp(-(pow(a - dst1/vS, 2))/(2*pow(sigma, 2)))*factor/pow(dst, 2)
                  + 0.836660027*math.exp(-(pow(a - dst2/vS, 2))/(2*pow(sigma, 2)))*factor/pow(dst, 2)
                  + 0.1*b for a, b in zip(vect, nois)]
            tstart = stz[0].stats.starttime + stz[0].stats.sac.a - 5
            tend = tstart + 50
            tr = Trace(np.asarray(tr, np.ndarray), st[0].stats)
            tr = tr.trim(tstart, tend, pad = True, fill_value = 0)
            #tr.stats.sac.t0 = stz[0].stats.sac.a
            #tr.stats.sac.a = stz[0].stats.sac.a
            tr.stats.sac.t0 = 5
            tr.stats.sac.a = 5
            os.chdir(path_results)
            if ('EW2' in fichier) or ('NS2' in fichier) or ('UD2' in fichier) == True:
                tr.write(fichier[:6] + fichier[-8:], format = 'SAC')
            else:
                tr.write(fichier[:6] + fichier[-7:], format = 'SAC')
Exemplo n.º 14
0
                nchannels = len(channels)

                for ichan in range(0, nchannels):
                    print("ista", ista)
                    st1.clear()
                    # print("FILE", file)
                    st1 = st.copy()
                    tw = Trace()
                    st2.clear()
                    print(st1.select(station=ista, channel=channels[ichan]))
                    st2 = st1.select(station=ista, channel=channels[ichan])

                    if st2.__nonzero__():
                        tw = st2[0]

                        if tw.trim(stime, etime).__nonzero__():
                            print(tw)
                            netwk = tw.stats.network
                            ch = tw.stats.channel
                            tw.trim(stime, etime)
                            newfile = (
                                temp_dir
                                + str(iev)
                                + "."
                                + netwk
                                + "."
                                + ista
                                + ".."
                                + ch
                                + ".mseed"
                            )
Exemplo n.º 15
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"')