def create_orthoganality_examples(N, E, angles):
    """Create examples where the second horizontal component is rotated out of orthoganality
  by the amount of degrees specified. The angle is the angle difference between the two
  components holding component 1 fixed."""
    for angle in angles:
        # We add 180 because the angle is back azimuth.  The rotation does not allow
        # negative angles so we continue on around the other way.
        rot_angle = 180 + angle - 90.

        if rot_angle < 0.:
            r, t = rotate.rotate_ne_rt(N[0].data, E[0].data,
                                       (360. + rot_angle))
        elif rot_angle > 360.:
            r, t = rotate.rotate_ne_rt(N[0].data, E[0].data,
                                       (rot_angle - 360.))
        else:
            r, t = rotate.rotate_ne_rt(N[0].data, E[0].data, rot_angle)
        dir = "orthogonality/%03d" % (angle)
        try:
            os.mkdir(dir)
        except:
            # Directory exists do nothing
            pass
        tr_e = E[0].copy()
        tr_e.data = t.astype('int32')
        N[0].write("%s/%s" % (dir, N[0].id), format='MSEED')
        tr_e.write("%s/%s" % (dir, tr_e.id), format='MSEED')
Beispiel #2
0
def rotateToGCP(tr):


    #begin loop over data stream
    for i in range(len(tr)-1):
      # split channel
      li0 = list(tr[i+0].stats['channel'])
      li1 = list(tr[i+1].stats['channel'])

      # chech if station and part 1 of channel is identical and location
      if li0[0] == li1[0] and li0[1] == li1[1] \
         and tr[i+0].stats['station']  == tr[i+1].stats['station']\
         and tr[i+0].stats['location'] == tr[i+1].stats['location']:

         rch = li0[0] + li0[1] + 'R'
         tch = li0[0] + li0[1] + 'T'

         # if yes 3 possibility: EN, NE , pass
         if li0[2]=="E" and li1[2]=="N":
            #baz
            baz = tr[i].stats['baz']
            if tr[i+0].stats['npts'] == tr[i+1].stats['npts']:
               # rotate 0-1
               (tr[i+1].data,tr[i+0].data) = rotate_ne_rt(tr[i+1].data,tr[i+0].data,baz)
               tr[i+0].stats['channel']=tch
               tr[i+1].stats['channel']=rch
               i=i+1
            else:
               print "Can't rotate ",tr[i+0].stats['station'],tr[i+0].stats['channel'], " and ", \
                      tr[i+1].stats['station'],tr[i+1].stats['channel']

         elif li0[2]=="N" and li1[2]=="E":
            #baz
            baz = tr[i].stats['baz']
            if tr[i+0].stats['npts'] == tr[i+1].stats['npts']:
#              # rotate 1-0
               (tr[i+0].data,tr[i+1].data) = rotate_ne_rt(tr[i+0].data,tr[i+1].baz)
               tr[i+1].stats['channel']=tch
               tr[i+0].stats['channel']=rch
               i=i+1
            else:
               print "Can't rotate ",tr[i+0].stats['station'],tr[i+0].stats['channel'], " and ", \
                      tr[i+1].stats['station'],tr[i+1].stats['channel']

         else:
            pass

    return tr
Beispiel #3
0
    def test_rotate2zne_against_ne_rt_picking_any_two_horizontal_comps(self):
        """
        This also tests non-orthogonal configurations to some degree.
        """
        np.random.seed(456)
        z = np.random.random(10)
        n = np.random.random(10)
        e = np.random.random(10)

        # Careful to not pick any coordinate axes.
        for ba in [14.325, 38.234, 78.1, 136.3435, 265.4, 351.35]:
            r, t = rotate_ne_rt(n=n, e=e, ba=ba)

            _r = [r, ba + 180, 0]
            _t = [t, ba + 270, 0]
            _n = [n, 0, 0]
            _e = [e, 90, 0]

            # Picking any two should be enough to reconstruct n and e.
            for a, b in itertools.permutations([_r, _t, _n, _e], 2):
                z_new, n_new, e_new = rotate2zne(z, 0, -90,
                                                 a[0], a[1], a[2],
                                                 b[0], b[1], b[2])
                np.testing.assert_allclose(z_new, z)
                np.testing.assert_allclose(n_new, n)
                np.testing.assert_allclose(e_new, e)
Beispiel #4
0
def azimuth_check(stack, st, debug=True):
    # stack is in the radial direction
    # for each R and T
    results = {}
    stas = list(set([tr.stats.station for tr in st]))
    for sta in stas:
        st_sta = st.select(station=sta)
        best_val = -100.
        for ang in range(-30, 30, 1):
            ang = float(ang)
            print(ang)
            st2 = st_sta.copy()
            # rotate
            R.data, T.data = rotate_ne_rt(
                st2.select(component='R')[0].data,
                st2.select(component='T')[0].data, ang)
            cc = correlation(st2[0].data, stack, 20)
            shift, value = xcorr_max(cc)
            if np.abs(value) > best_val:
                best_val = value
                best_ang = ang
        results[sta] = [best_val, best_ang]

    print(results)
    return results
Beispiel #5
0
 def test_rotate_ne_rt_vs_pitsa(self):
     """
     Test horizontal component rotation against PITSA.
     """
     # load test files
     with gzip.open(os.path.join(self.path, 'rjob_20051006_n.gz')) as f:
         data_n = np.loadtxt(f)
     with gzip.open(os.path.join(self.path, 'rjob_20051006_e.gz')) as f:
         data_e = np.loadtxt(f)
     # test different angles, one from each sector
     for angle in [30, 115, 185, 305]:
         # rotate traces
         datcorr_r, datcorr_t = rotate_ne_rt(data_n, data_e, angle)
         # load pitsa files
         with gzip.open(os.path.join(self.path,
                                     'rjob_20051006_r_%sdeg.gz' %
                                     angle)) as f:
             data_pitsa_r = np.loadtxt(f)
         with gzip.open(os.path.join(self.path,
                                     'rjob_20051006_t_%sdeg.gz' %
                                     angle)) as f:
             data_pitsa_t = np.loadtxt(f)
         # Assert.
         self.assertTrue(np.allclose(datcorr_r, data_pitsa_r, rtol=1E-3,
                                     atol=1E-5))
         self.assertTrue(np.allclose(datcorr_t, data_pitsa_t, rtol=1E-3,
                                     atol=1E-5))
Beispiel #6
0
def rotater(tr, inv, evlo, evla):
    lat = inv[0][0].latitude
    lon = inv[0][0].longitude
    dist, baz, _ = gps2dist_azimuth(lat, lon, evla, evlo)
    e = rotate_ne_rt(tr[0].data, tr[1].data, baz)
    tmptr = tr.copy()
    tmptr[0].data = e[0]
    tmptr[1].data = e[1]
    return tmptr, lat, lon, dist
Beispiel #7
0
    def procGUI(self):

        # get stream
        st = self.stn.stream

        self.resp = self.stn.response

        # get selected channels
        chn_filter = self.chn[0:2]
        st = st.select(channel="{:}*".format(chn_filter))

        # Shorten time range of stream to times given
        st = st.trim(starttime=UTCDateTime(self.lside), endtime=UTCDateTime(self.rside))


        STEP_DEG = 1

        ba_list = np.arange(0, 360, STEP_DEG)
        r_max = []
        t_max = []
        ba_max = []
        for ba in ba_list:
            z = st.select(channel="**Z")[0]
            n = st.select(channel="**N")[0]
            e = st.select(channel="**E")[0]

            # filter traces
            z, times =  procTrace(z, ref_datetime=self.ref_datetime, resp=self.resp, bandpass=[2, 8])
            n, _ =      procTrace(n, ref_datetime=self.ref_datetime, resp=self.resp, bandpass=[2, 8])
            e, _ =      procTrace(e, ref_datetime=self.ref_datetime, resp=self.resp, bandpass=[2, 8])

            z = z[0]
            n = n[0]
            e = e[0]
            times = times[0]

            r, t = rotate_ne_rt(n, e, ba)

            # a = st.rotate('NE->RT', back_azimuth=ba)
            # print(a[0].stats.back_azimuth)
            print("Current Back-Azimuth = {:} deg | RAD = {:.2f} | TRN = {:.2f}".format(ba, np.max(r), np.max(t)))
            ba_max.append(ba)
            r_max.append(np.max(r))
            t_max.append(np.max(t))
            self.zne_canvas[0].plot(x=times, y=z, update=True, clear=True)
            self.zne_canvas[1].plot(x=times, y=r, update=True, clear=True)
            self.zne_canvas[2].plot(x=times, y=t, update=True, clear=True)
            rad = pg.PlotCurveItem(ba_max, r_max, pen=pg.mkPen(color=(255, 0, 0)))
            trn = pg.PlotCurveItem(ba_max, t_max, pen=pg.mkPen(color=(0, 0, 255)))           

            self.backaz_canvas.addItem(rad, update=True, clear=True, name="Radial")
            self.backaz_canvas.addItem(trn, update=True, clear=True, name="Transverse")
            self.backaz_canvas.setLabel('left', "Positive Maximum Amplitude (Radial)")
            self.backaz_canvas.setLabel('bottom', "Back-Azimuth [deg]")

            # self.backaz_canvas.plot(x=ba_max, y=t_max, update=True, clear=True, name="Transverse", pen=pg.mkPen(color=(0, 0, 255)))
            pg.QtGui.QApplication.processEvents()
def test_SKS():
    import matplotlib
    matplotlib.use('Agg')
    import numpy as np
    from obspy.core import Stream
    from obspy.signal.rotate import rotate_ne_rt
    from telewavesim import utils as ut
    from telewavesim import wiggle as wg

    modfile = resource_filename('telewavesim',
                                'examples/models/model_SKS.txt')
    wvtype = 'SV'
    npts = 3000  # Number of samples
    dt = 0.05  # Sample distance in seconds
    slow = 0.04  # Horizontal slowness (or ray parameter) in s/km
    baz = np.arange(0., 360., 10.)
    model = ut.read_model(modfile)
    t1 = ut.calc_ttime(model, slow, wvtype=wvtype)
    assert round(t1, 1) == 21.6
    trR = Stream()
    trT = Stream()
    # Loop over range of data
    for bb in baz:
        # Calculate the plane wave seismograms
        trxyz = ut.run_plane(model, slow, npts, dt, bb, wvtype=wvtype)
        # Extract East, North and Vertical
        ntr = trxyz[0]
        etr = trxyz[1]
        ztr = trxyz[2]
        # Copy to radial and transverse
        rtr = ntr.copy()
        ttr = etr.copy()
        # Rotate to radial and transverse
        rtr.data, ttr.data = rotate_ne_rt(ntr.data, etr.data, bb)
        # Append to streams
        trR.append(rtr)
        trT.append(ttr)

    # Set frequency corners in Hz
    f1 = 0.01
    f2 = 0.2
    # Filter to get wave-like traces
    trR.filter('bandpass', freqmin=f1, freqmax=f2, corners=2, zerophase=True)
    trT.filter('bandpass', freqmin=f1, freqmax=f2, corners=2, zerophase=True)
    # Plot as wiggles
    with tempfile.TemporaryDirectory() as tempdir:
        wg.pw_wiggles_baz(trR, trT, 'test', btyp='baz', scale=0.05,
                          t1=t1, tmin=0., tmax=40, save=True,
                          ftitle=join(tempdir, 'sks'),
                          wvtype='SV')
Beispiel #9
0
def rotate_trace_to_zrt(str1):
    """
      This function rotates a stream object (either in ENZ or 12Z) in to a stream object of TRZ
    """

    for k, tr in enumerate(str1):
        if tr.stats.channel[2] == 'Z':
            tr_z = tr
        elif tr.stats.channel[2] == 'E' or tr.stats.channel[2] == '1':
            tr_e = tr
        elif tr.stats.channel[2] == 'N' or tr.stats.channel[2] == '2':
            tr_n = tr
        else:
            sys.exit('Problem with ' + tr.stats.channel)

    if 'tr_e' not in vars():
        sys.exit('No east component')
    else:
        tr_r = tr_e.copy()
    if 'tr_n' not in vars():
        sys.exit('No north component')
    else:
        tr_t = tr_n.copy()
    if 'tr_z' not in vars():
        sys.exit('No vertical component')
    else:
        tr_z2 = tr_z.copy()

    # note that even traces labelled as E or N in the channel name may not have the right cmpaz.
    (tr_z2.data, tr_n.data,
     tr_e.data) = rotate2zne(tr_z.data, tr_z.stats.cmpaz, tr_z.stats.dip,
                             tr_n.data, tr_n.stats.cmpaz, tr_n.stats.dip,
                             tr_e.data, tr_e.stats.cmpaz, tr_e.stats.dip)
    baz = tr_z2.stats.back_azimuth
    #baz=19.29817039741116 vs baz_sac= 1.937192e+01 # the baz in sac is not accurate enough that could cause discrepancy with the rotation results
    # what is in rotate_ne_to_tr (confirmed)
    # ba = radians(ba)
    #r = - e * sin(ba) - n * cos(ba)
    #t = - e * cos(ba) + n * sin(ba)
    (tr_r.data, tr_t.data) = rotate_ne_rt(tr_n.data, tr_e.data, baz)

    # after rotation, inclination is not changed but azimuth is changed
    (tr_r.stats.cmpinc, tr_t.stats.cmpinc) = (90, 90)
    (tr_r.stats.cmpaz, tr_t.stats.cmpaz) = ((baz + 180) % 360.,
                                            (baz + 270) % 360.)
    (tr_r.stats.channel, tr_t.stats.channel) = (tr_r.stats.channel[0:2] + 'R',
                                                tr_t.stats.channel[0:2] + 'T')

    str2 = Stream(traces=[tr_t, tr_r, tr_z2])
    return str2
Beispiel #10
0
    def test_rotate2zne_against_rotate_ne_rt(self):
        np.random.seed(123)
        z = np.random.random(10)
        n = np.random.random(10)
        e = np.random.random(10)

        for ba in [0.0, 14.325, 38.234, 78.1, 90.0, 136.3435, 265.4, 351.35]:
            r, t = rotate_ne_rt(n=n, e=e, ba=ba)

            # Unrotate with rotate2zne() - this should make sure the azimuth is
            # interpreted correctly.
            z_new, n_new, e_new = rotate2zne(z, 0, -90,
                                             r, ba + 180, 0,
                                             t, ba + 270, 0)
            np.testing.assert_allclose(z_new, z)
            np.testing.assert_allclose(n_new, n)
            np.testing.assert_allclose(e_new, e)
Beispiel #11
0
 def test_rotate_ne_rt_ne(self):
     """
     Rotating there and back with the same back-azimuth should not change
     the data.
     """
     # load the data
     with gzip.open(os.path.join(self.path, 'rjob_20051006_n.gz')) as f:
         data_n = np.loadtxt(f)
     with gzip.open(os.path.join(self.path, 'rjob_20051006_e.gz')) as f:
         data_e = np.loadtxt(f)
     # Use double precision to get more accuracy for testing.
     data_n = np.require(data_n, np.float64)
     data_e = np.require(data_e, np.float64)
     ba = 33.3
     new_n, new_e = rotate_ne_rt(data_n, data_e, ba)
     new_n, new_e = rotate_rt_ne(new_n, new_e, ba)
     self.assertTrue(np.allclose(data_n, new_n, rtol=1E-7, atol=1E-12))
     self.assertTrue(np.allclose(data_e, new_e, rtol=1E-7, atol=1E-12))
def test_Audet2016():
    import matplotlib
    matplotlib.use('Agg')
    from obspy.core import Stream
    from obspy.signal.rotate import rotate_ne_rt
    from telewavesim import utils as ut
    from telewavesim import wiggle as wg
    modfile = resource_filename('telewavesim',
                                'examples/models/model_Audet2016.txt')
    wvtype = 'P'
    npts = 3000  # Number of samples
    dt = 0.01  # Sample distance in seconds
    dp = 2000.  # Deployment depth below sea level in meters
    c = 1.500    # P-wave velocity in salt water (km/s)
    rhof = 1027.  # Density of salt water (kg/m^3)
    slow = 0.06  # Horizontal slowness (or ray parameter) in s/km
    # Back-azimuth direction in degrees
    # (has no influence if model is isotropic)
    baz = 0.
    model = ut.read_model(modfile)
    assert list(model.rho) == [2800.0, 2800.0, 3200.0]
    t1 = ut.calc_ttime(model, slow, wvtype=wvtype)
    assert round(t1, 1) == 1.1
    trxyz = ut.run_plane(model, slow, npts, dt, baz=baz, wvtype=wvtype,
                         obs=True, dp=dp, c=c, rhof=rhof)
    tfs = ut.tf_from_xyz(trxyz, pvh=False)
    ntr = trxyz[0]  # North component
    etr = trxyz[1]  # East component
    ztr = trxyz[2]  # Vertical component
    rtr = ntr.copy()  # Radial component
    ttr = etr.copy()  # Transverse component
    rtr.data, ttr.data = rotate_ne_rt(ntr.data, etr.data, baz)
    strf = Stream(traces=[tfs[0], ztr, rtr])
    # Set frequency corners in Hz
    f1 = 0.1
    f2 = 1.0
    # Plot as wiggles
    with tempfile.TemporaryDirectory() as tempdir:
        wg.pw_wiggles_Audet2016(strf, t1=t1, tmax=10., f1=f1, f2=f2,
                                ftitle=join(tempdir, 'audet2016'),
                                scale=2.e-7, save=True)
def check_rotation_examples(N, E, angles):
    """ Check rotation angles by rotating the partially rotated the rest of the way to 360 
  since obspy doesn't do the negative and compare to original values.  Should be close to 
  zero"""
    ntests = 0
    testsfailed = 0
    for angle in angles:
        dir = "%03d" % (angle)
        n = read("%s/%s" % (dir, N[0].stats.id))
        e = read("%s/%s" % (dir, N[0].stats.id))
        r, t = rotate.rotate_ne_rt(n[0].data, e[0].data, 360. - angle)
        try:
            npt.assert_almost_equal(N[0].data, r)
            ntests += 1
            npt.assert_almost_equal(E[0].data, t)
            ntests += 1
        except:
            testsfailed += 1
    print("Check rotation %d tests passed test %d tests failed" %
          (ntests, testsfailed))
    return True
def create_rotation_examples(N, E, angles):
    for angle in angles:
        # We add 180 because the angle is back azimuth.  The rotation does not allow
        # negative angles so we continue on around the other way.
        if angle < 180.:
            rangle = angle + 180.
        else:
            rangle = angle - 180.

        r, t = rotate.rotate_ne_rt(N[0].data, E[0].data, rangle)
        dir = "rotation/%03d" % (angle)
        try:
            os.mkdir(dir)
        except:
            # Directory exists do nothing
            pass
        tr_n = N[0].copy()
        tr_n.data = r.astype('int32')
        tr_e = E[0].copy()
        tr_e.data = t.astype('int32')
        tr_n.write("%s/%s" % (dir, tr_n.id), format='MSEED')
        tr_e.write("%s/%s" % (dir, tr_e.id), format='MSEED')
Beispiel #15
0
def DLcalc(stream, Rf, LPF, HPF, epi, baz, A, winlen=10., ptype=0):
    """
    DORAN-LASKE calculation for one freq, one orbit of surface wave

    ADRIAN. K. DORAN and GABI LASKE, DLOPy VERSION 1.0, 
    RELEASED APRIL 2017

    Parameters
    ----------
    stream : float
        Latitude of origin point (deg)
    lon1 : float
        Longitude of origin point (deg)
    lat2 : float
        Latitude of end point (deg)
    lon2 : float
        Longitude of end point (deg)
    map* : :class:`~numpy.ndarray`
        maps of Rayleigh-wave dispersion at various frequencies

    Returns
    -------
    R1 : :class:`~numpy.ndarray`
        R1 velocity path 

    R2 : :class:`~numpy.ndarray`
        R2 velocity path 

    """

    # Pre-process
    stream.taper(type='hann', max_percentage=0.05)
    stream.filter("lowpass", freq=LPF, corners=4, zerophase=True)
    stream.filter("highpass", freq=HPF, corners=4, zerophase=True)
    stream.detrend()

    # Window info
    Rvel = getf(Rf, A)  # Group velocity at Rf
    R1window = (1.0 / (Rf / 1000.)) * winlen
    arv = 1. / Rvel * epi
    r1 = arv - R1window / 2.
    r2 = arv + R1window / 2.

    dt = stream[0].stats.starttime
    st = stream.slice(starttime=dt + r1, endtime=dt + r2)

    # Extract waveform data for each component
    tr1 = st.select(component='1')[0].data
    tr2 = st.select(component='2')[0].data
    trZ = st.select(component='Z')[0].data

    # Calculate Hilbert transform of vertical trace data
    trZ = np.imag(sig.hilbert(trZ))

    # Ensure all data vectors are same length
    tr1, tr2, trZ = resiz(tr1, tr2, trZ)

    # Rotate through and find max normalized covariance
    dphi = 0.1
    ang = np.arange(0., 360., dphi)
    cc1 = np.zeros(len(ang))
    cc2 = np.zeros(len(ang))
    for k, a in enumerate(ang):
        R, T = rotate_ne_rt(tr1, tr2, a)
        covmat = np.corrcoef(R, trZ)
        cc1[k] = covmat[0, 1]
        cstar = np.cov(trZ, R) / np.cov(trZ)
        cc2[k] = cstar[0, 1]

    # Get argument of maximum of cc2
    ia = cc2.argmax()

    # Get azimuth and correct for angles above 360
    phi = (baz - float(ia) * dphi) + 180.
    if phi < 0.:
        phi += 360.
    if phi >= 360.:
        phi -= 360.

    # # plotting:
    # # ptype=0, no plot
    # # ptype=1, Rayleigh plot
    # # ptype=2, Love plot
    # if ptype == 1:
    #     import matplotlib.dates as dat
    #     X = P[0].times()
    #     T = np.zeros((len(X)))
    #     for q in np.arange((len(T))):
    #         T[q] = dt + r1 + X[q]
    #     ZZ = dat.epoch2num(T)
    #     Z = dat.num2date(ZZ)
    #     n, e = rot2d(rdat, rdat2, ANG/4.)
    #     plt.figure()
    #     plt.plot(Z, vdat, label='Vertical')
    #     plt.hold("on")
    #     plt.plot(Z, n, label='BH1')
    #     plt.legend(loc=4)
    #     plt.xlabel('Time')
    #     plt.ylabel('Counts')
    #     plt.title('D-L Results (%i mHz)' % (Rf))
    # elif ptype == 2:
    #     import matplotlib.dates as dat
    #     X = P[0].times()
    #     T = np.zeros((len(X)))
    #     for q in np.arange((len(T))):
    #         T[q] = dt+r1+X[q]
    #     ZZ = dat.epoch2num(T)
    #     Z = dat.num2date(ZZ)
    #     n, e = rot2d(rdat, rdat2, ANG/4.)
    #     plt.figure()
    #     plt.subplot(121)
    #     plt.plot(Z, vdat, label='Vertical')
    #     plt.hold("on")
    #     plt.plot(Z, n, label='BH1')
    #     plt.legend(loc=4)
    #     plt.xlabel('Time')
    #     plt.suptitle('D-L Results (%i mHz)' % (Rf))
    #     plt.subplot(122)
    #     plt.plot(Z, e, label='BH2')
    #     plt.xlabel('Time')
    #     plt.ylabel('Counts')
    #     plt.legend(loc=4)
    # elif ptype == 3:
    #     import matplotlib.dates as dat
    #     X = P[0].times()
    #     T = np.zeros((len(X)))
    #     for q in np.arange((len(T))):
    #         T[q] = dt+r1+X[q]
    #     n, e = rot2d(rdat, rdat2, ANG/4.)
    #     plt.figure()
    #     plt.plot(T, vdat, label='Vertical')

    # if ptype > 0:
    #     plt.show()

    return phi, cc1[ia]
   def get_P_rf(self, window_start=-10.0, window_end=100.0,
                      wl = 0.1,  rotation_method = 'RTZ', 
                      type = 'earth_model',plot = False,
                      decon_type='water_level'):

       self.window_start = window_start
       self.window_end   = window_end

       #initialize receiver function time series
       len_s    = self.window_end - self.window_start
       len_i    = int(len_s/self.ses3d_seismogram.dt)

       if(type == 'earth_model'):

          model = TauPyModel(model='pyrolite_5km')
          tt = model.get_travel_times(source_depth_in_km = self.eq_depth,
                                  distance_in_degree = self.delta_deg,
                                  phase_list=["P","P660s"])

          #just in case there's more than one phase arrival, loop through tt list
          for i in range(0,len(tt)):
             if tt[i].name == 'P':
                p_wave_arrival = tt[i].time
                p_i             = int(p_wave_arrival / self.ses3d_seismogram.dt)
             elif tt[i].name == 'P660s':
                self.slowness = tt[i].ray_param * (np.pi/180.0)

       
       elif(type == 'toy_model'):
          p_i = np.argmax(self.ses3d_seismogram.trace_z)
          p_wave_arrival = p_i * self.ses3d_seismogram.dt

       #window seismograms to [P-window_start : P+window_end] 
       wi_start   = int((p_wave_arrival+window_start)/self.ses3d_seismogram.dt) 
       wi_end     = int((p_wave_arrival+window_end)/self.ses3d_seismogram.dt)  
       trace_x_windowed = self.ses3d_seismogram.trace_x[wi_start:wi_end]
       trace_y_windowed = self.ses3d_seismogram.trace_y[wi_start:wi_end]
       trace_z_windowed = self.ses3d_seismogram.trace_z[wi_start:wi_end]

       #find incidence angle from P wave amplitudes. first rotate to rtz
       r_here, t_here  = rotate.rotate_ne_rt(trace_x_windowed, trace_y_windowed, self.back_az)
       z_here          = trace_z_windowed
       r_amp           = np.amax(r_here)
       z_amp           = np.amax(z_here)
       incidence_angle = np.arctan(r_amp/z_amp) * (180/np.pi)

       #rotate
       if rotation_method == 'RTZ':
          self.r, self.t = rotate.rotate_ne_rt(trace_x_windowed,
                                               trace_y_windowed,
                                               self.back_az)
          self.z         = trace_z_windowed
       elif rotation_method == 'LQT' and type == 'earth_model':
          self.z, self.r, self.t = rotate.rotate_zne_lqt(trace_z_windowed,
                                                         trace_x_windowed,
                                                         trace_y_windowed,
                                                         self.back_az,
                                                         incidence_angle)
       elif rotation_method == 'LQT' and type == 'toy_model':
          raise ValueError('rotation method LQT not implemented for type : toy_model')

       #deconvolve Z (apprx. P wave pulse) from R
       self.time = np.linspace(window_start, window_end, len(self.r))
       if decon_type == 'water_level':
          self.prf  = water_level(self.r,self.z,wl)
       elif decon_type == 'damped_lstsq':
          self.prf  = damped_lstsq(self.r,self.z,damping=0.001)

       #plot the two waveforms being deconvolved
       if plot == True:
          plt.plot(self.time, self.r)
          plt.plot(self.time, self.z)

       if decon_type=='water_level':
          #center of the receiver function on the P arrival
          spike       = np.exp((-1.0*(self.time)**2)/0.1)
          spike_omega = np.fft.fft(spike)
          prf_omega   = np.fft.fft(self.prf)
          prf_shifted = spike_omega*prf_omega
          self.prf    = np.real(np.fft.ifft(prf_shifted))

       #normalize
       self.prf /= self.prf.max()
       if rotation_method=='LQT':
          self.prf *= -1.0
Beispiel #17
0
def tf_from_xyz(trxyz, pvh=False):
    """
    Function to generate transfer functions from displacement traces. 

    Args:
        trxyz (obspy.stream): Obspy ``Stream`` object in cartesian coordinate system
        pvh (bool, optional): Whether to rotate from Z-R-T coordinate system to P-SV-SH wave mode

    Returns:
        (obspy.stream): tfs: Stream containing Radial and Transverse transfer functions

    """

    # Extract East, North and Vertical
    ntr = trxyz[0]
    etr = trxyz[1]
    ztr = trxyz[2]
    baz = cf.baz

    # Copy to radial and transverse
    rtr = ntr.copy()
    ttr = etr.copy()

    # Rotate to radial and transverse
    rtr.data, ttr.data = rotate_ne_rt(ntr.data, etr.data, baz)
    a = pyfftw.empty_aligned(len(rtr.data), dtype='float')
    # print(rtr.data, ttr.data)

    if pvh:
        vp = np.sqrt(cf.a[2,2,2,2,0])/1.e3
        vs = np.sqrt(cf.a[1,2,1,2,0])/1.e3
        trP, trV, trH = rotate_zrt_pvh(ztr, rtr, ttr, vp=vp, vs=vs)
        
        tfr = trV.copy(); tfr.data = np.zeros(len(tfr.data))
        tft = trH.copy(); tft.data = np.zeros(len(tft.data))
        ftfv = pyfftw.interfaces.numpy_fft.fft(trV.data)
        ftfh = pyfftw.interfaces.numpy_fft.fft(trH.data)
        ftfp = pyfftw.interfaces.numpy_fft.fft(trP.data)

        if cf.wvtype=='P':
            # Transfer function
            tfr.data = np.fft.fftshift(np.real(pyfftw.interfaces.numpy_fft.ifft(np.divide(ftfv,ftfp))))
            tft.data = np.fft.fftshift(np.real(pyfftw.interfaces.numpy_fft.ifft(np.divide(ftfh,ftfp))))
        elif cf.wvtype=='Si': 
            tfr.data = np.fft.fftshift(np.real(pyfftw.interfaces.numpy_fft.ifft(np.divide(-ftfp,ftfv))))
            tft.data = np.fft.fftshift(np.real(pyfftw.interfaces.numpy_fft.ifft(np.divide(-ftfp,ftfh))))
        elif cf.wvtype=='SV':
            tfr.data = np.fft.fftshift(np.real(pyfftw.interfaces.numpy_fft.ifft(np.divide(-ftfp,ftfv))))
        elif cf.wvtype=='SH':
            tft.data = np.fft.fftshift(np.real(pyfftw.interfaces.numpy_fft.ifft(np.divide(-ftfp,ftfh))))
    else:
        tfr = rtr.copy(); tfr.data = np.zeros(len(tfr.data))
        tft = ttr.copy(); tft.data = np.zeros(len(tft.data))
        ftfr = pyfftw.interfaces.numpy_fft.fft(rtr.data)
        ftft = pyfftw.interfaces.numpy_fft.fft(ttr.data)
        ftfz = pyfftw.interfaces.numpy_fft.fft(ztr.data)

        if cf.wvtype=='P':
            # Transfer function
            tfr.data = np.fft.fftshift(np.real(pyfftw.interfaces.numpy_fft.ifft(np.divide(ftfr,ftfz))))
            tft.data = np.fft.fftshift(np.real(pyfftw.interfaces.numpy_fft.ifft(np.divide(ftft,ftfz))))
        elif cf.wvtype=='Si':
            tfr.data = np.fft.fftshift(np.real(pyfftw.interfaces.numpy_fft.ifft(np.divide(-ftfz,ftfr))))
            tft.data = np.fft.fftshift(np.real(pyfftw.interfaces.numpy_fft.ifft(np.divide(-ftfz,ftft))))
        elif cf.wvtype=='SV':
            tfr.data = np.fft.fftshift(np.real(pyfftw.interfaces.numpy_fft.ifft(np.divide(-ftfz,ftfr))))
        elif cf.wvtype=='SH':
            tft.data = np.fft.fftshift(np.real(pyfftw.interfaces.numpy_fft.ifft(np.divide(-ftfz,ftft))))

    # Store in stream
    tfs = Stream(traces=[tfr, tft])

    # Return stream
    return tfs
Beispiel #18
0
def tf_from_xyz(trxyz, pvh=False, vp=None, vs=None):
    """
    Function to generate transfer functions from displacement traces.

    Args:
        trxyz (obspy.stream):
            Obspy ``Stream`` object in cartesian coordinate system
        pvh (bool, optional):
            Whether to rotate from Z-R-T coordinate system to P-SV-SH wave mode
        vp (float, optional):
            Vp velocity at surface for rotation to P-SV-SH system
        vs (float, optional):
            Vs velocity at surface for rotation to P-SV-SH system

    Returns:
        (obspy.stream):
            tfs: Stream containing Radial and Transverse transfer functions

    """

    # Extract East, North and Vertical
    ntr = trxyz[0]
    etr = trxyz[1]
    ztr = trxyz[2]
    baz = ntr.stats.baz
    slow = ntr.stats.slow
    wvtype = ntr.stats.wvtype

    # Copy to radial and transverse
    rtr = ntr.copy()
    ttr = etr.copy()

    # Rotate to radial and transverse
    rtr.data, ttr.data = rotate_ne_rt(ntr.data, etr.data, baz)

    if pvh:
        trP, trV, trH = rotate_zrt_pvh(ztr, rtr, ttr, slow, vp=vp, vs=vs)

        tfr = trV.copy()
        tfr.data = np.zeros(len(tfr.data))
        tft = trH.copy()
        tft.data = np.zeros(len(tft.data))
        ftfv = fft(trV.data)
        ftfh = fft(trH.data)
        ftfp = fft(trP.data)

        if wvtype == 'P':
            # Transfer function
            tfr.data = fftshift(np.real(ifft(np.divide(ftfv, ftfp))))
            tft.data = fftshift(np.real(ifft(np.divide(ftfh, ftfp))))
        elif wvtype == 'Si':
            tfr.data = fftshift(np.real(ifft(np.divide(-ftfp, ftfv))))
            tft.data = fftshift(np.real(ifft(np.divide(-ftfp, ftfh))))
        elif wvtype == 'SV':
            tfr.data = fftshift(np.real(ifft(np.divide(-ftfp, ftfv))))
        elif wvtype == 'SH':
            tft.data = fftshift(np.real(ifft(np.divide(-ftfp, ftfh))))
    else:
        tfr = rtr.copy()
        tfr.data = np.zeros(len(tfr.data))
        tft = ttr.copy()
        tft.data = np.zeros(len(tft.data))
        ftfr = fft(rtr.data)
        ftft = fft(ttr.data)
        ftfz = fft(ztr.data)

        if wvtype == 'P':
            # Transfer function
            tfr.data = fftshift(np.real(ifft(np.divide(ftfr, ftfz))))
            tft.data = fftshift(np.real(ifft(np.divide(ftft, ftfz))))
        elif wvtype == 'Si':
            tfr.data = fftshift(np.real(ifft(np.divide(-ftfz, ftfr))))
            tft.data = fftshift(np.real(ifft(np.divide(-ftfz, ftft))))
        elif wvtype == 'SV':
            tfr.data = fftshift(np.real(ifft(np.divide(-ftfz, ftfr))))
        elif wvtype == 'SH':
            tft.data = fftshift(np.real(ifft(np.divide(-ftfz, ftft))))

    # Store in stream
    tfs = Stream(traces=[tfr, tft])

    # Return stream
    return tfs
def getobs(mseed_filename,
           client,
           event,
           phases,
           frq4,
           windows,
           stas,
           stalocs,
           picks=None,
           delta_T={
               'P': 1.,
               'SH': 1.,
               'R': 10.,
               'L': 10.
           },
           taper=None,
           adjtime=None):
    # Connect to arclink server
    #st = read('../mseed/mini.seed')
    org = event.preferred_origin()
    if org is None:
        org = event.origins[0]
    st = read(mseed_filename)
    stobs = {'params': {'filter': frq4, 'windows': windows}}
    syn = {}
    torg = org.time
    trngmx = 3600.
    invout = None
    # First do any requried time adjustments
    if not adjtime is None:
        for tr in st:
            if not tr.stats.station in adjtime.keys():
                continue
            print 'Adjusting time for station %s by %g secs' % \
                (tr.stats.station,adjtime[tr.stats.station])
            tr.stats.starttime -= adjtime[tr.stats.station]

    for phase in phases:
        if not phase in stas.keys(): continue
        stobs[phase] = Stream()
        for sta in stas[phase]:
            # If this is a body wave phase find the pick - skip if none found
            if phase == 'P' or phase == 'SH':
                sta_pick = None
                # If no picks supplied then get them from events
                if picks is None:
                    for pick in event.picks:
                        if pick.phase_hint == phase[0:1] and \
                            pick.waveform_id.station_code == sta:
                            sta_pick = pick
                            break
                else:  # Get them from picks - e.g. returned by get_isctimes
                    if sta in picks.keys() and phase[0:1] in picks[sta]:
                        sta_pick = Pick()
                        sta_pick.time = picks[sta][phase[0:1]]
                if sta_pick is None:
                    print 'No %s pick found for station %s - skipping' % (
                        phase, sta)
                    continue

            # Set location code if prescribed, otherwise use '00' (preferred)
            if sta in stalocs.keys():
                loc = stalocs[sta]
            else:
                loc = '00'
            # Select the channels for this station - skip if none found
            chans = st.select(station=sta, location=loc)
            if len(chans) == 0:  # if nothing for loc='00', try also with ''
                loc = ''
                chans = st.select(station=sta, location=loc)
            if len(chans) == 0:
                print 'No channels found for %s' % sta
                continue
            try:
                inv = client.get_stations(network=chans[0].stats.network,
                                          station=sta,
                                          location=loc,
                                          starttime=torg,
                                          endtime=torg + 100.,
                                          level='response')
            except Exception as e:
                warnings.warn(str(e))
                print 'FDSNWS request failed for trace id %s - skipping' % sta
                continue
            try:
                coordinates = inv[0].get_coordinates(chans[0].id)
            except:
                print 'No coordinates found for station %s, channel %s' % \
                            (sta,chans[0].id)
                continue
            dist, azm, bazm = gps2dist_azimuth(org['latitude'],
                                               org['longitude'],
                                               coordinates['latitude'],
                                               coordinates['longitude'])
            gcarc = locations2degrees(org['latitude'], org['longitude'],
                                      coordinates['latitude'],
                                      coordinates['longitude'])
            if phase == 'R' or phase == 'P':  # Rayleigh or P wave
                try:
                    tr = st.select(station=sta, component='Z', location=loc)[0]
                except IndexError:
                    print 'No vertical for %s:%s' % (sta, loc)
                    continue
                try:
                    inv = client.get_stations(network=tr.stats.network,
                                              station=sta,
                                              channel=tr.stats.channel,
                                              location=loc,
                                              starttime=torg,
                                              endtime=torg + 100.,
                                              level='response')
                except Exception as e:
                    warnings.warn(str(e))
                    print 'FDSNWS request failed for trace id %s - skipping' % tr.id
                    continue
                tr = tr.copy()
                tr.stats.response = inv[0].get_response(tr.id, torg)
                tr.stats.coordinates = inv[0].get_coordinates(tr.id)
                tr.remove_response(pre_filt=frq4[phase], output='DISP')
                tr.stats.gcarc = gcarc
                tr.stats.azimuth = azm
                #t1 = minv[0].get_responeax(tr.stats.starttime,t+dist/rvmax)
                #t2 = min(tr.stats.endtime  ,t+dist/rvmin)
                t1 = max(torg, tr.stats.starttime)
                t2 = min(torg + trngmx, tr.stats.endtime)
                tr.trim(starttime=t1, endtime=t2)
                decim = int(0.01 + delta_T[phase] / tr.stats.delta)
                ch = inv.select(station=sta, channel=tr.stats.channel)[0][0][0]
                print tr.id,' ',tr.stats.sampling_rate,' decimated by ',decim,\
                        'sensitivity=',ch.response.instrument_sensitivity.value
                if tr.stats.starttime - torg < 0.:
                    tr.trim(starttime=torg)
                tr.decimate(factor=decim, no_filter=True)
                tr.data *= 1.e6  # Convert to microns
            elif phase == 'L' or phase == 'SH':  # Love or SH wave
                if len(chans.select(component='E')) != 0:
                    try:
                        tr1a = st.select(station=sta,
                                         component='E',
                                         location=loc)[0]
                        tr2a = st.select(station=sta,
                                         component='N',
                                         location=loc)[0]
                    except:
                        print 'Station %s does not have 2 horizontal componets -skipping' % sta
                        continue
                elif len(chans.select(component='1')) != 0:
                    try:
                        tr1a = st.select(station=sta,
                                         component='1',
                                         location=loc)[0]
                        tr2a = st.select(station=sta,
                                         component='2',
                                         location=loc)[0]
                    except:
                        print 'Station %s does not have 2 horizontal componets -skipping' % sta
                        continue
                tr1 = tr1a.copy()
                tr1.data = tr1a.data.copy()
                tr2 = tr2a.copy()
                tr2.data = tr2a.data.copy()
                ch1 = inv.select(station=sta,
                                 channel=tr1.stats.channel)[0][0][0]
                ch2 = inv.select(station=sta,
                                 channel=tr2.stats.channel)[0][0][0]
                tr1.stats.response = ch1.response
                tr1.remove_response(pre_filt=frq4[phase], output='DISP')
                tr2.stats.response = ch2.response
                tr2.remove_response(pre_filt=frq4[phase], output='DISP')
                strt = max(tr1.stats.starttime, tr2.stats.starttime)
                endt = min(tr1.stats.endtime, tr2.stats.endtime)
                tr1.trim(starttime=strt, endtime=endt)
                tr2.trim(starttime=strt, endtime=endt)
                # Rotate components first to ZNE
                vert, north, east = rotate2zne(tr1.data, ch1.azimuth, 0.,
                                               tr2.data, ch2.azimuth, 0.,
                                               np.zeros(tr1.stats.npts), 0.,
                                               0.)
                radial, transverse = rotate_ne_rt(north, east, bazm)
                tr = Trace(header=tr1.stats, data=transverse)
                tr2 = Trace(header=tr2.stats, data=radial)
                tr.stats.channel = tr.stats.channel[:-1] + 'T'
                # Change one of the invout channels to end in 'T'
                net = inv[-1]
                stn = net[0]
                chn = stn[0]
                chn.code = chn.code[:-1] + 'T'
                #
                tr.stats.gcarc = gcarc
                tr.stats.azimuth = azm
                decim = int(0.01 + delta_T[phase] / tr.stats.delta)
                print tr.id, ' ', tr.stats.sampling_rate, ' decimated by ', decim
                print '%s: sensitivity=%g, azimuth=%g, dip=%g' % (
                    ch1.code, ch1.response.instrument_sensitivity.value,
                    ch1.azimuth, ch1.dip)
                print '%s: sensitivity=%g, azimuth=%g, dip=%g' % (
                    ch2.code, ch2.response.instrument_sensitivity.value,
                    ch2.azimuth, ch2.dip)
                if tr.stats.starttime - torg < 0.:
                    tr.trim(starttime=torg)
                    tr2.trim(starttime=torg)
                tr.decimate(factor=decim, no_filter=True)
                tr2.decimate(factor=decim, no_filter=True)
                tr.radial = 1.e6 * tr2.data
                tr.stats.coordinates = coordinates
                tr.data *= 1.e6  # Convert to microns
            if phase == 'R' or phase == 'L':  # Window according to group velocity window
                gwin = windows[phase]
                tbeg, tend = (dist * .001 / gwin[1], dist * .001 / gwin[0])
                tr.trim(torg + tbeg, torg + tend)
            elif phase == 'P' or phase == 'SH':  # Window by times before and after pick
                tbef, taft = windows[phase]
                tr.trim(sta_pick.time - tbef, sta_pick.time + taft)
                idx = int(0.5 + tbef / tr.stats.delta)
                avg = tr.data[:idx].mean()
                tr.data -= avg
                if not taper is None:
                    itp = int(taper * tr.stats.npts)
                    for i in range(tr.stats.npts - itp, tr.stats.npts):
                        tr.data[i] *= 0.5 * (1. + mt.cos(
                            mt.pi * (i - (tr.stats.npts - itp)) / float(itp)))
                tr.stats.pick = sta_pick
            stobs[phase].append(tr)
            # Appen station inventory to invout
            if invout is None:
                invout = inv
            else:
                invout += inv
        # Pickle to file
    return stobs, invout
def SKS_Intensity_Chevrot(st_ev, ev_time, t_SKS, back_azimut, plot=True):
    #    SV_Az = []
    #    Az = []
    st_ev = st_ev.sort()

    #    for ev_step in range(0,len(ev_time_l)):
    ### SORT IT AS ZNE
    st_stream = obspy.Stream()
    tmp = st_ev[2]
    st_stream += tmp
    tmp = st_ev[1]
    st_stream += tmp
    tmp = st_ev[0]
    st_stream += tmp

    gridspec.GridSpec(2, 3)

    arrival_time = ev_time + t_SKS

    ### USE CORRECT ARRIVAL TIME
    ### Take small time window around arrival time
    twin = 15
    st_stream = st_stream.slice(arrival_time - twin,
                                arrival_time + twin,
                                nearest_sample=True)

    limits = np.max([abs(st_stream[2].data),
                     abs(st_stream[2].data)]) * 2 * 10**6

    #### CALC THE POLARIZATION OF PARTICLE MOTION
    ## only accept the upper half for Signal
    noise_level = st_stream[0].data**2 + st_stream[1].data**2 + st_stream[
        2].data**2
    azimuth, incidence, az_error, in_error = particle_motion_odr(
        st_stream,
        noise_thres=np.mean([np.max(noise_level),
                             np.min(noise_level)]) +
        np.std([np.max(noise_level), np.min(noise_level)]))
    #    print(az_error)
    ### ROTATE THE SYSTEM FROM NE TO RT
    st_rot_RT = rotate_ne_rt(st_stream[1].data, st_stream[2].data,
                             180 + azimuth)

    radial = st_rot_RT[0]
    r_dot = np.diff(radial) / st_stream[1].stats.delta

    radial = radial[0:len(r_dot)]
    transverse = st_rot_RT[1][0:len(r_dot)]

    r_2 = np.sum(r_dot**2)
    ### NORMALIZE SPLITTING VECTOR
    SV_EQ = -np.sum(2 * r_dot * transverse) / r_2

    sigma = np.sqrt(np.sum((transverse + 0.5 * r_dot * SV_EQ)**2))
    #    print(sigma)

    ### EVENT AZIMUT IS BACK-AZIMUT +180
    if back_azimut + 180 > 360:
        Az = back_azimut - 180
    else:
        Az = back_azimut + 180
    SV_Az = SV_EQ

    if plot == True:
        ### Only Plotting Below
        fig = plt.figure(figsize=(16, 9))
        #        plt.subplot2grid((2,3), (0,0), colspan=2, rowspan=1)
        ax1 = fig.add_axes([0.1, 0.5, 0.5, 0.3])
        ax2 = fig.add_axes([0.65, 0.5, 0.25, 0.3])
        ax3 = fig.add_axes([0.1, 0.1, 0.5, 0.3])
        ax4 = fig.add_axes([0.65, 0.1, 0.25, 0.3])

        timevec = np.linspace(float(st_stream[0].stats.starttime),
                              float(st_stream[0].stats.endtime),
                              st_stream[0].stats.npts)

        xxticks = np.linspace(timevec[0], timevec[-1], 10)
        xxlabels = []
        for i in range(0, len(xxticks)):
            tmp = UTCDateTime(xxticks[i]).strftime('%H:%M:%S')
            xxlabels.append(tmp)

    ########### SET PROPER TIME AXIS

        ax1.plot(timevec, st_stream[1].data * 10**6, 'g', label='North')
        ax1.plot(timevec, st_stream[2].data * 10**6, 'b', label='East')
        ax1.vlines(
            x=float(arrival_time),
            ymin=1.3 * np.min(
                np.min([st_stream[1].data * 10**6, st_stream[2].data * 10**6
                        ])),
            ymax=1.3 * np.max(
                np.max([st_stream[1].data * 10**6, st_stream[2].data * 10**6
                        ])),
            color='k',
            linewidth=0.5,
            label='SKS-Phase')
        ax1.set_title(
            '{0}, SKS-arrival at: {1}, Backazimut={2} $^\circ$, SI={3}'.format(
                st_stream[0].stats.station,
                arrival_time.strftime('%Y-%m-%d, %H:%M:%S'), round(Az, 2),
                round(SV_Az, 2)))
        ax1.set_xlabel('Time [s]')
        ax1.set_ylabel('displacement [$\mu$m]')
        ax1.set_xlim(timevec[0], timevec[-1])
        ax1.set_xticks(xxticks)
        ax1.set_xticklabels(xxlabels)
        ax1.grid()
        ax1.legend()

        #        plt.subplot2grid((2,3), (0,2))
        ax2.plot(st_stream[2].data * 10**6,
                 st_stream[1].data / 10**-6,
                 color='black',
                 linestyle='dashed')
        ax2.set_xlabel('East disp. [$\mu$m]')
        ax2.set_ylabel('North disp. [$\mu$m]')
        ax2.axis('equal')
        ax2.set_xlim(-limits, limits)
        ax2.set_ylim(-limits, limits)
        ax2.grid()
        ax2.set_title('Polarization: Azimuth={0}$^\circ$'.format(
            round(azimuth, 2)))

        #        limits = 1
        #        limits = np.max([np.max(radial),np.max(transverse)])

        # #        plt.subplot2grid((2,3), (1,0), colspan=2, rowspan=1)
        ax3.plot(timevec[0:-1], radial * 10**6, 'r', label='Radial')
        ax3.plot(timevec[0:-1], transverse * 10**6, 'b', label='Transverse')
        ax3.plot(timevec[0:-1],
                 -0.5 * r_dot * (np.max(transverse) / np.max(r_dot)) * 10**6,
                 color='g',
                 label='radial-derivate',
                 alpha=0.5,
                 linewidth=0.5)
        ax3.vlines(
            x=float(arrival_time),
            ymin=1.3 * np.min(
                np.min([st_stream[1].data * 10**6, st_stream[2].data * 10**6
                        ])),
            ymax=1.3 * np.max(
                np.max([st_stream[1].data * 10**6, st_stream[2].data * 10**6
                        ])),
            color='k',
            linewidth=0.5,
            label='SKS-Phase')
        ax3.set_xlabel('Time [s]')
        ax3.set_ylabel('displacement [$\mu$m]')
        ax3.set_xlim(timevec[0], timevec[-1])
        ax3.set_xticks(xxticks)
        ax3.set_xticklabels(xxlabels)
        ax3.grid()
        ax3.set_title('rotated System')
        ax3.legend()

        #        plt.subplot2grid((2,3), (1,2))
        ax4.plot(radial * 10**6,
                 transverse * 10**6,
                 color='black',
                 linestyle='dashed')
        ax4.set_xlabel('Radial disp. [$\mu$m]')
        ax4.set_ylabel('Transverse  disp. [$\mu$m]')
        ax4.axis('equal')
        #        ax4.set_xlim(-limits, limits)
        #        ax4.set_ylim(-limits, limits)
        ax4.grid()

        try:
            path_Methods = '/media/hein/home2/SplitWave_Results/Splitting_Intensity/{0}/'.format(
                st_stream[0].stats.station)
            os.mkdir(path_Methods)
        except:
            pass
        plt.savefig(
            '/media/hein/home2/SplitWave_Results/Splitting_Intensity/{0}/{0}_{1}'
            .format(st_stream[0].stats.station,
                    arrival_time.strftime('%Y-%m-%d, %H:%M:%S')))
        plt.close()
#        fig.close()
#    plt.show()

    return Az, SV_Az
Beispiel #21
0
def extract_s(taupy_model,
              picker,
              event,
              station_longitude,
              station_latitude,
              stn,
              ste,
              ba,
              win_start=-50,
              win_end=50,
              resample_hz=20,
              bp_freqmins=[0.05, 2],
              bp_freqmaxs=[0.5, 5],
              margin=20,
              max_amplitude=1e8):

    po = event.preferred_origin
    if (not po): return None

    atimes = []
    try:
        atimes = taupy_model.get_travel_times_geo(po.depthkm,
                                                  po.lat,
                                                  po.lon,
                                                  station_latitude,
                                                  station_longitude,
                                                  phase_list=('S', ))
    except:
        return None
    # end try

    if (len(atimes) == 0): return None
    tat = atimes[0].time  # theoretical arrival time

    tr = None
    try:
        stn = stn.slice(po.utctime + tat + win_start,
                        po.utctime + tat + win_end)
        stn.resample(resample_hz)

        if (ste):
            ste = ste.slice(po.utctime + tat + win_start,
                            po.utctime + tat + win_end)
            ste.resample(resample_hz)
        # end if

        if (ste):
            if (type(stn[0].data) == np.ndarray
                    and type(ste[0].data) == np.ndarray):
                rc, tc = rotate_ne_rt(stn[0].data, ste[0].data, ba)
                tr = Trace(data=tc, header=stn[0].stats)
                #tr = Trace(data=np.sqrt(np.power(rc,2) + np.power(tc,2)), header=stn[0].stats)
            # end if
        else:
            if (type(stn[0].data) == np.ndarray):
                tr = stn[0]
            # end if
        # end if
    except Exception as e:
        return None
    # end try

    if (tr):
        if (np.max(tr.data) > max_amplitude): return None

        pickslist = []
        snrlist = []
        residuallist = []

        tr.detrend('linear')
        for i in range(len(bp_freqmins)):
            trc = tr.copy()
            trc.filter('bandpass',
                       freqmin=bp_freqmins[i],
                       freqmax=bp_freqmaxs[i],
                       corners=4,
                       zerophase=True)

            try:
                scnl, picks, polarity, snr, uncert = picker.picks(trc)

                for ipick, pick in enumerate(picks):
                    actualArrival = pick - po.utctime
                    residual = actualArrival - tat

                    if (np.fabs(residual) < margin):
                        pickslist.append(pick)
                        snrlist.append(snr[ipick])
                        residuallist.append(residual)

                        #summary = fbpicker.FBSummary(picker, trc)
                        #summary = aicdpicker.AICDSummary(picker, trc)
                        #outputPath = '/home/rakib/work/pst/picking/sarr'
                        #outputPath = '/g/data1a/ha3/rakib/seismic/pst/tests/plots/new'
                        #ofn = '%s/%s.%s_%f_%d.s.png' % (outputPath, scnl, str(po.utctime), snr[0], i)
                        #summary.plot_picks(show=False, savefn=ofn)
                    # end if
                # end for
            except:
                continue
            # end try
        # end for

        if (len(pickslist)):
            optimal_pick_idx = np.argmax(np.array(snrlist))

            return pickslist[optimal_pick_idx], residuallist[optimal_pick_idx], \
                   snrlist[optimal_pick_idx], optimal_pick_idx
        # end if
    # end if

    return None
Beispiel #22
0
def extract_s(taupy_model,
              pickerlist,
              event,
              station_longitude,
              station_latitude,
              stn,
              ste,
              ba,
              win_start=-50,
              win_end=50,
              resample_hz=20,
              bp_freqmins=[0.01, 0.01, 0.5],
              bp_freqmaxs=[1, 2., 5.],
              margin=None,
              max_amplitude=1e8,
              plot_output_folder=None):

    po = event.preferred_origin
    if (not po): return None

    atimes = []
    try:
        atimes = taupy_model.get_travel_times_geo(po.depthkm,
                                                  po.lat,
                                                  po.lon,
                                                  station_latitude,
                                                  station_longitude,
                                                  phase_list=('S', ))
    except:
        return None
    # end try

    if (len(atimes) == 0): return None
    tat = atimes[0].time  # theoretical arrival time

    buffer_start = -10
    buffer_end = 10
    snrtr = None
    try:
        stn = stn.slice(po.utctime + tat + win_start + buffer_start,
                        po.utctime + tat + win_end + buffer_end)
        stn = stn.copy()
        stn.resample(resample_hz)
        stn.detrend('linear')

        if (ste):
            ste = ste.slice(po.utctime + tat + win_start + buffer_start,
                            po.utctime + tat + win_end + buffer_end)
            ste = ste.copy()
            ste.resample(resample_hz)
            ste.detrend('linear')
        # end if

        if (ste):
            if (type(stn[0].data) == np.ndarray
                    and type(ste[0].data) == np.ndarray):
                rc, tc = rotate_ne_rt(stn[0].data, ste[0].data, ba)
                snrtr = Trace(data=tc, header=stn[0].stats)
                snrtr.detrend('linear')
            # end if
        else:
            if (type(stn[0].data) == np.ndarray):
                snrtr = stn[0]
            # end if
        # end if
    except Exception as e:
        return None
    # end try

    if (type(snrtr.data) == np.ndarray):
        if (np.max(snrtr.data) > max_amplitude): return None

        pickslist = []
        snrlist = []
        residuallist = []
        bandindex = -1
        pickerindex = -1
        taper_percentage = float(buffer_end) / float(win_end)

        foundpicks = False
        for i in range(len(bp_freqmins)):
            trc = snrtr.copy()
            trc.taper(max_percentage=taper_percentage, type='hann')
            trc.filter('bandpass',
                       freqmin=bp_freqmins[i],
                       freqmax=bp_freqmaxs[i],
                       corners=4,
                       zerophase=True)
            trc = trc.slice(po.utctime + tat + win_start,
                            po.utctime + tat + win_end)

            for ipicker, picker in enumerate(pickerlist):
                try:
                    scnl, picks, polarity, snr, uncert = picker.picks(trc)

                    for ipick, pick in enumerate(picks):
                        actualArrival = pick - po.utctime
                        residual = actualArrival - tat

                        if ((margin and np.fabs(residual) < margin)
                                or (margin == None)):
                            pickslist.append(pick)

                            plotinfo = None
                            if (plot_output_folder):
                                plotinfo = {
                                    'eventid': event.public_id,
                                    'origintime': po.utctime,
                                    'mag':
                                    event.preferred_magnitude.magnitude_value,
                                    'net': trc.stats.network,
                                    'sta': trc.stats.station,
                                    'phase': 's',
                                    'ppsnr': snr[ipick],
                                    'pickid': ipick,
                                    'outputfolder': plot_output_folder
                                }
                            # end if

                            wab = snrtr.slice(pick - 3, pick + 3)
                            wab_filtered = trc.slice(pick - 3, pick + 3)
                            scales = np.logspace(0.5, 4, 30)
                            cwtsnr, dom_freq, slope_ratio = compute_quality_measures(
                                wab, wab_filtered, scales, plotinfo)
                            snrlist.append(
                                [snr[ipick], cwtsnr, dom_freq, slope_ratio])

                            residuallist.append(residual)
                            bandindex = i
                            pickerindex = ipicker

                            foundpicks = True
                        # end if
                    # end for
                except:
                    continue
                # end try
                if (foundpicks): break
            # end for
            if (foundpicks): break
        # end for

        if (len(pickslist)):
            return pickslist, residuallist, \
                   np.array(snrlist), bandindex, pickerindex
        # end if
    # end if

    return None
Beispiel #23
0
    def get_P_rf(self,
                 window_start=-10.0,
                 window_end=100.0,
                 wl=0.1,
                 rotation_method='RTZ',
                 type='earth_model',
                 plot=False,
                 decon_type='water_level'):

        self.window_start = window_start
        self.window_end = window_end

        #initialize receiver function time series
        len_s = self.window_end - self.window_start
        len_i = int(len_s / self.ses3d_seismogram.dt)

        if (type == 'earth_model'):

            model = TauPyModel(model='pyrolite_5km')
            tt = model.get_travel_times(source_depth_in_km=self.eq_depth,
                                        distance_in_degree=self.delta_deg,
                                        phase_list=["P", "P660s"])

            #just in case there's more than one phase arrival, loop through tt list
            for i in range(0, len(tt)):
                if tt[i].name == 'P':
                    p_wave_arrival = tt[i].time
                    p_i = int(p_wave_arrival / self.ses3d_seismogram.dt)
                elif tt[i].name == 'P660s':
                    self.slowness = tt[i].ray_param * (np.pi / 180.0)

        elif (type == 'toy_model'):
            p_i = np.argmax(self.ses3d_seismogram.trace_z)
            p_wave_arrival = p_i * self.ses3d_seismogram.dt

        #window seismograms to [P-window_start : P+window_end]
        wi_start = int(
            (p_wave_arrival + window_start) / self.ses3d_seismogram.dt)
        wi_end = int((p_wave_arrival + window_end) / self.ses3d_seismogram.dt)
        trace_x_windowed = self.ses3d_seismogram.trace_x[wi_start:wi_end]
        trace_y_windowed = self.ses3d_seismogram.trace_y[wi_start:wi_end]
        trace_z_windowed = self.ses3d_seismogram.trace_z[wi_start:wi_end]

        #find incidence angle from P wave amplitudes. first rotate to rtz
        r_here, t_here = rotate.rotate_ne_rt(trace_x_windowed,
                                             trace_y_windowed, self.back_az)
        z_here = trace_z_windowed
        r_amp = np.amax(r_here)
        z_amp = np.amax(z_here)
        incidence_angle = np.arctan(r_amp / z_amp) * (180 / np.pi)

        #rotate
        if rotation_method == 'RTZ':
            self.r, self.t = rotate.rotate_ne_rt(trace_x_windowed,
                                                 trace_y_windowed,
                                                 self.back_az)
            self.z = trace_z_windowed
        elif rotation_method == 'LQT' and type == 'earth_model':
            self.z, self.r, self.t = rotate.rotate_zne_lqt(
                trace_z_windowed, trace_x_windowed, trace_y_windowed,
                self.back_az, incidence_angle)
        elif rotation_method == 'LQT' and type == 'toy_model':
            raise ValueError(
                'rotation method LQT not implemented for type : toy_model')

        #deconvolve Z (apprx. P wave pulse) from R
        self.time = np.linspace(window_start, window_end, len(self.r))
        if decon_type == 'water_level':
            self.prf = water_level(self.r, self.z, wl)
        elif decon_type == 'damped_lstsq':
            self.prf = damped_lstsq(self.r, self.z, damping=0.001)

        #plot the two waveforms being deconvolved
        if plot == True:
            plt.plot(self.time, self.r)
            plt.plot(self.time, self.z)

        if decon_type == 'water_level':
            #center of the receiver function on the P arrival
            spike = np.exp((-1.0 * (self.time)**2) / 0.1)
            spike_omega = np.fft.fft(spike)
            prf_omega = np.fft.fft(self.prf)
            prf_shifted = spike_omega * prf_omega
            self.prf = np.real(np.fft.ifft(prf_shifted))

        #normalize
        self.prf /= self.prf.max()
        if rotation_method == 'LQT':
            self.prf *= -1.0
            elif st[itr].stats.channel == H2comp:
                h2 = st[itr].data
            elif st[itr].stats.channel == Zcomp:
                z = st[itr].data
        ba = st[0].stats.sac.baz
        
        # Rotate Z-H1-H2 to Z-N-E
        traces_zne = rotate2zne(data_1=z , azimuth_1=0, dip_1=-90, 
                   data_2=h1, azimuth_2=H1azi, dip_2=0, 
                   data_3=h2, azimuth_3=H1azi+90, dip_3=0)
        z2 = traces_zne[0]
        n = traces_zne[1]
        e = traces_zne[2]
        
        # Rotate N-E to R-T
        traces_rt = rotate_ne_rt(n=n, e=e, ba=ba)
        r = traces_rt[0]
        t = traces_rt[1]

        # Define new data streams
        st_bhn = st[0].copy()
        st_bhn.stats.channel = Ncomp
        st_bhn.data = n
        st_bhe = st[0].copy()
        st_bhe.stats.channel = Ecomp
        st_bhe.data = e
        st_bht = st[0].copy()
        st_bht.stats.channel = Tcomp
        st_bht.data = t
        st_bhr = st[0].copy()
        st_bhr.stats.channel = Rcomp
corrcoefs = []
for ic in xrange(0, len(RLAS[0]) // (int(sampling_rate * sec))):
        coeffs = xcorr(RLAS[0].data[sampling_rate * sec * ic : sampling_rate * sec * (ic + 1)],
                       AC[0].data[sampling_rate * sec * ic : sampling_rate * sec * (ic + 1)], 0)
        corrcoefs.append(coeffs[1])

# estimate the Backazimuth for each time window 
step = 10
backas = np.linspace(0, 360 - step, 360 / step)
corrbaz = []
ind=None
for i6 in xrange(0, len(backas)):
    for i7 in xrange(0, len(corrcoefs)):
        corrbazz = xcorr(RLAS[0][sampling_rate * sec * i7 : sampling_rate * sec * (i7 + 1)],
                             rotate_ne_rt(AC_original.select(component='N')[0].data, 
                                          AC_original.select(component='E')[0].data, backas[i6])
                             [1][sampling_rate * sec * i7 : sampling_rate * sec * (i7 + 1)],0)
        corrbaz.append(corrbazz[1])
corrbaz = np.asarray(corrbaz)
corrbaz = corrbaz.reshape(len(backas), len(corrcoefs))

maxcorr = []
for l1 in xrange(0, len(corrcoefs)):
    maxcor_r = backas[corrbaz[:, l1].argmax()]
    maxcorr.append(maxcor_r)
maxcorr = np.asarray(maxcorr)
X, Y = np.meshgrid(np.arange(0, sec * len(corrcoefs), sec), backas)



Beispiel #26
0
    def calc(self, dphi, dts, tt, bp=None, showplot=False):
        """
        Method to estimate azimuth of component `?H1` (or `?HN`). This
        method minimizes the energy (RMS) of the transverse component of
        P-wave data within some bandwidth. 

        Parameters
        ----------
        dphi : float
            Azimuth increment for search (deg)
        dts : float
            Length of time window on either side of 
            predicted P-wave arrival time (sec)
        tt : list
            List of two floats containing the time picks relative
            to P-wave time, within which to perform the estimation of
            station orientation (sec)
        bp : list
            List of two floats containing the low- and high-frequency
            corners of a bandpass filter (Hz)
        showplot : bool
            Whether or not to plot waveforms.

        Attributes
        ----------
        meta.phi : float
            Azimuth of H1 (or HN) component (deg)
        meta.cc : float
            Cross-correlation coefficient between
            vertical and radial component
        meta.snr : float
            Signal-to-noise ratio of P-wave measured on the 
            vertical seismogram
        meta.TR : float
            Measure of the transverse to radial ratio. In reality
            this is 1 - T/R
        meta.RZ : float
            Measure of the radial to vertical ratio. In reality 
            this is 1 - R/Z

        """

        # Work on a copy of the waveform data
        stream = self.data.copy()

        # Filter if specified
        if bp:
            stream.filter('bandpass',
                          freqmin=bp[0],
                          freqmax=bp[1],
                          zerophase=True)

        # Get data and noise based on symmetric waveform wrt arrival
        start = stream[0].stats.starttime
        stnoise = stream.copy().trim(start, start + dts + tt[0])
        stdata = stream.copy().trim(start + dts + tt[0], start + dts + tt[1])

        # Define signal and noise
        tr1 = stdata.select(component='1')[0].copy()
        tr2 = stdata.select(component='2')[0].copy()
        trZ = stdata.select(component='Z')[0].copy()
        ntrZ = stnoise.select(component='Z')[0].copy()

        # Calculate and store SNR as attribute
        self.meta.snr = 10. * np.log10(
            utils.rms(trZ) * utils.rms(trZ) / utils.rms(ntrZ) /
            utils.rms(ntrZ))

        # Search through azimuths from 0 to 180 deg and find best-fit azimuth
        ang = np.arange(0., 180., dphi)
        cc1 = np.zeros(len(ang))
        cc2 = np.zeros(len(ang))
        cc3 = np.zeros(len(ang))
        cc4 = np.zeros(len(ang))
        for k, a in enumerate(ang):
            R, T = rotate_ne_rt(tr1.data, tr2.data, a)
            covmat = np.corrcoef(R, trZ.data)
            cc1[k] = covmat[0, 1]
            cc2[k] = 1. - utils.rms(T) / utils.rms(R)
            cc3[k] = utils.rms(T)
            cc4[k] = 1. - utils.rms(R) / utils.rms(trZ.data)

        # Get argument of minimum of cc3 and store useful measures
        ia = cc3.argmin()
        self.meta.cc = cc1[ia]
        self.meta.TR = cc2[ia]
        self.meta.RZ = cc4[ia]

        # correct for angles above 360
        phi = (self.meta.baz - float(ia) * dphi)

        # Use azimuth where CC is negative
        if self.meta.cc < 0.:
            phi += 180.

        if phi < 0.:
            phi += 360.
        if phi >= 360.:
            phi -= 360.

        # Store the best-fit azimuth
        self.meta.phi = phi

        # If a plot is requested, rotate Z12 to ZNE and then ZRT
        if showplot:

            # Now rotate components to proper N, E and then R, T
            sttmp = stream.copy()

            # Apply filter if defined previously
            if bp:
                sttmp.filter('bandpass',
                             freqmin=bp[0],
                             freqmax=bp[1],
                             zerophase=True)

            # Copy traces
            trN = sttmp.select(component='1')[0].copy()
            trE = sttmp.select(component='2')[0].copy()

            # Rotating from 1,2 to N,E is the negative of
            # rotation from RT to NE, with baz corresponding
            # to azim of component 1, or phi previously determined
            azim = self.meta.phi
            N, E = rotate_rt_ne(trN.data, trE.data, azim)
            trN.data = -1. * N
            trE.data = -1. * E

            # Update stats of streams
            trN.stats.channel = trN.stats.channel[:-1] + 'N'
            trE.stats.channel = trE.stats.channel[:-1] + 'E'

            # Store corrected traces in new stream and rotate to
            # R, T using back-azimuth
            stcorr = Stream(traces=[trN, trE])
            stcorr.rotate('NE->RT', back_azimuth=self.meta.baz)

            # Merge original and corrected streams
            st = stream + stcorr

            # Plot
            plot = plotting.plot_bng_waveforms(self, st, dts, tt)
            plot.show()

        return
Beispiel #27
0
sec = 60  # window length for correlation
num_windows = len(RLAS[0]) // (int(sampling_rate * sec))

# estimate the Backazimuth for each time window
step = 10
backas = np.linspace(0, 360 - step, 360 / step)
corrbaz = []
ind = None
for i_deg in range(0, len(backas)):
    for i_win in range(0, num_windows):
        corrbazz = xcorr(
            RLAS[0][sampling_rate * sec * i_win:sampling_rate * sec *
                    (i_win + 1)],
            rotate_ne_rt(
                AC.select(component='N')[0].data,
                AC.select(component='E')[0].data,
                backas[i_deg])[1][sampling_rate * sec * i_win:sampling_rate *
                                  sec * (i_win + 1)], 0)
        corrbaz.append(corrbazz[1])
corrbaz = np.asarray(corrbaz)
corrbaz = corrbaz.reshape(len(backas), num_windows)

maxcorr = []
for l1 in range(0, num_windows):
    maxcor_r = backas[corrbaz[:, l1].argmax()]
    maxcorr.append(maxcor_r)
maxcorr = np.asarray(maxcorr)
X, Y = np.meshgrid(np.arange(0, sec * num_windows, sec), backas)
# -

# <br>