def get_rupture_enclosing_polygon(self, dilation=0):
        """
        Uses :meth:
        `openquake.hazardlib.geo.surface.base.BaseSurface.get_bounding_box()`
        and from bounding box coordinates create
        :class:`openquake.hazardlib.geo.mesh.RectangularMesh` and then calls
        :meth:`openquake.hazardlib.geo.mesh.Mesh.get_convex_hull()` to get a
        polygon representation of the bounding box. Note that this is needed
        to cope with the situation of a vertical rupture for which the bounding
        box collapses to a line. In this case the method ``get_convex_hull()``
        returns a valid polygon obtained by expanding the line by a small
        distance. Finally, a polygon is returned by calling
        :meth:`~openquake.hazardlib.geo.polygon.Polygon.dilate` passing in the
        ``dilation`` parameter.

        See :meth:`superclass method
        <openquake.hazardlib.source.base.BaseSeismicSource.get_rupture_enclosing_polygon>`
        for parameter and return value definition.
        """
        west, east, north, south = self.surface.get_bounding_box()
        mesh = RectangularMesh(numpy.array([[west, east], [west, east]]),
                               numpy.array([[north, north], [south, south]]),
                               None)
        poly = mesh.get_convex_hull()

        return poly.dilate(dilation)
Example #2
0
    def test_simple(self):
        lons = numpy.array([numpy.arange(-1, 1.2, 0.2)] * 11)
        lats = lons.transpose() + 1
        depths = lats + 10
        mesh = RectangularMesh(lons, lats, depths)

        check = lambda lon, lat, depth, expected_distance, **kwargs: \
            self.assertAlmostEqual(
                mesh.get_joyner_boore_distance(
                    Mesh.from_points_list([Point(lon, lat, depth)])
                )[0],
                expected_distance, **kwargs
            )

        check(lon=0, lat=0.5, depth=0, expected_distance=0)
        check(lon=1, lat=1, depth=0, expected_distance=0)
        check(lon=0.6, lat=-1, depth=0,
              expected_distance=Point(0.6, -1).distance(Point(0.6, 0)),
              delta=0.1)
        check(lon=-0.8, lat=2.1, depth=10,
              expected_distance=Point(-0.8, 2.1).distance(Point(-0.8, 2)),
              delta=0.02)
        check(lon=0.75, lat=2.3, depth=3,
              expected_distance=Point(0.75, 2.3).distance(Point(0.75, 2)),
              delta=0.04)
Example #3
0
 def test_even_rows_even_columns_with_depths(self):
     lons = numpy.array([[10, 20], [12, 22]])
     lats = numpy.array([[10, -10], [8, -9]])
     depths = numpy.array([[2, 3], [4, 5]])
     mesh = RectangularMesh(lons, lats, depths=depths)
     self.assertEqual(mesh.get_middle_point(),
                      Point(15.996712, -0.250993, 3.5))
    def get_middle_point(self):
        lons = numpy.array([self.corners_lons.take([0, 1]), self.corners_lons.take([3, 2])])
        lats = numpy.array([self.corners_lats.take([0, 1]), self.corners_lats.take([3, 2])])
        depths = numpy.array([self.corners_depths.take([0, 1]), self.corners_depths.take([3, 2])])
        mesh = RectangularMesh(lons, lats, depths)

        middle_point = mesh.get_middle_point()

        return (middle_point.longitude, middle_point.latitude, middle_point.depth)
Example #5
0
 def test_mesh_of_two_points(self):
     lons = numpy.array([[0, 0.5, 1]], float)
     lats = numpy.array([[0, 0, 0]], float)
     depths = numpy.array([[1, 0, 1]], float)
     mesh = RectangularMesh(lons, lats, depths)
     target_mesh = Mesh.from_points_list([Point(0.5, 1), Point(0.5, 0)])
     dists = mesh.get_joyner_boore_distance(target_mesh)
     expected_dists = [Point(0.5, 1).distance(Point(0.5, 0)), 0]
     numpy.testing.assert_almost_equal(dists, expected_dists)
Example #6
0
 def _test(self, lons, lats, depths, expected_coords):
     mesh = RectangularMesh(lons, lats, depths)
     proj, polygon = mesh._get_proj_enclosing_polygon()
     self.assertTrue(polygon.is_valid)
     self.assertEqual(list(polygon.interiors), [])
     coords = numpy.array(proj(*numpy.array(polygon.exterior).transpose(),
                               reverse=True)).transpose()
     numpy.testing.assert_almost_equal(coords, expected_coords, decimal=4)
     return polygon
Example #7
0
 def test_mesh_of_one_point(self):
     lons = numpy.array([[1.]])
     lats = numpy.array([[0.]])
     depths = numpy.array([[1.]])
     mesh = RectangularMesh(lons, lats, depths)
     target_mesh = Mesh.from_points_list([Point(1, 0), Point(0.5, 0)])
     dists = mesh.get_joyner_boore_distance(target_mesh)
     expected_dists = [0, Point(0.5, 0).distance(Point(1, 0))]
     self.assertTrue(numpy.allclose(dists, expected_dists, atol=0.2))
Example #8
0
 def _test(self, points, site, expected_distance):
     lons, lats, depths = numpy.array(points).transpose()
     lons = lons.transpose()
     lats = lats.transpose()
     depths = depths.transpose()
     mesh = RectangularMesh(lons, lats, depths)
     distance = mesh.get_joyner_boore_distance(
         Mesh.from_points_list([Point(*site)])
     )[0]
     self.assertAlmostEqual(distance, expected_distance, delta=0.02)
Example #9
0
 def test_vertical_mesh(self):
     lons = numpy.array([[0, 0.5, 1, 2], [0, 0.5, 1, 2]], float)
     lats = numpy.array([[0, 0, 0, 0], [0, 0, 0, 0]], float)
     depths = numpy.array([[1, 1, 1, 1], [2, 2, 2, 2]], float)
     mesh = RectangularMesh(lons, lats, depths)
     target_mesh = Mesh.from_points_list([Point(0.5, 0), Point(0.5, 1),
                                          Point(0.5, 5)])
     dists = mesh.get_joyner_boore_distance(target_mesh)
     expected_dists = [
         0, Point(0.5, 1).distance(Point(0.5, 0)),
         Point(0.5, 5).distance(Point(0.5, 0))]
     aac(dists, expected_dists, atol=1)
Example #10
0
 def test_mesh_width(self):
     lons = numpy.array([[0.1, 0.1, 0.1, 0.1],
                         [0.1, 0.1, 0.1, 0.1],
                         [0.1, 0.1, 0.1, 0.1]])
     lats = numpy.array([[0.1, 0.10899322, 0.11798643, 0.12697965],
                         [0.1, 0.10899322, 0.11798643, 0.12697965],
                         [0.1, 0.10899322, 0.11798643, 0.12697965]])
     depths = numpy.array([[2.0, 2.0, 2.0, 2.0],
                           [3.0, 3.0, 3.0, 3.0],
                           [4.0, 4.0, 4.0, 4.0]])
     mesh = RectangularMesh(lons, lats, depths)
     self.assertAlmostEqual(mesh.get_mean_width(), 2.0)
Example #11
0
 def _test(self, points, centroids, lengths, widths, areas):
     fake_coords = numpy.array([[0]])
     self.points = numpy.array(points, dtype=float)
     mesh = RectangularMesh(fake_coords, fake_coords, fake_coords)
     cell_center, cell_length, cell_width, cell_area \
             = mesh.get_cell_dimensions()
     self.assertTrue(numpy.allclose(cell_length, lengths),
                     '%s != %s' % (cell_length, lengths))
     self.assertTrue(numpy.allclose(cell_width, widths),
                     '%s != %s' % (cell_width, widths))
     self.assertTrue(numpy.allclose(cell_area, areas),
                     '%s != %s' % (cell_area, areas))
     self.assertTrue(numpy.allclose(cell_center, centroids),
                     '%s != %s' % (cell_center, centroids))
Example #12
0
 def test_version(self):
     # this test is sensitive to different versions of shapely/libgeos
     lons = numpy.array(
         [[-121.3956, -121.41050474, -121.42542273, -121.44035399,
           -121.45529855, -121.47025643],
          [-121.3956, -121.41050474, -121.42542273, -121.44035399,
           -121.45529855, -121.47025643]])
     lats = numpy.array(
         [[36.8257, 36.85963772, 36.89357357, 36.92750756,
           36.96143968, 36.99536993],
          [36.8257, 36.85963772, 36.89357357, 36.92750756,
           36.96143968,  36.99536993]])
     mesh = RectangularMesh(lons, lats)
     dist = mesh.get_joyner_boore_distance(
         Mesh.from_points_list([Point(-121.76, 37.23)]))
     dist_ubuntu_12_04 = 36.61260128
     dist_ubuntu_14_04 = 36.61389245
     self.assertTrue(numpy.allclose(dist, dist_ubuntu_12_04) or
                     numpy.allclose(dist, dist_ubuntu_14_04))
Example #13
0
    def test_dip_over_90_degree(self):
        top = [Point(0, -0.01), Point(0, 0.01)]
        bottom = [Point(-0.01, -0.01, 1.11), Point(-0.01, 0.01, 1.11)]

        mesh = RectangularMesh.from_points_list([top, bottom])
        dip, strike = mesh.get_mean_inclination_and_azimuth()
        # dip must be still in a range 0..90
        self.assertAlmostEqual(dip, 45, delta=0.05)
        # strike must be reversed
        self.assertAlmostEqual(strike, 180, delta=0.05)
    def from_fault_data(cls, fault_trace, upper_seismogenic_depth,
                        lower_seismogenic_depth, dip, mesh_spacing):
        """
        Create and return a fault surface using fault source data.

        :param openquake.hazardlib.geo.line.Line fault_trace:
            Geographical line representing the intersection between
            the fault surface and the earth surface.
        :param upper_seismo_depth:
            Minimum depth ruptures can reach, in km (i.e. depth
            to fault's top edge).
        :param lower_seismo_depth:
            Maximum depth ruptures can reach, in km (i.e. depth
            to fault's bottom edge).
        :param dip:
            Dip angle (i.e. angle between fault surface
            and earth surface), in degrees.
        :param mesh_spacing:
            Distance between two subsequent points in a mesh, in km.
        :returns:
            An instance of :class:`SimpleFaultSurface` created using that data.

        Uses :meth:`check_fault_data` for checking parameters.
        """
        cls.check_fault_data(fault_trace, upper_seismogenic_depth,
                             lower_seismogenic_depth, dip, mesh_spacing)
        # Loops over points in the top edge, for each point
        # on the top edge compute corresponding point on the bottom edge, then
        # computes equally spaced points between top and bottom points.

        vdist_top = upper_seismogenic_depth
        vdist_bottom = lower_seismogenic_depth

        hdist_top = vdist_top / math.tan(math.radians(dip))
        hdist_bottom = vdist_bottom / math.tan(math.radians(dip))

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

        mesh = []
        for point in fault_trace.resample(mesh_spacing):
            top = point.point_at(hdist_top, vdist_top, azimuth)
            bottom = point.point_at(hdist_bottom, vdist_bottom, azimuth)
            mesh.append(top.equally_spaced_points(bottom, mesh_spacing))

        # number of rows corresponds to number of points along dip
        # number of columns corresponds to number of points along strike
        surface_points = numpy.array(mesh).transpose().tolist()
        mesh = RectangularMesh.from_points_list(surface_points)
        assert 1 not in mesh.shape, (
            "Mesh must have at least 2 nodes along both length and width."
            " Possible cause: Mesh spacing could be too large with respect to"
            " the fault length and width."
        )
        return cls(mesh)
Example #15
0
 def test_simple(self):
     lons = numpy.array([[0, 0.0089946277931563321],
                         [0, 0.0089974527390248322]])
     lats = numpy.array([[0, 0], [0, 0]], dtype=float)
     depths = numpy.array([[1, 0.99992150706475513],
                           [3, 2.9999214824129012]])
     mesh = RectangularMesh(lons, lats, depths)
     points, along_azimuth, updip, diag = mesh.triangulate()
     self.assertTrue(numpy.allclose(points, [
         [(6370, 0, 0), (6370, 1, 0)],
         [(6368, 0, 0), (6368, 1, 0)]
     ]))
     self.assertTrue(numpy.allclose(along_azimuth, [
         [(0, 1, 0)], [(0, 1, 0)]
     ]))
     self.assertTrue(numpy.allclose(updip, [
         [(2, 0, 0)], [(2, 0, 0)],
     ]))
     self.assertTrue(numpy.allclose(diag, [
         [(2, 1, 0)]
     ]))
Example #16
0
    def from_points_list(cls, points):
        """
        Create a gridded surface from a list of points.

        :parameter points:
            A list of :class:`~openquake.hazardlib.geo.Point`
        :returns:
            An instance of
            :class:`~openquake.hazardlib.geo.surface.gridded.GriddedSurface`
        """

        return cls(RectangularMesh.from_points_list([points]))
Example #17
0
    def test_one_cell(self):
        top = [Point(0, -0.01), Point(0, 0.01)]
        bottom = [Point(0.01, -0.01, 1.11), Point(0.01, 0.01, 1.11)]

        mesh = RectangularMesh.from_points_list([top, bottom])
        dip, strike = mesh.get_mean_inclination_and_azimuth()
        self.assertAlmostEqual(dip, 45, delta=0.05)
        self.assertAlmostEqual(strike, 0, delta=0.05)

        row1 = [Point(45, -0.1), Point(45.2, 0.1)]
        row2 = [Point(45, -0.1, 1), Point(45.2, 0.1, 1)]
        mesh = RectangularMesh.from_points_list([row1, row2])
        dip, strike = mesh.get_mean_inclination_and_azimuth()
        self.assertAlmostEqual(dip, 90)
        self.assertAlmostEqual(strike, 45, delta=0.1)

        row1 = [Point(90, -0.1), Point(90, 0.1)]
        row2 = [Point(90, -0.1, 1), Point(90, 0.1, 1)]
        mesh = RectangularMesh.from_points_list([row1, row2])
        dip, strike = mesh.get_mean_inclination_and_azimuth()
        self.assertAlmostEqual(dip, 90)
        self.assertAlmostEqual(strike, 0, delta=0.1)
Example #18
0
    def get_rupture_enclosing_polygon(self, dilation=0):
        """
        Create instance of
        :class:`openquake.hazardlib.geo.surface.multi.MultiSurface` from all
        ruptures' surfaces and compute its bounding box. Calculate convex hull
        of bounding box, and return it dilated by ``dilation``.

        :param dilation:
            A buffer distance in km to extend the polygon borders to.
        :returns:
            Instance of :class:`openquake.hazardlib.geo.polygon.Polygon`.
        """
        surfaces = [rup.surface for (rup, _) in self.data]
        multi_surf = MultiSurface(surfaces)

        west, east, north, south = multi_surf.get_bounding_box()
        mesh = RectangularMesh(numpy.array([[west, east], [west, east]]),
                               numpy.array([[north, north], [south, south]]),
                               None)
        poly = mesh.get_convex_hull()

        return poly if dilation == 0 else poly.dilate(dilation)
Example #19
0
    def test_from_points_list(self):
        lons = [[0, 1], [2, 3], [4, 5]]
        lats = [[1, 2], [-1, -2], [10, 20]]
        depths = [[11.1, 11.2], [11.3, 11.4], [11.5, 11.6]]
        points = [
            [Point(lons[i][j], lats[i][j], depths[i][j])
             for j in range(len(lons[i]))]
            for i in range(len(lons))
        ]
        mesh = RectangularMesh.from_points_list(points)
        self.assertTrue((mesh.lons == lons).all())
        self.assertTrue((mesh.lats == lats).all())
        self.assertTrue((mesh.depths == depths).all())

        points = [
            [Point(lons[i][j], lats[i][j], depth=0)
             for j in range(len(lons[i]))]
            for i in range(len(lons))
        ]
        mesh = RectangularMesh.from_points_list(points)
        self.assertTrue((mesh.lons == lons).all())
        self.assertTrue((mesh.lats == lats).all())
        self.assertIsNone(mesh.depths)
Example #20
0
    def test_one_cell_unequal_area(self):
        # top-left triangle is vertical, has dip of 90 degrees, zero
        # strike and area of 1 by 1 over 2. bottom-right one has dip
        # of atan2(1, sqrt(2) / 2.0) which is 54.73561 degrees, strike
        # of 45 degrees and area that is 1.73246136 times area of the
        # first one's. weighted mean dip is 67.5 degrees and weighted
        # mean strike is 28.84 degrees
        top = [Point(0, -0.01), Point(0, 0.01)]
        bottom = [Point(0, -0.01, 2.22), Point(0.02, 0.01, 2.22)]

        mesh = RectangularMesh.from_points_list([top, bottom])
        dip, strike = mesh.get_mean_inclination_and_azimuth()
        self.assertAlmostEqual(dip, 67.5, delta=0.05)
        self.assertAlmostEqual(strike, 28.84, delta=0.05)
Example #21
0
    def from_fault_data(cls, edges, mesh_spacing):
        """
        Create and return a fault surface using fault source data.

        :param edges:
            A list of at least two horizontal edges of the surface
            as instances of :class:`openquake.hazardlib.geo.line.Line`. The
            list should be in top-to-bottom order (the shallowest edge first).
        :param mesh_spacing:
            Distance between two subsequent points in a mesh, in km.
        :returns:
            An instance of :class:`ComplexFaultSurface` created using
            that data.
        :raises ValueError:
            If requested mesh spacing is too big for the surface geometry
            (doesn't allow to put a single mesh cell along length and/or
            width).

        Uses :meth:`check_fault_data` for checking parameters.
        """
        cls.check_fault_data(edges, mesh_spacing)
        surface_nodes = [complex_fault_node(edges)]
        mean_length = numpy.mean([edge.get_length() for edge in edges])
        num_hor_points = int(round(mean_length / mesh_spacing)) + 1
        if num_hor_points <= 1:
            raise ValueError(
                'mesh spacing %.1f km is too big for mean length %.1f km' %
                (mesh_spacing, mean_length)
            )
        edges = [edge.resample_to_num_points(num_hor_points).points
                 for i, edge in enumerate(edges)]

        vert_edges = [Line(v_edge) for v_edge in zip(*edges)]
        mean_width = numpy.mean([v_edge.get_length() for v_edge in vert_edges])
        num_vert_points = int(round(mean_width / mesh_spacing)) + 1
        if num_vert_points <= 1:
            raise ValueError(
                'mesh spacing %.1f km is too big for mean width %.1f km' %
                (mesh_spacing, mean_width)
            )

        points = zip(*[v_edge.resample_to_num_points(num_vert_points).points
                       for v_edge in vert_edges])
        mesh = RectangularMesh.from_points_list(list(points))
        assert 1 not in mesh.shape
        self = cls(mesh)
        self.surface_nodes = surface_nodes
        return self
Example #22
0
    def test_two_cells(self):
        top = [Point(0, -0.01), Point(0, 0.01)]
        middle = [Point(0.01, -0.01, 1.11), Point(0.01, 0.01, 1.11)]
        bottom = [Point(0.01, -0.01, 2.22), Point(0.01, 0.01, 2.22)]

        mesh = RectangularMesh.from_points_list([top, middle, bottom])
        dip, strike = mesh.get_mean_inclination_and_azimuth()
        self.assertAlmostEqual(dip, math.degrees(math.atan2(2, 1)), delta=0.1)
        self.assertAlmostEqual(strike, 0, delta=0.02)

        bottom = [Point(0.01, -0.01, 3.33), Point(0.01, 0.01, 3.33)]
        mesh = RectangularMesh.from_points_list([top, middle, bottom])
        dip, strike = mesh.get_mean_inclination_and_azimuth()
        self.assertAlmostEqual(dip, math.degrees(math.atan2(3, 1)), delta=0.1)
        self.assertAlmostEqual(strike, 0, delta=0.02)

        row1 = [Point(90, -0.1), Point(90, 0), Point(90, 0.1)]
        row2 = [Point(90, -0.1, 1), Point(90, 0, 1), Point(90, 0.1, 1)]
        mesh = RectangularMesh.from_points_list([row1, row2])
        dip, strike = mesh.get_mean_inclination_and_azimuth()
        self.assertAlmostEqual(dip, 90)
        assert_angles_equal(self, strike, 360, delta=1e-7)

        row1 = [Point(-90.1, -0.1), Point(-90, 0), Point(-89.9, 0.1)]
        row2 = [Point(-90.0, -0.1, 1), Point(-89.9, 0, 1),
                Point(-89.8, 0.1, 1)]
        mesh = RectangularMesh.from_points_list([row1, row2])
        dip, strike = mesh.get_mean_inclination_and_azimuth()
        self.assertAlmostEqual(strike, 45, delta=1e-4)

        row1 = [Point(-90.1, -0.1), Point(-90, 0), Point(-89.9, 0.1)]
        row2 = [Point(-90.0, -0.1, 1), Point(-89.9, 0, 1),
                Point(-89.8, 0.1, 1)]
        mesh = RectangularMesh.from_points_list([row1, row2])
        dip, strike = mesh.get_mean_inclination_and_azimuth()
        self.assertAlmostEqual(strike, 45, delta=1e-3)

        row1 = [Point(-90.1, -0.1), Point(-90, 0), Point(-89.9, 0.1)]
        row2 = [Point(-90.2, -0.1, 1), Point(-90.1, 0, 1), Point(-90, 0.1, 1)]
        mesh = RectangularMesh.from_points_list([row1, row2])
        dip, strike = mesh.get_mean_inclination_and_azimuth()
        self.assertAlmostEqual(strike, 225, delta=1e-3)
Example #23
0
    def test_on_surface(self):
        row1 = [Point(0, 0), Point(0, 1)]
        row2 = [Point(1, 0), Point(1, 1)]
        mesh = RectangularMesh.from_points_list([row1, row2])
        dip, strike = mesh.get_mean_inclination_and_azimuth()
        self.assertEqual(dip, 0)
        self.assertAlmostEqual(strike, 0, delta=0.5)

        row1 = [Point(0, 0), Point(0, -1)]
        row2 = [Point(1, 0), Point(1, -1)]
        mesh = RectangularMesh.from_points_list([row1, row2])
        dip, strike = mesh.get_mean_inclination_and_azimuth()
        self.assertEqual(dip, 0)
        self.assertAlmostEqual(strike, 180, delta=0.5)

        row1 = [Point(0, 0), Point(1, 1)]
        row2 = [Point(1, 0), Point(2, 1)]
        mesh = RectangularMesh.from_points_list([row1, row2])
        dip, strike = mesh.get_mean_inclination_and_azimuth()
        self.assertEqual(dip, 0)
        self.assertAlmostEqual(strike, 45, delta=0.01)

        row1 = [Point(0, 0), Point(1, -1)]
        row2 = [Point(1, 0), Point(2, -1)]
        mesh = RectangularMesh.from_points_list([row1, row2])
        dip, strike = mesh.get_mean_inclination_and_azimuth()
        self.assertEqual(dip, 0)
        self.assertAlmostEqual(strike, 135, delta=0.01)

        row1 = [Point(0, 0), Point(-1, -1)]
        row2 = [Point(-1, 0), Point(-2, -1)]
        mesh = RectangularMesh.from_points_list([row1, row2])
        dip, strike = mesh.get_mean_inclination_and_azimuth()
        self.assertEqual(dip, 0)
        self.assertAlmostEqual(strike, 225, delta=0.01)

        row1 = [Point(0, 0), Point(-1, 1)]
        row2 = [Point(-1, 0), Point(-2, 1)]
        mesh = RectangularMesh.from_points_list([row1, row2])
        dip, strike = mesh.get_mean_inclination_and_azimuth()
        self.assertEqual(dip, 0)
        self.assertAlmostEqual(strike, 315, delta=0.01)
Example #24
0
 def test_invalid_mesh(self):
     lons = numpy.array([[0.1]])
     lats = numpy.array([[0.1]])
     depths = numpy.array([[2.0]])
     mesh = RectangularMesh(lons, lats, depths)
     self.assertRaises(AssertionError, mesh.get_mean_width)
Example #25
0
 def test_even_rows_even_columns_no_depths(self):
     lons = numpy.array([[10, 20], [10.002, 20.002]])
     lats = numpy.array([[10, -10], [8, -8]])
     mesh = RectangularMesh(lons, lats, depths=None)
     self.assertEqual(mesh.get_middle_point(), Point(15.001, 0))
Example #26
0
 def test_even_rows_odd_columns_no_depths(self):
     lons = numpy.array([[-1, 0, 1, 2, 3], [-1.5, 0.5, 1.5, 2.5, 3.5]])
     lats = numpy.array([[-0.01] * 5, [-0.015] * 5])
     mesh = RectangularMesh(lons, lats, depths=None)
     self.assertEqual(mesh.get_middle_point(), Point(1.25, -0.0125, 0))
Example #27
0
    def get_cdppvalue(self, target, buf=1.0, delta=0.01, space=2.):
        """
        Get the directivity prediction value, centred DPP(cdpp) at
        a given site as described in Spudich et al. (2013), and this cdpp is
        used in Chiou and Young(2014) GMPE for near-fault directivity
        term prediction.

        :param target_site:
            A mesh object representing the location of the target sites.
        :param buf:
            A float vaule presents  the buffer distance in km to extend the
            mesh borders to.
        :param delta:
            A float vaule presents the desired distance between two adjacent
            points in mesh
        :param space:
            A float vaule presents the tolerance for the same distance of the
            sites (default 2 km)
        :returns:
            A float value presents the centreed directivity predication value
            which used in Chioud and Young(2014) GMPE for directivity term
        """

        min_lon, max_lon, max_lat, min_lat = self.surface.get_bounding_box()

        min_lon -= buf
        max_lon += buf
        min_lat -= buf
        max_lat += buf

        lons = numpy.arange(min_lon, max_lon + delta, delta)
        lats = numpy.arange(min_lat, max_lat + delta, delta)
        lons, lats = numpy.meshgrid(lons, lats)

        target_rup = self.surface.get_min_distance(target)
        mesh = RectangularMesh(lons=lons, lats=lats, depths=None)
        mesh_rup = self.surface.get_min_distance(mesh)
        target_lons = target.lons
        target_lats = target.lats
        cdpp = numpy.empty(len(target_lons))

        for iloc, (target_lon,
                   target_lat) in enumerate(zip(target_lons, target_lats)):

            cdpp_sites_lats = mesh.lats[(mesh_rup <= target_rup[iloc] + space)
                                        &
                                        (mesh_rup >= target_rup[iloc] - space)]
            cdpp_sites_lons = mesh.lons[(mesh_rup <= target_rup[iloc] + space)
                                        &
                                        (mesh_rup >= target_rup[iloc] - space)]

            dpp_sum = []
            dpp_target = self.get_dppvalue(Point(target_lon, target_lat))

            for lon, lat in zip(cdpp_sites_lons, cdpp_sites_lats):
                site = Point(lon, lat, 0.)
                dpp_one = self.get_dppvalue(site)
                dpp_sum.append(dpp_one)

            mean_dpp = numpy.mean(dpp_sum)
            cdpp[iloc] = dpp_target - mean_dpp

        return cdpp
Example #28
0
def main(cfg_file):
    startTime = datetime.now()
    cfg = configparser.ConfigParser()
    cfg.read(cfg_file)

    (oq_param, source_model_file, matrixMagsMin, matrixMagsMax,
     matrixMagsStep, matrixDistsMin, matrixDistsMax,
     matrixDistsStep, limitIM, imt_filtering, trunc_level,
     im_filter, gmf_file, gmf_file_gmpe_rate, rup_mesh_spac,
     complex_mesh_spac, mfd_bin, area_discre, limit_max_mag,
            limit_min_mag) = read_config_file(cfg)

    # Set up the source model configuration
    conv1 = SourceConverter(1.0,  # Investigation time
                            rup_mesh_spac,   # Rupture mesh spacing
                            complex_fault_mesh_spacing=complex_mesh_spac,
                            width_of_mfd_bin=mfd_bin,
                            area_source_discretization=area_discre)
    # Parse the source Model
    if source_model_file:  # only one source model file
        source_model = to_python(source_model_file, conv1)
    else:  # source model has many files (in this case 2 - adapt for more)
        source_model_file2 = "demo_data/SA_RA_CATAL1_05.xml"
        source_model2 = to_python(source_model_file2, conv1)
        source_model = source_model+source_model2

    # Calculate total number of ruptures in the erf
    # num_rup = 0
    # rate_rup = []
    # for a in range(len(source_model)):
        # model_trt = source_model[a]
        # for b in range(len(model_trt)):
            # num_rup = num_rup + len(list(model_trt[b].iter_ruptures()))
            # for rup in model_trt[b].iter_ruptures():
                # rate_rup.append(rup.occurrence_rate)
    # print(num_rup)
    # print(sum(rate_rup))
    # print(rate_rup[0:10])
    
    # If exposure model is provided:
    haz_sitecol = get_site_collection(oq_param)
    sites, assets_by_site, _ = get_sitecol_assetcol(oq_param, haz_sitecol)
    # print(list(sites)[0:10])
    # np.savetxt('sites.csv',list(zip(sites.lons, sites.lats)))
    # If region coordinates are provided:
    # sites = get_site_collection(oq_param)

    gsimlt = get_gsim_lt(oq_param)
    gsim_list = [br.uncertainty for br in gsimlt.branches]
    GMPEmatrix = build_gmpe_table(matrixMagsMin, matrixMagsMax, matrixMagsStep,
                                  matrixDistsMin, matrixDistsMax,
                                  matrixDistsStep, imt_filtering, limitIM,
                                  gsim_list, limit_max_mag, limit_min_mag)

    # Calculate minimum distance between rupture and assets
    # Import exposure from .ini file
    depths = np.zeros(len(sites))
    exposureCoords = Mesh(sites.lons, sites.lats, depths)
    # To calculate Joyner Boore distance:
    exposurePoints = (exposureCoords, exposureCoords)
    recMeshExposure = RectangularMesh.from_points_list(exposurePoints)
    imts = ['PGA', 'SA(0.3)']
    cmake = ContextMaker(gsim_list)
    
    filter1 = SourceFilter(sites, oq_param.maximum_distance)

    if im_filter == 'True':  # Here we consider the IM and the MaxDist filter
        gmfs_median = calculate_gmfs_filter(source_model, gsimlt, filter1,
                                            cmake, gsim_list, recMeshExposure,
                                            matrixMagsMin, matrixMagsStep,
                                            matrixDistsMin, matrixDistsStep,
                                            GMPEmatrix, imts, trunc_level)
    else:  # No IM filter, just the MAxDist filter
        gmfs_median = calc_gmfs_no_IM_filter(source_model, imts, gsim_list,
                                             trunc_level, gsimlt,
                                             filter1, cmake)

    print("%s Ground Motion Fields" % len(gmfs_median))

    save_gmfs(gmf_file, gmf_file_gmpe_rate, gmfs_median, exposureCoords,
              gsim_list, imts)
    print(datetime.now() - startTime)
Example #29
0
    def from_fault_data(cls, fault_trace, upper_seismogenic_depth,
                        lower_seismogenic_depth, dip, mesh_spacing):
        """
        Create and return a fault surface using fault source data.

        :param openquake.hazardlib.geo.line.Line fault_trace:
            Geographical line representing the intersection between the fault
            surface and the earth surface. The line must be horizontal (i.e.
            all depth values must be equal). If the depths are not given, they
            are assumed to be zero, meaning the trace intersects the surface at
            sea level, e.g. fault_trace = Line([Point(1, 1), Point(1, 2)]).
        :param upper_seismo_depth:
            Minimum depth ruptures can reach, in km (i.e. depth
            to fault's top edge).
        :param lower_seismo_depth:
            Maximum depth ruptures can reach, in km (i.e. depth
            to fault's bottom edge).
        :param dip:
            Dip angle (i.e. angle between fault surface
            and earth surface), in degrees.
        :param mesh_spacing:
            Distance between two subsequent points in a mesh, in km.
        :returns:
            An instance of :class:`SimpleFaultSurface` created using that data.

        Uses :meth:`check_fault_data` for checking parameters.
        """
        cls.check_fault_data(fault_trace, upper_seismogenic_depth,
                             lower_seismogenic_depth, dip, mesh_spacing)
        # Loops over points in the top edge, for each point
        # on the top edge compute corresponding point on the bottom edge, then
        # computes equally spaced points between top and bottom points.

        vdist_top = upper_seismogenic_depth - fault_trace[0].depth
        vdist_bottom = lower_seismogenic_depth - fault_trace[0].depth

        hdist_top = vdist_top / math.tan(math.radians(dip))
        hdist_bottom = vdist_bottom / math.tan(math.radians(dip))

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

        mesh = []
        for point in fault_trace.resample(mesh_spacing):
            top = point.point_at(hdist_top, vdist_top, azimuth)
            bottom = point.point_at(hdist_bottom, vdist_bottom, azimuth)
            mesh.append(top.equally_spaced_points(bottom, mesh_spacing))

        # number of rows corresponds to number of points along dip
        # number of columns corresponds to number of points along strike
        surface_points = numpy.array(mesh).transpose().tolist()
        mesh = RectangularMesh.from_points_list(surface_points)
        assert 1 not in mesh.shape, (
            "Mesh must have at least 2 nodes along both length and width."
            " Possible cause: Mesh spacing could be too large with respect to"
            " the fault length and width."
        )
        self = cls(mesh)
        self.surface_nodes = [simple_fault_node(
            fault_trace, dip,
            upper_seismogenic_depth, lower_seismogenic_depth)]
        return self
 def __init__(self, coordinates_list):
     points = [[Point(*coordinates) for coordinates in row]
               for row in coordinates_list]
     self.mesh = RectangularMesh.from_points_list(points)
Example #31
0
 def test_preserving_the_type(self):
     lons = lats = numpy.array(range(100)).reshape((10, 10))
     mesh = RectangularMesh(lons, lats, depths=None)
     submesh = mesh[1:2, 3:4]
     self.assertIsInstance(submesh, RectangularMesh)
Example #32
0
 def test_wrong_shape(self):
     with self.assertRaises(AssertionError):
         RectangularMesh(numpy.array([0, 1, 2]),
                         numpy.array([0, 0, 0]), None)
         RectangularMesh(numpy.array([0, -1]), numpy.array([2, 10]),
                         numpy.array([5, 44]))
Example #33
0
 def test_odd_rows_odd_columns_with_depths(self):
     lons = numpy.array([numpy.arange(-1, 1.2, 0.2)] * 11)
     lats = lons.transpose() * 10
     depths = lats + 10
     mesh = RectangularMesh(lons, lats, depths)
     self.assertEqual(mesh.get_middle_point(), Point(0, 0, 10))
Example #34
0
 def test_odd_rows_even_columns_no_depths(self):
     lons = numpy.array([[10, 20, 30, 40]])
     lats = numpy.array([[30] * 4])
     mesh = RectangularMesh(lons, lats, depths=None)
     self.assertEqual(mesh.get_middle_point(), Point(25, 30.094679))
Example #35
0
 def test_even_rows_odd_columns_with_depth(self):
     lons = numpy.array([[20], [21]])
     lats = numpy.array([[-1], [1]])
     depths = numpy.array([[11.1], [11.3]])
     mesh = RectangularMesh(lons, lats, depths=depths)
     self.assertEqual(mesh.get_middle_point(), Point(20.5, 0, 11.2))
Example #36
0
 def test_even_rows_even_columns_no_depths(self):
     lons = numpy.array([[10, 20], [10.002, 20.002]])
     lats = numpy.array([[10, -10], [8, -8]])
     mesh = RectangularMesh(lons, lats, depths=None)
     self.assertEqual(mesh.get_middle_point(), Point(15.001, 0))
Example #37
0
 def test_odd_rows_odd_columns_with_depths(self):
     lons = numpy.array([numpy.arange(-1, 1.2, 0.2)] * 11)
     lats = lons.transpose() * 10
     depths = lats + 10
     mesh = RectangularMesh(lons, lats, depths)
     self.assertEqual(mesh.get_middle_point(), Point(0, 0, 10))
Example #38
0
 def test_odd_rows_even_columns_no_depths(self):
     lons = numpy.array([[10, 20, 30, 40]])
     lats = numpy.array([[30] * 4])
     mesh = RectangularMesh(lons, lats, depths=None)
     self.assertEqual(mesh.get_middle_point(), Point(25, 30.094679))
Example #39
0
 def test_odd_rows_even_columns_with_depths(self):
     lons = numpy.array([[0, 20, 30, 90]])
     lats = numpy.array([[30] * 4])
     depths = numpy.array([[2, 7, 8, 10]])
     mesh = RectangularMesh(lons, lats, depths=depths)
     self.assertEqual(mesh.get_middle_point(), Point(25, 30.094679, 7.5))
 def _create_mesh(self):
     points = [[Point(*coordinates) for coordinates in row]
               for row in self.coordinates_list]
     return RectangularMesh.from_points_list(points)
Example #41
0
 def test_even_rows_odd_columns_no_depths(self):
     lons = numpy.array([[-1, 0, 1, 2, 3], [-1.5, 0.5, 1.5, 2.5, 3.5]])
     lats = numpy.array([[-0.01] * 5, [-0.015] * 5])
     mesh = RectangularMesh(lons, lats, depths=None)
     self.assertEqual(mesh.get_middle_point(), Point(1.25, -0.0125, 0))
Example #42
0
    def from_profiles(cls,
                      profiles,
                      profile_sd,
                      edge_sd,
                      idl=False,
                      align=False):
        # TODO split this function into smaller components.
        """
        This method creates a quadrilateral mesh from a set of profiles. The
        construction of the mesh is done trying to get quadrilaterals as much
        as possible close to a square. Nonetheless some distorsions are
        possible and admitted.

        :param list profiles:
            A list of :class:`openquake.hazardlib.geo.Line.line` instances
        :param float profile_sd:
            The desired sampling distance along the profiles [dd] CHECK
        :param edge_sd:
            The desired sampling distance along the edges [dd] CHECK
        :param idl:
            Boolean true if IDL
        :param align:
            A boolean used to decide if profiles should or should not be
            aligned at the top.
        :returns:
            A :class:`numpy.ndarray` instance with the coordinates of nodes
            of the mesh representing the fault surface. The cardinality of
            this array is: number of edges x number of profiles x 3.
            The coordinate of the point at [0, 0, :] is first point along the
            trace defined using the right-hand rule.

                        [0, 0, :]            [0, -1, :]
            Upper edge  |--------------------|
                        |         V          | Fault dipping toward the
                        |                    | observer
            Lower edge  |____________________|

        """
        # Resample profiles using the resampling distance provided
        rprofiles = []
        for prf in profiles:
            rprofiles.append(_resample_profile(prf, profile_sd))

        # Set the reference profile i.e. the longest one
        ref_idx = None
        max_length = -1e10
        for idx, prf in enumerate(rprofiles):
            length = prf.get_length()
            if length > max_length:
                max_length = length
                ref_idx = idx

        # Check that in each profile the points are equally spaced
        for pro in rprofiles:
            pnts = [(p.longitude, p.latitude, p.depth) for p in pro.points]
            pnts = np.array(pnts)

            # Check that the profile is not crossing the IDL and compute the
            # distance between consecutive points along the profile
            assert np.all(pnts[:, 0] <= 180) & np.all(pnts[:, 0] >= -180)
            dst = distance(pnts[:-1, 0], pnts[:-1, 1], pnts[:-1, 2],
                           pnts[1:, 0], pnts[1:, 1], pnts[1:, 2])

            # Check that all the distances are within a tolerance
            np.testing.assert_allclose(dst, profile_sd, rtol=1.)

        # Find the delta needed to align profiles if requested
        shift = np.zeros(len(rprofiles) - 1)
        if align is True:
            for i in range(0, len(rprofiles) - 1):
                shift[i] = profiles_depth_alignment(rprofiles[i],
                                                    rprofiles[i + 1])
        shift = np.array([0] + list(shift))

        # Find the maximum back-shift
        ccsum = [shift[0]]
        for i in range(1, len(shift)):
            ccsum.append(shift[i] + ccsum[i - 1])
        add = ccsum - min(ccsum)

        # Create resampled profiles. Now the profiles should be all aligned
        # from the top (if align option is True)
        rprof = []
        maxnum = 0
        for i, pro in enumerate(rprofiles):
            j = int(add[i])
            coo = get_coords(pro, idl)
            tmp = [[np.nan, np.nan, np.nan] for a in range(0, j)]
            if len(tmp) > 0:
                points = tmp + coo
            else:
                points = coo
            rprof.append(points)
            maxnum = max(maxnum, len(rprof[-1]))

        # Now profiles will have the same number of samples (some of them can
        # be nan). This is needed to have an array to store the surface.
        for i, pro in enumerate(rprof):
            while len(pro) < maxnum:
                pro.append([np.nan, np.nan, np.nan])
            rprof[i] = np.array(pro)

        # Create mesh the in the forward direction
        prfr = get_mesh(rprof, ref_idx, edge_sd, idl)

        # Create the mesh in the backward direction
        if ref_idx > 0:
            prfl = get_mesh_back(rprof, ref_idx, edge_sd, idl)
        else:
            prfl = []
        prf = prfl + prfr
        msh = np.array(prf)

        # Convert from profiles to edges
        msh = msh.swapaxes(0, 1)
        msh = fix_mesh(msh)
        return cls(RectangularMesh(msh[:, :, 0], msh[:, :, 1], msh[:, :, 2]),
                   profiles)
Example #43
0
 def test_even_rows_odd_columns_with_depth(self):
     lons = numpy.array([[20], [21]])
     lats = numpy.array([[-1], [1]])
     depths = numpy.array([[11.1], [11.3]])
     mesh = RectangularMesh(lons, lats, depths=depths)
     self.assertEqual(mesh.get_middle_point(), Point(20.5, 0, 11.2))
Example #44
0
 def get_middle_point(self):
     mesh = RectangularMesh(self.lons, self.lats, self.depths)
     middle_point = mesh.get_middle_point()
     return (middle_point.longitude, middle_point.latitude,
             middle_point.depth)
Example #45
0
 def test_odd_rows_even_columns_with_depths(self):
     lons = numpy.array([[0, 20, 30, 90]])
     lats = numpy.array([[30] * 4])
     depths = numpy.array([[2, 7, 8, 10]])
     mesh = RectangularMesh(lons, lats, depths=depths)
     self.assertEqual(mesh.get_middle_point(), Point(25, 30.094679, 7.5))