def test_get_rupture_enclosing_polygon(self): source, _ = self.make_non_parametric_source() poly = source.get_rupture_enclosing_polygon(dilation=0) expected_poly = Polygon( [Point(-1, -1), Point(-1, 1), Point(1, 1), Point(1, -1)]) numpy.testing.assert_equal(poly.lons, expected_poly.lons) numpy.testing.assert_equal(poly.lats, expected_poly.lats) poly = source.get_rupture_enclosing_polygon(dilation=200) poly._init_polygon2d() expected_poly = expected_poly.dilate(200) expected_poly._init_polygon2d() # we check that the percent difference between the two polygons is # almost zero # in this case the area of the difference is ~ 8 km**2, with # respect to area of the computed polygon (~ 352795 km**2) and the area # of the predicted polygon (~ 352803 km**2) diff = 100 * poly._polygon2d.\ symmetric_difference(expected_poly._polygon2d).area diff /= expected_poly._polygon2d.area self.assertAlmostEqual(diff, 0, places=2)
def _get_limits_maximum_rjb(self, maximum_distance): """ Returns the bounding box of a polyon representing the locations of maximum distance from the rupture """ top_left = deepcopy(self.surface.top_left) top_left.depth = 0. top_right = deepcopy(self.surface.top_right) top_right.depth = 0. bottom_left = deepcopy(self.surface.bottom_left) bottom_left.depth = 0. bottom_right = deepcopy(self.surface.bottom_right) bottom_right.depth = 0. surface_projection = Polygon([top_left, top_right, bottom_right, bottom_left]) dilated_projection = surface_projection.dilate(maximum_distance) return (np.min(dilated_projection.lons), np.max(dilated_projection.lons), np.min(dilated_projection.lats), np.max(dilated_projection.lats))
def test_implied_point_sources(self): source = self.make_area_source(Polygon([Point(-2, -2), Point(0, -2), Point(0, 0), Point(-2, 0)]), discretization=66.7, rupture_mesh_spacing=5) ruptures = list(source.iter_ruptures()) self.assertEqual( len(ruptures), source.count_ruptures()) # 9 * 2 ruptures # resulting 3x3 mesh has points in these coordinates: lons = [-1.4, -0.8, -0.2] lats = [-0.6, -1.2, -1.8] depths = [4.0, 8.0] ruptures_iter = iter(ruptures) for lat in lats: for lon in lons: r1 = next(ruptures_iter) r2 = next(ruptures_iter) r3 = next(ruptures_iter) r4 = next(ruptures_iter) for iloc, rupture in enumerate([r1, r2]): self.assertAlmostEqual(rupture.hypocenter.longitude, lon, delta=1e-3) self.assertAlmostEqual(rupture.hypocenter.latitude, lat, delta=1e-3) self.assertAlmostEqual(rupture.hypocenter.depth, depths[iloc], delta=1e-3) self.assertEqual(r1.mag, 5.5) self.assertEqual(r2.mag, 5.5) self.assertEqual(r3.mag, 6.5) self.assertEqual(r4.mag, 6.5) self.assertEqual(len(ruptures), 9 * 4)
def test_implied_point_sources(self): source = self.make_area_source(Polygon([Point(-2, -2), Point(0, -2), Point(0, 0), Point(-2, 0)]), discretization=66.7, rupture_mesh_spacing=5) ruptures = list(source.iter_ruptures(PoissonTOM(50))) self.assertEqual(len(ruptures), 9 * 2) # resulting 3x3 mesh has points in these coordinates: lons = [-1.4, -0.8, -0.2] lats = [-0.6, -1.2, -1.8] ruptures_iter = iter(ruptures) for lat in lats: for lon in lons: r1 = next(ruptures_iter) r2 = next(ruptures_iter) for rupture in [r1, r2]: self.assertAlmostEqual(rupture.hypocenter.longitude, lon, delta=1e-3) self.assertAlmostEqual(rupture.hypocenter.latitude, lat, delta=1e-3) self.assertEqual(rupture.surface.mesh_spacing, 5) self.assertIs(rupture.source_typology, AreaSource) self.assertEqual(r1.mag, 5.5) self.assertEqual(r2.mag, 6.5) self.assertEqual(len(ruptures), 9 * 2)
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)
def test_dilated(self): source = make_area_source(Polygon( [Point(4, 6), Point(5, 6), Point(4, 5)]), discretization=100) polygon = source.get_rupture_enclosing_polygon(dilation=5) elons = [ 3.8387562, 3.8395259, 3.8418396, 3.8456751, 3.8509956, 3.8577500, 3.8658734, 3.8752878, 3.8859026, 3.8976158, 3.9103145, 3.9238767, 3.9381718, 3.9530621, 3.9684044, 3.9840509, 3.9998509, 5.0001491, 5.0159419, 5.0315815, 5.0469172, 5.0618016, 5.0760915, 5.0896495, 5.1023453, 5.1140566, 5.1246711, 5.1340866, 5.1422127, 5.1489714, 5.1542977, 5.1581407, 5.1604635, 5.1612438, 5.1604744, 5.1581627, 5.1543311, 5.1490166, 5.1422703, 5.1341571, 5.1247551, 5.1141547, 4.1141530, 4.1024651, 4.0897882, 4.0762448, 4.0619656, 4.0470884, 4.0317568, 4.0161187, 4.0003251, 3.9845284, 3.9688809, 3.9535336, 3.9386348, 3.9243281, 3.9107516, 3.8980364, 3.8863052, 3.8756714, 3.8662375, 3.8580948, 3.8513218, 3.8459842, 3.8421334, 3.8398068, 3.8390269 ] elats = [ 5.9999784, 6.0156881, 6.0312472, 6.0465059, 6.0613173, 6.0755391, 6.0890342, 6.1016728, 6.1133333, 6.1239034, 6.1332813, 6.1413768, 6.1481120, 6.1534219, 6.1572555, 6.1595758, 6.1603605, 6.1603605, 6.1595765, 6.1572583, 6.1534281, 6.1481229, 6.1413937, 6.1333052, 6.1239352, 6.1133738, 6.1017226, 6.0890937, 6.0756085, 6.0613967, 6.0465949, 6.0313455, 6.0157950, 6.0000929, 5.9843902, 5.9688377, 5.9535850, 5.9387786, 5.9245607, 5.9110681, 5.8984302, 5.8867686, 4.8869567, 4.8763401, 4.8669175, 4.8587797, 4.8520053, 4.8466598, 4.8427945, 4.8404470, 4.8396398, 4.8403806, 4.8426625, 4.8464633, 4.8517463, 4.8584606, 4.8665414, 4.8759108, 4.8864782, 4.8981417, 4.9107887, 4.9242972, 4.9385367, 4.9533698, 4.9686533, 4.9842397, 4.9999784 ] numpy.testing.assert_allclose(polygon.lons, elons) numpy.testing.assert_allclose(polygon.lats, elats)
def setUp(self): mfd = TruncatedGRMFD(min_mag=4.0, max_mag=6.0, bin_width=0.1, a_val=2.0, b_val=1.0) msr = WC1994() tom = PoissonTOM(1.0) pol = Polygon([Point(longitude=0.0, latitude=0.0), Point(longitude=1.0, latitude=0.0), Point(longitude=1.0, latitude=1.0), Point(longitude=0.0, latitude=1.0)]) npd = PMF([(1.0, NodalPlane(0.0, 90.0, 0.0))]) hpd = PMF([(0.7, 10.), (0.3, 20.0)]) self.src1 = AreaSource(source_id='1', name='1', tectonic_region_type='Test', mfd=mfd, rupture_mesh_spacing=1, magnitude_scaling_relationship=msr, rupture_aspect_ratio=1., temporal_occurrence_model=tom, upper_seismogenic_depth=0, lower_seismogenic_depth=100., nodal_plane_distribution=npd, hypocenter_distribution=hpd, polygon=pol, area_discretization=10.)
def test_occurrence_rate_rescaling(self): mfd = EvenlyDiscretizedMFD(min_mag=4, bin_width=1, occurrence_rates=[3]) polygon = Polygon([Point(0, 0), Point(0, -0.2248), Point(-0.2248, -0.2248), Point(-0.2248, 0)]) source = self.make_area_source(polygon, discretization=10, mfd=mfd) self.assertIs(source.mfd, mfd) ruptures = list(source.iter_ruptures()) self.assertEqual(len(ruptures), 8) for rupture in ruptures: self.assertNotEqual(rupture.occurrence_rate, 3) self.assertEqual(rupture.occurrence_rate, 3.0 / 8.0)
def source_shapefile_to_dictionary(filename): """ """ sf = shapefile.Reader(filename) fields = [fld[0] for fld in sf.fields[1:]] data = [] for rec in sf.shapeRecords(): zone = dict([(key, val) for key, val in zip(fields[1:], rec.record)]) zone["geometry"] = Polygon( [Point(pnt[0], pnt[1]) for pnt in rec.shape.points]) data.append(zone) return data
def parse_sites(oqparam): if (oqparam.region is not None): assert oqparam.region.startswith('POLYGON') """ raise ValueError('More than one site is specified (N={len(site_ctx)}). Although ' 'technically faesible using OQ library, this is not reasonable ' 'for VPSHA calculations') """ # Convert region specifications to polygon: reg_lons = [ float(x.split(' ')[0]) for x in oqparam.region[9:-2].split(', ') ] reg_lats = [ float(x.split(' ')[1]) for x in oqparam.region[9:-2].split(', ') ] pts = [Point(lon, lat) for lon, lat in zip(reg_lons, reg_lats)] poly = Polygon(pts) # Convert polygon to sitecolllection: mesh = poly.discretize(oqparam.region_grid_spacing) sites = [ Site(Point(lon, lat, depth), vs30=oqparam.reference_vs30_value, z1pt0=oqparam.reference_depth_to_1pt0km_per_sec, z2pt5=oqparam.reference_depth_to_2pt5km_per_sec) for lon, lat, depth in zip(mesh.lons, mesh.lats, mesh.depths) ] sites_col = SiteCollection(sites) elif isinstance(oqparam.sites, list): sites = [ Site(Point(s[0], s[1], s[2]), vs30=oqparam.reference_vs30_value, z1pt0=oqparam.reference_depth_to_1pt0km_per_sec, z2pt5=oqparam.reference_depth_to_2pt5km_per_sec) for s in oqparam.sites ] sites_col = SiteCollection(sites) else: assert isinstance(oqparam.sites, SiteCollection) sites_col = oqparam.sites return sites_col
def test_end_to_end(self): """ Tests PenalizedMLE with bootstrapping and increased sample size and asserts that the known b-value and (approx) rate are within a narrow range (0.4 - 0.6 quantiles) """ poly1 = Polygon([ Point(20.0, 30.0), Point(20.0, 40.0), Point(30.0, 40.0), Point(30.0, 30.0) ]) self.config = { "b_prior": 0.9, "reference_magnitude": 3.0, "b_prior_weight": 25.0, "a_prior": 0.0, "a_prior_weight": 0.0, "area": area_of_polygon(poly1), "mmax": 8.0 } sample_size = [5, 10, 20, 50, 100, 200, 500, 1000] expected_b = 0.9 for sample in sample_size: outputs = [] expected_rate = (float(sample) / float(self.catalogue.get_number_events())) * 100. for i in range(1000): idx = np.arange(self.catalogue.get_number_events()) np.random.shuffle(idx) idx = idx[:sample] new_cat = deepcopy(self.catalogue) new_cat.select_catalogue_events(np.sort(idx)) mle = PenalizedMLE() bval, sigmab, rate, sigma_rate = mle.calculate( new_cat, self.config, self.completeness) outputs.append([bval, sigmab, rate, sigma_rate]) outputs = np.array(outputs) mean_b = np.mean(outputs[:, 0]) mean_sigmab = np.mean(outputs[:, 1]) mean_rate = np.mean(outputs[:, 2]) mean_sigma_rate = np.mean(outputs[:, 3]) # Assert that b-value is in the expected range l_b, u_b = (norm.ppf(0.4, loc=mean_b, scale=mean_sigmab), norm.ppf(0.6, loc=mean_b, scale=mean_sigmab)) self.assertTrue((0.9 >= l_b) and (0.9 <= u_b)) # Assert that rate is in the expected range l_b, u_b = (norm.ppf(0.4, loc=mean_rate, scale=mean_sigma_rate), norm.ppf(0.6, loc=mean_rate, scale=mean_sigma_rate)) self.assertTrue((expected_rate >= l_b) and (expected_rate <= u_b))
def test_get_rupture_enclosing_polygon(self): source, _ = self.make_non_parametric_source() poly = source.get_rupture_enclosing_polygon(dilation=0) expected_poly = Polygon( [Point(-1, -1), Point(-1, 1), Point(1, 1), Point(1, -1)] ) numpy.testing.assert_equal(poly.lons, expected_poly.lons) numpy.testing.assert_equal(poly.lats, expected_poly.lats) poly = source.get_rupture_enclosing_polygon(dilation=200) poly._init_polygon2d() expected_poly = expected_poly.dilate(200) expected_poly._init_polygon2d() # we check that the percent difference between the two polygons is # almost zero # in this case the area of the difference is ~ 8 km**2, with # respect to area of the computed polygon (~ 352795 km**2) and the area # of the predicted polygon (~ 352803 km**2) diff = 100 * poly._polygon2d.\ symmetric_difference(expected_poly._polygon2d).area diff /= expected_poly._polygon2d.area self.assertAlmostEqual(diff, 0, places=2)
def test_no_dilation(self): source = make_area_source(Polygon( [Point(-4, -4), Point(-5, -4), Point(-4, -5)]), discretization=100) polygon = source.get_rupture_enclosing_polygon() elons = [ -3.8843265, -3.8841675, -3.8847229, -3.8863892, -3.8891507, -3.8929806, -3.8978421, -3.9036884, -3.9104632, -3.9181013, -3.9265289, -3.9356649, -3.9454212, -3.9557038, -3.9664135, -3.9774470, -3.9886980, -4.0000580, -4.0114174, -4.0226667, -4.0336974, -4.0444032, -4.0546808, -4.0644312, -4.0735603, -4.0819801, -5.0819794, -5.0895794, -5.0963177, -5.1021293, -5.1069586, -5.1107589, -5.1134939, -5.1151373, -5.1156733, -5.1150967, -5.1134133, -5.1106391, -5.1068010, -5.1019359, -5.0960906, -5.0893213, -5.0816932, -5.0732797, -5.0641616, -5.0544266, -5.0441683, -5.0334855, -5.0224807, -5.0112597, -4.9999306, -4.0000694, -3.9887278, -3.9774948, -3.9664787, -3.9557855, -3.9455184, -3.9357761, -3.9266527, -3.9182361, -3.9106073, -3.9038400, -3.8979993, -3.8931415, -3.8893136, -3.8865525, -3.8848847 ] elats = [ -3.9999909, -4.9999908, -5.0113054, -5.0225111, -5.0334999, -5.0441660, -5.0544065, -5.0641226, -5.0732208, -5.0816133, -5.0892192, -5.0959651, -5.1017861, -5.1066260, -5.1104381, -5.1131856, -5.1148422, -5.1153917, -5.1148289, -5.1131593, -5.1103988, -5.1065743, -5.1017224, -5.0958901, -5.0891335, -5.0815178, -4.0814048, -4.0730023, -4.0638977, -4.0541785, -4.0439382, -4.0332754, -4.0222926, -4.0110954, -3.9997916, -3.9884899, -3.9772990, -3.9663264, -3.9556777, -3.9454554, -3.9357577, -3.9266778, -3.9183031, -3.9107141, -3.9039838, -3.8981768, -3.8933490, -3.8895469, -3.8868069, -3.8851554, -3.8846083, -3.8846083, -3.8851566, -3.8868117, -3.8895577, -3.8933680, -3.8982061, -3.9040252, -3.9107693, -3.9183735, -3.9267644, -3.9358611, -3.9455761, -3.9558157, -3.9664812, -3.9774699, -3.9886758 ] numpy.testing.assert_allclose(polygon.lons, elons) numpy.testing.assert_allclose(polygon.lats, elats)
def _get_cluster_correction(dat, C, ctx, imt): """ Get cluster correction. The use can specify various options through the cluster parameter. The available options are: - cluster = None In this case the code finds the most appropriate correction using the rupture position - cluster = 0 No cluster correction - cluser = 1 or 4 or 5 The code uses the correction for the given cluster """ cluster = dat.cluster shape = ctx.sids.shape correction = np.zeros_like(shape) # st.dev. tau_L2L = np.zeros(shape) Bp_model = np.zeros(shape) phi_P2P = np.zeros(shape) # No cluster correction if cluster == 0: tau_L2L = C['tau_L2L'] phi_P2P = C['phi_P2P'] return correction, tau_L2L, Bp_model, phi_P2P # the code finds the most appropriate correction if cluster is None: mesh = Mesh(np.array([ctx.hypo_lon]), np.array([ctx.hypo_lat])) # midp = ctx.surface.get_middle_point() # mesh = Mesh(np.array([midp.longitude]),np.array([midp.latitude])) for key in REGIONS: coo = np.array(REGIONS[key]) pnts = [Point(lo, la) for lo, la in zip(coo[:, 0], coo[:, 1])] poly = Polygon(pnts) within = poly.intersects(mesh) if all(within): cluster = int(key) break # if OUT clusters do not apply corrections if cluster is None: tau_L2L = C['tau_L2L'] phi_P2P = C['phi_P2P'] return correction, tau_L2L, Bp_model, phi_P2P else: # if IN clusters apply corrections # Cluster coefficients fname = 'P_model_cluster{:d}.csv'.format(cluster) fname = os.path.join(DATA_FOLDER, fname) data = np.loadtxt(fname, delimiter=",", skiprows=1) # for st.dev. fname2 = 'beta_dP2P_cluster{:d}.csv'.format(cluster) fname2 = os.path.join(DATA_FOLDER, fname2) data2 = np.loadtxt(fname2, delimiter=",", skiprows=1) # Compute the coefficients correction = np.zeros(shape) per = imt.period for idx in np.unique(dat.idxs): tmp = data[int(idx)] correction[dat.idxs == idx] = np.interp(per, dat.PERIODS, tmp[0:5]) # Adding L2L correction label = "dL2L_cluster{:d}".format(cluster) correction += C[label] # compute st.dev. for idx in np.unique(dat.idxs): tmp2 = data2[int(idx)] Bp_model[dat.idxs == idx] = np.interp(per, dat.PERIODS, tmp2[0:5]) return correction, tau_L2L, Bp_model, phi_P2P
def test_areasource(self): nodalplane = NodalPlane(strike=0.0, dip=90.0, rake=0.0) src = AreaSource(source_id='src_1', name='area source', tectonic_region_type='Active Shallow Crust', mfd=TruncatedGRMFD(a_val=3.5, b_val=1.0, min_mag=5.0, max_mag=6.5, bin_width=0.1), nodal_plane_distribution=PMF([(1.0, nodalplane)]), hypocenter_distribution=PMF([(1.0, 5.0)]), upper_seismogenic_depth=0.0, lower_seismogenic_depth=10.0, magnitude_scaling_relationship=WC1994(), rupture_aspect_ratio=1.0, polygon=Polygon([ Point(-0.5, -0.5), Point(-0.5, 0.5), Point(0.5, 0.5), Point(0.5, -0.5) ]), area_discretization=9.0, rupture_mesh_spacing=1.0, temporal_occurrence_model=PoissonTOM(50.)) site = Site(location=Point(0.0, 0.0), vs30=800.0, vs30measured=True, z1pt0=500.0, z2pt5=2.0) gsims = {'Active Shallow Crust': BooreAtkinson2008()} imt = SA(period=0.1, damping=5.0) iml = 0.2 truncation_level = 3.0 n_epsilons = 3 mag_bin_width = 0.2 # in km dist_bin_width = 10.0 # in decimal degree coord_bin_width = 0.2 # compute disaggregation bin_edges, diss_matrix = disagg.disaggregation( [src], site, imt, iml, gsims, truncation_level, n_epsilons, mag_bin_width, dist_bin_width, coord_bin_width) mag_bins, dist_bins, lon_bins, lat_bins, eps_bins, trt_bins = bin_edges numpy.testing.assert_almost_equal( mag_bins, [5., 5.2, 5.4, 5.6, 5.8, 6., 6.2, 6.4, 6.6]) numpy.testing.assert_almost_equal( dist_bins, [0., 10., 20., 30., 40., 50., 60., 70., 80.]) numpy.testing.assert_almost_equal( lat_bins, [-0.6, -0.4, -0.2, 0., 0.2, 0.4, 0.6]) numpy.testing.assert_almost_equal( lon_bins, [-0.6, -0.4, -0.2, 0., 0.2, 0.4, 0.6]) numpy.testing.assert_almost_equal(eps_bins, [-3., -1., 1., 3.]) self.assertEqual(trt_bins, ['Active Shallow Crust']) expected_matrix = numpy.fromstring( codecs.decode( codecs.decode( b"""\ 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\ """, 'base64'), 'zip')).reshape((8, 8, 6, 6, 3, 1)) numpy.testing.assert_almost_equal(diss_matrix, expected_matrix)
def polygon(self): """ The underlying polygon `""" lons, lats = self.surface.surface_projection return Polygon([Point(lo, la) for lo, la in zip(lons, lats)])
SET1_CASE10_SOURCE_POLYGON = SET1_CASE11_SOURCE_POLYGON = Polygon([ Point(-122.000, 38.901), Point(-121.920, 38.899), Point(-121.840, 38.892), Point(-121.760, 38.881), Point(-121.682, 38.866), Point(-121.606, 38.846), Point(-121.532, 38.822), Point(-121.460, 38.794), Point(-121.390, 38.762), Point(-121.324, 38.727), Point(-121.261, 38.688), Point(-121.202, 38.645), Point(-121.147, 38.600), Point(-121.096, 38.551), Point(-121.050, 38.500), Point(-121.008, 38.446), Point(-120.971, 38.390), Point(-120.940, 38.333), Point(-120.913, 38.273), Point(-120.892, 38.213), Point(-120.876, 38.151), Point(-120.866, 38.089), Point(-120.862, 38.026), Point(-120.863, 37.963), Point(-120.869, 37.900), Point(-120.881, 37.838), Point(-120.899, 37.777), Point(-120.921, 37.717), Point(-120.949, 37.658), Point(-120.982, 37.601), Point(-121.020, 37.545), Point(-121.063, 37.492), Point(-121.110, 37.442), Point(-121.161, 37.394), Point(-121.216, 37.349), Point(-121.275, 37.308), Point(-121.337, 37.269), Point(-121.403, 37.234), Point(-121.471, 37.203), Point(-121.542, 37.176), Point(-121.615, 37.153), Point(-121.690, 37.133), Point(-121.766, 37.118), Point(-121.843, 37.108), Point(-121.922, 37.101), Point(-122.000, 37.099), Point(-122.078, 37.101), Point(-122.157, 37.108), Point(-122.234, 37.118), Point(-122.310, 37.133), Point(-122.385, 37.153), Point(-122.458, 37.176), Point(-122.529, 37.203), Point(-122.597, 37.234), Point(-122.663, 37.269), Point(-122.725, 37.308), Point(-122.784, 37.349), Point(-122.839, 37.394), Point(-122.890, 37.442), Point(-122.937, 37.492), Point(-122.980, 37.545), Point(-123.018, 37.601), Point(-123.051, 37.658), Point(-123.079, 37.717), Point(-123.101, 37.777), Point(-123.119, 37.838), Point(-123.131, 37.900), Point(-123.137, 37.963), Point(-123.138, 38.026), Point(-123.134, 38.089), Point(-123.124, 38.151), Point(-123.108, 38.213), Point(-123.087, 38.273), Point(-123.060, 38.333), Point(-123.029, 38.390), Point(-122.992, 38.446), Point(-122.950, 38.500), Point(-122.904, 38.551), Point(-122.853, 38.600), Point(-122.798, 38.645), Point(-122.739, 38.688), Point(-122.676, 38.727), Point(-122.610, 38.762), Point(-122.540, 38.794), Point(-122.468, 38.822), Point(-122.394, 38.846), Point(-122.318, 38.866), Point(-122.240, 38.881), Point(-122.160, 38.892), Point(-122.080, 38.899), ])
def setUp(self): self.pol = Polygon([Point(longitude=0.0, latitude=0.0), Point(longitude=1.0, latitude=0.0), Point(longitude=1.0, latitude=1.0), Point(longitude=0.0, latitude=1.0)])
src = AreaSource( source_id='1', name='area', tectonic_region_type='Active Shallow Crust', mfd=TruncatedGRMFD(min_mag=5., max_mag=6.5, bin_width=0.2, a_val=3.45, b_val=0.98), rupture_mesh_spacing=2., magnitude_scaling_relationship=WC1994(), rupture_aspect_ratio=1., temporal_occurrence_model=PoissonTOM(50.), upper_seismogenic_depth=2., lower_seismogenic_depth=12., nodal_plane_distribution=PMF([(1, NodalPlane(strike=45, dip=30, rake=0))]), hypocenter_distribution=PMF([(1, 7.)]), polygon=Polygon([Point(133.5, -22.5), Point(133.5, -23.0), Point(130.75, -23.75), Point(130.75, -24.5), Point(133.5, -26.0), Point(133.5, -27.0), Point(130.75, -27.0), Point(128.977, -25.065), Point(128.425, -23.436), Point(126.082, -23.233), Point(125.669, -22.351), Point(125.4, -20.5), Point(125.75, -20.25), Point(126.7, -21.25), Point(128.5, -21.25), Point(129.25, -20.6), Point(130.0, -20.6), Point(130.9, -22.25), Point(133.0, -22.0), Point(133.5, -22.5)]), area_discretization=20. ) src = area_model # loop over ruptures, extract rupture surface boundary and magnitude min_lon, max_lon, min_lat, max_lat, m = get_map_projection(src) boundaries = [] mags = [] for rup in src.iter_ruptures(): surf = rup.surface
def test_areasource(self): nodalplane = NodalPlane(strike=0.0, dip=90.0, rake=0.0) src = AreaSource(source_id='src_1', name='area source', tectonic_region_type='Active Shallow Crust', mfd=TruncatedGRMFD(a_val=3.5, b_val=1.0, min_mag=5.0, max_mag=6.5, bin_width=0.1), nodal_plane_distribution=PMF([(1.0, nodalplane)]), hypocenter_distribution=PMF([(1.0, 5.0)]), upper_seismogenic_depth=0.0, lower_seismogenic_depth=10.0, magnitude_scaling_relationship=WC1994(), rupture_aspect_ratio=1.0, polygon=Polygon([ Point(-0.5, -0.5), Point(-0.5, 0.5), Point(0.5, 0.5), Point(0.5, -0.5) ]), area_discretization=9.0, rupture_mesh_spacing=1.0, temporal_occurrence_model=PoissonTOM(50.)) site = Site(location=Point(0.0, 0.0), vs30=800.0, vs30measured=True, z1pt0=500.0, z2pt5=2.0) gsims = {'Active Shallow Crust': BooreAtkinson2008()} imt = SA(period=0.1, damping=5.0) iml = 0.2 truncation_level = 3.0 n_epsilons = 3 mag_bin_width = 0.2 # in km dist_bin_width = 10.0 # in decimal degree coord_bin_width = 0.2 # compute disaggregation bin_edges, diss_matrix = disagg.disaggregation( [src], site, imt, iml, gsims, truncation_level, n_epsilons, mag_bin_width, dist_bin_width, coord_bin_width) mag_bins, dist_bins, lon_bins, lat_bins, eps_bins, trt_bins = bin_edges numpy.testing.assert_almost_equal( mag_bins, [5., 5.2, 5.4, 5.6, 5.8, 6., 6.2, 6.4, 6.6]) numpy.testing.assert_almost_equal( dist_bins, [0., 10., 20., 30., 40., 50., 60., 70., 80.]) numpy.testing.assert_almost_equal(lat_bins, [ -6.5544231e-01, -4.9158173e-01, -3.2772115e-01, -1.6386058e-01, 1.1102230e-16, 1.6386058e-01, 3.2772115e-01, 4.9158173e-01, 6.5544231e-01 ]) numpy.testing.assert_almost_equal(lon_bins, [ -6.5544231e-01, -4.9158173e-01, -3.2772115e-01, -1.6386058e-01, 1.1102230e-16, 1.6386058e-01, 3.2772115e-01, 4.9158173e-01, 6.5544231e-01 ]) numpy.testing.assert_almost_equal(eps_bins, [-3., -1., 1., 3.]) self.assertEqual(trt_bins, ['Active Shallow Crust']) self.assertEqual(diss_matrix.shape, (8, 8, 8, 8, 3, 1)) expected = [ 0.0245487, 0.0231275, 0.0210702, 0.0185196, 0.0157001, 0.0130175, 0.0107099, 0.0045489 ] numpy.testing.assert_almost_equal( diss_matrix.sum(axis=(1, 2, 3, 4, 5)), expected)