Exemple #1
0
 def test_2d_mesh(self):
     mesh = Mesh(numpy.array([[0., 1.], [2., 3.]]),
                 numpy.array([[0., 0.], [0., 0.]]), None)
     target_mesh = Mesh(
         numpy.array([[3., 4., 5.], [-6., -7., 8.], [9., 10., 11.]]),
         numpy.array([[0., 0., 0.], [0., 0., 0.], [0., 0., 0.]]), None)
     self._test(mesh,
                target_mesh,
                expected_distance_indices=[3, 3, 3, 0, 0, 3, 3, 3, 3])
Exemple #2
0
    def __init__(self, sites):
        self.indices = None
        self.vs30 = numpy.zeros(len(sites))
        self.vs30measured = numpy.zeros(len(sites), dtype=bool)
        self.z1pt0 = self.vs30.copy()
        self.z2pt5 = self.vs30.copy()
        lons = self.vs30.copy()
        lats = self.vs30.copy()

        for i in xrange(len(sites)):
            self.vs30[i] = sites[i].vs30
            self.vs30measured[i] = sites[i].vs30measured
            self.z1pt0[i] = sites[i].z1pt0
            self.z2pt5[i] = sites[i].z2pt5
            lons[i] = sites[i].location.longitude
            lats[i] = sites[i].location.latitude

        self.mesh = Mesh(lons, lats, depths=None)

        # protect arrays from being accidentally changed. it is useful
        # because we pass these arrays directly to a GMPE through
        # a SiteContext object and if a GMPE is implemented poorly it could
        # modify the site values, thereby corrupting site and all the
        # subsequent calculation. note that this doesn't protect arrays from
        # being changed by calling itemset()
        for arr in (self.vs30, self.vs30measured, self.z1pt0, self.z2pt5,
                    self.mesh.lons, self.mesh.lats):
            arr.flags.writeable = False
Exemple #3
0
 def test_many_points(self):
     lons = numpy.array([0.7, 0.6, 0.4, 0.6, 0.3, 0.9, 0.5, 0.4])
     lats = numpy.array([0.8, 0.5, 0.2, 0.7, 0.2, 0.4, 0.9, 0.4])
     mesh = Mesh(lons, lats, None)
     polygon = mesh.get_convex_hull()
     elons = [0.4, 0.3, 0.5, 0.7, 0.9]
     elats = [0.2, 0.2, 0.9, 0.8, 0.4]
     numpy.testing.assert_allclose(polygon.lons, elons)
     numpy.testing.assert_allclose(polygon.lats, elats)
Exemple #4
0
 def test(self):
     mesh = Mesh(numpy.array([0., 1., 2., 3.]), numpy.zeros(4), None)
     matrix = mesh.get_distance_matrix()
     aaae = numpy.testing.assert_array_almost_equal
     aaae(matrix[0], [[0, 111.2, 222.4, 333.6]], decimal=1)
     aaae(matrix[1], [[111.2, 0, 111.2, 222.4]], decimal=1)
     aaae(matrix[2], [[222.4, 111.2, 0, 111.2]], decimal=1)
     aaae(matrix[3], [[333.6, 222.4, 111.2, 0]], decimal=1)
     for i in xrange(4):
         for j in xrange(i, 4):
             self.assertEqual(matrix[i, j], matrix[j, i])
Exemple #5
0
    def filter(self, mask):
        """
        Create a new collection with only a subset of sites from this one.

        :param mask:
            Numpy array of boolean values of the same length as this sites
            collection. ``True`` values should indicate that site with that
            index should be included into the filtered collection.
        :returns:
            A new :class:`SiteCollection` instance, unless all the values
            in ``mask`` are ``True``, in which case this site collection
            is returned, or if all the values in ``mask`` are ``False``,
            in which case method returns ``None``. New collection has data
            of only those sites that were marked for inclusion in mask.

        See also :meth:`expand`.
        """
        assert len(mask) == len(self)
        if mask.all():
            # all sites satisfy the filter, return
            # this collection unchanged
            return self
        if not mask.any():
            # no sites pass the filter, return None
            return None
        col = object.__new__(SiteCollection)
        # extract indices of Trues from the mask
        [indices] = mask.nonzero()
        # take only needed values from this collection
        # to a new one
        col.vs30 = self.vs30.take(indices)
        col.vs30measured = self.vs30measured.take(indices)
        col.z1pt0 = self.z1pt0.take(indices)
        col.z2pt5 = self.z2pt5.take(indices)
        col.mesh = Mesh(self.mesh.lons.take(indices),
                        self.mesh.lats.take(indices),
                        depths=None)
        if self.indices is not None:
            # if this collection was already a subset of some other
            # collection (a result of :meth:`filter` itself) than mask's
            # indices represent values in a filtered collection, but
            # we need to keep track of original indices in the whole
            # (unfiltered) collection. here we save original indices
            # of sites in this double- (or more times) filtered
            # collection
            col.indices = self.indices.take(indices)
        else:
            col.indices = indices
        # do the same as in the constructor
        for arr in (col.vs30, col.vs30measured, col.z1pt0, col.z2pt5,
                    col.mesh.lons, col.mesh.lats):
            arr.flags.writeable = False
        return col
Exemple #6
0
 def test_two_points(self):
     mesh = Mesh(numpy.array([-10., -11.]), numpy.array([-12., -13.]), None)
     polygon = mesh.get_convex_hull()
     self.assertIsInstance(polygon, Polygon)
     elons = [
         -10.99996704, -11.0000323, -11.00003296, -10.00003295, -9.99996795,
         -9.99996705
     ]
     elats = [
         -13.00003147, -13.00003212, -12.99996853, -11.99996865,
         -11.99996776, -12.00003135
     ]
     numpy.testing.assert_allclose(polygon.lons, elons)
     numpy.testing.assert_allclose(polygon.lats, elats)
Exemple #7
0
    def get_closest_points(self, mesh):
        """
        See :meth:`superclass' method
        <nhlib.geo.surface.base.BaseSurface.get_closest_points>`.

        This is an optimized version specific to planar surface that doesn't
        make use of the mesh.
        """
        dists, xx, yy = self._project(mesh.lons, mesh.lats, mesh.depths)
        mxx = xx.clip(0, self.length)
        myy = yy.clip(0, self.width)
        dists.fill(0)
        lons, lats, depths = self._project_back(dists, mxx, myy)
        return Mesh(lons, lats, depths)
Exemple #8
0
    def test_against_mesh_to_mesh(self):
        corners = [Point(2.6, 3.7, 20), Point(2.90102155, 3.99961567, 20),
                   Point(3.2, 3.7, 75), Point(2.89905849, 3.40038407, 75)]
        surface = PlanarSurface(0.5, 45, 70, *corners)
        lons, lats = numpy.meshgrid(numpy.linspace(2.2, 3.6, 7),
                                    numpy.linspace(3.4, 4.2, 7))
        sites = Mesh(lons, lats, depths=None)

        res1 = surface.get_closest_points(sites)
        res2 = super(PlanarSurface, surface).get_closest_points(sites)

        aae = numpy.testing.assert_almost_equal
        # precision up to ~1 km
        aae(res1.lons, res2.lons, decimal=2)
        aae(res1.lats, res2.lats, decimal=2)
        aae(res1.depths, res2.depths, decimal=0)
Exemple #9
0
    def surface_projection_from_fault_data(cls, edges):
        """
        Get a surface projection of the complex fault surface.

        :param edges:
            A list of horizontal edges of the surface as instances
            of :class:`nhlib.geo.line.Line`.
        :returns:
            Instance of :class:`~nhlib.geo.polygon.Polygon` describing
            the surface projection of the complex fault.
        """
        # collect lons and lats of all the vertices of all the edges
        lons, lats = numpy.array([[[point.longitude, point.latitude]
                                   for point in edge] for edge in edges],
                                 dtype=float).reshape((-1, 2)).transpose()
        return Mesh(lons, lats, depths=None).get_convex_hull()
Exemple #10
0
    def discretize(self, mesh_spacing):
        """
        Get a mesh of uniformly spaced points inside the polygon area
        with distance of ``mesh_spacing`` km between.

        :returns:
            An instance of :class:`~nhlib.geo.mesh.Mesh` that holds
            the points data. Mesh is created with no depth information
            (all the points are on the Earth surface).
        """
        self._init_polygon2d()

        west, east, north, south = self._bbox

        lons = []
        lats = []

        # we cover the bounding box (in spherical coordinates) from highest
        # to lowest latitude and from left to right by longitude. we step
        # by mesh spacing distance (linear measure). we check each point
        # if it is inside the polygon and yield the point object, if so.
        # this way we produce an uniformly-spaced mesh regardless of the
        # latitude.
        latitude = north
        while latitude > south:
            longitude = west
            while utils.get_longitudinal_extent(longitude, east) > 0:
                # we use Cartesian space just for checking if a point
                # is inside of the polygon.
                x, y = self._projection(longitude, latitude)
                if self._polygon2d.contains(shapely.geometry.Point(x, y)):
                    lons.append(longitude)
                    lats.append(latitude)

                # move by mesh spacing along parallel...
                longitude, _, = geodetic.point_at(longitude, latitude, 90,
                                                  mesh_spacing)
            # ... and by the same distance along meridian in outer one
            _, latitude = geodetic.point_at(west, latitude, 180, mesh_spacing)

        lons = numpy.array(lons)
        lats = numpy.array(lats)

        return Mesh(lons, lats, depths=None)
Exemple #11
0
    def test1(self):
        lons, lats, depths = geo_utils.cartesian_to_spherical(
            numpy.array([[60, -10, -10], [60, -10, 10],
                         [60, 10, 10], [60, 10, -10]], float)
        )
        surface = PlanarSurface(10, 20, 30, *Mesh(lons, lats, depths))
        aaae = numpy.testing.assert_array_almost_equal

        plons, plats, pdepths = geo_utils.cartesian_to_spherical(
            numpy.array([[60, -10, -10], [59, 0, 0], [70, -11, -10]], float)
        )

        dists, xx, yy =  surface._project(plons, plats, pdepths)
        aaae(xx, [0, 10, 0])
        aaae(yy, [0, 10, -1])
        aaae(dists, [0, 1, -10])

        lons, lats, depths = surface._project_back(dists, xx, yy)
        aaae(lons, plons)
        aaae(lats, plats)
        aaae(depths, pdepths)
Exemple #12
0
    def surface_projection_from_fault_data(cls, fault_trace,
                                           upper_seismogenic_depth,
                                           lower_seismogenic_depth, dip):
        """
        Get a surface projection of the simple fault surface.

        Parameters are the same as for :meth:`from_fault_data`, excluding
        mesh spacing.

        :returns:
            Instance of :class:`~nhlib.geo.polygon.Polygon` describing
            the surface projection of the simple fault with specified
            parameters.
        """
        # similar to :meth:`from_fault_data`, we just don't resample edges
        dip_tan = math.tan(math.radians(dip))
        hdist_top = upper_seismogenic_depth / dip_tan
        hdist_bottom = lower_seismogenic_depth / dip_tan

        strike = fault_trace[0].azimuth(fault_trace[-1])
        azimuth = (strike + 90.0) % 360

        # collect coordinates of vertices in both top and bottom edges
        lons = []
        lats = []
        for point in fault_trace.points:
            top_edge_point = point.point_at(hdist_top, 0, azimuth)
            bottom_edge_point = point.point_at(hdist_bottom, 0, azimuth)
            lons.append(top_edge_point.longitude)
            lats.append(top_edge_point.latitude)
            lons.append(bottom_edge_point.longitude)
            lats.append(bottom_edge_point.latitude)

        lons = numpy.array(lons, float)
        lats = numpy.array(lats, float)
        return Mesh(lons, lats, depths=None).get_convex_hull()
Exemple #13
0
 def _make_mesh(self, lons, lats, depths=None):
     mesh = Mesh(lons, lats, depths)
     self.assertIs(mesh.lons, lons)
     self.assertIs(mesh.lats, lats)
     self.assertIs(mesh.depths, depths)
     return mesh
Exemple #14
0
 def test_zeroes(self):
     mesh = Mesh(numpy.zeros(1000), numpy.zeros(1000), None)
     matrix = mesh.get_distance_matrix()
     self.assertIsInstance(matrix, numpy.matrix)
     self.assertEqual(matrix.shape, (1000, 1000))
     self.assertTrue((matrix == 0).all())