Пример #1
0
    def test_array_transff_freqslowness(self):

        coords = np.array(
            [[10.0, 60.0, 0.0], [200.0, 50.0, 0.0], [-120.0, 170.0, 0.0], [-100.0, -150.0, 0.0], [30.0, -220.0, 0.0]]
        )

        coords /= 1000.0

        coordsll = np.zeros(coords.shape)
        for i in np.arange(len(coords)):
            coordsll[i, 0], coordsll[i, 1] = utlLonLat(0.0, 0.0, coords[i, 0], coords[i, 1])

        slim = 40.0
        fmin = 1.0
        fmax = 10.0
        fstep = 1.0

        sstep = slim / 2.0

        transff = array_transff_freqslowness(coords, slim, sstep, fmin, fmax, fstep, coordsys="xy")

        transffll = array_transff_freqslowness(coordsll, slim, sstep, fmin, fmax, fstep, coordsys="lonlat")

        transffth = np.array(
            [
                [0.41915119, 0.33333333, 0.32339525, 0.24751548, 0.67660475],
                [0.25248452, 0.41418215, 0.34327141, 0.65672859, 0.33333333],
                [0.24751548, 0.25248452, 1.00000000, 0.25248452, 0.24751548],
                [0.33333333, 0.65672859, 0.34327141, 0.41418215, 0.25248452],
                [0.67660475, 0.24751548, 0.32339525, 0.33333333, 0.41915119],
            ]
        )

        np.testing.assert_array_almost_equal(transff, transffth, decimal=6)
        np.testing.assert_array_almost_equal(transffll, transffth, decimal=6)
Пример #2
0
def plotARF_slowaz(coords, slim, sstep, freqlow, freqhigh, fstep, coordsys='xy'):
    """
    Add ability to plot range of frequency ranges
    """
    transff = array_transff_freqslowness(coords, slim, sstep, freqlow, freqhigh, fstep, coordsys=coordsys)
    xgrid = np.arange(-slim, slim+sstep, sstep)
    slow = np.empty((len(xgrid), len(xgrid)))
    baz = slow.copy()
    for i in np.arange(len(xgrid)):
        for j in np.arange(len(xgrid)):
            # compute baz, slow
            slow_x = xgrid[i]
            slow_y = xgrid[j]
            slow[i, j] = np.sqrt(slow_x ** 2 + slow_y ** 2)
            if slow[i, j] < 1e-8:
                slow[i, j] = 1e-8
            azimut = 180 * math.atan2(slow_x, slow_y) / math.pi
            baz[i, j] = azimut % -360 + 180
    baz[baz < 0.0] += 360
    # transform to radian,
    baz = np.radians(baz)
    cmap = cm.RdYlBu
    fig = plt.figure(figsize=(8, 8))
    cax = fig.add_axes([0.85, 0.2, 0.05, 0.5])
    ax = fig.add_axes([0.10, 0.1, 0.70, 0.7], polar=True)
    ax.pcolormesh(baz, slow, transff, vmin=0., vmax=1., cmap=cmap)
    ax.set_theta_direction(-1)
    ax.set_theta_zero_location("N")
    ax.set_ylim(0, slim)
    ax.grid()
    fig.suptitle('Array response function')
    ColorbarBase(cax, cmap=cmap, norm=Normalize(vmin=0., vmax=1.))
    plt.show()
Пример #3
0
    def test_array_transff_freqslowness(self):

        coords = np.array([[10., 60., 0.], [200., 50., 0.], [-120., 170., 0.],
                           [-100., -150., 0.], [30., -220., 0.]])

        coords /= 1000.

        coordsll = np.zeros(coords.shape)
        for i in np.arange(len(coords)):
            coordsll[i, 0], coordsll[i, 1] = utlLonLat(0., 0., coords[i, 0],
                                                       coords[i, 1])

        slim = 40.
        fmin = 1.
        fmax = 10.
        fstep = 1.

        sstep = slim / 2.

        transff = array_transff_freqslowness(coords,
                                             slim,
                                             sstep,
                                             fmin,
                                             fmax,
                                             fstep,
                                             coordsys='xy')

        transffll = array_transff_freqslowness(coordsll,
                                               slim,
                                               sstep,
                                               fmin,
                                               fmax,
                                               fstep,
                                               coordsys='lonlat')

        transffth = np.array(
            [[0.41915119, 0.33333333, 0.32339525, 0.24751548, 0.67660475],
             [0.25248452, 0.41418215, 0.34327141, 0.65672859, 0.33333333],
             [0.24751548, 0.25248452, 1.00000000, 0.25248452, 0.24751548],
             [0.33333333, 0.65672859, 0.34327141, 0.41418215, 0.25248452],
             [0.67660475, 0.24751548, 0.32339525, 0.33333333, 0.41915119]])

        np.testing.assert_array_almost_equal(transff, transffth, decimal=6)
        np.testing.assert_array_almost_equal(transffll, transffth, decimal=6)
Пример #4
0
    def arf(self, coords, fmin, flim, slim, sgrid):

        sstep = sgrid
        fstep = flim / 40
        fmax = flim
        transff = array_transff_freqslowness(coords,
                                             slim,
                                             sstep,
                                             fmin,
                                             fmax,
                                             fstep,
                                             coordsys='lonlat')

        return transff
Пример #5
0
def plotARF_slowaz(coords,
                   slim,
                   sstep,
                   freqlow,
                   freqhigh,
                   fstep,
                   coordsys='xy'):
    """
    Add ability to plot range of frequency ranges
    """
    transff = array_transff_freqslowness(coords,
                                         slim,
                                         sstep,
                                         freqlow,
                                         freqhigh,
                                         fstep,
                                         coordsys=coordsys)
    xgrid = np.arange(-slim, slim + sstep, sstep)
    slow = np.empty((len(xgrid), len(xgrid)))
    baz = slow.copy()
    for i in np.arange(len(xgrid)):
        for j in np.arange(len(xgrid)):
            # compute baz, slow
            slow_x = xgrid[i]
            slow_y = xgrid[j]
            slow[i, j] = np.sqrt(slow_x**2 + slow_y**2)
            if slow[i, j] < 1e-8:
                slow[i, j] = 1e-8
            azimut = 180 * math.atan2(slow_x, slow_y) / math.pi
            baz[i, j] = azimut % -360 + 180
    baz[baz < 0.0] += 360
    # transform to radian,
    baz = np.radians(baz)
    cmap = cm.RdYlBu
    fig = plt.figure(figsize=(8, 8))
    cax = fig.add_axes([0.85, 0.2, 0.05, 0.5])
    ax = fig.add_axes([0.10, 0.1, 0.70, 0.7], polar=True)
    ax.pcolormesh(baz, slow, transff, vmin=0., vmax=1., cmap=cmap)
    ax.set_theta_direction(-1)
    ax.set_theta_zero_location("N")
    ax.set_ylim(0, slim)
    ax.grid()
    fig.suptitle('Array response function')
    ColorbarBase(cax, cmap=cmap, norm=Normalize(vmin=0., vmax=1.))
    plt.show()
Пример #6
0
def array_analysis_helper(stream, inventory, method, frqlow, frqhigh,
                          filter=True, baz_plot=True, static3D=False,
                          vel_corr=4.8, wlen=-1, slx=(-10, 10),
                          sly=(-10, 10), sls=0.5, array_response=True):
    """
    Array analysis wrapper routine for MESS 2014.

    :param stream: Waveforms for the array processing.
    :type stream: :class:`obspy.core.stream.Stream`
    :param inventory: Station metadata for waveforms
    :type inventory: :class:`obspy.station.inventory.Inventory`
    :param method: Method used for the array analysis
     (one of "FK": Frequnecy Wavenumber, "DLS": Delay and Sum,
     "PWS": Phase Weighted Stack, "SWP": Slowness Whitened Power).
    :type method: str
    :param filter: Whether to bandpass data to selected frequency range
    :type filter: bool
    :param frqlow: Low corner of frequency range for array analysis
    :type frqlow: float
    :param frqhigh: High corner of frequency range for array analysis
    :type frqhigh: float
    :param baz_plot: Whether to show backazimuth-slowness map (True) or
     slowness x-y map (False).
    :type baz_plot: str
    :param static3D: static correction of topography using `vel_corr` as
     velocity (slow!)
    :type static3D: bool
    :param vel_corr: Correction velocity for static topography correction in
     km/s.
    :type vel_corr: float
    :param wlen: sliding window for analysis in seconds, use -1 to use the
     whole trace without windowing.
    :type wlen: float
    :param slx: Min/Max slowness for analysis in x direction.
    :type slx: (float, float)
    :param sly: Min/Max slowness for analysis in y direction.
    :type sly: (float, float)
    :param sls: step width of slowness grid
    :type sls: float
    :param array_response: superimpose array reponse function in plot (slow!)
    :type array_response: bool
    """

    if method not in ("FK", "DLS", "PWS", "SWP"):
        raise ValueError("Invalid method: ''" % method)

    sllx, slmx = slx
    slly, slmy = sly

    starttime = max([tr.stats.starttime for tr in stream])
    endtime = min([tr.stats.endtime for tr in stream])
    stream.trim(starttime, endtime)

    #stream.attach_response(inventory)
    stream.merge()
    for tr in stream:
        for station in inventory[0].stations:
            if tr.stats.station == station.code:
                tr.stats.coordinates = \
                    AttribDict(dict(latitude=station.latitude,
                                    longitude=station.longitude,
                                    elevation=station.elevation))
                break

    if filter:
        stream.filter('bandpass', freqmin=frqlow, freqmax=frqhigh,
                      zerophase=True)

    print stream
    spl = stream.copy()

    tmpdir = tempfile.mkdtemp(prefix="obspy-")
    filename_patterns = (os.path.join(tmpdir, 'pow_map_%03d.npy'),
                         os.path.join(tmpdir, 'apow_map_%03d.npy'))

    def dump(pow_map, apow_map, i):
        np.save(filename_patterns[0] % i, pow_map)
        np.save(filename_patterns[1] % i, apow_map)

    try:
        # next step would be needed if the correction velocity needs to be
        # estimated
        #
        sllx /= KM_PER_DEG
        slmx /= KM_PER_DEG
        slly /= KM_PER_DEG
        slmy /= KM_PER_DEG
        sls /= KM_PER_DEG
        vc = vel_corr
        if method == 'FK':
            kwargs = dict(
                #slowness grid: X min, X max, Y min, Y max, Slow Step
                sll_x=sllx, slm_x=slmx, sll_y=slly, slm_y=slmy, sl_s=sls,
                # sliding window properties
                win_len=wlen, win_frac=0.8,
                # frequency properties
                frqlow=frqlow, frqhigh=frqhigh, prewhiten=0,
                # restrict output
                store=dump,
                semb_thres=-1e9, vel_thres=-1e9, verbose=False,
                timestamp='julsec', stime=starttime, etime=endtime,
                method=0, correct_3dplane=False, vel_cor=vc,
                static_3D=static3D)

            # here we do the array processing
            start = UTCDateTime()
            out = AA.array_processing(stream, **kwargs)
            print "Total time in routine: %f\n" % (UTCDateTime() - start)

            # make output human readable, adjust backazimuth to values
            # between 0 and 360
            t, rel_power, abs_power, baz, slow = out.T

        else:
            kwargs = dict(
                # slowness grid: X min, X max, Y min, Y max, Slow Step
                sll_x=sllx, slm_x=slmx, sll_y=slly, slm_y=slmy, sl_s=sls,
                # sliding window properties
                # frequency properties
                frqlow=frqlow, frqhigh=frqhigh,
                # restrict output
                store=dump,
                win_len=wlen, win_frac=0.5,
                nthroot=4, method=method,
                verbose=False, timestamp='julsec',
                stime=starttime, etime=endtime, vel_cor=vc,
                static_3D=False)

            # here we do the array processing
            start = UTCDateTime()
            out = AA.beamforming(stream, **kwargs)
            print "Total time in routine: %f\n" % (UTCDateTime() - start)

            # make output human readable, adjust backazimuth to values
            # between 0 and 360
            trace = []
            t, rel_power, baz, slow_x, slow_y, slow = out.T

            # calculating array response
        if array_response:
            stepsfreq = (frqhigh - frqlow) / 10.
            tf_slx = sllx
            tf_smx = slmx
            tf_sly = slly
            tf_smy = slmy
            transff = AA.array_transff_freqslowness(
                stream, (tf_slx, tf_smx, tf_sly, tf_smy), sls, frqlow,
                frqhigh, stepsfreq, coordsys='lonlat',
                correct_3dplane=False, static_3D=False, vel_cor=vc)

        # now let's do the plotting
        cmap = cm.rainbow

        #
        # we will plot everything in s/deg
        slow *= KM_PER_DEG
        sllx *= KM_PER_DEG
        slmx *= KM_PER_DEG
        slly *= KM_PER_DEG
        slmy *= KM_PER_DEG
        sls *= KM_PER_DEG

        numslice = len(t)
        powmap = []
        slx = np.arange(sllx-sls, slmx, sls)
        sly = np.arange(slly-sls, slmy, sls)
        if baz_plot:
            maxslowg = np.sqrt(slmx*slmx + slmy*slmy)
            bzs = np.arctan2(sls, np.sqrt(slmx*slmx + slmy*slmy))*180/np.pi
            xi = np.arange(0., maxslowg, sls)
            yi = np.arange(-180., 180., bzs)
            grid_x, grid_y = np.meshgrid(xi, yi)
        # reading in the rel-power maps
        for i in xrange(numslice):
            powmap.append(np.load(filename_patterns[0] % i))
            if method != 'FK':
                trace.append(np.load(filename_patterns[1] % i))

        npts = stream[0].stats.npts
        df = stream[0].stats.sampling_rate
        T = np.arange(0, npts / df, 1 / df)

        # if we choose windowlen > 0. we now move through our slices
        for i in xrange(numslice):
            slow_x = np.sin((baz[i]+180.)*np.pi/180.)*slow[i]
            slow_y = np.cos((baz[i]+180.)*np.pi/180.)*slow[i]
            st = UTCDateTime(t[i]) - starttime
            if wlen <= 0:
                en = endtime
            else:
                en = st + wlen
            print UTCDateTime(t[i])
            # add polar and colorbar axes
            fig = plt.figure(figsize=(12, 12))
            ax1 = fig.add_axes([0.1, 0.87, 0.7, 0.10])
            # here we plot the first trace on top of the slowness map
            # and indicate the possibiton of the lsiding window as green box
            if method == 'FK':
                ax1.plot(T, spl[0].data, 'k')
                if wlen > 0.:
                    try:
                        ax1.axvspan(st, en, facecolor='g', alpha=0.3)
                    except IndexError:
                        pass
            else:
                T = np.arange(0, len(trace[i])/df, 1 / df)
                ax1.plot(T, trace[i], 'k')

            ax1.yaxis.set_major_locator(MaxNLocator(3))

            ax = fig.add_axes([0.10, 0.1, 0.70, 0.7])

            # if we have chosen the baz_plot option a re-griding
            # of the sx,sy slowness map is needed
            if baz_plot:
                slowgrid = []
                transgrid = []
                pow = np.asarray(powmap[i])
                for ix, sx in enumerate(slx):
                    for iy, sy in enumerate(sly):
                        bbaz = np.arctan2(sx, sy)*180/np.pi+180.
                        if bbaz > 180.:
                            bbaz = -180. + (bbaz-180.)
                        slowgrid.append((np.sqrt(sx*sx+sy*sy), bbaz,
                                         pow[ix, iy]))
                        if array_response:
                            tslow = (np.sqrt((sx+slow_x) *
                                     (sx+slow_x)+(sy+slow_y) *
                                     (sy+slow_y)))
                            tbaz = (np.arctan2(sx+slow_x, sy+slow_y) *
                                    180 / np.pi + 180.)
                            if tbaz > 180.:
                                tbaz = -180. + (tbaz-180.)
                            transgrid.append((tslow, tbaz,
                                              transff[ix, iy]))

                slowgrid = np.asarray(slowgrid)
                sl = slowgrid[:, 0]
                bz = slowgrid[:, 1]
                slowg = slowgrid[:, 2]
                grid = spi.griddata((sl, bz), slowg, (grid_x, grid_y),
                                    method='nearest')
                ax.pcolormesh(xi, yi, grid, cmap=cmap)

                if array_response:
                    level = np.arange(0.1, 0.5, 0.1)
                    transgrid = np.asarray(transgrid)
                    tsl = transgrid[:, 0]
                    tbz = transgrid[:, 1]
                    transg = transgrid[:, 2]
                    trans = spi.griddata((tsl, tbz), transg,
                                         (grid_x, grid_y),
                                         method='nearest')
                    ax.contour(xi, yi, trans, level, colors='k',
                               linewidth=0.2)

                ax.set_xlabel('slowness [s/deg]')
                ax.set_ylabel('backazimuth [deg]')
                ax.set_xlim(xi[0], xi[-1])
                ax.set_ylim(yi[0], yi[-1])
            else:
                ax.set_xlabel('slowness [s/deg]')
                ax.set_ylabel('slowness [s/deg]')
                slow_x = np.cos((baz[i]+180.)*np.pi/180.)*slow[i]
                slow_y = np.sin((baz[i]+180.)*np.pi/180.)*slow[i]
                ax.pcolormesh(slx, sly, powmap[i].T)
                ax.arrow(0, 0, slow_y, slow_x, head_width=0.005,
                         head_length=0.01, fc='k', ec='k')
                if array_response:
                    tslx = np.arange(sllx+slow_x, slmx+slow_x+sls, sls)
                    tsly = np.arange(slly+slow_y, slmy+slow_y+sls, sls)
                    try:
                        ax.contour(tsly, tslx, transff.T, 5, colors='k',
                                   linewidth=0.5)
                    except:
                        pass
                ax.set_ylim(slx[0], slx[-1])
                ax.set_xlim(sly[0], sly[-1])
            new_time = t[i]

            result = "BAZ: %.2f, Slow: %.2f s/deg, Time %s" % (
                baz[i], slow[i], UTCDateTime(new_time))
            ax.set_title(result)

            plt.show()
    finally:
        shutil.rmtree(tmpdir)
Пример #7
0
def array_transfer_helper(stream, inventory, sx=(-10, 10), sy=(-10, 10),
                          sls=0.5, freqmin=0.1, freqmax=4.0, numfreqs=10,
                          coordsys='lonlat', correct3dplane=False,
                          static3D=False, velcor=4.8):
    """
    Array Response wrapper routine for MESS 2014.

    :param stream: Waveforms for the array processing.
    :type stream: :class:`obspy.core.stream.Stream`
    :param inventory: Station metadata for waveforms
    :type inventory: :class:`obspy.station.inventory.Inventory`
    :param slx: Min/Max slowness for analysis in x direction.
    :type slx: (float, float)
    :param sly: Min/Max slowness for analysis in y direction.
    :type sly: (float, float)
    :param sls: step width of slowness grid
    :type sls: float
    :param frqmin: Low corner of frequency range for array analysis
    :type frqmin: float
    :param frqmax: High corner of frequency range for array analysis
    :type frqmax: float
    :param numfreqs: number of frequency values used for computing array
     transfer function
    :type numfreqs: int
    :param coordsys: defined coordingate system of stations (lonlat or km)
    :type coordsys: string
    :param correct_3dplane: correct for an inclined surface (not used)
    :type correct_3dplane: bool
    :param static_3D: correct topography
    :type static_3D: bool
    :param velcor: velocity used for static_3D correction
    :type velcor: float
    """

    for tr in stream:
        for station in inventory[0].stations:
            if tr.stats.station == station.code:
                tr.stats.coordinates = \
                    AttribDict(dict(latitude=station.latitude,
                               longitude=station.longitude,
                               elevation=station.elevation))
                break

    sllx, slmx = sx
    slly, slmy = sx
    sllx /= KM_PER_DEG
    slmx /= KM_PER_DEG
    slly /= KM_PER_DEG
    slmy /= KM_PER_DEG
    sls = sls/KM_PER_DEG

    stepsfreq = (freqmax - freqmin) / float(numfreqs)
    transff = AA.array_transff_freqslowness(
        stream, (sllx, slmx, slly, slmy), sls, freqmin, freqmax, stepsfreq,
        coordsys=coordsys, correct_3dplane=False, static_3D=static3D,
        vel_cor=velcor)

    sllx *= KM_PER_DEG
    slmx *= KM_PER_DEG
    slly *= KM_PER_DEG
    slmy *= KM_PER_DEG
    sls *= KM_PER_DEG

    slx = np.arange(sllx, slmx+sls, sls)
    sly = np.arange(slly, slmy+sls, sls)
    fig = plt.figure(figsize=(12, 12))
    ax = fig.add_axes([0.1, 0.1, 0.8, 0.8])

    #ax.pcolormesh(slx, sly, transff.T)
    ax.contour(sly, slx, transff.T, 10)
    ax.set_xlabel('slowness [s/deg]')
    ax.set_ylabel('slowness [s/deg]')
    ax.set_ylim(slx[0], slx[-1])
    ax.set_xlim(sly[0], sly[-1])
    plt.show()