def test_source_errors(self): # exercise `hazard_curves_poissonian` in the case of an exception, # whereby we expect the source_id to be reported in the error message fail_source = self.FailSource(self.source2.source_id, self.source2.ruptures, self.source2.time_span) sources = iter([self.source1, fail_source]) with self.assertRaises(ValueError) as ae: hazard_curves(sources, self.sites, self.imts, self.gsims, self.truncation_level) expected_error = ( 'An error occurred with source id=2. Error: Something bad happened' ) self.assertEqual(expected_error, ae.exception.message)
def reference_psha_calculation_openquake(): """ Sets up the reference PSHA calculation calling OpenQuake directly. All subsequent implementations should match this example """ # Site model - 3 Sites site_model = SiteCollection([ Site(Point(30.0, 30.0), 760., True, 1.0, 1.0, 1), Site(Point(30.25, 30.25), 760., True, 1.0, 1.0, 2), Site(Point(30.4, 30.4), 760., True, 1.0, 1.0, 2)]) # Source Model Two Point Sources mfd_1 = TruncatedGRMFD(4.5, 8.0, 0.1, 4.0, 1.0) mfd_2 = TruncatedGRMFD(4.5, 7.5, 0.1, 3.5, 1.1) source_model = [PointSource('001', 'Point1', 'Active Shallow Crust', mfd_1, 1.0, WC1994(), 1.0, PoissonTOM(50.0), 0.0, 30.0, Point(30.0, 30.5), PMF([(1.0, NodalPlane(0.0, 90.0, 0.0))]), PMF([(1.0, 10.0)])), PointSource('002', 'Point2', 'Active Shallow Crust', mfd_2, 1.0, WC1994(), 1.0, PoissonTOM(50.0), 0.0, 30.0, Point(30.0, 30.5), PMF([(1.0, NodalPlane(0.0, 90.0, 0.0))]), PMF([(1.0, 10.0)]))] imts = {PGA(): [0.01, 0.1, 0.2, 0.5, 0.8], SA(period=0.5, damping=5.0): [0.01, 0.1, 0.2, 0.5, 0.8]} # Akkar & Bommer (2010) GMPE gsims = {'Active Shallow Crust': gsim.akkar_bommer_2010.AkkarBommer2010()} truncation_level = None return hazard_curves(source_model, site_model, imts, gsims, truncation_level)
def test1(self): site1_pga_poe_expected = [0.0639157, 0.03320212, 0.02145989] site2_pga_poe_expected = [0.06406232, 0.02965879, 0.01864331] site1_pgd_poe_expected = [0.16146619, 0.1336553] site2_pgd_poe_expected = [0.15445961, 0.13437589] curves = hazard_curves(self.sources, self.sites, self.imts, self.gsims, self.truncation_level) self.assertIsInstance(curves, dict) self.assertEqual(set(curves.keys()), set([imt.PGA(), imt.PGD()])) pga_curves = curves[imt.PGA()] self.assertIsInstance(pga_curves, numpy.ndarray) self.assertEqual(pga_curves.shape, (2, 3)) # two sites, three IMLs site1_pga_poe, site2_pga_poe = pga_curves self.assertTrue(numpy.allclose(site1_pga_poe, site1_pga_poe_expected), str(site1_pga_poe)) self.assertTrue(numpy.allclose(site2_pga_poe, site2_pga_poe_expected), str(site2_pga_poe)) pgd_curves = curves[imt.PGD()] self.assertIsInstance(pgd_curves, numpy.ndarray) self.assertEqual(pgd_curves.shape, (2, 2)) # two sites, two IMLs site1_pgd_poe, site2_pgd_poe = pgd_curves self.assertTrue(numpy.allclose(site1_pgd_poe, site1_pgd_poe_expected), str(site1_pgd_poe)) self.assertTrue(numpy.allclose(site2_pgd_poe, site2_pgd_poe_expected), str(site2_pgd_poe))
def calculate_hazard(self, num_workers=DEFAULT_WORKERS, num_src_workers=1): """ Calculates the hazard :param int num_workers: Number of workers for parallel calculation :param int num_src_workers: Number of elements per worker """ return hazard_curve.hazard_curves(self.source_model, self.sites, self.imts, self.gmpes, self.truncation_level, self.src_filter, self.rup_filter)
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 = {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( iter(sources), sitecol, imts, gsims, truncation_level, source_site_filter=source_site_filter, rupture_site_filter=rupture_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])]) self.assertEqual(rupture_site_filter.counts, [(6, [4]), (8, [3, 4])])