Ejemplo n.º 1
0
    def __init__(self,
                 z: np.ndarray,
                 vp: np.ndarray,
                 vs: np.ndarray,
                 lat: np.ndarray,
                 lon: np.ndarray,
                 flatten=True,
                 zf: np.ndarray = None):
        """
        Velocity model based on GyPSuM model. Compiled and loaded with function
        load_gyps(). The model will be compiled once into a relatively large
        pickle file. Afterwards, the file will be unpickled rather than
        recompiled. Self.vpf, self.vsf, and self.zf are contain values for
        an Earth-flattening approximation.

        Parameters
        ----------
        z : 1D ndarray
            Contains depths in km.
        vp : 3D ndarray
            P-wave velocity grid with velocities in km/s. Spherical
        vs : 3D ndarray
            S-wave velocity grid with velocities in km/s. Spherical
        lat : 1D ndarray
            Latitude vector.
        lon : 1D ndarray
            Longitude vector.
        flatten : Bool - optional
            Apply Earth flattening. Should be False for submodels. In that
            case the values for vp and vs are already flattened.
        zf : 1d ndarray
            flattened depth vector. Only necessary if flatten=False.

        Returns
        -------
        None.

        """
        self.lat = lat
        self.lon = lon
        grid = np.meshgrid(self.lat, self.lon)
        self.coords = (grid[0].ravel(), grid[1].ravel())
        del grid

        xs, ys, zs = geo2cart(R_EARTH, self.coords[0], self.coords[1])

        self.tree = KDTree(list(zip(xs, ys, zs)))
        del xs, ys, zs

        self.z = z

        if flatten:
            self.vpf, self.vsf, self.zf = self.flatten(vp, vs)
        else:
            self.vpf = vp
            self.vsf = vs
            self.zf = zf
Ejemplo n.º 2
0
    def query(self, lat, lon, z):
        """
        Query the 3D velocity model.

        Parameters
        ----------
        lat : float/int
            Latitude.
        lon : float/int
            Longitude.
        z : float/int
            depth.

        Returns
        -------
        vp : float
            P-wave velocity.
        vs : float
            S-wave velocity.

        """
        xs, ys, zs = geo2cart(R_EARTH, lat, lon)
        d, i = self.tree.query([xs, ys, zs])

        if d > (self.lat[1] - self.lat[0]) * DEG2KM * 1.25:
            raise self.CoverageError([
                """ The chosen velocity model does not cover the queried area.
                 You queried the following lat, lon:""", lat, lon
            ])

        m = np.where(self.lat == self.coords[0][i])[0][0]
        n = np.where(self.lon == self.coords[1][i])[0][0]
        p = np.where(round(z) == self.z)[0][0]

        vp = self.vpf[m, n, p]
        vs = self.vsf[m, n, p]
        return vp, vs
Ejemplo n.º 3
0
def line_buffer(lat, lon, delta=1.0):
    """Creates buffer around geographical line using from pole rotated cap 
    outlines. This is far from perfect, but it does "a" job. There isn't much
    more that one can and be spherically accurate. As long as the amount of 
    points in the line is fair this should have no problem to immitate a true 
    buffer.

    Parameters
    ----------
    lat : np.ndarray
        latitudes
    lon : np.ndarray
        longitudes
    delta : float, optional
        epicentral distance to line, by default 1.0

    Returns
    -------
    np.ndarray
        Nx2 matrix with coordinates of a polygon that forms a buffer around 
        the line


    Notes
    -----

    :Authors:
        Lucas Sawade ([email protected])

    :Last Modified:
        2021.04.21 20.00 (Lucas Sawade)

    """

    # Buffer circle around z axis
    r = 1
    phi = np.arange(0, 2 * np.pi, 2 * np.pi / 100)
    theta = delta * np.pi / 180

    # Circle around z axis in cartesian
    x = r * np.sin(theta) * np.cos(phi)
    y = r * np.sin(theta) * np.sin(phi)
    z = r * np.cos(theta) * np.ones_like(phi)
    points = np.vstack((x, y, z))

    # Get circlse around the local coordinates
    rcoordset = []

    for _lat, _lon in zip(lat, lon):

        # Convert line coordinates
        x1 = geo2cart(1, _lat, _lon)

        # Compute rotation matrix compute the new set of points
        rpoints = Ra2b((0, 0, 1), x1) @ points

        # Append x and y coordinates
        rcoordset.append(cart2geo(rpoints[0, :], rpoints[1, :], rpoints[2, :]))

    # Generate and combine polygons
    polygons = []
    circles = []

    for _i, coords in enumerate(rcoordset):
        circles.append((coords[2], coords[1]))
        polygon = Polygon([(_x, _y) for _x, _y in zip(coords[2], coords[1])])
        polygons.append(polygon)

    # Combine from converted points
    upoly = cascaded_union(polygons)

    if upoly.type == 'MultiPolygon':
        polyplot = [np.array(x.exterior.xy).T for x in upoly.geoms]
    else:
        polyplot = [np.array(upoly.exterior.xy).T]

    return polyplot, circles