예제 #1
0
파일: area.py 프로젝트: tieganh/oq-engine
    def iter_ruptures(self, **kwargs):
        """
        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
        # NB: all this mumbo-jumbo is done to avoid multiple calls to
        # PointSource._get_rupture_surface
        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 = geo.Point(latitude=epicenter0.latitude,
                                           longitude=epicenter0.longitude,
                                           depth=hc_depth)
                    occurrence_rate = (mag_occ_rate * np_prob * hc_prob *
                                       rate_scaling_factor)
                    surface, nhc = PointSource._get_rupture_surface(
                        self, mag, np, hypocenter)
                    if kwargs.get('shift_hypo'):
                        hc_depth = nhc.depth
                    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,
                    occ_rate, self.temporal_occurrence_model)
                yield rupture
예제 #2
0
    def test_latitude_inside_range(self):
        self.assertRaises(ValueError, geo.Point, 0.0, 90.1, 0.0)
        self.assertRaises(ValueError, geo.Point, 0.0, -90.1, 0.0)

        geo.Point(0.0, 90.0, 0.0)
        geo.Point(0.0, -90.0, 0.0)
예제 #3
0
    def test_no_points_outside_of_polygon(self):
        dist = 1e-4
        points = [
            geo.Point(0, 0),
            geo.Point(dist * 4.5, 0),
            geo.Point(dist * 4.5, -dist * 4.5),
            geo.Point(dist * 3.5, -dist * 4.5),
            geo.Point(dist * (4.5 - 0.8), -dist * 1.5),
            geo.Point(0, -dist * 1.5)
        ]
        poly = geo.Polygon(points)
        mesh = list(poly.discretize(mesh_spacing=1.1e-2))
        self.assertEqual(mesh, [
            geo.Point(dist, -dist),
            geo.Point(dist * 2, -dist),
            geo.Point(dist * 3, -dist),
            geo.Point(dist * 4, -dist),

            geo.Point(dist * 4, -dist * 2),
            geo.Point(dist * 4, -dist * 3),
            geo.Point(dist * 4, -dist * 4),
        ])
예제 #4
0
 def test_azimuth_over_180_degree(self):
     p1 = geo.Point(0.0, 0.0)
     p2 = geo.Point(0.5, 0.5)
     self.assertAlmostEqual(225.0010908, p2.azimuth(p1))
예제 #5
0
 def test_equally_spaced_points_last_point(self):
     points = geo.Point(0, 50).equally_spaced_points(geo.Point(10, 50), 10)
     self.assertAlmostEqual(points[-1].latitude, 50, places=2)
예제 #6
0
 def test_equally_spaced_points_4(self):
     p1 = geo.Point(0, 0, 10)
     p2 = geo.Point(0, 0, 7)
     points = p1.equally_spaced_points(p2, 1)
     self.assertEqual(points,
                      [p1, geo.Point(0, 0, 9), geo.Point(0, 0, 8), p2])
예제 #7
0
 def test_point_at_2(self):
     p1 = geo.Point(0.0, 0.0, 10.0)
     expected = geo.Point(0.0635916667129, 0.0635916275455, 5.0)
     self.assertEqual(expected, p1.point_at(10.0, -5.0, 45.0))
예제 #8
0
class TrtModelTestCase(unittest.TestCase):
    SITES = [
        site.Site(geo.Point(-121.0, 37.0), 0.1, True, 3, 4),
        site.Site(geo.Point(-121.1, 37.0), 1, True, 3, 4),
        site.Site(geo.Point(-121.0, -37.15), 2, True, 3, 4),
        site.Site(geo.Point(-121.0, 37.49), 3, True, 3, 4),
        site.Site(geo.Point(-121.0, -37.5), 4, True, 3, 4),
    ]

    @classmethod
    def setUpClass(cls):
        cls.parser = SourceModelParser(
            s.SourceConverter(
                investigation_time=50.,
                rupture_mesh_spacing=1,  # km
                complex_fault_mesh_spacing=1,  # km
                width_of_mfd_bin=1.,  # for Truncated GR MFDs
                area_source_discretization=1.))
        cls.source_collector = {
            sc.trt: sc
            for sc in cls.parser.parse_trt_models(MIXED_SRC_MODEL)
        }
        cls.sitecol = site.SiteCollection(cls.SITES)

    def check(self, trt, attr, value):
        sc = self.source_collector[trt]
        self.assertEqual(getattr(sc, attr), value)

    def test_content(self):
        trts = [sc.trt for sc in self.source_collector.values()]
        self.assertEqual(trts, [
            'Volcanic', 'Subduction Interface', 'Stable Continental Crust',
            'Active Shallow Crust'
        ])

        self.check('Volcanic', 'max_mag', 6.5)
        self.check('Subduction Interface', 'max_mag', 6.5)
        self.check('Stable Continental Crust', 'max_mag', 6.5)
        self.check('Active Shallow Crust', 'max_mag', 6.95)

        self.check('Volcanic', 'min_mag', 5.0)
        self.check('Subduction Interface', 'min_mag', 5.5)
        self.check('Stable Continental Crust', 'min_mag', 5.5)
        self.check('Active Shallow Crust', 'min_mag', 5.0)

    def test_repr(self):
        self.assertEqual(
            repr(self.source_collector['Volcanic']),
            '<TrtModel #0 Volcanic, 3 source(s), -1 effective rupture(s)>')
        self.assertEqual(
            repr(self.source_collector['Stable Continental Crust']),
            '<TrtModel #0 Stable Continental Crust, 1 source(s), '
            '-1 effective rupture(s)>')
        self.assertEqual(
            repr(self.source_collector['Subduction Interface']),
            '<TrtModel #0 Subduction Interface, 1 source(s), '
            '-1 effective rupture(s)>')
        self.assertEqual(
            repr(self.source_collector['Active Shallow Crust']),
            '<TrtModel #0 Active Shallow Crust, 2 source(s), -1'
            ' effective rupture(s)>')
예제 #9
0
def get_mesh(oqparam):
    """
    Extract the mesh of points to compute from the sites,
    the sites_csv, or the region.

    :param oqparam:
        an :class:`openquake.commonlib.oqvalidation.OqParam` instance
    """
    global pmap
    if oqparam.sites:
        return geo.Mesh.from_coords(sorted(oqparam.sites))
    elif 'sites' in oqparam.inputs:
        csv_data = open(oqparam.inputs['sites'], 'U').readlines()
        has_header = csv_data[0].startswith('site_id')
        if has_header:  # strip site_id
            data = []
            for i, line in enumerate(csv_data[1:]):
                row = line.replace(',', ' ').split()
                sid = row[0]
                if sid != str(i):
                    raise InvalidFile('%s: expected site_id=%d, got %s' %
                                      (oqparam.inputs['sites'], i, sid))
                data.append(' '.join(row[1:]))
        elif 'gmfs' in oqparam.inputs:
            raise InvalidFile('Missing header in %(sites)s' % oqparam.inputs)
        else:
            data = [line.replace(',', ' ') for line in csv_data]
        coords = valid.coordinates(','.join(data))
        start, stop = oqparam.sites_slice
        c = coords[start:stop] if has_header else sorted(coords[start:stop])
        return geo.Mesh.from_coords(c)
    elif 'hazard_curves' in oqparam.inputs:
        fname = oqparam.inputs['hazard_curves']
        if fname.endswith('.csv'):
            mesh, pmap = get_pmap_from_csv(oqparam, fname)
        elif fname.endswith('.xml'):
            mesh, pmap = get_pmap_from_nrml(oqparam, fname)
        else:
            raise NotImplementedError('Reading from %s' % fname)
        return mesh
    elif oqparam.region:
        # close the linear polygon ring by appending the first
        # point to the end
        firstpoint = geo.Point(*oqparam.region[0])
        points = [geo.Point(*xy) for xy in oqparam.region] + [firstpoint]
        try:
            mesh = geo.Polygon(points).discretize(oqparam.region_grid_spacing)
            lons, lats = zip(*sorted(zip(mesh.lons, mesh.lats)))
            return geo.Mesh(numpy.array(lons), numpy.array(lats))
        except:
            raise ValueError(
                'Could not discretize region %(region)s with grid spacing '
                '%(region_grid_spacing)s' % vars(oqparam))
    elif oqparam.hazard_calculation_id:
        # return the mesh corresponding to the complete site collection
        with datastore.read(oqparam.hazard_calculation_id) as dstore:
            sitecol = dstore['sitecol'].complete
        return geo.Mesh(sitecol.lons, sitecol.lats, sitecol.depths)
    elif 'exposure' in oqparam.inputs:
        # the mesh will be extracted from the exposure later
        return
    elif 'site_model' in oqparam.inputs:
        coords = [(param.lon, param.lat, param.depth)
                  for param in get_site_model(oqparam)]
        mesh = geo.Mesh.from_coords(sorted(coords))
        mesh.from_site_model = True
        return mesh
예제 #10
0
 def test_intersects_itself_being_closed(self):
     msg = 'polygon perimeter intersects itself'
     points = [geo.Point(0, 0), geo.Point(0, 1),
               geo.Point(1, 0), geo.Point(1, 1)]
     self.assert_failed_creation(points, ValueError, msg)
예제 #11
0
from hmtk.sources import source_model, area_source

from openquake.nrmllib import models
from openquake.hazardlib import geo

from decimal import Decimal

a = area_source.mtkAreaSource(identifier = "01", 
                  name = "area source name", 
                  trt = "stable crust", 
                  geometry = geo.Polygon([geo.Point(-58.73, -10.33),
                                          geo.Point(-58.74, -13.54),
                                          geo.Point(-55.94, -13.59), 
                                          geo.Point(-56.58, -10.31),
                                          geo.Point(-58.73, -10.33)]), 
                  upper_depth = "0", 
                  lower_depth = "30", 
                  mag_scale_rel = "WC1994", # default 
                  rupt_aspect_ratio = 1, 
                  mfd = models.TGRMFD(min_mag=3.0,
                                      max_mag=7.0, 
                                      b_val=0.847, 
                                      a_val=0.737), 
                  nodal_plane_dist = models.NodalPlane(Decimal('1.0'), 
                                                       strike=0., 
                                                       dip=90.,
                                                       rake=0.), 
                  hypo_depth_dist = None)

#a.create_oqnrml_source
예제 #12
0
 def test_less_than_three_unique_points(self):
     msg = 'polygon must have at least 3 unique vertices'
     points = [geo.Point(1, 2)] * 3 + [geo.Point(4, 5)]
     self.assert_failed_creation(points, ValueError, msg)
예제 #13
0
 def test_less_than_three_points(self):
     msg = 'polygon must have at least 3 unique vertices'
     self.assert_failed_creation([], ValueError, msg)
     self.assert_failed_creation([geo.Point(1, 1)], ValueError, msg)
     self.assert_failed_creation([geo.Point(1, 1),
                                  geo.Point(2, 1)], ValueError, msg)
예제 #14
0
 def setUp(self):
     self.corners = [
         geo.Point(-10, 10), geo.Point(10, 10), geo.Point(10, -10),
         geo.Point(-10, -10),
     ]
     self.poly = geo.Polygon(self.corners)
예제 #15
0
    def _expected_complex(self):
        tgr_mfd = mfd.TruncatedGRMFD(a_val=-3.5,
                                     b_val=1.0,
                                     min_mag=5.0,
                                     max_mag=6.5,
                                     bin_width=1.0)

        edges = [
            geo.Line([
                geo.Point(-124.704, 40.363, 0.5493260E+01),
                geo.Point(-124.977, 41.214, 0.4988560E+01),
                geo.Point(-125.140, 42.096, 0.4897340E+01),
            ]),
            geo.Line([
                geo.Point(-124.704, 40.363, 0.5593260E+01),
                geo.Point(-124.977, 41.214, 0.5088560E+01),
                geo.Point(-125.140, 42.096, 0.4997340E+01),
            ]),
            geo.Line([
                geo.Point(-124.704, 40.363, 0.5693260E+01),
                geo.Point(-124.977, 41.214, 0.5188560E+01),
                geo.Point(-125.140, 42.096, 0.5097340E+01),
            ]),
            geo.Line([
                geo.Point(-123.829, 40.347, 0.2038490E+02),
                geo.Point(-124.137, 41.218, 0.1741390E+02),
                geo.Point(-124.252, 42.115, 0.1752740E+02),
            ]),
        ]

        cmplx = source.ComplexFaultSource(
            source_id="4",
            name="Cascadia Megathrust",
            tectonic_region_type="Subduction Interface",
            mfd=tgr_mfd,
            rupture_mesh_spacing=self.complex_fault_mesh_spacing,
            magnitude_scaling_relationship=scalerel.WC1994(),
            rupture_aspect_ratio=2.0,
            edges=edges,
            rake=30.0,
            temporal_occurrence_model=PoissonTOM(50.))
        cmplx.num_ruptures = cmplx.count_ruptures()
        return cmplx
예제 #16
0
 def test_international_date_line(self):
     self.assertEqual(
         geo.Point(*utils.get_middle_point(-178, 10, 178, -10)),
         geo.Point(180, 0))
     self.assertEqual(geo.Point(*utils.get_middle_point(-179, 43, 179, 43)),
                      geo.Point(180, 43.004353))
예제 #17
0
    def _expected_char_complex(self):
        incr_mfd = mfd.EvenlyDiscretizedMFD(min_mag=5.0,
                                            bin_width=0.1,
                                            occurrence_rates=[
                                                0.0010614989, 8.8291627E-4,
                                                7.3437777E-4, 6.108288E-4,
                                                5.080653E-4
                                            ])

        edges = [
            geo.Line([
                geo.Point(-124.704, 40.363, 0.5493260E+01),
                geo.Point(-124.977, 41.214, 0.4988560E+01),
                geo.Point(-125.140, 42.096, 0.4897340E+01),
            ]),
            geo.Line([
                geo.Point(-124.704, 40.363, 0.5593260E+01),
                geo.Point(-124.977, 41.214, 0.5088560E+01),
                geo.Point(-125.140, 42.096, 0.4997340E+01),
            ]),
            geo.Line([
                geo.Point(-124.704, 40.363, 0.5693260E+01),
                geo.Point(-124.977, 41.214, 0.5188560E+01),
                geo.Point(-125.140, 42.096, 0.5097340E+01),
            ]),
            geo.Line([
                geo.Point(-123.829, 40.347, 0.2038490E+02),
                geo.Point(-124.137, 41.218, 0.1741390E+02),
                geo.Point(-124.252, 42.115, 0.1752740E+02),
            ])
        ]
        complex_surface = geo.ComplexFaultSurface.from_fault_data(
            edges, self.complex_fault_mesh_spacing)

        char = source.CharacteristicFaultSource(
            source_id="6",
            name="characteristic source, complex fault",
            tectonic_region_type="Volcanic",
            mfd=incr_mfd,
            surface=complex_surface,
            rake=60.0,
            temporal_occurrence_model=PoissonTOM(50.0))
        char.num_ruptures = char.count_ruptures()
        return char
예제 #18
0
 def test_exact_duplicates(self):
     a, b, c = geo.Point(1, 2, 3), geo.Point(3, 4, 5), geo.Point(5, 6, 7)
     self.assertEqual(utils.clean_points([a, a, a, b, a, c, c]),
                      [a, b, a, c])
예제 #19
0
    def test_depth_inside_range(self):
        self.assertRaises(ValueError, geo.Point, 0.0, 0.0, EARTH_RADIUS)
        self.assertRaises(ValueError, geo.Point, 0.0, 0.0, EARTH_RADIUS + 0.1)

        geo.Point(0.0, 90.0, EARTH_RADIUS - 0.1)
예제 #20
0
 def test_close_duplicates(self):
     a, b, c = geo.Point(1e-4, 1e-4), geo.Point(0, 0), geo.Point(1e-6, 1e-6)
     self.assertEqual(utils.clean_points([a, b, c]), [a, b])
예제 #21
0
    def test_azimuth(self):
        p1 = geo.Point(0.0, 0.0)
        p2 = geo.Point(0.5, 0.5)

        self.assertAlmostEqual(44.9989091554, p1.azimuth(p2))
예제 #22
0
 def test_line_of_one_point(self):
     line = geo.Line([geo.Point(0, 0)])
     self.assertRaises(AssertionError, line.resample_to_num_points, 10)
예제 #23
0
    def test_distance(self):
        p1 = geo.Point(0.0, 0.0, 0.0)
        p2 = geo.Point(0.5, 0.5, 5.0)

        self.assertAlmostEqual(78.7849704355, p1.distance(p2), places=4)
예제 #24
0
 def test_hangup(self):
     p1 = geo.Point(0.00899322032502, 0., 0.)
     p2 = geo.Point(0.01798644058385, 0., 1.)
     p3 = geo.Point(0.02697966087241, 0., 2.)
     line = geo.Line([p1, p2, p3]).resample_to_num_points(3)
     self.assertEqual(line.points, [p1, p2, p3])
예제 #25
0
    def test_longitude_inside_range(self):
        self.assertRaises(ValueError, geo.Point, 180.1, 0.0, 0.0)
        self.assertRaises(ValueError, geo.Point, -180.1, 0.0, 0.0)

        geo.Point(180.0, 0.0)
        geo.Point(-180.0, 0.0)
예제 #26
0
 def test(self):
     line = geo.Line([geo.Point(0, 0), geo.Point(0, 1), geo.Point(1, 2)])
     length = line.get_length()
     expected_length = line.points[0].distance(line.points[1]) \
                       + line.points[1].distance(line.points[2])
     self.assertEqual(length, expected_length)
예제 #27
0
 def test_from_vector(self):
     point = geo.Point(12.34, -56.78, 91.011)
     vector = spherical_to_cartesian(point.x, point.y, point.z)
     self.assertEqual(point, geo.Point.from_vector(vector))
예제 #28
0
    def _characteristic_to_hazardlib(self, src):
        """
        Convert a NRML characteristic fault source to the HazardLib equivalent.

        The surface of a characteristic fault source can be one of the
        following:
            * simple fault
            * complex fault
            * one or more planar surfaces

        See :mod:`openquake.nrmllib.models` and
        :mod:`openquake.hazardlib.source`.

        :param src:
            :class:`openquake.nrmllib.models.CharacteristicSource` instance.
        :returns:
            The HazardLib representation of the input source.
        """
        mf_dist = self._mfd_to_hazardlib(src.mfd)

        if isinstance(src.surface, nrml_models.SimpleFaultGeometry):
            shapely_line = wkt.loads(src.surface.wkt)
            fault_trace = geo.Line(
                [geo.Point(*x) for x in shapely_line.coords])

            surface = geo.SimpleFaultSurface.from_fault_data(
                fault_trace,
                src.surface.upper_seismo_depth,
                src.surface.lower_seismo_depth,
                src.surface.dip,
                self.rupture_mesh_spacing,
            )
        elif isinstance(src.surface, nrml_models.ComplexFaultGeometry):
            edges_wkt = []
            edges_wkt.append(src.surface.top_edge_wkt)
            edges_wkt.extend(src.surface.int_edges)
            edges_wkt.append(src.surface.bottom_edge_wkt)

            edges = []

            for edge in edges_wkt:
                shapely_line = wkt.loads(edge)
                line = geo.Line([geo.Point(*x) for x in shapely_line.coords])
                edges.append(line)

            surface = geo.ComplexFaultSurface.from_fault_data(
                edges, self.rupture_mesh_spacing)
        else:
            # A collection of planar surfaces
            planar_surfaces = []
            for planar_surface in src.surface:
                kwargs = planar_surface.__dict__
                kwargs.update(dict(mesh_spacing=self.rupture_mesh_spacing))

                planar_surfaces.append(geo.PlanarSurface(**kwargs))

            surface = geo.MultiSurface(planar_surfaces)

        char = source.CharacteristicFaultSource(
            source_id=src.id,
            name=src.name,
            tectonic_region_type=src.trt,
            mfd=mf_dist,
            surface=surface,
            rake=src.rake,
            temporal_occurrence_model=self.default_tom,
        )
        return char