Exemple #1
0
 def test_LAX_to_JFK(self):
     dist = geodetic.geodetic_distance(*(LAX + JFK))
     self.assertAlmostEqual(dist,
                            0.623585 * geodetic.EARTH_RADIUS,
                            delta=0.1)
     dist2 = geodetic.geodetic_distance(*(JFK + LAX))
     self.assertAlmostEqual(dist, dist2)
Exemple #2
0
def _plot_volc(axes, csda):
    """
    :parameter axes:
    :parameter csda:
    """
    if csda.volc is None:
        return

    olo = csda.csec.olo
    ola = csda.csec.ola
    patches = []

    if (len(csda.volc)-1) >= 1:
        vuls = geodetic_distance(olo, ola,
                                 csda.volc[:, 0],
                                 csda.volc[:, 1])
        for v in vuls:
            square = Rectangle((v, -10.0), 7, 12)
            patches.append(square)

    else:
        vuls = geodetic_distance(olo, ola,
                                 csda.volc[0],
                                 csda.volc[1])
        square = Rectangle((vuls, -10.0), 7, 12)
        patches.append(square)

    vv = PatchCollection(patches, zorder=6, color='red', edgecolors='red')
    vv.set_alpha(0.85)
    axes.add_collection(vv)
Exemple #3
0
 def test_one_to_many(self):
     dist = geodetic.geodetic_distance(0, 0, [-1, 1], [0, 0])
     self.assertTrue(numpy.allclose(dist, [111.195, 111.195]), str(dist))
     dist = geodetic.geodetic_distance(0, 0, [[-1, 0], [1, 0]],
                                             [[0, 0], [0, 0]])
     self.assertTrue(numpy.allclose(dist, [[111.195, 0], [111.195, 0]]),
                     str(dist))
Exemple #4
0
def inc_stations(j,i,N,K,r,site_collection_SM, site_collection_station, dist_mat, X, inc_ind):
    """
    If there are stations included within the radius for a point, this function will add those stations to the 
    distance matrix and determine the array of points included in the radius, x
    
    INPUTS: 
    i,j- current points row and column 
    N,K - number of points in row and total number of stations
    r- radius 
    site_collection_SM/station- site collections for ShakeMap and station data
    dist_mat- reduced distance matrix
    X- array of previously calculated correlation values
    inc_ind- indices of included points
    inc_indices- total number of points in the top most row of distance matrix
    OUTPUTS: 
    dist_mat- reduced distance matrix, modified to include stations
    x- array of points in X included in radius and stations included 
    inc_sta_indices- indices of stations included in the radius
    """
    
    # Compute the distances for all stations to the grid point we're looking at
    dist_sta_sit = np.array(geodetic_distance(site_collection_SM.lons[j+i*N], site_collection_SM.lats[j+i*N],
                                              site_collection_station.lons[0:K], site_collection_station.lats[0:K]))
        
    # Find which of those stations are in the radius we are considering
    inc_sta_indices = np.where(dist_sta_sit < r)[0]
    if np.size(inc_sta_indices) != 0:
        sta_to_sta_dist = np.zeros([np.size(inc_sta_indices), np.size(inc_sta_indices)])
        sta_to_grd_dist = np.zeros([np.size(inc_sta_indices), np.size(inc_ind)])

        iinds = np.array(inc_ind).T[0]
        # Calculate distance between each included station and all included grid points, then calculate the distance
        # from each included station to every other included station
        for eta in range(0, np.size(inc_sta_indices)):
            sta_to_grd_dist[eta, :] = geodetic_distance(
                site_collection_station.lons[inc_sta_indices[eta]], site_collection_station.lats[inc_sta_indices[eta]], 
                site_collection_SM.lons[iinds], site_collection_SM.lats[iinds])
            sta_to_sta_dist[eta, eta+1:] = geodetic_distance(
                site_collection_station.lons[inc_sta_indices[eta]], site_collection_station.lats[inc_sta_indices[eta]],
                site_collection_station.lons[inc_sta_indices[eta+1:]], site_collection_station.lats[inc_sta_indices[eta+1:]])
            
        sta_to_sta_dist = sta_to_sta_dist + sta_to_sta_dist.T
        station_distance_matrix = np.concatenate((sta_to_sta_dist, sta_to_grd_dist), axis=1)
                        
        # Concatenate the station distance matrix with the modified distance matrix, dist_mat
        dist_mat = np.concatenate((station_distance_matrix[:, np.size(inc_sta_indices):], dist_mat), axis=0)
        dist_mat = np.concatenate((station_distance_matrix.T, dist_mat), axis=1)
            
        # x: vector of previously calculated covariance values
        x = np.concatenate((np.zeros([np.size(inc_sta_indices),1]),X[inc_ind,0]), axis = 0)
        x = np.mat(x[0:-1])

    else:
        # x: vector of previously calculated covariance values
        x = X[inc_ind,0]
        x = np.mat(x[0:-1])
    
    return {'dist_mat':dist_mat, 'x':x, 'inc_sta_indices':inc_sta_indices}
Exemple #5
0
def inc_stations(j,i,N,K,r,site_collection_SM, site_collection_station, dist_mat, X, inc_ind, inc_indices):
    #####
    # If there are stations included within the radius for a point, this function will add those stations to the 
    # distance matrix and determine the array of points included in the radius, x
    # IN: i,j- current points row and column 
    #     N,K - number of points in row and total number of stations
    #     r- radius 
    #     site_collection_SM/station- site collections for ShakeMap and station data
    #     dist_mat- reduced distance matrix
    #     X- array of previously calculated correlation values
    #     inc_ind- indices of included points
    #     inc_indices- total number of points in the top most row of distance matrix
    #OUT: dist_mat- reduced distance matrix, modified to include stations
    #     x- array of points in X included in radius and stations included 
    #     inc_sta_indices- indices of stations included in the radius
    #####

    num = i*N+j
    
    # Compute the distances for all stations to the grid point we're looking at                                                                                                                
    dist_sta_sit = np.array(geodetic_distance(site_collection_SM.lons[j+i*N], site_collection_SM.lats[j+i*N],
                                              site_collection_station.lons[0:K], site_collection_station.lats[0:K]))
        
    # Find which of those stations are in the radius we are considering
    inc_sta_indices = np.where(dist_sta_sit < r)
    if np.size(inc_sta_indices) != 0:
            
        station_distance_matrix = np.zeros([np.size(inc_sta_indices), np.size(inc_sta_indices)+np.size(inc_ind)])
        # Calculate distance between each included station and all included grid points, then calculate the distance
        # from each included station to every other included station
        for eta in range(0, np.size(inc_sta_indices)):
            for beta in range(0,np.size(inc_ind)):
                station_distance_matrix[eta,np.size(inc_sta_indices) + beta] = geodetic_distance(
                    site_collection_station.lons[inc_sta_indices[0][eta]], site_collection_station.lats[inc_sta_indices[0][eta]], 
                    site_collection_SM.lons[inc_ind[beta]], site_collection_SM.lats[inc_ind[beta]])
            for beta in range(0, np.size(inc_sta_indices)):
                station_distance_matrix[eta, beta] = geodetic_distance(
                    site_collection_station.lons[inc_sta_indices[0][eta]], site_collection_station.lats[inc_sta_indices[0][eta]],
                    site_collection_station.lons[inc_sta_indices[0][beta]], site_collection_station.lats[inc_sta_indices[0][beta]])
            
        # Concatenate the station distance matrix with the modified distance matrix, dist_mat
        dist_mat = np.concatenate((station_distance_matrix[:, np.size(inc_sta_indices):], dist_mat), axis=0)
        dist_mat = np.concatenate((station_distance_matrix.T, dist_mat), axis=1)

        # x: vector of previously calculated covariance values
        x = np.concatenate((np.zeros([np.size(inc_sta_indices),1]),X[inc_ind,0]), axis = 0)
        x = np.mat(x[0:-1])
            
    else:
        # x: vector of previously calculated covariance values
        x = X[inc_ind,0]
        x = np.mat(x[0:-1])
    
    return {'dist_mat':dist_mat, 'x':x, 'inc_sta_indices':inc_sta_indices}
Exemple #6
0
 def test_get_area(self):
     computed = self.msrf.get_area()
     length = geodetic_distance(0.0, 0.0, 0.3, 0.0)
     expected = length * 20.0
     perc_diff = abs(computed - expected) / computed * 100
     msg = 'Multi fault surface: area is wrong'
     self.assertTrue(perc_diff < 2, msg=msg)
Exemple #7
0
    def get_distance_matrix(self):
        """
        Compute and return distances between each pairs of points in the mesh.

        This method requires that all the points lie on Earth surface (have
        zero depth) and coordinate arrays are one-dimensional.

        .. warning::
            Because of its quadratic space and time complexity this method
            is safe to use for meshes of up to several thousand points. For
            mesh of 10k points it needs ~800 Mb for just the resulting matrix
            and four times that much for intermediate storage.

        :returns:
            Two-dimensional numpy array, square matrix of distances. The matrix
            has zeros on main diagonal and positive distances in kilometers
            on all other cells. That is, value in cell (3, 5) is the distance
            between mesh's points 3 and 5 in km, and it is equal to value
            in cell (5, 3).

        Uses :func:`openquake.hazardlib.geo.geodetic.geodetic_distance`.
        """
        assert self.lons.ndim == 1
        assert self.depths is None or (self.depths == 0).all()
        distances = geodetic.geodetic_distance(
            self.lons.reshape(self.lons.shape + (1, )),
            self.lats.reshape(self.lats.shape + (1, )), self.lons, self.lats)
        return numpy.matrix(distances, copy=False)
Exemple #8
0
    def average_azimuth(self):
        """
        Calculate and return weighted average azimuth of all line's segments
        in decimal degrees.

        Uses formula from
        http://en.wikipedia.org/wiki/Mean_of_circular_quantities

        >>> from openquake.hazardlib.geo.point import Point as P
        >>> str(Line([P(0, 0), P(1e-5, 1e-5)]).average_azimuth())
        '45.0'
        >>> str(Line([P(0, 0), P(0, 1e-5), P(1e-5, 1e-5)]).average_azimuth())
        '45.0'
        >>> line = Line([P(0, 0), P(-2e-5, 0), P(-2e-5, 1.154e-5)])
        >>> '%.1f' % line.average_azimuth()
        '300.0'
        """
        if len(self.points) == 2:
            return self.points[0].azimuth(self.points[1])
        lons = numpy.array([point.longitude for point in self.points])
        lats = numpy.array([point.latitude for point in self.points])
        azimuths = geodetic.azimuth(lons[:-1], lats[:-1], lons[1:], lats[1:])
        distances = geodetic.geodetic_distance(lons[:-1], lats[:-1], lons[1:],
                                               lats[1:])
        azimuths = numpy.radians(azimuths)
        # convert polar coordinates to Cartesian ones and calculate
        # the average coordinate of each component
        avg_x = numpy.mean(distances * numpy.sin(azimuths))
        avg_y = numpy.mean(distances * numpy.cos(azimuths))
        # find the mean azimuth from that mean vector
        azimuth = numpy.degrees(numpy.arctan2(avg_x, avg_y))
        if azimuth < 0:
            azimuth += 360
        return azimuth
Exemple #9
0
def get_xyz_from_ll(projected, reference):
    """
    This method computes the x, y and z coordinates of a set of points
    provided a reference point

    :param projected:
        :class:`~openquake.hazardlib.geo.point.Point` object
        representing the coordinates of target point to be projected
    :param reference:
        :class:`~openquake.hazardlib.geo.point.Point` object
        representing the coordinates of the reference point.

    :returns:
            x
            y
            z
    """

    azims = geod.azimuth(reference.longitude, reference.latitude,
                         projected.longitude, projected.latitude)
    depths = np.subtract(reference.depth, projected.depth)
    dists = geod.geodetic_distance(reference.longitude,
                                   reference.latitude,
                                   projected.longitude,
                                   projected.latitude)
    return (dists * math.sin(math.radians(azims)),
            dists * math.cos(math.radians(azims)),
            depths)
Exemple #10
0
    def translate(self, p1, p2):
        """
        Translate the surface for a specific distance along a specific azimuth
        direction.

        Parameters are two points (instances of
        :class:`openquake.hazardlib.geo.point.Point`) representing the
        direction and an azimuth for translation. The resulting surface corner
        points will be that far along that azimuth from respective corner
        points of this surface as ``p2`` is located with respect to ``p1``.

        :returns:
            A new :class:`PlanarSurface` object with the same mesh spacing,
            dip, strike, width, length and depth but with corners longitudes
            and latitudes translated.
        """
        azimuth = geodetic.azimuth(p1.longitude, p1.latitude,
                                   p2.longitude, p2.latitude)
        distance = geodetic.geodetic_distance(p1.longitude, p1.latitude,
                                              p2.longitude, p2.latitude)
        # avoid calling PlanarSurface's constructor
        nsurf = object.__new__(PlanarSurface)
        # but do call BaseQuadrilateralSurface's one
        BaseQuadrilateralSurface.__init__(nsurf)
        nsurf.mesh_spacing = self.mesh_spacing
        nsurf.dip = self.dip
        nsurf.strike = self.strike
        nsurf.corner_lons, nsurf.corner_lats = geodetic.point_at(
            self.corner_lons, self.corner_lats, azimuth, distance
        )
        nsurf.corner_depths = self.corner_depths.copy()
        nsurf._init_plane()
        nsurf.width = self.width
        nsurf.length = self.length
        return nsurf
Exemple #11
0
    def distance_to_mesh(self, mesh, with_depths=True):
        """
        Compute distance (in km) between this point and each point of ``mesh``.

        :param mesh:
            :class:`~openquake.hazardlib.geo.mesh.Mesh` of points to calculate
            distance to.
        :param with_depths:
            If ``True`` (by default), distance is calculated between actual
            point and the mesh, geodetic distance of projections is combined
            with vertical distance (difference of depths). If this is set
            to ``False``, only geodetic distance between projections
            is calculated.
        :returns:
            Numpy array of floats of the same shape as ``mesh`` with distance
            values in km in respective indices.
        """
        if with_depths:
            if mesh.depths is None:
                mesh_depths = numpy.zeros_like(mesh.lons)
            else:
                mesh_depths = mesh.depths
            return geodetic.distance(self.longitude, self.latitude, self.depth,
                                     mesh.lons, mesh.lats, mesh_depths)
        else:
            return geodetic.geodetic_distance(self.longitude, self.latitude,
                                              mesh.lons, mesh.lats)
Exemple #12
0
def _plot_eqks(axes, csda):
    """
    :parameter axes:
    :parameter csda:
    """

    if csda.ecat is None:
        return

    newcat = csda.ecat

    olo = csda.csec.olo
    ola = csda.csec.ola
    dsts = geodetic_distance(olo, ola,
                             newcat.data['longitude'],
                             newcat.data['latitude'])
    # MN: 'sze' assigned but never used
    sze = (newcat.data['magnitude'])**0.5
    patches = []
    for dst, dep, mag in zip(dsts,
                             newcat.data['depth'],
                             newcat.data['magnitude']):
        circle = Circle((dst, dep), (mag*0.5)**1.5, ec='white')
        patches.append(circle)
    colors = newcat.data['magnitude']
    p = PatchCollection(patches, zorder=6, edgecolors='white')
    p.set_alpha(0.5)
    p.set_array(numpy.array(colors))
    axes.add_collection(p)
Exemple #13
0
    def translate(self, p1, p2):
        """
        Translate the surface for a specific distance along a specific azimuth
        direction.

        Parameters are two points (instances of
        :class:`openquake.hazardlib.geo.point.Point`) representing the
        direction and an azimuth for translation. The resulting surface corner
        points will be that far along that azimuth from respective corner
        points of this surface as ``p2`` is located with respect to ``p1``.

        :returns:
            A new :class:`PlanarSurface` object with the same mesh spacing,
            dip, strike, width, length and depth but with corners longitudes
            and latitudes translated.
        """
        azimuth = geodetic.azimuth(p1.longitude, p1.latitude, p2.longitude,
                                   p2.latitude)
        distance = geodetic.geodetic_distance(p1.longitude, p1.latitude,
                                              p2.longitude, p2.latitude)
        # avoid calling PlanarSurface's constructor
        nsurf = object.__new__(PlanarSurface)
        nsurf.dip = self.dip
        nsurf.strike = self.strike
        nsurf.corner_lons, nsurf.corner_lats = geodetic.point_at(
            self.corner_lons, self.corner_lats, azimuth, distance)
        nsurf.corner_depths = self.corner_depths.copy()
        nsurf._init_plane()
        nsurf.width = self.width
        nsurf.length = self.length
        return nsurf
Exemple #14
0
    def get_distance_matrix(self):
        """
        Compute and return distances between each pairs of points in the mesh.

        This method requires that the coordinate arrays are one-dimensional.
        NB: the depth of the points is ignored

        .. warning::
            Because of its quadratic space and time complexity this method
            is safe to use for meshes of up to several thousand points. For
            mesh of 10k points it needs ~800 Mb for just the resulting matrix
            and four times that much for intermediate storage.

        :returns:
            Two-dimensional numpy array, square matrix of distances. The matrix
            has zeros on main diagonal and positive distances in kilometers
            on all other cells. That is, value in cell (3, 5) is the distance
            between mesh's points 3 and 5 in km, and it is equal to value
            in cell (5, 3).

        Uses :func:`openquake.hazardlib.geo.geodetic.geodetic_distance`.
        """
        assert self.lons.ndim == 1
        distances = geodetic.geodetic_distance(
            self.lons.reshape(self.lons.shape + (1, )),
            self.lats.reshape(self.lats.shape + (1, )),
            self.lons,
            self.lats)
        return numpy.matrix(distances, copy=False)
    def build_time_distance_arrays(self):
        """
        Determines the arrays of distance between events and from
        events to target sites
        """
        neq = self.learning_catalogue.get_number_events()
        print "Building Time arrays"
        time_dset = self.fle.create_dataset("time", (neq, neq), dtype="f")
        #nearest_tset = self.fle.create_dataset("nearest_time", (neq, neq),
        #                                       dtype="i")
        counter1 = ProgressCounter(neq, timer=True)
        for i in range(neq - 1):
            counter1.update(i)
            # Get time difference (in DAYS)
            time_kernel = (365.25 * (self.learning_catalogue.data["dtime"] -
                                     self.learning_catalogue.data["dtime"][i]))
            time_dset[i, :] = time_kernel
            #nearest_tset[i, :] = np.argsort(time_kernel)

        print "Building Distance Arrays"
        distance_dset = self.fle.create_dataset("distance", (neq, neq),
                                                dtype="f")
        nearest_dset = self.fle.create_dataset("d_nearest", (neq, neq),
                                               dtype="i")
        counter1.reset()
        for i in range(neq - 1):
            counter1.update(i)
            epi_distance = geodetic.geodetic_distance(
                self.learning_catalogue.data["longitude"][i],
                self.learning_catalogue.data["latitude"][i],
                self.learning_catalogue.data["longitude"],
                self.learning_catalogue.data["latitude"])
            distance_dset[i, :] = epi_distance
            nearest_dset[i, :] = np.argsort(epi_distance)
Exemple #16
0
def get_xyz_from_ll(projected, reference):
    """
    This method computes the x, y and z coordinates of a set of points
    provided a reference point

    :param projected:
        :class:`~openquake.hazardlib.geo.point.Point` object
        representing the coordinates of target point to be projected
    :param reference:
        :class:`~openquake.hazardlib.geo.point.Point` object
        representing the coordinates of the reference point.

    :returns:
            x
            y
            z
    """

    azims = geod.azimuth(reference.longitude, reference.latitude,
                         projected.longitude, projected.latitude)
    depths = np.subtract(reference.depth, projected.depth)
    dists = geod.geodetic_distance(reference.longitude, reference.latitude,
                                   projected.longitude, projected.latitude)
    return (dists * math.sin(math.radians(azims)),
            dists * math.cos(math.radians(azims)), depths)
Exemple #17
0
    def distance_to_mesh(self, mesh, with_depths=True):
        """
        Compute distance (in km) between this point and each point of ``mesh``.

        :param mesh:
            :class:`~openquake.hazardlib.geo.mesh.Mesh` of points to calculate
            distance to.
        :param with_depths:
            If ``True`` (by default), distance is calculated between actual
            point and the mesh, geodetic distance of projections is combined
            with vertical distance (difference of depths). If this is set
            to ``False``, only geodetic distance between projections
            is calculated.
        :returns:
            Numpy array of floats of the same shape as ``mesh`` with distance
            values in km in respective indices.
        """
        if with_depths:
            if mesh.depths is None:
                mesh_depths = numpy.zeros_like(mesh.lons)
            else:
                mesh_depths = mesh.depths
            return geodetic.distance(self.longitude, self.latitude, self.depth,
                                     mesh.lons, mesh.lats, mesh_depths)
        else:
            return geodetic.geodetic_distance(self.longitude, self.latitude,
                                              mesh.lons, mesh.lats)
Exemple #18
0
    def average_azimuth(self):
        """
        Calculate and return weighted average azimuth of all line's segments
        in decimal degrees.

        Uses formula from
        http://en.wikipedia.org/wiki/Mean_of_circular_quantities

        >>> from openquake.hazardlib.geo.point import Point as P
        >>> '%.1f' % Line([P(0, 0), P(1e-5, 1e-5)]).average_azimuth()
        '45.0'
        >>> '%.1f' % Line([P(0, 0), P(0, 1e-5), P(1e-5, 1e-5)]).average_azimuth()
        '45.0'
        >>> line = Line([P(0, 0), P(-2e-5, 0), P(-2e-5, 1.154e-5)])
        >>> '%.1f' % line.average_azimuth()
        '300.0'
        """
        if len(self.points) == 2:
            return self.points[0].azimuth(self.points[1])
        lons = numpy.array([point.longitude for point in self.points])
        lats = numpy.array([point.latitude for point in self.points])
        azimuths = geodetic.azimuth(lons[:-1], lats[:-1], lons[1:], lats[1:])
        distances = geodetic.geodetic_distance(lons[:-1], lats[:-1],
                                               lons[1:], lats[1:])
        azimuths = numpy.radians(azimuths)
        # convert polar coordinates to Cartesian ones and calculate
        # the average coordinate of each component
        avg_x = numpy.mean(distances * numpy.sin(azimuths))
        avg_y = numpy.mean(distances * numpy.cos(azimuths))
        # find the mean azimuth from that mean vector
        azimuth = numpy.degrees(numpy.arctan2(avg_x, avg_y))
        if azimuth < 0:
            azimuth += 360
        return azimuth
    def getMatchingEvents(self, solve=True):
        """Return a list of dictionaries matching input parameters.

        Args:
            solve (bool):
                If set to True, then this method
                should return a list with a maximum of one event.

        Returns:
            list: List of event dictionaries, with fields:
                  - time Event time (UTC)
                  - lat Event latitude
                  - lon Event longitude
                  - depth Event depth
                  - mag Event magnitude
        """
        start_time = self.time - timedelta(seconds=3600)
        end_time = self.time + timedelta(seconds=3600)

        tpl = (start_time.strftime(TIMEFMT), end_time.strftime(TIMEFMT))
        url = CATBASE % tpl
        req = requests.get(url)
        logging.debug("GeoNet search url: %s", str(url))
        logging.debug("GeoNet search response code: %s", req.status_code)
        data = req.text
        f = io.StringIO(data)
        df = pd.read_csv(f, parse_dates=["origintime"])
        f.close()
        # some of the column names have spaces in them
        cols = df.columns
        newcols = {}
        for col in cols:
            newcol = col.strip()
            newcols[col] = newcol
        df = df.rename(columns=newcols)
        lats = df["latitude"].to_numpy()
        lons = df["longitude"].to_numpy()
        etime = pd.Timestamp(self.time)
        dtimes = np.abs(df["origintime"] - etime)
        distances = geodetic_distance(self.lon, self.lat, lons, lats)
        didx = distances <= self.radius
        tidx = (dtimes <= np.timedelta64(int(self.dt), "s")).to_numpy()
        newdf = df[didx & tidx]
        events = []
        for idx, row in newdf.iterrows():
            eventdict = {
                "time": UTCDateTime(row["origintime"]),
                "lat": row["latitude"],
                "lon": row["longitude"],
                "depth": row["depth"],
                "mag": row["magnitude"],
            }
            events.append(eventdict)

        if solve and len(events) > 1:
            event = self.solveEvents(events)
            events = [event]

        return events
Exemple #20
0
def set_up_grid_dist(M,N, site_collection_SM):
    ######
    # Calculates the vertical and horozontal spacing between points for each row
    # IN: M,N- number of points in grid vertically and horozontally
    #     site_collection_SM- site collection for ShakeMap data
    # OUT: l,d- vectors of distances between points vertically and horozontally
    ######

    l = np.zeros([M-1])
    d = np.zeros([M])
    
    # Calculate vertical and horozonal spacing between points for each row
    l[:] = geodetic_distance(site_collection_SM.lons[range(N,N*M,N)],   site_collection_SM.lats[range(N,N*M,N)],
                             site_collection_SM.lons[range(0,N*M-N,N)], site_collection_SM.lats[range(0,N*M-N,N)])
    d[:] = geodetic_distance(site_collection_SM.lons[range(0, M*N, N)], site_collection_SM.lats[range(0, M*N, N)],
                             site_collection_SM.lons[range(1, M*N, N)], site_collection_SM.lats[range(1, M*N, N)])
    return {'l':l, 'd':d}
    def getMatchingEvents(self, solve=True):
        """Return a list of dictionaries matching input parameters.

        Args:
            solve (bool):
                If set to True, then this method
                should return a list with a maximum of one event.

        Returns:
            list: List of event dictionaries, with fields:
                  - time Event time (UTC)
                  - lat Event latitude
                  - lon Event longitude
                  - depth Event depth
                  - mag Event magnitude
        """
        start_time = self.time - timedelta(seconds=3600)
        end_time = self.time + timedelta(seconds=3600)

        tpl = (start_time.strftime(TIMEFMT), end_time.strftime(TIMEFMT))
        url = CATBASE % tpl
        req = requests.get(url)
        data = req.text
        f = io.StringIO(data)
        df = pd.read_csv(f, parse_dates=['origintime'])
        # some of the column names have spaces in them
        cols = df.columns
        newcols = {}
        for col in cols:
            newcol = col.strip()
            newcols[col] = newcol
        df = df.rename(columns=newcols)
        lats = df['latitude'].values
        lons = df['longitude'].values
        etime = pd.Timestamp(self.time)
        dtimes = np.abs(df['origintime'] - etime)
        distances = geodetic_distance(self.lon, self.lat, lons, lats)
        didx = distances <= self.radius
        tidx = (dtimes <= np.timedelta64(int(self.dt), 's')).values
        newdf = df[didx & tidx]
        events = []
        for idx, row in newdf.iterrows():
            eventdict = {
                'time': UTCDateTime(row['origintime']),
                'lat': row['latitude'],
                'lon': row['longitude'],
                'depth': row['depth'],
                'mag': row['magnitude']
            }
            events.append(eventdict)

        if solve and len(events) > 1:
            event = self.solveEvents(events)
            events = [event]

        return events
Exemple #22
0
def set_up_grid_dist(M,N, site_collection_SM):
    """
    Calculates the vertical and horozontal spacing between points for each row
    
    INPUTS: 
    M,N- number of points in grid vertically and horozontally
    site_collection_SM- site collection for ShakeMap data
    OUTPUTS: 
    l,d- vectors of distances between points vertically and horozontally
    """
    l = np.zeros([M-1])
    d = np.zeros([M])
    
    # Calculate vertical and horozonal spacing between points for each row
    l[:] = geodetic_distance(site_collection_SM.lons[range(N,N*M,N)],   site_collection_SM.lats[range(N,N*M,N)],
                             site_collection_SM.lons[range(0,N*M-N,N)], site_collection_SM.lats[range(0,N*M-N,N)])
    d[:] = geodetic_distance(site_collection_SM.lons[range(0, M*N, N)], site_collection_SM.lats[range(0, M*N, N)],
                             site_collection_SM.lons[range(1, M*N, N)], site_collection_SM.lats[range(1, M*N, N)])
    return {'l':l, 'd':d}
Exemple #23
0
 def test_areas(self):
     """ Compute the areas of surfaces """
     length = geodetic_distance(0.0, 0.0, 0.3, 0.0)
     expected = np.array([length * 20.0, 10 * 14.14])
     computed = self.msrf._get_areas()
     msg = 'Multi fault surface: areas are wrong'
     np.testing.assert_almost_equal(expected,
                                    computed,
                                    err_msg=msg,
                                    decimal=-1)
Exemple #24
0
 def test_rx_kite(self):
     spc = 2.0
     pro1 = Line([Point(0.2, 0.0, 0.0), Point(0.2, 0.05, 15.0)])
     pro2 = Line([Point(0.0, 0.0, 0.0), Point(0.0, 0.05, 15.0)])
     sfc1 = KiteSurface.from_profiles([pro1, pro2], spc, spc)
     msurf = MultiSurface([sfc1])
     pcoo = numpy.array([[0.2, 0.1], [0.0, -0.1]])
     mesh = Mesh(pcoo[:, 0], pcoo[:, 1])
     # Compute expected distances
     lo = pro1.points[0].longitude
     la = pro1.points[0].longitude
     tmp0 = geodetic_distance(lo, la, pcoo[0, 0], pcoo[0, 1])
     lo = pro2.points[0].longitude
     la = pro2.points[0].longitude
     tmp1 = geodetic_distance(lo, la, pcoo[1, 0], pcoo[1, 1])
     # Checking
     rx = msurf.get_rx_distance(mesh)
     expected = numpy.array([tmp0, -tmp1])
     numpy.testing.assert_almost_equal(expected, rx, decimal=5)
    def getMatchingEvents(self, solve=True):
        """Return a list of dictionaries matching input parameters.

        Args:
            solve (bool):
                If set to True, then this method
                should return a list with a maximum of one event.

        Returns:
            list: List of event dictionaries, with fields:
                  - time Event time (UTC)
                  - lat Event latitude
                  - lon Event longitude
                  - depth Event depth
                  - mag Event magnitude
        """
        start_time = self.time - timedelta(seconds=3600)
        end_time = self.time + timedelta(seconds=3600)

        tpl = (start_time.strftime(TIMEFMT),
               end_time.strftime(TIMEFMT))
        url = CATBASE % tpl
        req = requests.get(url)
        data = req.text
        f = io.StringIO(data)
        df = pd.read_csv(f, parse_dates=['origintime'])
        # some of the column names have spaces in them
        cols = df.columns
        newcols = {}
        for col in cols:
            newcol = col.strip()
            newcols[col] = newcol
        df = df.rename(columns=newcols)
        lats = df['latitude'].values
        lons = df['longitude'].values
        etime = pd.Timestamp(self.time)
        dtimes = np.abs(df['origintime'] - etime)
        distances = geodetic_distance(self.lon, self.lat, lons, lats)
        didx = distances <= self.radius
        tidx = (dtimes <= np.timedelta64(int(self.dt), 's')).values
        newdf = df[didx & tidx]
        events = []
        for idx, row in newdf.iterrows():
            eventdict = {'time': UTCDateTime(row['origintime']),
                         'lat': row['latitude'],
                         'lon': row['longitude'],
                         'depth': row['depth'],
                         'mag': row['magnitude']}
            events.append(eventdict)

        if solve and len(events) > 1:
            event = self.solveEvents(events)
            events = [event]

        return events
Exemple #26
0
def get_quake_desc(event,lat,lon,isMainEvent):
    ndeaths = event['TotalDeaths']
    #summarize the exposure values
    exposures = np.array([event['MMI1'],event['MMI2'],event['MMI3'],event['MMI4'],event['MMI5'],
                         event['MMI6'],event['MMI7'],event['MMI8'],event['MMI9+']])
    exposures = np.array([round_to_nearest(exp,1000) for exp in exposures])
    #get the highest two exposures greater than zero
    iexp = np.where(exposures > 0)[0][::-1]

    romans = ['I', 'II', 'III', 'IV', 'V', 'VI', 'VII', 'VIII', 'IX or greater']
    if len(iexp) >= 2:
        exposures = [exposures[iexp[1]],exposures[iexp[0]]]
        ilevels = [romans[iexp[1]],romans[iexp[0]]]
        expfmt = ', with estimated population exposures of %s at intensity'
        expfmt = expfmt + ' %s and %s at intensity %s'
        exptxt = expfmt % (commify(int(exposures[0])),ilevels[0],commify(int(exposures[1])),ilevels[1])
    else:
        exptxt = ''

    #create string describing this most impactful event
    dfmt = 'A magnitude %.1f earthquake %i km %s of this event struck %s on %s (UTC)%s'

    mag = event['Magnitude']
    etime = event['Time'].strftime('%B %d, %Y')
    etime = re.sub(' 0',' ',etime)
    country = Country()
    if not event['Name']:
        if event['CountryCode'] == 'UM' and event['Latitude'] > 40: #hack for persistent error in expocat
            cdict = country.getCountryCode('US')
        else:
            cdict = country.getCountryCode(event['CountryCode'])
        if cdict:
            cname = cdict['Name']
        else:
            cname = 'in the open ocean'
    else:
        cname = event['Name'].replace('"','')
        
    cdist = round(geodetic_distance(event['Lat'],event['Lon'],lat,lon))
    cdir = get_compass_dir(lat,lon,event['Lat'],event['Lon'],format='long').lower()
    if ndeaths and str(ndeaths) != "nan":
        dfmt = dfmt + ', resulting in a reported %s %s.'
        
        if ndeaths > 1:
            dstr = 'fatalities'
        else:
            dstr = 'fatality'

        ndeathstr = commify(int(ndeaths))
        eqdesc = dfmt % (mag,cdist,cdir,cname,etime,exptxt,ndeathstr,dstr)
    else:
        dfmt = dfmt + ', with no reported fatalities.'
        eqdesc = dfmt % (mag,cdist,cdir,cname,etime,exptxt)

    return eqdesc
Exemple #27
0
    def selectByRadius(self, clat, clon, radius):
        """Select events by restricting to those within a search radius around a set of coordinates.

        """
        lons = self._dataframe['Lon']
        lats = self._dataframe['Lat']
        distances = geodetic_distance(clon, clat, lons, lats)
        iclose = pd.Series(distances < radius)
        newdf = self._dataframe[iclose]
        d1 = distances[distances < radius]
        newdf = newdf.assign(Distance=d1)
        return ExpoCat(newdf)
Exemple #28
0
    def get_closest(self, lon, lat):
        """
        Get the closest object to the given longitude and latitude
        and its distance.

        :param lon: longitude in degrees
        :param lat: latitude in degrees
        :param max_distance: distance in km (or None)
        """
        x, y = self.proj(lon, lat)
        idx = list(self.index.nearest((x, y, x, y), 1))[0]
        min_dist = geodetic_distance(
            lon, lat, self.lons[idx], self.lats[idx])
        return self.objects[idx], min_dist
def conditional_simulation(known_sites,
                           residuals,
                           unknown_sites,
                           imt,
                           nsim,
                           correlation_model=DEFAULT_CORRELATION):
    """
    Generates the residuals for a set of sites, conditioned upon the
    known residuals at a set of observation locations
    :param known_sites:
        Locations of known sites as instance of :class: 
        openquake.hazardlib.sites.SiteCollection
    :param dict residuals:
        Dictionary of residuals for specifc GMPE and IMT
    :param unknown_sites:
        Locations of unknown sites as instance of :class: 
        openquake.hazardlib.sites.SiteCollection
    :param imt:
        Intensity measure type
    :psram int nsim:
        Number of simulations
    :param correlation_model:
        Chosen correlation model

    """
    # Get site to site distances for known
    imt = from_string(imt)
    # Make sure that sites are at the surface (to check!)
    known_sites.depths = np.zeros_like(known_sites.depths)
    unknown_sites.depths = np.zeros_like(unknown_sites.depths)
    cov_kk = correlation_model._get_correlation_matrix(known_sites, imt).I
    cov_uu = correlation_model._get_correlation_matrix(unknown_sites, imt)
    d_k_uk = np.zeros([known_sites.total_sites, unknown_sites.total_sites],
                      dtype=float)
    for iloc in range(0, known_sites.total_sites):
        d_k_uk[iloc, :] = geodetic_distance(known_sites.lons[iloc],
                                            known_sites.lats[iloc],
                                            unknown_sites.lons,
                                            unknown_sites.lats)
    cov_ku = correlation_model._get_correlation_model(d_k_uk, imt)
    mu = cov_ku.T * cov_kk * np.matrix(residuals).T
    stddev = cov_uu - (cov_ku.T * cov_kk * cov_ku)
    unknown_residuals = np.matrix(
        np.random.normal(0., 1., [len(unknown_sites), nsim]))
    lower_matrix = np.linalg.cholesky(stddev)
    output_residuals = np.zeros_like(unknown_residuals)
    for iloc in range(0, nsim):
        output_residuals[:, iloc] = mu + \
            lower_matrix * unknown_residuals[:, iloc]
    return output_residuals
Exemple #30
0
 def test_arrays(self):
     lons1 = numpy.array([[-50.03824533, -153.97808192],
                          [-106.36068694, 47.06944014]])
     lats1 = numpy.array([[52.20211151, 17.018482],
                          [-26.06421527, -20.30383723]])
     lons2 = numpy.array([[49.97448794, 52.3126795],
                          [-165.13925579, 162.16421979]])
     lats2 = numpy.array([[-27.66510775, -73.66591257],
                          [-60.24498761,  -9.92908014]])
     edist = numpy.array([[13061.87935023, 13506.24000062],
                          [5807.34519649, 12163.45759805]])
     dist = geodetic.geodetic_distance(lons1, lats1, lons2, lats2)
     self.assertEqual(dist.shape, edist.shape)
     self.assertTrue(numpy.allclose(dist, edist))
Exemple #31
0
def get_middle_point(lon1, lat1, lon2, lat2):
    """
    Given two points return the point exactly in the middle lying on the same
    great circle arc.

    Parameters are point coordinates in degrees.

    :returns:
        Tuple of longitude and latitude of the point in the middle.
    """
    if lon1 == lon2 and lat1 == lat2:
        return lon1, lat1
    dist = geodetic.geodetic_distance(lon1, lat1, lon2, lat2)
    azimuth = geodetic.azimuth(lon1, lat1, lon2, lat2)
    return geodetic.point_at(lon1, lat1, azimuth, dist / 2.0)
Exemple #32
0
def get_middle_point(lon1, lat1, lon2, lat2):
    """
    Given two points return the point exactly in the middle lying on the same
    great circle arc.

    Parameters are point coordinates in degrees.

    :returns:
        Tuple of longitude and latitude of the point in the middle.
    """
    if lon1 == lon2 and lat1 == lat2:
        return lon1, lat1
    dist = geodetic.geodetic_distance(lon1, lat1, lon2, lat2)
    azimuth = geodetic.azimuth(lon1, lat1, lon2, lat2)
    return geodetic.point_at(lon1, lat1, azimuth, dist / 2.0)
Exemple #33
0
def _plot_topo(axes, csda):
    """
    :parameter axes:
    :parameter csda:
    """
    if csda.topo is None:
        return
    plt.sca(axes)
    olo = csda.csec.olo
    ola = csda.csec.ola
    topo = csda.topo
    tbsts = geodetic_distance(olo, ola, topo[:, 0], topo[:, 1])
    jjj = numpy.argsort(tbsts)
    plt.plot(tbsts[jjj], ((-1*topo[jjj, 2])/1000.), '-g', zorder=100,
             linewidth=2)
def conditional_simulation(
        known_sites, residuals, unknown_sites, imt, nsim,
        correlation_model=DEFAULT_CORRELATION):
    """
    Generates the residuals for a set of sites, conditioned upon the
    known residuals at a set of observation locations
    :param known_sites:
        Locations of known sites as instance of :class:
        `openquake.hazardlib.sites.SiteCollection`
    :param dict residuals:
        Dictionary of residuals for specifc GMPE and IMT
    :param unknown_sites:
        Locations of unknown sites as instance of :class:
        `openquake.hazardlib.sites.SiteCollection`
    :param imt:
        Intensity measure type
    :psram int nsim:
        Number of simulations
    :param correlation_model:
        Chosen correlation model, i.e. jbcorrelation

    """
    # Get site to site distances for known
    imt = from_string(imt)
    # Make sure that sites are at the surface (to check!)
    known_sites.depths = np.zeros_like(known_sites.depths)
    unknown_sites.depths = np.zeros_like(unknown_sites.depths)
    cov_kk = np.linalg.inv(correlation_model(known_sites, imt))
    cov_uu = correlation_model(unknown_sites, imt)
    d_k_uk = np.zeros([len(known_sites), len(unknown_sites)],
                      dtype=float)
    klons, klats = known_sites.lons, known_sites.lats
    ulons, ulats = unknown_sites.lons, unknown_sites.lats
    for iloc in range(len(known_sites)):
        d_k_uk[iloc, :] = geodetic_distance(klons[iloc], klats[iloc],
                                            ulons, ulats)
    cov_ku = correlation_model(d_k_uk, imt)
    mu = cov_ku.T @ cov_kk @ residuals.T
    stddev = cov_uu - (cov_ku.T @ cov_kk @ cov_ku)
    unknown_residuals = np.random.normal(
        0., 1., [len(unknown_sites), nsim])
    lower_matrix = np.linalg.cholesky(stddev)
    output_residuals = np.zeros_like(unknown_residuals)
    for iloc in range(0, nsim):
        output_residuals[:, iloc] = mu + \
            lower_matrix @ unknown_residuals[:, iloc]
    return output_residuals
Exemple #35
0
def _plot_litho(axes, csda):
    """
    :parameter axes:
    :parameter csda:
    """
    if csda.litho is None:
        print("No LITHO1.0...")
        return
    plt.sca(axes)
    olo = csda.csec.olo
    ola = csda.csec.ola
    litho = csda.litho
    if litho.size == 3:
        litho = numpy.concatenate((litho, litho), axis=0).reshape((2, 3))
    lists = geodetic_distance(olo, ola, litho[:, 0], litho[:, 1])
    lll = numpy.argsort(lists)
    plt.plot(lists[lll], litho[lll, 2], '-.', zorder=100, linewidth=2)
Exemple #36
0
def _plot_moho(axes, csda):
    """
    :parameter axes:
    :parameter csda:
    """
    if csda.moho is None:
        print("No CRUST1.0...")
        return
    plt.sca(axes)
    olo = csda.csec.olo
    ola = csda.csec.ola
    moho = csda.moho
    if moho.size == 3:
        moho = numpy.concatenate((moho, moho), axis=0).reshape((2, 3))
    mdsts = geodetic_distance(olo, ola, moho[:, 0], moho[:, 1])
    iii = numpy.argsort(mdsts)
    plt.plot(mdsts[iii], moho[iii, 2], '--p', zorder=100, linewidth=2)
Exemple #37
0
def _plot_slab1pt0(axes, csda):
    """
    :parameter axes:
    :parameter csda:
    """
    if csda.slab1pt0 is None:
        return
    plt.sca(axes)
    olo = csda.csec.olo
    ola = csda.csec.ola
    slab1pt0 = csda.slab1pt0
    slb_dst = geodetic_distance(olo, ola, slab1pt0[:, 0], slab1pt0[:, 1])
    slb_dep = slab1pt0[:, 2]
    iii = numpy.argsort(slb_dst)
    if len(iii) > 2:
        plt.plot(slb_dst[iii], -1*slb_dep[iii], '-b', linewidth=3, zorder=30)
        plt.text(slb_dst[iii[-1]], -1*slb_dep[iii[-1]], 'Slab1.0', fontsize=8)
def _plot_focal_mech(axes, csda):
    """
    :parameter axes:
    :parameter csda:
    """
    if csda.gcmt is None:
        return

    olo = csda.csec.olo
    ola = csda.csec.ola

    cat_gcmt = csda.gcmt
    cmt_dst = geodetic_distance(olo, ola, cat_gcmt.data['longitude'],
                                cat_gcmt.data['latitude'])
    cmt_dep = cat_gcmt.data['depth']
    cmts = numpy.array(cat_gcmt.gcmts)

    idx = 0
    for ddd, dep, eve, mag, yea in zip(list(cmt_dst), list(cmt_dep),
                                       list(cmts), cat_gcmt.data['magnitude'],
                                       cat_gcmt.data['year']):

        if yea > 1000 and mag > 1.0:

            # Kaverina classification
            plungeb = cat_gcmt.data['plunge_b'][idx]
            plungep = cat_gcmt.data['plunge_p'][idx]
            plunget = cat_gcmt.data['plunge_t'][idx]
            mclass = mecclass(plunget, plungeb, plungep)

            com = eve.moment_tensor._to_6component()
            # REMOVE
            try:
                bcc = beach(com,
                            xy=(ddd, dep),
                            width=eve.magnitude * 2,
                            linewidth=1,
                            zorder=20,
                            size=mag,
                            facecolor=KAVERINA[mclass])
                bcc.set_alpha(0.5)
                axes.add_collection(bcc)
            except:
                pass
        idx += 1
Exemple #39
0
def _plot_np_intersection(axes, csda):
    """
    """

    if csda.gcmt is None:
        return

    olo = csda.csec.olo
    ola = csda.csec.ola

    cat_gcmt = csda.gcmt
    cmt_dst = geodetic_distance(olo, ola, cat_gcmt.data['longitude'],
                                cat_gcmt.data['latitude'])
    cmt_dep = cat_gcmt.data['depth']
    cmts = numpy.array(cat_gcmt.gcmts)

    idx = 0
    for ddd, dep, eve, mag, yea in zip(list(cmt_dst),
                                       list(cmt_dep),
                                       list(cmts),
                                       cat_gcmt.data['magnitude'],
                                       cat_gcmt.data['year']):

        if yea > 1000 and mag > 1.0:

            # Kaverina classification
            plungeb = cat_gcmt.data['plunge_b'][idx]
            plungep = cat_gcmt.data['plunge_p'][idx]
            plunget = cat_gcmt.data['plunge_t'][idx]
            mclass = mecclass(plunget, plungeb, plungep)

            plot_planes_at(ddd,
                           dep,
                           [eve.nodal_planes.nodal_plane_1['strike'],
                            eve.nodal_planes.nodal_plane_2['strike']],
                           [eve.nodal_planes.nodal_plane_1['dip'],
                            eve.nodal_planes.nodal_plane_2['dip']],
                           [mag, mag],
                           strike_cs=csda.csec.strike[0],
                           dip_cs=90.,
                           aratio=1.0,
                           color=KAVERINA[mclass],
                           linewidth=2.0,
                           axis=axes)
        idx += 1
Exemple #40
0
 def limitByRadius(self,lat,lon,radius):
     """Search for cities within a radius (km) around a central point.
     :param lat:
       Central latitude coordinate (dd).
     :param lon:
       Central longitude coordinate (dd).
     :param radius:
       Radius (km) around which cities will be searched.
     :returns:
       New Cities instance containing smaller cities data set.
     """
     #TODO - figure out what to do with a meridian crossing?
     newdf = self._dataframe.copy()
     dist = geodetic_distance(lon,lat,self._dataframe['lon'],self._dataframe['lat'])
     newdf['dist'] = dist
     newdf = newdf[newdf['dist'] <= radius]
     del newdf['dist']
     return type(self)(newdf)
Exemple #41
0
    def get_closest(self, lon, lat):
        """
        Get the closest object to the given longitude and latitude
        and its distance.

        :param lon: longitude in degrees
        :param lat: latitude in degrees
        :param max_distance: distance in km (or None)
        """
        if rtree:
            x, y = self.proj(lon, lat)
            idx = list(self.index.nearest((x, y, x, y), 1))[0]
            min_dist = geodetic_distance(lon, lat, self.lons[idx],
                                         self.lats[idx])
        else:
            zeros = numpy.zeros_like(self.lons)
            idx, min_dist = min_idx_dst(self.lons, self.lats, zeros, lon, lat)
        return self.objects[idx], min_dist
Exemple #42
0
def get_resampled_coordinates(lons, lats):
    """
    Resample polygon line segments and return the coordinates of the new
    vertices. This limits distortions when projecting a polygon onto a
    spherical surface.

    Parameters define longitudes and latitudes of a point collection in the
    form of lists or numpy arrays.

    :return:
        A tuple of two numpy arrays: longitudes and latitudes
        of resampled vertices.
    """
    num_coords = len(lons)
    assert num_coords == len(lats)

    lons1 = numpy.array(lons)
    lats1 = numpy.array(lats)
    lons2 = numpy.concatenate((lons1[1:], lons1[0:1]))
    lats2 = numpy.concatenate((lats1[1:], lats1[0:1]))
    distances = geodetic.geodetic_distance(lons1, lats1, lons2, lats2)

    resampled_lons = [lons[0]]
    resampled_lats = [lats[0]]
    for i in xrange(num_coords):
        next_point = (i + 1) % num_coords
        lon1, lat1 = lons[i], lats[i]
        lon2, lat2 = lons[next_point], lats[next_point]

        distance = distances[i]
        num_points = int(distance / UPSAMPLING_STEP_KM) + 1
        if num_points >= 2:
            # We need to increase the resolution of this arc by adding new
            # points.
            new_lons, new_lats, _ = geodetic.npoints_between(
                lon1, lat1, 0, lon2, lat2, 0, num_points
            )
            resampled_lons.extend(new_lons[1:])
            resampled_lats.extend(new_lats[1:])
        else:
            resampled_lons.append(lon2)
            resampled_lats.append(lat2)
    # we cut off the last point because it repeats the first one.
    return numpy.array(resampled_lons[:-1]), numpy.array(resampled_lats[:-1])
def conditional_simulation(known_sites, residuals, unknown_sites, imt, nsim,
    correlation_model=DEFAULT_CORRELATION):
    """
    Generates the residuals for a set of sites, conditioned upon the
    known residuals at a set of observation locations
    :param known_sites:
        Locations of known sites as instance of :class: 
        openquake.hazardlib.sites.SiteCollection
    :param dict residuals:
        Dictionary of residuals for specifc GMPE and IMT
    :param unknown_sites:
        Locations of unknown sites as instance of :class: 
        openquake.hazardlib.sites.SiteCollection
    :param imt:
        Intensity measure type
    :psram int nsim:
        Number of simulations
    :param correlation_model:
        Chosen correlation model

    """
    # Get site to site distances for known
    imt = from_string(imt)
    cov_kk = correlation_model._get_correlation_matrix(known_sites, imt).I
    cov_uu = correlation_model._get_correlation_matrix(unknown_sites, imt)
    d_k_uk = np.zeros([known_sites.total_sites, unknown_sites.total_sites],
                       dtype=float)
    for iloc in range(0, known_sites.total_sites):
        d_k_uk[iloc, :] = geodetic_distance(known_sites.lons[iloc],
                                            known_sites.lats[iloc],
                                            unknown_sites.lons,
                                            unknown_sites.lats)
    cov_ku = correlation_model._get_correlation_model(d_k_uk, imt)
    mu = cov_ku.T * cov_kk * np.matrix(residuals).T
    stddev = cov_uu - (cov_ku.T * cov_kk * cov_ku)
    unknown_residuals = np.matrix(np.random.normal(0., 1., 
                                                   [len(unknown_sites), nsim]))
    lower_matrix = np.linalg.cholesky(stddev)
    output_residuals = np.zeros_like(unknown_residuals)
    for iloc in range(0, nsim):
        output_residuals[:, iloc] = mu + \
            lower_matrix * unknown_residuals[:, iloc]
    return output_residuals
    def solveEvents(self, events):
        """Reduce a list of events down to one that best matches the input.

        Args:
            events (list): 
                List of dictionaries with fields:
                - time Event time (UTC)
                - lat Event latitude
                - lon Event longitude
                - depth Event depth
                - mag Event magnitude

        Returns:
            dict: Event dictionary (see above)
        """
        edict = {'time': UTCDateTime(self.time),
                 'lat': self.lat,
                 'lon': self.lon,
                 'depth': self.depth,
                 'mag': self.magnitude}

        zmin = 9e12
        minevent = None
        for i in range(0, len(events)):
            event = events[i]
            ddist = geodetic_distance(edict['lon'], edict['lat'],
                                      event['lon'], event['lat'])
            ddist_norm = ddist / self.radius
            dt_norm = np.abs(edict['time'] - event['time']) / self.dt
            ddepth_norm = np.abs(edict['depth'] - event['depth']) / self.ddepth
            dmag_norm = np.abs(edict['mag'] - event['mag']) / self.dmag
            ddsq = np.power(ddist_norm, 2)
            dtsq = np.power(dt_norm, 2)
            dzsq = np.power(ddepth_norm, 2)
            dmsq = np.power(dmag_norm, 2)
            z = np.sqrt(ddsq + dtsq + dzsq + dmsq)
            if z < zmin:
                zmin = z
                minevent = event

        return minevent
Exemple #45
0
    def get_closest(self, lon, lat, max_distance=None):
        """
        Get the closest object to the given longitude and latitude
        and its distance. If the `max_distance` is given and all objects
        are farther than the maximum distance, returns (None, None).

        :param lon: longitude in degrees
        :param lat: latitude in degrees
        :param max_distance: distance in km (or None)
        """
        if rtree:
            x, y = self.proj(lon, lat)
            idx = list(self.index.nearest((x, y, x, y), 1))[0]
            min_dist = geodetic_distance(
                lon, lat, self.lons[idx], self.lats[idx])
        else:
            zeros = numpy.zeros_like(self.lons)
            idx, min_dist = min_idx_dst(self.lons, self.lats, zeros, lon, lat)
        if max_distance is not None and min_dist > max_distance:
            return None, None
        return self.objects[idx], min_dist
    def getMatchingEvents(self, solve=True):
        """Return a list of dictionaries matching input parameters.

        Args:
            solve (bool):
                If set to True, then this method
                should return a list with a maximum of one event.

        Returns:
            list: List of event dictionaries, with fields:
                  - time Event time (UTC)
                  - lat Event latitude
                  - lon Event longitude
                  - depth Event depth
                  - mag Event magnitude
        """
        df = get_turkey_dataframe(self.time, 1)
        lats = df['latitude'].values
        lons = df['longitude'].values
        etime = pd.Timestamp(self.time)
        dtimes = np.abs(df['origintime'] - etime)
        distances = geodetic_distance(self.lon, self.lat, lons, lats)
        didx = distances <= self.radius
        tidx = (dtimes <= np.timedelta64(int(self.dt), 's')).values
        newdf = df[didx & tidx]
        events = []
        for idx, row in newdf.iterrows():
            eventdict = {'time': UTCDateTime(row['origintime']),
                         'lat': row['latitude'],
                         'lon': row['longitude'],
                         'depth': row['depth'],
                         'url': row['url'],
                         'mag': row['magnitude']}
            events.append(eventdict)

        if solve and len(events) > 1:
            event = self.solveEvents(events)
            events = [event]

        return events
Exemple #47
0
def calc_full_dist(row, vert, hor, N, site_collection_SM):
    """
    Calculates full distance matrix. Called once per row.
    
    INPUTS:
    vert- number of included rows
    hor- number of columns within radius 
    N- number of points in row
    site_collection_SM- site collection for ShakeMap data
    OUTPUTS:
    grid_indices- indices of points included in distance matrix
    distance_matrix- full distance matrix
    """

    # gathers indices for full distance matrix for each row
    grid_indices = [None]*(vert*(2*hor+1))
    n_grid_indices = 0
    for k in range(row-vert+1, row+1):
        if k == row:
            for j in range(0,hor+1):
                grid_indices[n_grid_indices] = j + N*k
                n_grid_indices += 1
        else:
            for j in range(0,2*hor+1):
                grid_indices[n_grid_indices] = j + N*k
                n_grid_indices += 1 
    del grid_indices[n_grid_indices:]

    distance_matrix = np.zeros([np.size(grid_indices), np.size(grid_indices)])

    # Create full distance matrix for row
    for k in range(0, np.size(grid_indices)):
        distance_matrix[k, k:] = geodetic_distance(
            site_collection_SM.lons[grid_indices[k ]], site_collection_SM.lats[grid_indices[k]],
            site_collection_SM.lons[grid_indices[k:]], site_collection_SM.lats[grid_indices[k:]]).flatten()
    
    distance_matrix = distance_matrix + distance_matrix.T
    
    return {'grid_indices':grid_indices, 'distance_matrix':distance_matrix}
Exemple #48
0
def calc_full_dist(vert, hor, N, site_collection_SM):
    #####
    # Calculates full distance matrix. Called once per row.
    # IN: vert- number of included rows
    #     hor- number of columns within radius 
    #     N- number of points in row
    #     site_collection_SM- site collection for ShakeMap data
    #OUT: grid_indices- indices of points included in distance matrix
    #     distance_matrix- full distance matrix
    #####

    # gathers indices for full distance matrix for each row
    grid_indices = [None]*(vert*(2*hor+1))
    n_grid_indices = 0
    for k in range(0, vert):
        if k == vert-1:
            for j in range(0,hor+1):
                grid_indices[n_grid_indices] = [j + N*k]
                n_grid_indices += 1
        else:
            for j in range(0,2*hor+1):
                grid_indices[n_grid_indices] = [j + N*k]
                n_grid_indices += 1 
    del grid_indices[n_grid_indices:]

    distance_matrix = np.zeros([np.size(grid_indices), np.size(grid_indices)])
    grid_indices = np.vstack(grid_indices)
    
    # Create full distance matrix for row
    for k in range(0, np.size(grid_indices)):
        distance_matrix[k, k:] = geodetic_distance(
                   site_collection_SM.lons[grid_indices[k ]], site_collection_SM.lats[grid_indices[k]],
                   site_collection_SM.lons[grid_indices[k:]], site_collection_SM.lats[grid_indices[k:]]).flatten()
    
    distance_matrix = distance_matrix + distance_matrix.T
    
    return {'grid_indices':grid_indices, 'distance_matrix':distance_matrix}
Exemple #49
0
    def get_dppvalue(self, site):
        """
        Get the directivity prediction value, DPP at
        a given site as described in Spudich et al. (2013).

        :param site:
            :class:`~openquake.hazardlib.geo.point.Point` object
            representing the location of the target site
        :returns:
            A float number, directivity prediction value (DPP).
        """

        origin = self.surface.get_resampled_top_edge()[0]
        dpp_multi = []
        index_patch = self.surface.hypocentre_patch_index(
            self.hypocenter, self.surface.get_resampled_top_edge(),
            self.surface.mesh.depths[0][0], self.surface.mesh.depths[-1][0],
            self.surface.get_dip())
        idx_nxtp = True
        hypocenter = self.hypocenter

        while idx_nxtp:

            # E Plane Calculation
            p0, p1, p2, p3 = self.surface.get_fault_patch_vertices(
                self.surface.get_resampled_top_edge(),
                self.surface.mesh.depths[0][0],
                self.surface.mesh.depths[-1][0],
                self.surface.get_dip(), index_patch=index_patch)

            [normal, dist_to_plane] = get_plane_equation(
                p0, p1, p2, origin)

            pp = projection_pp(site, normal, dist_to_plane, origin)
            pd, e, idx_nxtp = directp(
                p0, p1, p2, p3, hypocenter, origin, pp)
            pd_geo = origin.point_at(
                (pd[0] ** 2 + pd[1] ** 2) ** 0.5, -pd[2],
                numpy.degrees(math.atan2(pd[0], pd[1])))

            # determine the lower bound of E path value
            f1 = geodetic_distance(p0.longitude,
                                   p0.latitude,
                                   p1.longitude,
                                   p1.latitude)
            f2 = geodetic_distance(p2.longitude,
                                   p2.latitude,
                                   p3.longitude,
                                   p3.latitude)

            if f1 > f2:
                f = f1
            else:
                f = f2

            fs, rd, r_hyp = average_s_rad(site, hypocenter, origin,
                                          pp, normal, dist_to_plane, e, p0,
                                          p1, self.rupture_slip_direction)
            cprime = isochone_ratio(e, rd, r_hyp)

            dpp_exp = cprime * numpy.maximum(e, 0.1 * f) *\
                numpy.maximum(fs, 0.2)
            dpp_multi.append(dpp_exp)

            # check if go through the next patch of the fault
            index_patch = index_patch + 1

            if (len(self.surface.get_resampled_top_edge())
                <= 2) and (index_patch >=
                           len(self.surface.get_resampled_top_edge())):

                idx_nxtp = False
            elif index_patch >= len(self.surface.get_resampled_top_edge()):
                idx_nxtp = False
            elif idx_nxtp:
                hypocenter = pd_geo
                idx_nxtp = True

        # calculate DPP value of the site.
        dpp = numpy.log(numpy.sum(dpp_multi))

        return dpp
 def test_along_meridian(self):
     coords = list(map(numpy.array, [(77.5, -150.), (-10., 15.),
                                     (77.5, -150.), (-20., 25.)]))
     dist = geodetic.geodetic_distance(*coords)
     assert_aeq(dist, [1111.949, 1111.949], decimal=3)
    def getMatchingEvents(self, solve=True):
        """Return a list of dictionaries matching input parameters.

        Args:
            solve (bool):
                If set to True, then this method
                should return a list with a maximum of one event.

        Returns:
            list: List of event dictionaries, with fields:
                  - time Event time (UTC)
                  - lat Event latitude
                  - lon Event longitude
                  - depth Event depth
                  - mag Event magnitude
        """
        jpyear = str(self.jptime.year)
        jpquarter = str(QUARTERS[self.jptime.month])
        url = SEARCH_URL.replace('YEAR', jpyear)
        url = url.replace('QUARTER', jpquarter)
        req = requests.get(url)
        data = req.text
        soup = BeautifulSoup(data, features="lxml")
        select = soup.find('select')
        options = select.find_all('option')
        times = []
        lats = []
        lons = []
        depths = []
        mags = []
        values = []
        for option in options:
            eventstr = option.contents[0]
            timestr = re.search(TIMEPAT, eventstr).group()
            latstr = re.search(LATPAT, eventstr).group()
            lonstr = re.search(LONPAT, eventstr).group()
            depstr = re.search(DEPPAT, eventstr).group()
            magstr = re.search(MAGPAT, eventstr).group()
            lat = float(latstr.replace('N', ''))
            lon = float(lonstr.replace('E', ''))
            depth = float(depstr.replace('km', ''))
            mag = float(magstr.replace('M', ''))
            etime = datetime.strptime(timestr, TIMEFMT)
            times.append(np.datetime64(etime))
            lats.append(lat)
            lons.append(lon)
            depths.append(depth)
            mags.append(mag)
            values.append(option.get('value'))

        times = np.array(times)
        lats = np.array(lats)
        lons = np.array(lons)
        depths = np.array(depths)
        mags = np.array(mags)
        values = np.array(values)
        distances = geodetic_distance(self.lon, self.lat, lons, lats)
        didx = distances <= self.radius
        jptime = np.datetime64(self.jptime)
        # dtimes is in microseconds
        dtimes = np.abs(jptime - times)
        tidx = dtimes <= np.timedelta64(int(self.dt), 's')
        etimes = times[didx & tidx]
        elats = lats[didx & tidx]
        elons = lons[didx & tidx]
        edepths = depths[didx & tidx]
        emags = mags[didx & tidx]
        evalues = values[didx & tidx]
        events = []
        for etime, elat, elon, edep, emag, evalue in zip(etimes, elats,
                                                         elons, edepths,
                                                         emags, evalues):
            jtime = UTCDateTime(str(etime))
            utime = jtime - JST_OFFSET
            edict = {'time': utime,
                     'lat': elat,
                     'lon': elon,
                     'depth': edep,
                     'mag': emag,
                     'cgi_value': evalue}
            events.append(edict)

        if solve and len(events) > 1:
            event = self.solveEvents(events)
            events = [event]

        return events
 def test_LAX_to_JFK(self):
     dist = geodetic.geodetic_distance(*(LAX + JFK))
     self.assertAlmostEqual(dist, 0.623585 * geodetic.EARTH_RADIUS,
                            delta=0.1)
     dist2 = geodetic.geodetic_distance(*(JFK + LAX))
     self.assertAlmostEqual(dist, dist2)
 def test_one_to_many(self):
     dist = geodetic.geodetic_distance(0, 0, [-1, 1], [0, 0])
     assert_aeq(dist, [111.195, 111.195], decimal=4)
     dist = geodetic.geodetic_distance(0, 0, [[-1, 0], [1, 0]],
                                             [[0, 0], [0, 0]])
     assert_aeq(dist, [[111.195, 0], [111.195, 0]], decimal=4)
 def test_on_equator(self):
     dist = geodetic.geodetic_distance(0, 0, 1, 0)
     self.assertAlmostEqual(dist, 111.1949266)
     [dist2] = geodetic.geodetic_distance([-5], [0], [-6], [0])
     self.assertAlmostEqual(dist, dist2)
 def test_along_meridian(self):
     coords = list(map(numpy.array, [(77.5, -150.), (-10., 15.),
                                (77.5, -150.), (-20., 25.)]))
     dist = geodetic.geodetic_distance(*coords)
     self.assertTrue(numpy.allclose(dist, [1111.949, 1111.949]), str(dist))
 def test_one_point_on_pole(self):
     dist = geodetic.geodetic_distance(0, 90, 0, 88)
     self.assertAlmostEqual(dist, 222.3898533)
 def test_small_distance(self):
     dist = geodetic.geodetic_distance(0, 0, 0, 1e-10)
     self.assertAlmostEqual(dist, 0)
     dist = geodetic.geodetic_distance(-1e-12, 0, 0, 0)
     self.assertAlmostEqual(dist, 0)
 def test_opposite_points(self):
     dist = geodetic.geodetic_distance(110, -10, -70, 10)
     self.assertAlmostEqual(dist, geodetic.EARTH_RADIUS * numpy.pi,
                            places=3)