def _verify_curves(self, gsim_name, truncation_level, ndp=3): """ Implements the core verification. Initially the hazard calculation is run with the "Mean" GMPE (this has the mean weightings inside the GMPE). Then the "low", "average" and "high" cases are run separately and the resulting curves summed with their respective weights. A small degree of mismatch is found though this typcially takes place at very low probabilities. Curves are compared in the logarithmic domain (ignoring 0 values) """ gsim0 = {"Active Shallow Crust": self.gsim_set[gsim_name][0]} # Run new weighted mean curve wmean_curve = calc_hazard_curves(self.sources, self.sites, self.imtls, gsim0, truncation_level) # Now run low, mid and high curves curves = {"PGA": np.zeros_like(wmean_curve["PGA"])} for iloc in range(1, 4): gsim_i = { "Active Shallow Crust": self.gsim_set[gsim_name][iloc][1] } wgt = self.gsim_set[gsim_name][iloc][0] curves["PGA"] += ( wgt * calc_hazard_curves(self.sources, self.sites, self.imtls, gsim_i, truncation_level)["PGA"]) # Ignore cases where values are equal to zero idx = wmean_curve["PGA"] > 0.0 np.testing.assert_array_almost_equal( np.log(wmean_curve["PGA"][idx]), np.log(curves["PGA"][idx]), ndp)
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(0.5)': [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 calc_hazard_curves(source_model, site_model, imts, gsims, truncation_level)
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: calc_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 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 = calc_hazard_curves( self.sources, self.sites, self.imts, self.gsims, self.truncation_level) self.assertEqual(set(curves.dtype.fields), set(['PGA', 'PGD'])) pga_curves = curves['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['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 test_hazard_curve_X(self): # Test the former calculator curves = calc_hazard_curves([self.src2], self.sites, self.imtls, self.gsim_by_trt, truncation_level=None) crv = curves[0][0] self.assertAlmostEqual(0.3, crv[0])
def test_hazard_curve_B(self): # Test classical case i.e. independent sources in a list instance curves = calc_hazard_curves([self.src1, self.src2], self.sites, self.imtls, self.gsim_by_trt, truncation_level=None) crv = curves[0][0] npt.assert_almost_equal(numpy.array([0.58000, 0.53, 0.1347]), crv, decimal=4)
def test(self): d = os.path.dirname(os.path.dirname(__file__)) source_model = os.path.join(d, 'source_model/multi-point-source.xml') groups = nrml.to_python(source_model, SourceConverter( investigation_time=50., rupture_mesh_spacing=2.)) site = Site(Point(0.1, 0.1), 800, z1pt0=100., z2pt5=1.) sitecol = SiteCollection([site]) imtls = DictArray({'PGA': [0.01, 0.02, 0.04, 0.08, 0.16]}) gsim_by_trt = {'Stable Continental Crust': Campbell2003()} hcurves = calc_hazard_curves(groups, sitecol, imtls, gsim_by_trt) expected = [0.99999778, 0.9084039, 0.148975348, 0.0036909656, 2.76326e-05] npt.assert_almost_equal(hcurves['PGA'][0], expected) # splitting in point sources [[mps1, mps2]] = groups psources = list(mps1) + list(mps2) hcurves = calc_hazard_curves(psources, sitecol, imtls, gsim_by_trt) npt.assert_almost_equal(hcurves['PGA'][0], expected)
def test_hazard_curve_A(self): # Test back-compatibility # Classical case i.e. independent sources in a list instance curves = calc_hazard_curves([self.src2], self.sites, self.imtls, self.gsim_by_trt, truncation_level=None) crv = curves[0][0] npt.assert_almost_equal(numpy.array([0.30000, 0.2646, 0.0625]), crv, decimal=4)
def test_hazard_curve_B(self): # Test simple calculation group = SourceGroup( TRT.ACTIVE_SHALLOW_CRUST, [self.src2], 'test', 'indep', 'indep') groups = [group] curves = calc_hazard_curves(groups, self.sites, self.imtls, self.gsim_by_trt, truncation_level=None) npt.assert_almost_equal(numpy.array([0.30000, 0.2646, 0.0625]), curves[0][0], decimal=4)
def test(self): source_model = os.path.join(os.path.dirname(__file__), 'nankai.xml') groups = nrml.to_python(source_model, SourceConverter( investigation_time=50., rupture_mesh_spacing=2.)) site = Site(Point(135.68, 35.68), 400, z1pt0=100., z2pt5=1.) s_filter = SourceFilter(SiteCollection([site]), {}) imtls = DictArray({'PGV': [20, 40, 80]}) gsim_by_trt = {'Subduction Interface': SiMidorikawa1999SInter()} hcurves = calc_hazard_curves(groups, s_filter, imtls, gsim_by_trt) npt.assert_almost_equal( [1.1262869e-01, 3.9968668e-03, 3.1005840e-05], hcurves['PGV'][0])
def test_non_parametric_source(self): # non-parametric source equivalent to case 2 simple fault source data = test_data.SET1_CASE2_SOURCE_DATA ruptures = [] for i in range(data['num_rups_dip']): for j in range(data['num_rups_strike']): lons = data['lons'] lats = data['lats'][j] depths = data['depths'][i] mesh = RectangularMesh(lons, lats, depths) surf = SimpleFaultSurface(mesh) hypo = Point( data['hypo_lons'][i, j], data['hypo_lats'][i, j], data['hypo_depths'][i, j] ) rup = Rupture(data['mag'], data['rake'], data['tectonic_region_type'], hypo, surf, data['source_typology']) ruptures.append((rup, data['pmf'])) npss = NonParametricSeismicSource( 'id', 'name', data['tectonic_region_type'], ruptures ) sites = SiteCollection([ test_data.SET1_CASE1TO9_SITE1, test_data.SET1_CASE1TO9_SITE2, test_data.SET1_CASE1TO9_SITE3, test_data.SET1_CASE1TO9_SITE4, test_data.SET1_CASE1TO9_SITE5, test_data.SET1_CASE1TO9_SITE6, test_data.SET1_CASE1TO9_SITE7 ]) gsims = {const.TRT.ACTIVE_SHALLOW_CRUST: SadighEtAl1997()} truncation_level = 0 imts = {str(test_data.IMT): test_data.SET1_CASE2_IMLS} curves = calc_hazard_curves([npss], sites, imts, gsims, truncation_level) s1hc, s2hc, s3hc, s4hc, s5hc, s6hc, s7hc = curves[str(test_data.IMT)] assert_hazard_curve_is(self, s1hc, test_data.SET1_CASE2_SITE1_POES, atol=3e-3, rtol=1e-5) assert_hazard_curve_is(self, s2hc, test_data.SET1_CASE2_SITE2_POES, atol=2e-5, rtol=1e-5) assert_hazard_curve_is(self, s3hc, test_data.SET1_CASE2_SITE3_POES, atol=2e-5, rtol=1e-5) assert_hazard_curve_is(self, s4hc, test_data.SET1_CASE2_SITE4_POES, atol=1e-3, rtol=1e-5) assert_hazard_curve_is(self, s5hc, test_data.SET1_CASE2_SITE5_POES, atol=1e-3, rtol=1e-5) assert_hazard_curve_is(self, s6hc, test_data.SET1_CASE2_SITE6_POES, atol=1e-3, rtol=1e-5) assert_hazard_curve_is(self, s7hc, test_data.SET1_CASE2_SITE7_POES, atol=2e-5, rtol=1e-5)
def test(self): # mutually exclusive ruptures d = os.path.dirname(os.path.dirname(__file__)) tmps = 'nonparametric-source-mutex-ruptures.xml' source_model = os.path.join(d, 'source_model', tmps) groups = nrml.to_python(source_model, SourceConverter( investigation_time=50., rupture_mesh_spacing=2.)) site = Site(Point(143.5, 39.5), 800, z1pt0=100., z2pt5=1.) sitecol = SiteCollection([site]) imtls = DictArray({'PGA': [0.01, 0.1, 0.2, 0.5]}) gsim_by_trt = {'Some TRT': Campbell2003()} hcurves = calc_hazard_curves(groups, sitecol, imtls, gsim_by_trt) # expected results obtained with an ipython notebook expected = [4.3998728e-01, 1.1011728e-01, 7.5495312e-03, 8.5812844e-06] npt.assert_almost_equal(hcurves['PGA'][0], expected)
def test(self): sitecol = SiteCollection([Site(Point(30.0, 30.0), 760., 1.0, 1.0)]) mfd = TruncatedGRMFD(4.5, 8.0, 0.1, 4.0, 1.0) sources = [ PointSource('001', 'Point1', 'Active Shallow Crust', mfd, 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)])) ] imtls = {'PGA': [0.01, 0.1, 0.2, 0.5, 0.8]} hc1 = calc_hazard_curves( sources, sitecol, imtls, {'Active Shallow Crust': AkkarBommer2010()})['PGA'] hc2 = calc_hazard_curves( sources, sitecol, imtls, {'Active Shallow Crust': SadighEtAl1997()})['PGA'] hc = .6 * hc1 + .4 * hc2 ag = AvgGMPE(b1=dict(AkkarBommer2010={'weight': .6}), b2=dict(SadighEtAl1997={'weight': .4})) hcm = calc_hazard_curves(sources, sitecol, imtls, {'Active Shallow Crust': ag})['PGA'] # the AvgGMPE is not producing real means!! numpy.testing.assert_almost_equal(hc, hcm, decimal=3)
def test_two_sites(self): site1 = Site(Point(0, 0), vs30=760., z1pt0=48.0, z2pt5=0.607, vs30measured=True) site2 = Site(Point(0, 0.5), vs30=760., z1pt0=48.0, z2pt5=0.607, vs30measured=True) sitecol = SiteCollection([site1, site2]) srcfilter = SourceFilter(sitecol, IntegrationDistance.new('200')) imtls = {"PGA": [.123]} for period in numpy.arange(.1, .5, .1): imtls['SA(%.2f)' % period] = [.123] assert len(imtls) == 5 # 5 periods gsim_by_trt = {'Stable Continental Crust': ExampleA2021()} hcurves = calc_hazard_curves( [asource], srcfilter, DictArray(imtls), gsim_by_trt) print(hcurves)
def main(job_ini): logging.basicConfig(level=logging.INFO) oq = readinput.get_oqparam(job_ini) sitecol = readinput.get_site_collection(oq) src_filter = SourceFilter(sitecol, oq.maximum_distance) csm = readinput.get_composite_source_model(oq) for smr, rlzs in csm.full_lt.get_rlzs_by_smr().items(): groups = csm.get_groups(smr) for rlz in rlzs: hcurves = calc_hazard_curves(groups, src_filter, oq.imtls, csm.full_lt.gsim_by_trt(rlz), oq.truncation_level, parallel.Starmap.apply) print('rlz=%s, hcurves=%s' % (rlz, hcurves)) parallel.Starmap.shutdown()
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.calc_hazard_curves(self.source_model, self.sites, self.imts, self.gmpes, self.truncation_level, self.src_filter, self.rup_filter)
def test(self): # mutually exclusive ruptures d = os.path.dirname(os.path.dirname(__file__)) source_model = os.path.join( d, 'source_model/nonparametric-source-mutex-ruptures.xml') groups = nrml.to_python( source_model, SourceConverter(investigation_time=50., rupture_mesh_spacing=2.)) site = Site(Point(143.5, 39.5), 800, z1pt0=100., z2pt5=1.) sitecol = SiteCollection([site]) imtls = DictArray({'PGA': [0.01, 0.1, 0.2, 0.5]}) gsim_by_trt = {'Some TRT': Campbell2003()} hcurves = calc_hazard_curves(groups, sitecol, imtls, gsim_by_trt) # expected results obtained with an ipython notebook expected = [4.3998728e-01, 1.1011728e-01, 7.5495312e-03, 8.5812844e-06] npt.assert_almost_equal(hcurves['PGA'][0], expected)
def test_hazard_curve(self): # Classical PSHA with cluster source curves = calc_hazard_curves(self.sg, self.sites, self.imtls, self.gsim_by_trt, truncation_level=None) crv = curves[0][0] # Expected results computed with a notebook using the original USGS # formulation as described in Appendix F of Petersen et al. (2008). # The rates of exceedance were converted a posteriori into # probabilities. rates = np.array([1.00000000e-03, 9.98565030e-04, 8.42605169e-04, 4.61559062e-04, 1.10100503e-06]) expected = 1 - np.exp(-rates) np.testing.assert_almost_equal(crv, expected)
def test(self): site = Site(Point(0, 0), vs30=760., z1pt0=48.0, z2pt5=0.607, vs30measured=True) sitecol = SiteCollection([site]) imtls = {"PGA": valid.logscale(.1, 1, 10)} gsim = BooreAtkinson2008() [hcurve] = calc_hazard_curves([asource], sitecol, imtls, {"Stable Continental Crust": gsim}) exp = [ 0.879914, 0.747273, 0.566655, 0.376226, 0.217617, 0.110198, 0.049159, 0.019335, 0.006663, 0.001989 ] numpy.testing.assert_allclose(hcurve['PGA'], exp, atol=1E-5)
def test(self): sitecol = SiteCollection([ Site(Point(-65.13490, 0.0), vs30=760., z1pt0=48.0, z2pt5=0.607, vs30measured=True) ]) mfd = ArbitraryMFD([6.0], [0.01604252]) trace = Line([Point(-65.0000, -0.11240), Point(-65.000, 0.11240)]) # 1.0 km Mesh Spacing mesh_spacing = 1.0 msr = PeerMSR() sources = [ SimpleFaultSource("001", "PEER Fault Set 2.5", "Active Shallow Crust", mfd, mesh_spacing, msr, 2.0, PoissonTOM(1.0), 0.0, 12., trace, 90., 0.) ] imtls = { "PGA": [ 0.001, 0.01, 0.05, 0.1, 0.2, 0.4, 0.6, 0.8, 1.0, 1.25, 1.5, 2.0, 2.5, 3.0, 4.0, 5.0, 6.0, 7.0 ] } gmpe = ChiouYoungs2014PEER(mixture_model={ "factors": [0.8, 1.2], "weights": [0.5, 0.5] }) hcm = calc_hazard_curves(sources, sitecol, imtls, {"Active Shallow Crust": gmpe}) # Match against the benchmark is not exact - but differences in the # log space should be on the order of less than 0.04 % in log space expected = numpy.array([ -4.140470001, -4.140913368, -4.259457496, -4.724733842, -5.900747959, -7.734816415, -9.019329629, -10.03864778, -10.90333404, -11.83885783, -12.65826442, -14.05429951, -15.22535996, -16.23988897, -17.94685518, -19.36079032, -20.57460101, -21.64201335 ]) expected = numpy.around(expected, 5) hcm_lnpga = numpy.around(numpy.log(hcm["PGA"].flatten()), 5) perc_diff = 100.0 * ((hcm_lnpga / expected) - 1.0) numpy.testing.assert_allclose(perc_diff, numpy.zeros(len(perc_diff)), atol=0.04)
def test_hazard_curve(self): # Classical PSHA with cluster source curves = calc_hazard_curves(self.sg, self.sites, self.imtls, self.gsim_by_trt, truncation_level=None) crv = curves[0][0] # Expected results computed with a notebook using the original USGS # formulation as described in Appendix F of Petersen et al. (2008). # The rates of exceedance were converted a posteriori into # probabilities. rates = np.array([ 1.00000000e-03, 9.98565030e-04, 8.42605169e-04, 4.61559062e-04, 1.10100503e-06 ]) expected = 1 - np.exp(-rates) np.testing.assert_almost_equal(crv, expected)
def test_case_11(self): hypocenter_probability = ( Decimal(1) / len(test_data.SET1_CASE11_HYPOCENTERS) ) hypocenter_pmf = PMF([ (hypocenter_probability, hypocenter) for hypocenter in test_data.SET1_CASE11_HYPOCENTERS ]) # apart from hypocenter pmf repeats case 10 sources = [AreaSource( source_id='area', name='area', tectonic_region_type=const.TRT.ACTIVE_SHALLOW_CRUST, mfd=test_data.SET1_CASE11_MFD, nodal_plane_distribution=PMF([(1, NodalPlane(0.0, 90.0, 0.0))]), hypocenter_distribution=hypocenter_pmf, upper_seismogenic_depth=0.0, lower_seismogenic_depth=10.0, magnitude_scaling_relationship=PointMSR(), rupture_aspect_ratio=test_data.SET1_RUPTURE_ASPECT_RATIO, temporal_occurrence_model=PoissonTOM(1.), polygon=test_data.SET1_CASE11_SOURCE_POLYGON, area_discretization=10.0, rupture_mesh_spacing=10.0 )] sites = SiteCollection([ test_data.SET1_CASE11_SITE1, test_data.SET1_CASE11_SITE2, test_data.SET1_CASE11_SITE3, test_data.SET1_CASE11_SITE4 ]) gsims = {const.TRT.ACTIVE_SHALLOW_CRUST: SadighEtAl1997()} truncation_level = 0 imts = {str(test_data.IMT): test_data.SET1_CASE11_IMLS} curves = calc_hazard_curves( sources, sites, imts, gsims, truncation_level) s1hc, s2hc, s3hc, s4hc = curves[str(test_data.IMT)] assert_hazard_curve_is(self, s1hc, test_data.SET1_CASE11_SITE1_POES, atol=1e-4, rtol=1e-1) assert_hazard_curve_is(self, s2hc, test_data.SET1_CASE11_SITE2_POES, atol=1e-4, rtol=1e-1) assert_hazard_curve_is(self, s3hc, test_data.SET1_CASE11_SITE3_POES, atol=1e-4, rtol=1e-1) assert_hazard_curve_is(self, s4hc, test_data.SET1_CASE11_SITE4_POES, atol=1e-4, rtol=1e-1)
def test_case_5(self): # only mfd differs from case 2 sources = [SimpleFaultSource(source_id='fault1', name='fault1', tectonic_region_type=const.TRT.ACTIVE_SHALLOW_CRUST, mfd=test_data.SET1_CASE5_MFD, rupture_mesh_spacing=1.0, magnitude_scaling_relationship=PeerMSR(), rupture_aspect_ratio=test_data.SET1_RUPTURE_ASPECT_RATIO, temporal_occurrence_model=PoissonTOM(1.), upper_seismogenic_depth=test_data.SET1_CASE1TO9_UPPER_SEISMOGENIC_DEPTH, lower_seismogenic_depth=test_data.SET1_CASE1TO9_LOWER_SEISMOGENIC_DEPTH, fault_trace=test_data.SET1_CASE1TO9_FAULT_TRACE, dip=test_data.SET1_CASE1TO9_DIP, rake=test_data.SET1_CASE1TO9_RAKE )] sites = SiteCollection([ test_data.SET1_CASE1TO9_SITE1, test_data.SET1_CASE1TO9_SITE2, test_data.SET1_CASE1TO9_SITE3, test_data.SET1_CASE1TO9_SITE4, test_data.SET1_CASE1TO9_SITE5, test_data.SET1_CASE1TO9_SITE6, test_data.SET1_CASE1TO9_SITE7 ]) gsims = {const.TRT.ACTIVE_SHALLOW_CRUST: SadighEtAl1997()} truncation_level = 0 imts = {str(test_data.IMT): test_data.SET1_CASE5_IMLS} curves = calc_hazard_curves( sources, sites, imts, gsims, truncation_level) s1hc, s2hc, s3hc, s4hc, s5hc, s6hc, s7hc = curves[str(test_data.IMT)] assert_hazard_curve_is(self, s1hc, test_data.SET1_CASE5_SITE1_POES, atol=1e-3, rtol=1e-5) assert_hazard_curve_is(self, s2hc, test_data.SET1_CASE5_SITE2_POES, atol=1e-3, rtol=1e-5) assert_hazard_curve_is(self, s3hc, test_data.SET1_CASE5_SITE3_POES, atol=1e-3, rtol=1e-5) assert_hazard_curve_is(self, s4hc, test_data.SET1_CASE5_SITE4_POES, atol=1e-3, rtol=1e-5) assert_hazard_curve_is(self, s5hc, test_data.SET1_CASE5_SITE5_POES, atol=1e-3, rtol=1e-5) assert_hazard_curve_is(self, s6hc, test_data.SET1_CASE5_SITE6_POES, atol=1e-3, rtol=1e-5) assert_hazard_curve_is(self, s7hc, test_data.SET1_CASE5_SITE7_POES, atol=1e-3, rtol=1e-5)
def example_calc(apply): sitecol = SiteCollection([ Site(Point(30.0, 30.0), 760., True, 1.0, 1.0), Site(Point(30.25, 30.25), 760., True, 1.0, 1.0), Site(Point(30.4, 30.4), 760., True, 1.0, 1.0)]) 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) sources = [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)]))] imtls = {'PGA': [0.01, 0.1, 0.2, 0.5, 0.8], 'SA(0.5)': [0.01, 0.1, 0.2, 0.5, 0.8]} gsims = {'Active Shallow Crust': akkar_bommer_2010.AkkarBommer2010()} return calc_hazard_curves(sources, sitecol, imtls, gsims, apply=apply)
def example_calc(apply): sitecol = SiteCollection([ Site(Point(30.0, 30.0), 760., 1.0, 1.0), Site(Point(30.25, 30.25), 760., 1.0, 1.0), Site(Point(30.4, 30.4), 760., 1.0, 1.0)]) 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) sources = [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)]))] imtls = {'PGA': [0.01, 0.1, 0.2, 0.5, 0.8], 'SA(0.5)': [0.01, 0.1, 0.2, 0.5, 0.8]} gsims = {'Active Shallow Crust': AkkarBommer2010()} return calc_hazard_curves(sources, sitecol, imtls, gsims, apply=apply)
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.SitesCounterSourceFilter( filters.source_site_distance_filter(30)) rupture_site_filter = self.SitesCounterRuptureFilter( filters.rupture_site_distance_filter(30)) calc_hazard_curves(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])])
def test_non_parametric_source(self): # non-parametric source equivalent to case 2 simple fault source data = test_data.SET1_CASE2_SOURCE_DATA ruptures = [] for i in range(data['num_rups_dip']): for j in range(data['num_rups_strike']): lons = data['lons'] lats = data['lats'][j] depths = data['depths'][i] mesh = RectangularMesh(lons, lats, depths) surf = SimpleFaultSurface(mesh) hypo = Point(data['hypo_lons'][i, j], data['hypo_lats'][i, j], data['hypo_depths'][i, j]) rup = BaseRupture(data['mag'], data['rake'], data['tectonic_region_type'], hypo, surf) ruptures.append((rup, data['pmf'])) npss = NonParametricSeismicSource('id', 'name', data['tectonic_region_type'], ruptures) sites = SiteCollection([ test_data.SET1_CASE1TO9_SITE1, test_data.SET1_CASE1TO9_SITE2, test_data.SET1_CASE1TO9_SITE3, test_data.SET1_CASE1TO9_SITE4, test_data.SET1_CASE1TO9_SITE5, test_data.SET1_CASE1TO9_SITE6, test_data.SET1_CASE1TO9_SITE7 ]) gsims = {const.TRT.ACTIVE_SHALLOW_CRUST: SadighEtAl1997()} truncation_level = 0 imts = {str(test_data.IMT): test_data.SET1_CASE2_IMLS} curves = calc_hazard_curves([npss], sites, imts, gsims, truncation_level) s1hc, s2hc, s3hc, s4hc, s5hc, s6hc, s7hc = curves[str(test_data.IMT)] assert_hazard_curve_is(self, s1hc, test_data.SET1_CASE2_SITE1_POES, atol=3e-3, rtol=1e-5) assert_hazard_curve_is(self, s2hc, test_data.SET1_CASE2_SITE2_POES, atol=2e-5, rtol=1e-5) assert_hazard_curve_is(self, s3hc, test_data.SET1_CASE2_SITE3_POES, atol=2e-5, rtol=1e-5) assert_hazard_curve_is(self, s4hc, test_data.SET1_CASE2_SITE4_POES, atol=1e-3, rtol=1e-5) assert_hazard_curve_is(self, s5hc, test_data.SET1_CASE2_SITE5_POES, atol=1e-3, rtol=1e-5) assert_hazard_curve_is(self, s6hc, test_data.SET1_CASE2_SITE6_POES, atol=1e-3, rtol=1e-5) assert_hazard_curve_is(self, s7hc, test_data.SET1_CASE2_SITE7_POES, atol=2e-5, rtol=1e-5)
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.SitesCounterSourceFilter( filters.source_site_distance_filter(30) ) rupture_site_filter = self.SitesCounterRuptureFilter( filters.rupture_site_distance_filter(30) ) calc_hazard_curves( 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])])
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, 2, 3), openquake.hazardlib.site.Site(Point(10, 16), 2, 2, 3), openquake.hazardlib.site.Site(Point(10, 10.6, 1), 3, 2, 3), openquake.hazardlib.site.Site(Point(10, 10.7, -1), 4, 2, 3)] sitecol = openquake.hazardlib.site.SiteCollection(sites) gsims = {const.TRT.ACTIVE_SHALLOW_CRUST: SadighEtAl1997()} truncation_level = 1 imts = {'PGA': [0.1, 0.5, 1.3]} s_filter = SourceFilter(sitecol, {const.TRT.ACTIVE_SHALLOW_CRUST: 30}) result = calc_hazard_curves( sources, s_filter, imts, gsims, truncation_level)['PGA'] # 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(result.shape, (4, 3)) # 4 sites, 3 levels numpy.testing.assert_allclose(result[0], 0) # no contrib to site 1 numpy.testing.assert_allclose(result[1], 0) # no contrib to site 2 # test that depths are kept after filtering (sites 3 and 4 remain) s_filter = SourceFilter(sitecol, {'default': 100}) numpy.testing.assert_array_equal( s_filter.get_close_sites(sources[0]).depths, ([1, -1]))
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, 2, 3), openquake.hazardlib.site.Site(Point(10, 16), 2, 2, 3), openquake.hazardlib.site.Site(Point(10, 10.6, 1), 3, 2, 3), openquake.hazardlib.site.Site(Point(10, 10.7, -1), 4, 2, 3) ] sitecol = openquake.hazardlib.site.SiteCollection(sites) gsims = {const.TRT.ACTIVE_SHALLOW_CRUST: SadighEtAl1997()} truncation_level = 1 imts = {'PGA': [0.1, 0.5, 1.3]} s_filter = SourceFilter(sitecol, {const.TRT.ACTIVE_SHALLOW_CRUST: 30}) result = calc_hazard_curves(sources, s_filter, imts, gsims, truncation_level)['PGA'] # 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(result.shape, (4, 3)) # 4 sites, 3 levels numpy.testing.assert_allclose(result[0], 0) # no contrib to site 1 numpy.testing.assert_allclose(result[1], 0) # no contrib to site 2 # test that depths are kept after filtering (sites 3 and 4 remain) s_filter = SourceFilter(sitecol, {'default': 100}) numpy.testing.assert_array_equal( s_filter.get_close_sites(sources[0]).depths, ([1, -1]))