예제 #1
0
    def get_rx_distance(self, mesh):
        """
        See :meth:`superclass method
        <.base.BaseSurface.get_rx_distance>`
        for spec of input and result values.

        The method extracts the top edge of the surface. For each point in mesh,
        it then computes the Rx distance to each segment the top edge is made
        of. The calculation is done by calling the function
        :func:`openquake.hazardlib.geo.geodetic.distance_to_arc`. The final Rx
        distance matrix is then constructed by taking, for each point in mesh,
        the minimum Rx distance value computed.
        """
        top_edge = self.get_mesh()[0:1]

        dists = []
        for i in range(top_edge.lons.shape[1] - 1):
            p1 = Point(
                top_edge.lons[0, i], top_edge.lats[0, i], top_edge.depths[0, i]
            )
            p2 = Point(
                top_edge.lons[0, i + 1], top_edge.lats[0, i + 1],
                top_edge.depths[0, i + 1]
            )
            azimuth = p1.azimuth(p2)
            dists.append(
                geodetic.distance_to_arc(
                    p1.longitude, p1.latitude, azimuth, mesh.lons, mesh.lats
                )
            )
        dists = numpy.array(dists)

        return numpy.min(dists, axis=0)
예제 #2
0
    def iter_ruptures(self):
        """
        See :meth:`openquake.hazardlib.source.base.BaseSeismicSource.iter_ruptures`
        for description of parameters and return value.

        Area sources are treated as a collection of point sources
        (see :mod:`openquake.hazardlib.source.point`) with uniform parameters.
        Ruptures of area source are just a union of ruptures
        of those point sources. The actual positions of the implied
        point sources form a uniformly spaced mesh on the polygon.
        Polygon's method :meth:
        `~openquake.hazardlib.geo.polygon.Polygon.discretize`
        is used for creating a mesh of points on the source's area.
        Constructor's parameter ``area_discretization`` is used as
        polygon's discretization spacing (not to be confused with
        rupture surface's mesh spacing which is as well provided
        to the constructor).

        The ruptures' occurrence rates are rescaled with respect to number
        of points the polygon discretizes to.
        """
        polygon_mesh = self.polygon.discretize(self.area_discretization)
        rate_scaling_factor = 1.0 / len(polygon_mesh)

        # take the very first point of the polygon mesh
        [epicenter0] = polygon_mesh[0:1]
        # generate "reference ruptures" -- all the ruptures that have the same
        # epicenter location (first point of the polygon's mesh) but different
        # magnitudes, nodal planes, hypocenters' depths and occurrence rates
        ref_ruptures = []
        for (mag, mag_occ_rate) in self.get_annual_occurrence_rates():
            for (np_prob, np) in self.nodal_plane_distribution.data:
                for (hc_prob, hc_depth) in self.hypocenter_distribution.data:
                    hypocenter = Point(latitude=epicenter0.latitude,
                                       longitude=epicenter0.longitude,
                                       depth=hc_depth)
                    occurrence_rate = (mag_occ_rate
                                       * float(np_prob) * float(hc_prob))
                    occurrence_rate *= rate_scaling_factor
                    surface = self._get_rupture_surface(mag, np, hypocenter)
                    ref_ruptures.append((mag, np.rake, hc_depth,
                                         surface, occurrence_rate))

        # for each of the epicenter positions generate as many ruptures
        # as we generated "reference" ones: new ruptures differ only
        # in hypocenter and surface location
        for epicenter in polygon_mesh:
            for mag, rake, hc_depth, surface, occ_rate in ref_ruptures:
                # translate the surface from first epicenter position
                # to the target one preserving it's geometry
                surface = surface.translate(epicenter0, epicenter)
                hypocenter = deepcopy(epicenter)
                hypocenter.depth = hc_depth
                rupture = ParametricProbabilisticRupture(
                    mag, rake, self.tectonic_region_type, hypocenter,
                    surface, type(self), occ_rate,
                    self.temporal_occurrence_model
                )
                yield rupture
예제 #3
0
 def filter_sites_by_distance_to_rupture(cls, rupture, integration_distance, sites):
     """
     Filter sites that are closer than rupture's projection radius
     plus integration distance along the great circle arc from rupture's
     epicenter location. Overrides the :meth:`base class' method
     <openquake.hazardlib.source.base.SeismicSource.filter_sites_by_distance_to_rupture>`.
     """
     rup_length, rup_width = rupture.surface.length, rupture.surface.width
     rup_width = rup_width * math.cos(math.radians(rupture.surface.dip))
     radius = math.sqrt(rup_length ** 2 + rup_width ** 2) / 2.0
     radius += integration_distance
     epicenter = Point(rupture.hypocenter.longitude, rupture.hypocenter.latitude)
     return sites.filter(epicenter.closer_than(sites.mesh, radius))
예제 #4
0
def _rup_to_point(distance, surface, origin, azimuth, distance_type='rjb',
        iter_stop=1E-3, maxiter=1000):
    """
    Place a point at a given distance from a rupture along a specified azimuth
    """
    pt0 = origin
    pt1 = origin.point_at(distance, 0., azimuth)
    #print pt0, pt1
    r_diff = np.inf
    dip = surface.dip
    sin_dip = np.sin(np.radians(dip))
    dist_sin_dip = distance / sin_dip
    #max_surf_dist = surface.width / np.cos(np.radians(dip))
    iterval = 0
    while (np.fabs(r_diff) >= iter_stop) and (iterval <= maxiter):
        pt1mesh = Mesh(np.array([pt1.longitude]),
                       np.array([pt1.latitude]),
                       None)
        if distance_type == 'rjb' or np.fabs(dip - 90.0) < 1.0E-3:
            r_diff =  (distance -
                       surface.get_joyner_boore_distance(pt1mesh)).flatten()
            pt0 = Point(pt1.longitude, pt1.latitude)
            if r_diff > 0.:
                pt1 = pt0.point_at(r_diff, 0., azimuth)
            else:
                pt1 = pt0.point_at(np.fabs(r_diff), 0.,
                                   (azimuth + 180.) % 360.)
        elif distance_type == 'rrup':
            rrup = surface.get_min_distance(pt1mesh).flatten()
            if azimuth >= 0.0 and azimuth <= 180.0:
                # On hanging wall
                r_diff = dist_sin_dip - (rrup / sin_dip)   

            else:
                # On foot wall
                r_diff = distance - rrup 
            pt0 = Point(pt1.longitude, pt1.latitude)
            
            #print azimuth, (azimuth + 180.0) % 360,  rrup, r_diff, np.fabs(r_diff)
            if r_diff > 0.:
                pt1 = pt0.point_at(r_diff, 0., azimuth)
            else:
                pt1 = pt0.point_at(np.fabs(r_diff), 0.,
                                   (azimuth + 180.) % 360.)
            
        else:
            raise ValueError('Distance type must be rrup or rjb!')
        iterval += 1
    return pt1
예제 #5
0
 def test2_sites_parallel_to_fault_ends(self):
     surface = self._test1to7surface()
     sites = Mesh.from_points_list([Point(0.0, 0.05),
                                    Point(-0.10, -0.05)])
     dists = surface.get_ry0_distance(sites)
     numpy.testing.assert_allclose(dists, numpy.array([0.0, 0.0]))
예제 #6
0
    def get_rx_distance(self, mesh):
        """
        Compute distance between each point of mesh and surface's great circle
        arc.

        Distance is measured perpendicular to the rupture strike, from
        the surface projection of the updip edge of the rupture, with
        the down dip direction being positive (this distance is usually
        called ``Rx``).

        In other words, is the horizontal distance to top edge of rupture
        measured perpendicular to the strike. Values on the hanging wall
        are positive, values on the footwall are negative.

        :param mesh:
            :class:`~openquake.hazardlib.geo.mesh.Mesh` of points to calculate
            Rx-distance to.
        :returns:
            Numpy array of distances in km.
        """
        top_edge = self.mesh[0:1]
        dists = []

        ia = 0
        ib = top_edge.lons.shape[1] - 2
        if (self.__class__.__name__ == 'KiteSurface'):
            idxs = numpy.nonzero(numpy.isfinite(top_edge.lons[0, :]))[0]
            ia = min(idxs)
            ib = sorted(idxs)[-2]

        if top_edge.lons.shape[1] < 3:
            i = 0

            if ((self.__class__.__name__ == 'KiteSurface')
                    and (numpy.isnan(top_edge.lons[0, i])
                         or numpy.isnan(top_edge.lons[0, i + 1]))):
                msg = 'Rx calculation. Top of rupture has less than two points'
                raise ValueError(msg)

            p1 = Point(top_edge.lons[0, i], top_edge.lats[0, i],
                       top_edge.depths[0, i])
            p2 = Point(top_edge.lons[0, i + 1], top_edge.lats[0, i + 1],
                       top_edge.depths[0, i + 1])
            azimuth = p1.azimuth(p2)
            dists.append(
                geodetic.distance_to_arc(p1.longitude, p1.latitude, azimuth,
                                         mesh.lons, mesh.lats))

        else:

            for i in range(top_edge.lons.shape[1] - 1):

                if ((self.__class__.__name__ == 'KiteSurface')
                        and (numpy.isnan(top_edge.lons[0, i])
                             or numpy.isnan(top_edge.lons[0, i + 1]))):
                    continue

                p1 = Point(top_edge.lons[0, i], top_edge.lats[0, i],
                           top_edge.depths[0, i])
                p2 = Point(top_edge.lons[0, i + 1], top_edge.lats[0, i + 1],
                           top_edge.depths[0, i + 1])

                # Swapping
                if i == 0:
                    pt = p1
                    p1 = p2
                    p2 = pt

                # Computing azimuth and distance
                if i == ia or i == ib:
                    azimuth = p1.azimuth(p2)
                    tmp = geodetic.distance_to_semi_arc(
                        p1.longitude, p1.latitude, azimuth, mesh.lons,
                        mesh.lats)
                else:
                    tmp = geodetic.min_distance_to_segment(
                        numpy.array([p1.longitude, p2.longitude]),
                        numpy.array([p1.latitude, p2.latitude]), mesh.lons,
                        mesh.lats)
                # Correcting the sign of the distance
                if i == 0:
                    tmp *= -1
                dists.append(tmp)

        # Computing distances
        dists = numpy.array(dists)
        iii = abs(dists).argmin(axis=0)
        dst = dists[iii, list(range(dists.shape[1]))]

        if numpy.any(numpy.isnan(dst)):
            raise ValueError('NaN in Rx')

        return dst
예제 #7
0
 def test6_one_degree_distance(self):
     surface = self._test1to7surface()
     sites = Mesh.from_points_list([Point(0.05, -1), Point(20, 1)])
     dists = surface.get_rx_distance(sites)
     expected_dists = [-111.19505230826488, +111.19505230826488]
     aac(dists, expected_dists, rtol=1E-5)
예제 #8
0
 def _test1to7surface(self):
     corners = [Point(0, 0, 8), Point(-0.1, 0, 8),
                Point(-0.1, 0, 9), Point(0, 0, 9)]
     surface = PlanarSurface(270, 90, *corners)
     return surface
예제 #9
0
 def test_point_outside(self):
     corners = [Point(0.1, -0.1, 1), Point(-0.1, -0.1, 1),
                Point(-0.1, 0.1, 2), Point(0.1, 0.1, 2)]
     surface = PlanarSurface(270, 45, *corners)
     sites = Mesh.from_points_list([
         Point(-0.2, -0.2), Point(1, 1, 1), Point(4, 5),
         Point(0.8, 0.01), Point(0.2, -0.15), Point(0.02, -0.12),
         Point(-0.14, 0), Point(-3, 3), Point(0.05, 0.15, 10)
     ])
     dists = surface.get_joyner_boore_distance(sites)
     expected_dists = [
         Point(-0.2, -0.2).distance(Point(-0.1, -0.1)),
         Point(1, 1).distance(Point(0.1, 0.1)),
         Point(4, 5).distance(Point(0.1, 0.1)),
         Point(0.8, 0.01).distance(Point(0.1, 0.01)),
         Point(0.2, -0.15).distance(Point(0.1, -0.1)),
         Point(0.02, -0.12).distance(Point(0.02, -0.1)),
         Point(-0.14, 0).distance(Point(-0.1, 0)),
         Point(-3, 3).distance(Point(-0.1, 0.1)),
         Point(0.05, 0.15).distance(Point(0.05, 0.1))
     ]
     aac(dists, expected_dists, atol=0.5)
예제 #10
0
 def test3_site_on_centroid(self):
     surface = self._test1to7surface()
     sites = Mesh.from_points_list([Point(0.05, 0)])
     self.assertAlmostEqual(surface.get_rx_distance(sites)[0], 0)
예제 #11
0
class _BaseSeismicSourceTestCase(unittest.TestCase):
    POLYGON = Polygon(
        [Point(0, 0),
         Point(0, 0.001),
         Point(0.001, 0.001),
         Point(0.001, 0)])
    SITES = [
        Site(Point(0.0005, 0.0005, -0.5), 0.1, 3, 4),  # inside, middle
        Site(Point(0.0015, 0.0005), 1, 3, 4),  # outside, middle-east
        Site(Point(-0.0005, 0.0005), 2, 3, 4),  # outside, middle-west
        Site(Point(0.0005, 0.0015), 3, 3, 4),  # outside, north-middle
        Site(Point(0.0005, -0.0005), 4, 3, 4),  # outside, south-middle
        Site(Point(0., 0.), 5, 3, 4),  # south-west corner
        Site(Point(0., 0.001), 6, 3, 4),  # north-west corner
        Site(Point(0.001, 0.001), 7, 3, 4),  # north-east corner
        Site(Point(0.001, 0.), 8, 3, 4),  # south-east corner
        Site(Point(0., -0.01), 9, 3, 4),  # 1.1 km away
        Site(Point(0.3, 0.3), 10, 3, 4),  # 47 km away
        Site(Point(0., -1), 11, 3, 4),  # 111.2 km away
    ]

    def setUp(self):
        self.source_class = FakeSource
        mfd = EvenlyDiscretizedMFD(min_mag=3,
                                   bin_width=1,
                                   occurrence_rates=[5, 6, 7])
        self.source = FakeSource('source_id',
                                 'name',
                                 const.TRT.VOLCANIC,
                                 mfd=mfd,
                                 rupture_mesh_spacing=2,
                                 magnitude_scaling_relationship=PeerMSR(),
                                 rupture_aspect_ratio=1,
                                 temporal_occurrence_model=PoissonTOM(50.))
        self.sitecol = SiteCollection(self.SITES)
예제 #12
0
 def test_topo(self):
     surface = PlanarSurface(2, 3, *tdata.TEST_7_RUPTURE_9_CORNERS)
     sites = Mesh.from_points_list([Point(-0.3, 0.4, -8)])
     self.assertAlmostEqual(55.6159556,
                            surface.get_min_distance(sites)[0], delta=0.6)
예제 #13
0
    def test_point_sources(self):
        sources = [
            openquake.hazardlib.source.PointSource(
                source_id='point1',
                name='point1',
                tectonic_region_type=const.TRT.ACTIVE_SHALLOW_CRUST,
                mfd=openquake.hazardlib.mfd.EvenlyDiscretizedMFD(
                    min_mag=4, bin_width=1, occurrence_rates=[5]),
                nodal_plane_distribution=openquake.hazardlib.pmf.PMF([
                    (1,
                     openquake.hazardlib.geo.NodalPlane(strike=0.0,
                                                        dip=90.0,
                                                        rake=0.0))
                ]),
                hypocenter_distribution=openquake.hazardlib.pmf.PMF([(1, 10)]),
                upper_seismogenic_depth=0.0,
                lower_seismogenic_depth=10.0,
                magnitude_scaling_relationship=openquake.hazardlib.scalerel.
                PeerMSR(),
                rupture_aspect_ratio=2,
                temporal_occurrence_model=PoissonTOM(1.),
                rupture_mesh_spacing=1.0,
                location=Point(10, 10)),
            openquake.hazardlib.source.PointSource(
                source_id='point2',
                name='point2',
                tectonic_region_type=const.TRT.ACTIVE_SHALLOW_CRUST,
                mfd=openquake.hazardlib.mfd.EvenlyDiscretizedMFD(
                    min_mag=4, bin_width=2, occurrence_rates=[5, 6, 7]),
                nodal_plane_distribution=openquake.hazardlib.pmf.PMF([
                    (1,
                     openquake.hazardlib.geo.NodalPlane(strike=0,
                                                        dip=90,
                                                        rake=0.0)),
                ]),
                hypocenter_distribution=openquake.hazardlib.pmf.PMF([(1, 10)]),
                upper_seismogenic_depth=0.0,
                lower_seismogenic_depth=10.0,
                magnitude_scaling_relationship=openquake.hazardlib.scalerel.
                PeerMSR(),
                rupture_aspect_ratio=2,
                temporal_occurrence_model=PoissonTOM(1.),
                rupture_mesh_spacing=1.0,
                location=Point(10, 11)),
        ]
        sites = [
            openquake.hazardlib.site.Site(Point(11, 10), 1, True, 2, 3),
            openquake.hazardlib.site.Site(Point(10, 16), 2, True, 2, 3),
            openquake.hazardlib.site.Site(Point(10, 10.6), 3, True, 2, 3),
            openquake.hazardlib.site.Site(Point(10, 10.7), 4, True, 2, 3)
        ]
        sitecol = openquake.hazardlib.site.SiteCollection(sites)

        from openquake.hazardlib.gsim.sadigh_1997 import SadighEtAl1997
        gsims = {const.TRT.ACTIVE_SHALLOW_CRUST: SadighEtAl1997()}
        truncation_level = 1
        imts = {'PGA': [0.1, 0.5, 1.3]}

        from openquake.hazardlib.calc import filters
        source_site_filter = self.SitesCounterSourceSitesFilter(
            filters.SourceSitesFilter(30))
        calc_hazard_curves(sources,
                           sitecol,
                           imts,
                           gsims,
                           truncation_level,
                           source_site_filter=source_site_filter)
        # there are two sources and four sites. The first source contains only
        # one rupture, the second source contains three ruptures.
        #
        # the first source has 'maximum projection radius' of 0.707 km
        # the second source has 'maximum projection radius' of 500.0 km
        #
        # the epicentral distances for source 1 are: [ 109.50558394,
        # 667.16955987,   66.71695599,   77.83644865]
        # the epicentral distances for source 2 are: [ 155.9412148 ,
        # 555.97463322,   44.47797066,   33.35847799]
        #
        # Considering that the source site filtering distance is set to 30 km,
        # for source 1, all sites have epicentral distance larger than
        # 0.707 + 30 km. This means that source 1 ('point 1') is not considered
        # in the calculation because too far.
        # for source 2, the 1st, 3rd and 4th sites have epicentral distances
        # smaller than 500.0 + 30 km. This means that source 2 ('point 2') is
        # considered in the calculation for site 1, 3, and 4.
        #
        # JB distances for rupture 1 in source 2 are: [ 155.43860273,
        #  555.26752644,   43.77086388,   32.65137121]
        # JB distances for rupture 2 in source 2 are: [ 150.98882575,
        #  548.90356541,   37.40690285,   26.28741018]
        # JB distances for rupture 3 in source 2 are: [ 109.50545819,
        # 55.97463322,    0.        ,    0.        ]
        #
        # Considering that the rupture site filtering distance is set to 30 km,
        # rupture 1 (magnitude 4) is not considered because too far, rupture 2
        # (magnitude 6) affect only the 4th site, rupture 3 (magnitude 8)
        # affect the 3rd and 4th sites.
        self.assertEqual(source_site_filter.counts, [('point2', [1, 3, 4])])
예제 #14
0
    def test_point_sources(self):
        sources = [
            openquake.hazardlib.source.PointSource(
                source_id='point1', name='point1',
                tectonic_region_type=const.TRT.ACTIVE_SHALLOW_CRUST,
                mfd=openquake.hazardlib.mfd.EvenlyDiscretizedMFD(
                    min_mag=4, bin_width=1, occurrence_rates=[5]
                ),
                nodal_plane_distribution=openquake.hazardlib.pmf.PMF([
                    (1, openquake.hazardlib.geo.NodalPlane(strike=0.0,
                                                           dip=90.0,
                                                           rake=0.0))
                ]),
                hypocenter_distribution=openquake.hazardlib.pmf.PMF([(1, 10)]),
                upper_seismogenic_depth=0.0,
                lower_seismogenic_depth=10.0,
                magnitude_scaling_relationship=
                openquake.hazardlib.scalerel.PeerMSR(),
                rupture_aspect_ratio=2,
                rupture_mesh_spacing=1.0,
                location=Point(10, 10)
            ),
            openquake.hazardlib.source.PointSource(
                source_id='point2', name='point2',
                tectonic_region_type=const.TRT.ACTIVE_SHALLOW_CRUST,
                mfd=openquake.hazardlib.mfd.EvenlyDiscretizedMFD(
                    min_mag=4, bin_width=2, occurrence_rates=[5, 6, 7]
                ),
                nodal_plane_distribution=openquake.hazardlib.pmf.PMF([
                    (1, openquake.hazardlib.geo.NodalPlane(strike=0,
                                                           dip=90,
                                                           rake=0.0)),
                ]),
                hypocenter_distribution=openquake.hazardlib.pmf.PMF([(1, 10)]),
                upper_seismogenic_depth=0.0,
                lower_seismogenic_depth=10.0,
                magnitude_scaling_relationship=
                openquake.hazardlib.scalerel.PeerMSR(),
                rupture_aspect_ratio=2,
                rupture_mesh_spacing=1.0,
                location=Point(10, 11)
            ),
        ]
        sites = [openquake.hazardlib.site.Site(Point(11, 10), 1, True, 2, 3),
                 openquake.hazardlib.site.Site(Point(10, 16), 2, True, 2, 3),
                 openquake.hazardlib.site.Site(Point(10, 10.6), 3, True, 2, 3),
                 openquake.hazardlib.site.Site(Point(10, 10.7), 4, True, 2, 3)]
        sitecol = openquake.hazardlib.site.SiteCollection(sites)

        from openquake.hazardlib.gsim.sadigh_1997 import SadighEtAl1997
        gsims = {const.TRT.ACTIVE_SHALLOW_CRUST: SadighEtAl1997()}
        truncation_level = 1
        time_span = 1.0
        imts = {openquake.hazardlib.imt.PGA(): [0.1, 0.5, 1.3]}

        from openquake.hazardlib.calc import filters
        source_site_filter = self.SitesCounterSourceFilter(
            filters.source_site_distance_filter(30)
        )
        rupture_site_filter = self.SitesCounterRuptureFilter(
            filters.rupture_site_distance_filter(30)
        )
        hazard_curves_poissonian(
            iter(sources), sitecol, imts, time_span, gsims, truncation_level,
            source_site_filter=source_site_filter,
            rupture_site_filter=rupture_site_filter
        )
        # there are two sources and four sites. first source should
        # be filtered completely since it is too far from all the sites.
        # the second one should take only three sites -- all except (10, 16).
        # it generates three ruptures with magnitudes 4, 6 and 8, from which
        # the first one doesn't affect any of sites and should be ignored,
        # second only affects site (10, 10.7) and the last one affects all
        # three.
        self.assertEqual(source_site_filter.counts,
                         [('point2', [1, 3, 4])])
        self.assertEqual(rupture_site_filter.counts,
                         [(6, [4]), (8, [1, 3, 4])])
예제 #15
0
 def setUp(self):
     super(PointSourceRuptureFilterTestCase, self).setUp()
     self.hypocenter = Point(2, 0, 50)
     self.sitecol = SiteCollection(self.SITES)
예제 #16
0
class PointSourceRuptureFilterTestCase(unittest.TestCase):
    SITES = PointSourceSourceFilterTestCase.SITES

    def setUp(self):
        super(PointSourceRuptureFilterTestCase, self).setUp()
        self.hypocenter = Point(2, 0, 50)
        self.sitecol = SiteCollection(self.SITES)

    def _make_rupture(self, width, length, dip):
        mid_left = self.hypocenter.point_at(length / 2.0, 0, azimuth=270)
        mid_right = self.hypocenter.point_at(length / 2.0, 0, azimuth=90)
        hwidth = width * numpy.cos(numpy.radians(dip)) / 2.0
        vwidth = width * numpy.sin(numpy.radians(dip)) / 2.0
        top_left = mid_left.point_at(hwidth, -vwidth, azimuth=0)
        bottom_left = mid_left.point_at(hwidth, vwidth, azimuth=180)
        top_right = mid_right.point_at(hwidth, -vwidth, azimuth=0)
        bottom_right = mid_right.point_at(hwidth, vwidth, azimuth=180)
        surface = PlanarSurface(1, 2, dip, top_left, top_right, bottom_right,
                                bottom_left)
        rupture = ParametricProbabilisticRupture(
            mag=1,
            rake=2,
            tectonic_region_type=TRT.VOLCANIC,
            hypocenter=self.hypocenter,
            surface=surface,
            source_typology=PointSource,
            occurrence_rate=3,
            temporal_occurrence_model=PoissonTOM(1))
        return rupture

    def test_zero_integration_distance(self):
        rup = self._make_rupture(10, 15, 45)
        # the JB distances are [8.29156163, 5.05971598, 15.13297135,
        # 495.78630103, 496.89812309], so given that the integration
        # distance is 0 all sites are filtered out
        filtered = filters.filter_sites_by_distance_to_rupture(
            rup, integration_distance=0, sites=self.sitecol)
        self.assertIs(filtered, None)

    def test_495_km(self):
        rup = self._make_rupture(7, 10, 30)
        # the JB distance area [5.84700762, 6.8290327, 14.53519629,
        # 496.25926891, 497.37116174] so given that the integration
        # distance is 495 only the first 3 sites are kept
        filtered = filters.filter_sites_by_distance_to_rupture(
            rup, integration_distance=495, sites=self.sitecol)
        expected_filtered = SiteCollection(self.SITES[:3])
        numpy.testing.assert_array_equal(filtered.indices, [0, 1, 2])
        numpy.testing.assert_array_equal(filtered.vs30, expected_filtered.vs30)
        numpy.testing.assert_array_equal(filtered.vs30measured,
                                         expected_filtered.vs30measured)
        numpy.testing.assert_array_equal(filtered.z1pt0,
                                         expected_filtered.z1pt0)
        numpy.testing.assert_array_equal(filtered.z2pt5,
                                         expected_filtered.z2pt5)
        numpy.testing.assert_array_equal(filtered.mesh.lons,
                                         expected_filtered.mesh.lons)
        numpy.testing.assert_array_equal(filtered.mesh.lats,
                                         expected_filtered.mesh.lats)
        numpy.testing.assert_array_equal(filtered.mesh.depths,
                                         expected_filtered.mesh.depths)

    def test_filter_all_out(self):
        rup = self._make_rupture(50, 80, 9)
        # the JB distances are [47.0074159, 37.99716685, 40.7944923,
        #  476.2521365, 477.36015879]
        for int_dist in (0, 1, 10, 20, 37.99):
            filtered = filters.filter_sites_by_distance_to_rupture(
                rup, integration_distance=int_dist, sites=self.sitecol)
            self.assertIs(filtered, None)
예제 #17
0
class PointSourceSourceFilterTestCase(unittest.TestCase):
    SITES = [
        Site(Point(2.0, 0.0), 0.1, True, 3, 4),  # on epicenter
        Site(Point(2.1, 0.0), 1, True, 3, 4),  # 11.1 km away
        Site(Point(2.0, -0.15), 2, True, 3, 4),  # 16.7 km away
        Site(Point(2.0, 4.49), 3, True, 3, 4),  # 499.3 km away
        Site(Point(2.0, -4.5), 4, True, 3, 4),  # 500.3 km away
    ]

    def setUp(self):
        super(PointSourceSourceFilterTestCase, self).setUp()
        self.sitecol = SiteCollection(self.SITES)

        self.source1 = make_point_source(
            mfd=EvenlyDiscretizedMFD(min_mag=5,
                                     bin_width=1,
                                     occurrence_rates=[1]),
            rupture_aspect_ratio=1.9,
            upper_seismogenic_depth=0,
            lower_seismogenic_depth=18.5,
            magnitude_scaling_relationship=PeerMSR(),
            nodal_plane_distribution=PMF([
                (0.5, NodalPlane(strike=1, dip=2, rake=3)),
                (0.5, NodalPlane(strike=1, dip=20, rake=3)),
            ]),
            location=Point(2.0, 0.0),
        )
        self.source2 = make_point_source(
            mfd=EvenlyDiscretizedMFD(min_mag=6.5,
                                     bin_width=1,
                                     occurrence_rates=[1]),
            rupture_aspect_ratio=0.5,
            upper_seismogenic_depth=0,
            lower_seismogenic_depth=18.5,
            magnitude_scaling_relationship=PeerMSR(),
            nodal_plane_distribution=PMF([
                (0.5, NodalPlane(strike=1, dip=10, rake=3)),
                (0.5, NodalPlane(strike=1, dip=20, rake=3)),
            ]),
            location=Point(2.0, 0.0),
        )

    def test_zero_integration_distance(self):
        filtered = self.source1.filter_sites_by_distance_to_source(
            integration_distance=0, sites=self.sitecol)
        self.assertIsInstance(filtered, FilteredSiteCollection)
        self.assertIsNot(filtered, self.sitecol)
        numpy.testing.assert_array_equal(filtered.indices, [0])
        numpy.testing.assert_array_equal(filtered.vs30, [0.1])

        filtered = self.source2.filter_sites_by_distance_to_source(
            integration_distance=0, sites=self.sitecol)
        numpy.testing.assert_array_equal(filtered.indices, [0, 1])

    def test_fifty_km(self):
        filtered = self.source1.filter_sites_by_distance_to_source(
            integration_distance=50, sites=self.sitecol)
        numpy.testing.assert_array_equal(filtered.indices, [0, 1, 2])

        filtered = self.source2.filter_sites_by_distance_to_source(
            integration_distance=50, sites=self.sitecol)
        numpy.testing.assert_array_equal(filtered.indices, [0, 1, 2])

    def test_495_km(self):
        filtered = self.source1.filter_sites_by_distance_to_source(
            integration_distance=495, sites=self.sitecol)
        numpy.testing.assert_array_equal(filtered.indices, [0, 1, 2])

        filtered = self.source2.filter_sites_by_distance_to_source(
            integration_distance=495, sites=self.sitecol)
        self.assertIs(filtered, self.sitecol)  # nothing filtered

    def test_filter_all_out(self):
        self.source1.location.latitude = 13.6
        for int_dist in (0, 1, 10, 100, 1000):
            filtered = self.source1.filter_sites_by_distance_to_source(
                integration_distance=int_dist, sites=self.sitecol)
            self.assertIs(filtered, None)
예제 #18
0
    def get_rx_distance(self, mesh):
        """
        See :meth:`superclass method
        <.base.BaseSurface.get_rx_distance>`
        for spec of input and result values.

        The method extracts the top edge of the surface. For each point in mesh
        it computes the Rx distance to each segment the top edge is made
        of. The calculation is done by calling the function
        :func:`openquake.hazardlib.geo.geodetic.distance_to_arc`. The final Rx
        distance matrix is then constructed by taking, for each point in mesh,
        the minimum Rx distance value computed.
        """
        top_edge = self.get_mesh()[0:1]

        dists = []
        if top_edge.lons.shape[1] < 3:

            i = 0
            p1 = Point(
                top_edge.lons[0, i],
                top_edge.lats[0, i],
                top_edge.depths[0, i]
            )
            p2 = Point(
                top_edge.lons[0, i + 1], top_edge.lats[0, i + 1],
                top_edge.depths[0, i + 1]
            )
            azimuth = p1.azimuth(p2)
            dists.append(
                geodetic.distance_to_arc(
                    p1.longitude, p1.latitude, azimuth,
                    mesh.lons, mesh.lats
                )
            )

        else:

            for i in range(top_edge.lons.shape[1] - 1):
                p1 = Point(
                    top_edge.lons[0, i],
                    top_edge.lats[0, i],
                    top_edge.depths[0, i]
                )
                p2 = Point(
                    top_edge.lons[0, i + 1],
                    top_edge.lats[0, i + 1],
                    top_edge.depths[0, i + 1]
                )
                # Swapping
                if i == 0:
                    pt = p1
                    p1 = p2
                    p2 = pt

                # Computing azimuth and distance
                if i == 0 or i == top_edge.lons.shape[1] - 2:
                    azimuth = p1.azimuth(p2)
                    tmp = geodetic.distance_to_semi_arc(p1.longitude,
                                                        p1.latitude,
                                                        azimuth,
                                                        mesh.lons, mesh.lats)
                else:
                    tmp = geodetic.min_distance_to_segment([p1.longitude,
                                                            p2.longitude],
                                                           [p1.latitude,
                                                            p2.latitude],
                                                           mesh.lons,
                                                           mesh.lats)
                # Correcting the sign of the distance
                if i == 0:
                    tmp *= -1
                dists.append(tmp)

        # Computing distances
        dists = numpy.array(dists)
        iii = abs(dists).argmin(axis=0)
        dst = dists[iii, list(range(dists.shape[1]))]

        return dst
예제 #19
0
 def setUp(self):
     """
     Builds a simple dipping/bending fault source with a characteristic
     source model. Compares the curves for four sites, two on the hanging
     wall and two on the footwall.
     The source model is taken from the PEER Tests
     """
     point_order_dipping_east = [
         Point(-64.78365, -0.45236),
         Point(-64.80164, -0.45236),
         Point(-64.90498, -0.36564),
         Point(-65.0000, -0.16188),
         Point(-65.0000, 0.0000)
     ]
     trace_dip_east = Line(point_order_dipping_east)
     site_1 = Site(Point(-64.98651, -0.15738),
                   760.0,
                   48.0,
                   0.607,
                   vs30measured=True)
     site_2 = Site(Point(-64.77466, -0.45686),
                   760.0,
                   48.0,
                   0.607,
                   vs30measured=True)
     site_3 = Site(Point(-64.92747, -0.38363),
                   760.0,
                   48.0,
                   0.607,
                   vs30measured=True)
     site_4 = Site(Point(-65.05396, -0.17088),
                   760.0,
                   48.0,
                   0.607,
                   vs30measured=True)
     self.sites = SiteCollection([site_1, site_2, site_3, site_4])
     self.imtls = {
         "PGA": [
             0.001, 0.01, 0.05, 0.1, 0.15, 0.2, 0.25, 0.3, 0.35, 0.4, 0.45,
             0.5, 0.55, 0.6, 0.7, 0.8, 0.9, 1.0
         ]
     }
     fault_surface1 = SimpleFaultSurface.from_fault_data(
         trace_dip_east, 0.0, 12.0, 60., 0.5)
     mfd1 = EvenlyDiscretizedMFD(6.75, 0.01, [0.01])
     tom = PoissonTOM(1.0)
     self.sources = [
         CharacteristicFaultSource(
             "PEER_CHAR_FLT_EAST",
             "Peer Bending Fault Dipping East - Characteristic",
             "Active Shallow Crust", mfd1, tom, fault_surface1, 90.0)
     ]
     # We will check all the GMPEs
     self.gsim_set = {
         "ASK": [
             NSHMP2014(gmpe_name='AbrahamsonEtAl2014', sgn=0),
             (0.185, NSHMP2014(gmpe_name='AbrahamsonEtAl2014', sgn=-1)),
             (0.63, AbrahamsonEtAl2014()),
             (0.185, NSHMP2014(gmpe_name='AbrahamsonEtAl2014', sgn=1))
         ],
         "BSSA": [
             NSHMP2014(gmpe_name='BooreEtAl2014', sgn=0),
             (0.185, NSHMP2014(gmpe_name='BooreEtAl2014', sgn=-1)),
             (0.63, BooreEtAl2014()),
             (0.185, NSHMP2014(gmpe_name='BooreEtAl2014', sgn=1))
         ],
         "CB": [
             NSHMP2014(gmpe_name='CampbellBozorgnia2014', sgn=0),
             (0.185, NSHMP2014(gmpe_name='CampbellBozorgnia2014', sgn=-1)),
             (0.63, CampbellBozorgnia2014()),
             (0.185, NSHMP2014(gmpe_name='CampbellBozorgnia2014', sgn=1))
         ],
         "CY": [
             NSHMP2014(gmpe_name='ChiouYoungs2014', sgn=0),
             (0.185, NSHMP2014(gmpe_name='ChiouYoungs2014', sgn=-1)),
             (0.63, ChiouYoungs2014()),
             (0.185, NSHMP2014(gmpe_name='ChiouYoungs2014', sgn=1))
         ],
         "ID": [
             NSHMP2014(gmpe_name='Idriss2014', sgn=0),
             (0.185, NSHMP2014(gmpe_name='Idriss2014', sgn=-1)),
             (0.63, Idriss2014()),
             (0.185, NSHMP2014(gmpe_name='Idriss2014', sgn=1))
         ]
     }
예제 #20
0
class JB2009CorrelationMatrixTestCase(unittest.TestCase):
    SITECOL = SiteCollection([Site(Point(2, -40), 1, True, 1, 1),
                              Site(Point(2, -40.1), 1, True, 1, 1),
                              Site(Point(2, -40), 1, True, 1, 1),
                              Site(Point(2, -39.9), 1, True, 1, 1)])

    def test_no_clustering(self):
        cormo = JB2009CorrelationModel(vs30_clustering=False)
        imt = SA(period=0.1, damping=5)
        corma = cormo._get_correlation_matrix(self.SITECOL, imt)
        aaae(corma, [[1,          0.03823366, 1,          0.03823366],
                     [0.03823366, 1,          0.03823366, 0.00146181],
                     [1,          0.03823366, 1,          0.03823366],
                     [0.03823366, 0.00146181, 0.03823366, 1]])

        imt = SA(period=0.95, damping=5)
        corma = cormo._get_correlation_matrix(self.SITECOL, imt)
        aaae(corma, [[1,          0.26107857, 1,          0.26107857],
                     [0.26107857, 1,          0.26107857, 0.06816202],
                     [1,          0.26107857, 1,          0.26107857],
                     [0.26107857, 0.06816202, 0.26107857, 1]])

    def test_clustered(self):
        cormo = JB2009CorrelationModel(vs30_clustering=True)
        imt = SA(period=0.001, damping=5)
        corma = cormo._get_correlation_matrix(self.SITECOL, imt)
        aaae(corma, [[1,          0.44046654, 1,          0.44046654],
                     [0.44046654, 1,          0.44046654, 0.19401077],
                     [1,          0.44046654, 1,          0.44046654],
                     [0.44046654, 0.19401077, 0.44046654, 1]])

        imt = SA(period=0.5, damping=5)
        corma = cormo._get_correlation_matrix(self.SITECOL, imt)
        aaae(corma, [[1,          0.36612758, 1,          0.36612758],
                     [0.36612758, 1,          0.36612758, 0.1340494],
                     [1,          0.36612758, 1,          0.36612758],
                     [0.36612758, 0.1340494, 0.36612758, 1]])

    def test_period_one_and_above(self):
        cormo = JB2009CorrelationModel(vs30_clustering=False)
        cormo2 = JB2009CorrelationModel(vs30_clustering=True)
        imt = SA(period=1.0, damping=5)
        corma = cormo._get_correlation_matrix(self.SITECOL, imt)
        aaae(corma, [[1,         0.2730787, 1,          0.2730787],
                     [0.2730787, 1,          0.2730787, 0.07457198],
                     [1,         0.2730787, 1,          0.2730787],
                     [0.2730787, 0.07457198, 0.2730787, 1]])
        corma2 = cormo2._get_correlation_matrix(self.SITECOL, imt)
        self.assertTrue((corma == corma2).all())

        imt = SA(period=10.0, damping=5)
        corma = cormo._get_correlation_matrix(self.SITECOL, imt)
        aaae(corma, [[1,          0.56813402, 1,          0.56813402],
                     [0.56813402, 1,          0.56813402, 0.32277627],
                     [1,          0.56813402, 1,          0.56813402],
                     [0.56813402, 0.32277627, 0.56813402, 1]])
        corma2 = cormo2._get_correlation_matrix(self.SITECOL, imt)
        self.assertTrue((corma == corma2).all())

    def test_pga(self):
        sa = SA(period=1e-50, damping=5)
        pga = PGA()

        cormo = JB2009CorrelationModel(vs30_clustering=False)
        corma = cormo._get_correlation_matrix(self.SITECOL, sa)
        corma2 = cormo._get_correlation_matrix(self.SITECOL, pga)
        self.assertTrue((corma == corma2).all())

        cormo = JB2009CorrelationModel(vs30_clustering=True)
        corma = cormo._get_correlation_matrix(self.SITECOL, sa)
        corma2 = cormo._get_correlation_matrix(self.SITECOL, pga)
        self.assertTrue((corma == corma2).all())
예제 #21
0
Generalized coordinate systems require an additional level of testing under
a variety of fault conditions - we separate these out away from the main
fault surface testing modules
"""

import os
import unittest
import numpy

from openquake.hazardlib.geo.surface.multi import MultiSurface
from openquake.hazardlib.geo import Mesh, Point, Line, PlanarSurface,\
    SimpleFaultSurface
from openquake.hazardlib.geo.surface.base import (downsample_mesh,
                                                  downsample_trace)

PNT1 = Point(-64.78365, -0.45236, 0.0)
PNT2 = Point(-64.80164, -0.45236, 0.0)
PNT3 = Point(-64.90498, -0.36564, 0.0)
PNT4 = Point(-65.00000, -0.16188, 0.0)
PNT5 = Point(-65.00000,  0.00000, 0.0)

AS_ARRAY = numpy.array([[pnt.longitude, pnt.latitude, pnt.depth]
                        for pnt in [PNT1, PNT2, PNT3, PNT4, PNT5]])


class CartesianTestingMultiSurface(MultiSurface):
    """
    This test surface is used to verify the values given by Spudich & Chiou
    in their report. Here, the fault is built directly from the cartesian
    points so we over-ride the call to the function to render the coordinates
    to cartesian
예제 #22
0
 def v2p(*vectors):  # "vectors to points"
     return [Point(*coords)
             for coords in zip(*geo_utils.cartesian_to_spherical(
                 numpy.array(vectors, dtype=float)
             ))]
예제 #23
0
    def test_7_many_ruptures(self):
        source_id = name = 'test7-source'
        trt = TRT.VOLCANIC
        mag1 = 4.5
        mag2 = 5.5
        mag1_rate = 9e-3
        mag2_rate = 9e-4
        hypocenter1 = 9.0
        hypocenter2 = 10.0
        hypocenter1_weight = 0.8
        hypocenter2_weight = 0.2
        nodalplane1 = NodalPlane(strike=45, dip=90, rake=0)
        nodalplane2 = NodalPlane(strike=0, dip=45, rake=10)
        nodalplane1_weight = 0.3
        nodalplane2_weight = 0.7
        upper_seismogenic_depth = 2
        lower_seismogenic_depth = 16
        rupture_aspect_ratio = 2
        rupture_mesh_spacing = 0.5
        location = Point(0, 0)
        magnitude_scaling_relationship = PeerMSR()
        tom = PoissonTOM(time_span=50)

        mfd = EvenlyDiscretizedMFD(min_mag=mag1,
                                   bin_width=(mag2 - mag1),
                                   occurrence_rates=[mag1_rate, mag2_rate])
        nodal_plane_distribution = PMF([(nodalplane1_weight, nodalplane1),
                                        (nodalplane2_weight, nodalplane2)])
        hypocenter_distribution = PMF([(hypocenter1_weight, hypocenter1),
                                       (hypocenter2_weight, hypocenter2)])
        point_source = PointSource(
            source_id, name, trt, mfd, rupture_mesh_spacing,
            magnitude_scaling_relationship, rupture_aspect_ratio, tom,
            upper_seismogenic_depth, lower_seismogenic_depth, location,
            nodal_plane_distribution, hypocenter_distribution)
        actual_ruptures = list(point_source.iter_ruptures())
        self.assertEqual(len(actual_ruptures), point_source.count_ruptures())
        expected_ruptures = {
            (mag1, nodalplane1.rake, hypocenter1): (
                # probabilistic rupture's occurrence rate
                9e-3 * 0.3 * 0.8,
                # rupture surface corners
                planar_surface_test_data.TEST_7_RUPTURE_1_CORNERS),
            (mag2, nodalplane1.rake, hypocenter1):
            (9e-4 * 0.3 * 0.8,
             planar_surface_test_data.TEST_7_RUPTURE_2_CORNERS),
            (mag1, nodalplane2.rake, hypocenter1):
            (9e-3 * 0.7 * 0.8,
             planar_surface_test_data.TEST_7_RUPTURE_3_CORNERS),
            (mag2, nodalplane2.rake, hypocenter1):
            (9e-4 * 0.7 * 0.8,
             planar_surface_test_data.TEST_7_RUPTURE_4_CORNERS),
            (mag1, nodalplane1.rake, hypocenter2):
            (9e-3 * 0.3 * 0.2,
             planar_surface_test_data.TEST_7_RUPTURE_5_CORNERS),
            (mag2, nodalplane1.rake, hypocenter2):
            (9e-4 * 0.3 * 0.2,
             planar_surface_test_data.TEST_7_RUPTURE_6_CORNERS),
            (mag1, nodalplane2.rake, hypocenter2):
            (9e-3 * 0.7 * 0.2,
             planar_surface_test_data.TEST_7_RUPTURE_7_CORNERS),
            (mag2, nodalplane2.rake, hypocenter2):
            (9e-4 * 0.7 * 0.2,
             planar_surface_test_data.TEST_7_RUPTURE_8_CORNERS)
        }
        for actual_rupture in actual_ruptures:
            expected_occurrence_rate, expected_corners = expected_ruptures[(
                actual_rupture.mag, actual_rupture.rake,
                actual_rupture.hypocenter.depth)]
            self.assertTrue(
                isinstance(actual_rupture, ParametricProbabilisticRupture))
            self.assertAlmostEqual(actual_rupture.occurrence_rate,
                                   expected_occurrence_rate)
            self.assertIs(actual_rupture.temporal_occurrence_model, tom)
            self.assertEqual(actual_rupture.tectonic_region_type, trt)
            surface = actual_rupture.surface

            tl, tr, br, bl = expected_corners
            self.assertEqual(tl, surface.top_left)
            self.assertEqual(tr, surface.top_right)
            self.assertEqual(bl, surface.bottom_left)
            self.assertEqual(br, surface.bottom_right)

        # check avg_ruptures
        avg_ruptures = list(point_source.avg_ruptures())
        self.assertEqual([pr.hypocenter.depth for pr in avg_ruptures],
                         [9.2, 9.2])  # weighted mean between 9 and 10
예제 #24
0
 def test2_site_on_the_foot_wall(self):
     surface = self._test1to7surface()
     sites = Mesh.from_points_list([Point(0.05, -0.05), Point(-140, -0.05)])
     dists = surface.get_rx_distance(sites)
     expected_dists = [-5.559752615413244] * 2
     aac(dists, expected_dists, rtol=1E-5)
예제 #25
0
 def test_middle_point_single_surface(self):
     surf = MultiSurface([self.surfaces_mesh2D[0]])
     middle_point = surf.get_middle_point()
     self.assertTrue(Point(0.1, 1.1, 1.1) == middle_point)
예제 #26
0
 def test_bottom_edge_depth_differs(self):
     corners = [Point(0, -1, 0.3), Point(0, 1, 0.3),
                Point(0, 1, 0.5), Point(0, -1, 0.499999)]
     msg = 'top and bottom edges must be parallel to the earth surface'
     self.assert_failed_creation(0, 90, corners, ValueError, msg)
예제 #27
0
 def get_middle_point(self):
     return Point(self.lons.flatten()[0],
                  self.lats.flatten()[0],
                  self.depths.flatten()[0])
예제 #28
0
 def test7_ten_degrees_distance(self):
     surface = self._test1to7surface()
     sites = Mesh.from_points_list([Point(0, -10), Point(-15, 10)])
     dists = surface.get_rx_distance(sites)
     expected_dists = [-1111.9505230826488, +1111.9505230826488]
     aac(dists, expected_dists, rtol=1E-5)
예제 #29
0
    def get_rx_distance(self, mesh):
        """
        See :meth:`superclass method
        <.base.BaseSurface.get_rx_distance>`
        for spec of input and result values.

        The method extracts the top edge of the surface. For each point in mesh
        it computes the Rx distance to each segment the top edge is made
        of. The calculation is done by calling the function
        :func:`openquake.hazardlib.geo.geodetic.distance_to_arc`. The final Rx
        distance matrix is then constructed by taking, for each point in mesh,
        the minimum Rx distance value computed.
        """
        top_edge = self.get_mesh()[0:1]

        dists = []
        if top_edge.lons.shape[1] < 3:

            i = 0
            p1 = Point(top_edge.lons[0, i], top_edge.lats[0, i],
                       top_edge.depths[0, i])
            p2 = Point(top_edge.lons[0, i + 1], top_edge.lats[0, i + 1],
                       top_edge.depths[0, i + 1])
            azimuth = p1.azimuth(p2)
            dists.append(
                geodetic.distance_to_arc(p1.longitude, p1.latitude, azimuth,
                                         mesh.lons, mesh.lats))

        else:

            for i in range(top_edge.lons.shape[1] - 1):
                p1 = Point(top_edge.lons[0, i], top_edge.lats[0, i],
                           top_edge.depths[0, i])
                p2 = Point(top_edge.lons[0, i + 1], top_edge.lats[0, i + 1],
                           top_edge.depths[0, i + 1])
                # Swapping
                if i == 0:
                    pt = p1
                    p1 = p2
                    p2 = pt

                # Computing azimuth and distance
                if i == 0 or i == top_edge.lons.shape[1] - 2:
                    azimuth = p1.azimuth(p2)
                    tmp = geodetic.distance_to_semi_arc(
                        p1.longitude, p1.latitude, azimuth, mesh.lons,
                        mesh.lats)
                else:
                    tmp = geodetic.min_distance_to_segment(
                        [p1.longitude, p2.longitude],
                        [p1.latitude, p2.latitude], mesh.lons, mesh.lats)
                # Correcting the sign of the distance
                if i == 0:
                    tmp *= -1
                dists.append(tmp)

        # Computing distances
        dists = numpy.array(dists)
        iii = abs(dists).argmin(axis=0)
        dst = dists[iii, range(dists.shape[1])]

        return dst
예제 #30
0
 def test1_sites_within_fault_width(self):
     surface = self._test1to7surface()
     sites = Mesh.from_points_list([Point(-0.05, 0.05),
                                    Point(-0.05, -0.05)])
     dists = surface.get_ry0_distance(sites)
     numpy.testing.assert_allclose(dists, numpy.array([0.0, 0.0]))
예제 #31
0
class PointSourceRuptureFilterTestCase(unittest.TestCase):
    SITES = PointSourceSourceFilterTestCase.SITES

    def setUp(self):
        super(PointSourceRuptureFilterTestCase, self).setUp()
        self.hypocenter = Point(2, 0, 50)
        self.sitecol = SiteCollection(self.SITES)

    def _make_rupture(self, width, length, dip):
        mid_left = self.hypocenter.point_at(length / 2.0, 0, azimuth=270)
        mid_right = self.hypocenter.point_at(length / 2.0, 0, azimuth=90)
        hwidth = width * numpy.cos(numpy.radians(dip)) / 2.0
        vwidth = width * numpy.sin(numpy.radians(dip)) / 2.0
        top_left = mid_left.point_at(hwidth, -vwidth, azimuth=0)
        bottom_left = mid_left.point_at(hwidth, vwidth, azimuth=180)
        top_right = mid_right.point_at(hwidth, -vwidth, azimuth=0)
        bottom_right = mid_right.point_at(hwidth, vwidth, azimuth=180)
        surface = PlanarSurface(1, 2, dip, top_left, top_right,
                                bottom_right, bottom_left)
        rupture = ProbabilisticRupture(
            mag=1, rake=2, tectonic_region_type=TRT.VOLCANIC,
            hypocenter=self.hypocenter, surface=surface,
            source_typology=PointSource, occurrence_rate=3,
            temporal_occurrence_model=PoissonTOM(1)
        )
        return rupture

    def test_zero_integration_distance(self):
        rup = self._make_rupture(10, 15, 45)  # 8 km radius
        filtered = PointSource.filter_sites_by_distance_to_rupture(
            rup, integration_distance=0, sites=self.sitecol
        )
        self.assertIsInstance(filtered, SiteCollection)
        self.assertIsNot(filtered, self.sitecol)
        numpy.testing.assert_array_equal(filtered.indices, [0])
        numpy.testing.assert_array_equal(filtered.vs30, [0.1])

        rup = self._make_rupture(50, 30, 90)  # 14.8 km radius
        filtered = PointSource.filter_sites_by_distance_to_rupture(
            rup, integration_distance=0, sites=self.sitecol
        )
        numpy.testing.assert_array_equal(filtered.indices, [0, 1])

    def test_495_km(self):
        rup = self._make_rupture(5, 8, 5)  # 4.68 km radius
        filtered = PointSource.filter_sites_by_distance_to_rupture(
            rup, integration_distance=495, sites=self.sitecol
        )
        numpy.testing.assert_array_equal(filtered.indices, [0, 1, 2, 3])

        rup = self._make_rupture(7, 10, 30)  # 5.8 km radius
        filtered = PointSource.filter_sites_by_distance_to_rupture(
            rup, integration_distance=495, sites=self.sitecol
        )
        self.assertIs(filtered.indices, None)
        self.assertIs(filtered, self.sitecol)

    def test_filter_all_out(self):
        rup = self._make_rupture(50, 80, 9)  # 46.64 km radius
        self.hypocenter.longitude = 11.515
        for int_dist in (0, 1, 10, 100, 1000):
            filtered = PointSource.filter_sites_by_distance_to_rupture(
                rup, integration_distance=int_dist, sites=self.sitecol
            )
            self.assertIs(filtered, None)
예제 #32
0
    def get_rx_distance(self, mesh):
        """
        Compute distance between each point of mesh and surface's great circle
        arc.

        Distance is measured perpendicular to the rupture strike, from
        the surface projection of the updip edge of the rupture, with
        the down dip direction being positive (this distance is usually
        called ``Rx``).

        In other words, is the horizontal distance to top edge of rupture
        measured perpendicular to the strike. Values on the hanging wall
        are positive, values on the footwall are negative.

        :param mesh:
            :class:`~openquake.hazardlib.geo.mesh.Mesh` of points to calculate
            Rx-distance to.
        :returns:
            Numpy array of distances in km.
        """
        top_edge = self.mesh[0:1]

        dists = []
        if top_edge.lons.shape[1] < 3:

            i = 0
            p1 = Point(
                top_edge.lons[0, i],
                top_edge.lats[0, i],
                top_edge.depths[0, i]
            )
            p2 = Point(
                top_edge.lons[0, i + 1], top_edge.lats[0, i + 1],
                top_edge.depths[0, i + 1]
            )
            azimuth = p1.azimuth(p2)
            dists.append(
                geodetic.distance_to_arc(
                    p1.longitude, p1.latitude, azimuth,
                    mesh.lons, mesh.lats
                )
            )

        else:

            for i in range(top_edge.lons.shape[1] - 1):
                p1 = Point(
                    top_edge.lons[0, i],
                    top_edge.lats[0, i],
                    top_edge.depths[0, i]
                )
                p2 = Point(
                    top_edge.lons[0, i + 1],
                    top_edge.lats[0, i + 1],
                    top_edge.depths[0, i + 1]
                )
                # Swapping
                if i == 0:
                    pt = p1
                    p1 = p2
                    p2 = pt

                # Computing azimuth and distance
                if i == 0 or i == top_edge.lons.shape[1] - 2:
                    azimuth = p1.azimuth(p2)
                    tmp = geodetic.distance_to_semi_arc(p1.longitude,
                                                        p1.latitude,
                                                        azimuth,
                                                        mesh.lons, mesh.lats)
                else:
                    tmp = geodetic.min_distance_to_segment(
                        numpy.array([p1.longitude, p2.longitude]),
                        numpy.array([p1.latitude, p2.latitude]),
                        mesh.lons, mesh.lats)
                # Correcting the sign of the distance
                if i == 0:
                    tmp *= -1
                dists.append(tmp)

        # Computing distances
        dists = numpy.array(dists)
        iii = abs(dists).argmin(axis=0)
        dst = dists[iii, list(range(dists.shape[1]))]

        return dst
예제 #33
0
파일: planar.py 프로젝트: gem/oq-hazardlib
def _corners(array):
    # convert a composite array with fields lon, lat, depth into Points
    points = []
    for p in array:
        points.append(Point(p['lon'], p['lat'], p['depth']))
    return points
예제 #34
0
class PointSourceRuptureFilterTestCase(unittest.TestCase):
    SITES = PointSourceSourceFilterTestCase.SITES

    def setUp(self):
        super(PointSourceRuptureFilterTestCase, self).setUp()
        self.hypocenter = Point(2, 0, 50)
        self.sitecol = SiteCollection(self.SITES)

    def _make_rupture(self, width, length, dip):
        mid_left = self.hypocenter.point_at(length / 2.0, 0, azimuth=270)
        mid_right = self.hypocenter.point_at(length / 2.0, 0, azimuth=90)
        hwidth = width * numpy.cos(numpy.radians(dip)) / 2.0
        vwidth = width * numpy.sin(numpy.radians(dip)) / 2.0
        top_left = mid_left.point_at(hwidth, -vwidth, azimuth=0)
        bottom_left = mid_left.point_at(hwidth, vwidth, azimuth=180)
        top_right = mid_right.point_at(hwidth, -vwidth, azimuth=0)
        bottom_right = mid_right.point_at(hwidth, vwidth, azimuth=180)
        surface = PlanarSurface(1, 2, dip, top_left, top_right,
                                bottom_right, bottom_left)
        rupture = ProbabilisticRupture(
            mag=1, rake=2, tectonic_region_type=TRT.VOLCANIC,
            hypocenter=self.hypocenter, surface=surface,
            source_typology=PointSource, occurrence_rate=3,
            temporal_occurrence_model=PoissonTOM(1)
        )
        return rupture

    def test_zero_integration_distance(self):
        rup = self._make_rupture(10, 15, 45)
        # the JB distances are [8.29156163, 5.05971598, 15.13297135,
        # 495.78630103, 496.89812309], so given that the integration
        # distance is 0 all sites are filtered out
        filtered = PointSource.filter_sites_by_distance_to_rupture(
            rup, integration_distance=0, sites=self.sitecol
        )
        self.assertIs(filtered, None)

    def test_495_km(self):
        rup = self._make_rupture(7, 10, 30)
        # the JB distance area [5.84700762, 6.8290327, 14.53519629,
        # 496.25926891, 497.37116174] so given that the integration
        # distance is 495 only the first 3 sites are kept
        filtered = PointSource.filter_sites_by_distance_to_rupture(
            rup, integration_distance=495, sites=self.sitecol
        )
        expected_filtered = SiteCollection(self.SITES[:3])
        numpy.testing.assert_array_equal(filtered.indices, [0, 1, 2])
        numpy.testing.assert_array_equal(
            filtered.vs30, expected_filtered.vs30
        )
        numpy.testing.assert_array_equal(
            filtered.vs30measured, expected_filtered.vs30measured
        )
        numpy.testing.assert_array_equal(
            filtered.z1pt0, expected_filtered.z1pt0
        )
        numpy.testing.assert_array_equal(
            filtered.z2pt5, expected_filtered.z2pt5
        )
        numpy.testing.assert_array_equal(
            filtered.mesh.lons, expected_filtered.mesh.lons
        )
        numpy.testing.assert_array_equal(
            filtered.mesh.lats, expected_filtered.mesh.lats
        )
        numpy.testing.assert_array_equal(
            filtered.mesh.depths, expected_filtered.mesh.depths
        )

    def test_filter_all_out(self):
        rup = self._make_rupture(50, 80, 9)
        # the JB distances are [47.0074159, 37.99716685, 40.7944923,
        #  476.2521365, 477.36015879]
        for int_dist in (0, 1, 10, 20, 37.99):
            filtered = PointSource.filter_sites_by_distance_to_rupture(
                rup, integration_distance=int_dist, sites=self.sitecol
            )
            self.assertIs(filtered, None)
예제 #35
0
 def test_3(self):
     surface = PlanarSurface(2, 3, *tdata.TEST_7_RUPTURE_2_CORNERS)
     sites = Mesh.from_points_list([Point(0, 0)])
     self.assertAlmostEqual(7.01186304977,
                            surface.get_min_distance(sites)[0], places=2)
예제 #36
0
 def test_edges_differ_in_length_within_tolerance(self):
     self.assert_successfull_creation(
         2, 3,
         Point(0, -1, 1), Point(0, 1, 1),
         Point(0, 1.000001, 2), Point(0, -1, 2)
     )
예제 #37
0
class HM2018CorrelationMatrixTestCase(unittest.TestCase):
    SITECOL = SiteCollection([Site(Point(2, -40), 1, True, 1, 1),
                              Site(Point(2, -40.1), 1, True, 1, 1),
                              Site(Point(2, -40), 1, True, 1, 1),
                              Site(Point(2, -39.9), 1, True, 1, 1)])

    def test_correlation_no_uncertainty(self):
        cormo = HM2018CorrelationModel(uncertainty_multiplier=0)

        imt = SA(period=0.1, damping=5)
        corma = cormo._get_correlation_matrix(self.SITECOL,imt)
        aaae(corma, [[1.0000000,    0.3981537,    1.0000000,    0.3981537,],
                     [0.3981537,    1.0000000,    0.3981537,    0.2596809,],
                     [1.0000000,    0.3981537,    1.0000000,    0.3981537,],
                     [0.3981537,    0.2596809,    0.3981537,    1.0000000,]])

        imt = SA(period=0.5, damping=5)
        corma = cormo._get_correlation_matrix(self.SITECOL, imt)
        aaae(corma, [[1.0000000,    0.3809173,    1.0000000,    0.3809173,],
                     [0.3809173,    1.0000000,    0.3809173,    0.2433886,],
                     [1.0000000,    0.3809173,    1.0000000,    0.3809173,],
                     [0.3809173,    0.2433886,    0.3809173,    1.0000000,]])

        imt = SA(period=1, damping=5)
        corma = cormo._get_correlation_matrix(self.SITECOL, imt)
        aaae(corma, [[1.0000000,    0.3906193,    1.0000000,    0.3906193,],
                     [0.3906193,    1.0000000,    0.3906193,    0.2525181,],
                     [1.0000000,    0.3906193,    1.0000000,    0.3906193,],
                     [0.3906193,    0.2525181,    0.3906193,    1.0000000,]])

        imt = SA(period=2, damping=5)
        corma = cormo._get_correlation_matrix(self.SITECOL, imt)
        aaae(corma, [[1.0000000,    0.4011851,    1.0000000,    0.4011851,],
                     [0.4011851,    1.0000000,    0.4011851,    0.2625807,],
                     [1.0000000,    0.4011851,    1.0000000,    0.4011851,],
                     [0.4011851,    0.2625807,    0.4011851,    1.0000000,]])

        imt = SA(period=4, damping=5)
        corma = cormo._get_correlation_matrix(self.SITECOL, imt)
        aaae(corma, [[1.0000000,    0.3522765,    1.0000000,    0.3522765,],
                     [0.3522765,    1.0000000,    0.3522765,    0.2170695,],
                     [1.0000000,    0.3522765,    1.0000000,    0.3522765,],
                     [0.3522765,    0.2170695,    0.3522765,    1.0000000,]])

        imt = SA(period=6, damping=5)
        corma = cormo._get_correlation_matrix(self.SITECOL, imt)
        aaae(corma, [[1.0000000,    0.3159779,    1.0000000,    0.3159779,],
                     [0.3159779,    1.0000000,    0.3159779,    0.1851206,],
                     [1.0000000,    0.3159779,    1.0000000,    0.3159779,],
                     [0.3159779,    0.1851206,    0.3159779,    1.0000000,]])

    def test_correlation_small_uncertainty(self):
        imt = SA(period=1.5, damping=5)

        cormo = HM2018CorrelationModel(uncertainty_multiplier=0)
        corma = cormo._get_correlation_matrix(self.SITECOL, imt)

        cormo2 = HM2018CorrelationModel(uncertainty_multiplier=1E-30)
        corma2 = cormo2._get_correlation_matrix(self.SITECOL, imt)
        self.assertTrue((corma == corma2).all())

    def test_pga_no_uncertainty(self):
        sa = SA(period=1e-50, damping=5)
        pga = PGA()

        cormo = HM2018CorrelationModel(uncertainty_multiplier=0)
        
        corma = cormo._get_correlation_matrix(self.SITECOL, sa)
        corma2 = cormo._get_correlation_matrix(self.SITECOL, pga)
        self.assertTrue((corma == corma2).all())

    def test_correlation_with_uncertainty(self):
        Nsim = 100000
        cormo = HM2018CorrelationModel(uncertainty_multiplier=1)
        imt = SA(period=3, damping=5)
        
        corma_3d = numpy.zeros((len(self.SITECOL), len(self.SITECOL), Nsim))

        # For each simulation, construct a new correlation matrix
        for isim in range(0, Nsim):
            corma_3d[0:, 0:, isim] = \
                cormo._get_correlation_matrix(self.SITECOL, imt)

        # Mean and Coefficient of Variation (COV) of correlation matrix
        MEANcorMa = corma_3d.mean(2)
        COVcorma = numpy.divide(corma_3d.std(2), MEANcorMa)

        aaae(MEANcorMa,[[1.0000000,    0.3766436,    1.0000000,    0.3766436,],
                     [0.3766436,    1.0000000,    0.3766436,    0.2534904,],
                     [1.0000000,    0.3766436,    1.0000000,    0.3766436,],
                     [0.3766436,    0.2534904,    0.3766436,    1.00000,]], 2)

        aaae(COVcorma,[[0.0000000,    0.4102512,    0.0000000,    0.4102512,],
                     [0.4102512,    0.0000000,    0.4102512,    0.5636907,],
                     [0.0000000,    0.4102512,    0.0000000,    0.4102512,],
                     [0.4102512,    0.5636907,    0.4102512,    0.00000,]], 2)
예제 #38
0
 def setUp(self):
     super(PointSourceRuptureFilterTestCase, self).setUp()
     self.hypocenter = Point(2, 0, 50)
     self.sitecol = SiteCollection(self.SITES)
예제 #39
0
 def test_2(self):
     surface = PlanarSurface(2, 3, *tdata.TEST_7_RUPTURE_6_CORNERS)
     sites = Mesh.from_points_list([Point(-0.25, 0.25)])
     self.assertAlmostEqual(40.1213468,
                            surface.get_min_distance(sites)[0], places=1)