def test_depths_go_to_zero(self): # Depth information is meant to be discarded when a site collection is # created. s1 = Site(location=Point(10, 20, 30), vs30=1.2, vs30measured=True, z1pt0=3.4, z2pt5=5.6) s2 = Site(location=Point(-1.2, -3.4, -5.6), vs30=55.4, vs30measured=False, z1pt0=66.7, z2pt5=88.9) cll = SiteCollection([s1, s2]) cll_sites = list(cll) exp_s1 = Site(location=Point(10, 20, 0.0), vs30=1.2, vs30measured=True, z1pt0=3.4, z2pt5=5.6) exp_s2 = Site(location=Point(-1.2, -3.4, 0.0), vs30=55.4, vs30measured=False, z1pt0=66.7, z2pt5=88.9) for i, s in enumerate([exp_s1, exp_s2]): self.assertEqual(s, cll_sites[i]) # test equality of site collections sc = SiteCollection([exp_s1, exp_s2]) self.assertEqual(cll, sc) # test nonequality of site collections # (see https://github.com/gem/oq-hazardlib/pull/403) sc._vs30 = numpy.array([numpy.nan, numpy.nan]) self.assertNotEqual(cll, sc)
def test_expand_1d(self): col = SiteCollection(self.SITES) col = col.filter(numpy.array([1, 0, 1, 1])) data_condensed = numpy.array([5, 6, 7]) data_expanded = col.expand(data_condensed, placeholder=100) data_expanded_expected = numpy.array([5, 100, 6, 7]) numpy.testing.assert_array_equal(data_expanded, data_expanded_expected)
def test_within_region(self): region = wkt.loads('POLYGON((0 0, 9 0, 9 9, 0 9, 0 0))') col = SiteCollection(self.SITES) reducedcol = col.within(region) # point (10, 20) is out, point (11, 12) is out, point (0, 2) # is on the boundary i.e. out, (1, 1) is in self.assertEqual(len(reducedcol), 1)
def test_expand_no_filtering(self): col = SiteCollection(self.SITES) data_condensed = numpy.array([3, 2, 1, 0]) data_expanded = col.expand(data_condensed, total_sites=4, placeholder=100) data_expanded_expected = data_condensed numpy.testing.assert_array_equal(data_expanded, data_expanded_expected)
def test_filter(self): col = SiteCollection(self.SITES) filtered = col.filter(numpy.array([True, False, True, False])) arreq = numpy.testing.assert_array_equal arreq(filtered.vs30, [1.2, 2]) arreq(filtered.vs30measured, [True, True]) arreq(filtered.z1pt0, [3, 9]) arreq(filtered.z2pt5, [5, 17]) arreq(filtered.mesh.lons, [10, 0]) arreq(filtered.mesh.lats, [20, 2]) arreq(filtered.mesh.depths, [30, 0]) arreq(filtered.sids, [0, 2]) filtered = col.filter(numpy.array([False, True, True, True])) arreq(filtered.vs30, [55.4, 2, 4]) arreq(filtered.vs30measured, [False, True, False]) arreq(filtered.z1pt0, [6, 9, 22]) arreq(filtered.z2pt5, [8, 17, 11]) arreq(filtered.mesh.lons, [11, 0, 1]) arreq(filtered.mesh.lats, [12, 2, 1]) arreq(filtered.mesh.depths, [13, 0, 3]) # test serialization to hdf5 fd, fpath = tempfile.mkstemp(suffix='.hdf5') os.close(fd) with hdf5.File(fpath, 'w') as f: f['sitecol'] = filtered saved = f['sitecol'] self.assertEqual(saved, filtered) os.remove(fpath)
def test_from_sites(self): s1 = Site(location=Point(10, 20, 30), vs30=1.2, vs30measured=True, z1pt0=3.4, z2pt5=5.6, backarc=True) s2 = Site(location=Point(-1.2, -3.4, -5.6), vs30=55.4, vs30measured=False, z1pt0=66.7, z2pt5=88.9, backarc=False) cll = SiteCollection([s1, s2]) self.assertTrue((cll.vs30 == [1.2, 55.4]).all()) self.assertTrue((cll.vs30measured == [True, False]).all()) self.assertTrue((cll.z1pt0 == [3.4, 66.7]).all()) self.assertTrue((cll.z2pt5 == [5.6, 88.9]).all()) self.assertTrue((cll.mesh.lons == [10, -1.2]).all()) self.assertTrue((cll.mesh.lats == [20, -3.4]).all()) self.assertTrue((cll.backarc == [True, False]).all()) self.assertIs(cll.mesh.depths, None) for arr in (cll.vs30, cll.z1pt0, cll.z2pt5): self.assertIsInstance(arr, numpy.ndarray) self.assertEqual(arr.flags.writeable, False) self.assertEqual(arr.dtype, float) for arr in (cll.vs30measured, cll.backarc): self.assertIsInstance(arr, numpy.ndarray) self.assertEqual(arr.flags.writeable, False) self.assertEqual(arr.dtype, bool) self.assertEqual(len(cll), 2) # test __toh5__ and __fromh5__ array, attrs = cll.__toh5__() newcll = cll.__new__(cll.__class__) newcll.__fromh5__(array, attrs) self.assertEqual(newcll, cll)
def test_split(self): col = SiteCollection(self.SITES) close_sites, far_sites = col.split(Point(10, 19), distance=200) self.assertEqual(len(close_sites), 1) self.assertEqual(len(far_sites), 3) close_sites, far_sites = col.split(Point(10, 19), distance=0) self.assertIsNone(close_sites) self.assertEqual(len(far_sites), 4) close_sites, far_sites = col.split(Point(10, 19), distance=None) self.assertEqual(len(close_sites), 4) self.assertIsNone(far_sites)
def test_double_filter(self): col = SiteCollection(self.SITES) filtered = col.filter(numpy.array([True, False, True, True])) filtered2 = filtered.filter(numpy.array([False, True, False])) arreq = numpy.testing.assert_array_equal arreq(filtered2.vs30, [2]) arreq(filtered2.vs30measured, [True]) arreq(filtered2.z1pt0, [9]) arreq(filtered2.z2pt5, [17]) arreq(filtered2.mesh.lons, [0]) arreq(filtered2.mesh.lats, [2]) arreq(filtered2.mesh.depths, [0]) filtered2 = filtered.filter(numpy.array([True, False, True])) arreq(filtered2.vs30, [1.2, 4.])
def test_expand_2d(self): col = SiteCollection(self.SITES).filter(numpy.array([False, True, False, True])) data_condensed = numpy.array([ [1, 2, 3], [5, 6, 7], ]) data_expanded = col.expand(data_condensed, placeholder=-1) data_expanded_expected = numpy.array([ [-1, -1, -1], [1, 2, 3], [-1, -1, -1], [5, 6, 7], ]) numpy.testing.assert_array_equal(data_expanded, data_expanded_expected)
def filter_hanging_wall(self, filter_type=None): """ Opt to consider only hanging wall or footwall sites """ if not filter_type: # Considers both footwall and hanging wall return self.target_sites elif not filter_type in ['HW', 'FW']: raise ValueError('Hanging wall filter must be either "HW" or "FW"') else: pass # Gets the Rx distance r_x = self.surface.get_rx_distance(self.target_sites.mesh) selected_sites = [] if filter_type == "HW": # Only hanging wall idx = np.where(r_x >= 0.)[0] else: # Only footwall idx = np.where(r_x < 0.)[0] for val in idx: selected_sites.append(self.target_sites.sites[val]) self.target_sites = SiteCollection(selected_sites) return self.target_sites
def test_from_points(self): lons = [10, -1.2] lats = [20, -3.4] cll = SiteCollection.from_points(lons, lats, [1, 2], SiteModelParam()) assert_eq(cll.vs30, [1.2, 1.2]) assert_eq(cll.vs30measured, [True, True]) assert_eq(cll.z1pt0, [3.4, 3.4]) assert_eq(cll.z2pt5, [5.6, 5.6]) assert_eq(cll.mesh.lons, [10, -1.2]) assert_eq(cll.mesh.lats, [20, -3.4]) assert_eq(cll.mesh.depths, None) assert_eq(cll.backarc, [False, False]) for arr in (cll.vs30, cll.z1pt0, cll.z2pt5): self.assertIsInstance(arr, numpy.ndarray) self.assertEqual(arr.dtype, float) for arr in (cll.vs30measured, cll.backarc): self.assertIsInstance(arr, numpy.ndarray) self.assertEqual(arr.flags.writeable, False) self.assertEqual(arr.dtype, bool) self.assertEqual(len(cll), 2) # test split_in_tiles tiles = cll.split_in_tiles(0) self.assertEqual(len(tiles), 1) tiles = cll.split_in_tiles(1) self.assertEqual(len(tiles), 1) tiles = cll.split_in_tiles(2) self.assertEqual(len(tiles), 2)
def _append_target_sites(self, distances, azimuth, origin_location, vs30, line_azimuth=90., origin_point=(0.5, 0.5), as_log=False, vs30measured=True, z1pt0=None, z2pt5=None, backarc=False): """ Appends the target sites along a line with respect to the rupture, given an already set origin target site """ for offset in distances: target_loc = origin_location.point_at(offset, 0., azimuth) self.target_sites.append(Site(target_loc, vs30, z1pt0, z2pt5, vs30measured=vs30measured, backarc=backarc)) self.target_sites_config = { "TYPE": "Line", "RMAX": distances[-1], "SPACING": np.nan if len(distances) < 2 else distances[1] - distances[0], # FIXME does it make sense? "AZIMUTH": line_azimuth, "ORIGIN": origin_point, "AS_LOG": as_log, "VS30": vs30, "VS30MEASURED": vs30measured, "Z1.0": z1pt0, "Z2.5": z2pt5, "BACKARC": backarc} self.target_sites = SiteCollection(self.target_sites) return self.target_sites
def test_from_points(self): lons = [10, -1.2] lats = [20, -3.4] depths = [30, -5.6] req_params = 'vs30 vs30measured z1pt0 z2pt5 backarc'.split() cll = SiteCollection.from_points( lons, lats, depths, SiteModelParam(), req_params) assert_eq(cll.vs30, [1.2, 1.2]) assert_eq(cll.vs30measured, [True, True]) assert_eq(cll.z1pt0, [3.4, 3.4]) assert_eq(cll.z2pt5, [5.6, 5.6]) assert_eq(cll.mesh.lons, [10, -1.1999999999999886]) assert_eq(cll.mesh.lats, [20, -3.4]) assert_eq(cll.mesh.depths, [30, -5.6]) assert_eq(cll.backarc, [False, False]) for arr in (cll.vs30, cll.z1pt0, cll.z2pt5): self.assertIsInstance(arr, numpy.ndarray) self.assertEqual(arr.dtype, float) for arr in (cll.vs30measured, cll.backarc): self.assertIsInstance(arr, numpy.ndarray) self.assertEqual(arr.dtype, bool) self.assertEqual(len(cll), 2) # test split_in_tiles tiles = cll.split_in_tiles(0) self.assertEqual(len(tiles), 1) tiles = cll.split_in_tiles(1) self.assertEqual(len(tiles), 1) tiles = cll.split_in_tiles(2) self.assertEqual(len(tiles), 2)
def get_target_sites_line(self, maximum_distance, spacing, vs30, line_azimuth=90., origin_point=(0.5, 0.5), vs30measured=True, z1pt0=None, z2pt5=None): """ Defines the target sites along a line with respect to the rupture """ azimuth, origin_point, z1pt0, z2pt5 = _setup_site_peripherals( line_azimuth, origin_point, vs30, z1pt0, z2pt5, self.strike, self.surface) targets = [origin_point] self.target_sites = [] distance = 0. cum_dist = distance + spacing while distance < maximum_distance: target_loc= origin_point.point_at(cum_dist, 0., azimuth) # Get Rupture distance temp_mesh = Mesh(np.array(target_loc.longitude), np.array(target_loc.latitude), np.array(target_loc.depth)) distance = self.surface.get_min_distance(temp_mesh) self.target_sites.append(Site(target_loc, vs30, vs30measured, z1pt0, z2pt5)) cum_dist += spacing self.target_sites = SiteCollection(self.target_sites) return self.target_sites
def test_normal(self): lons = [10, -1.2] lats = [20, -3.4] maximum_distance = {"Subduction IntraSlab": 200} sitecol = SiteCollection.from_points(lons, lats, SiteModelParam()) tile = Tile(sitecol, maximum_distance) self.assertEqual(repr(tile), "<Tile -1 <= lon <= 10, -3 <= lat <= 20>") src = make_point_source(1, 10) self.assertTrue(src in tile)
def test_cross_idl(self): lons = [-179.2, 178.0] lats = [3.0, 4.0] maximum_distance = {"Subduction IntraSlab": 200} sitecol = SiteCollection.from_points(lons, lats, SiteModelParam()) tile = Tile(sitecol, maximum_distance) self.assertEqual(repr(tile), "<Tile 178 <= lon <= 180, 3 <= lat <= 4>") src = make_point_source(-179.3, 3.5) self.assertTrue(src in tile) src = make_point_source(178.2, 3.5) self.assertTrue(src in tile)
def get_target_sites_line(self, maximum_distance, spacing, vs30, line_azimuth=90., origin_point=(0.5, 0.5), as_log=False, vs30measured=True, z1pt0=None, z2pt5=None, backarc=False): """ Defines the target sites along a line with respect to the rupture """ #input_origin_point = deepcopy(origin_point) azimuth, origin_location, z1pt0, z2pt5 = _setup_site_peripherals( line_azimuth, origin_point, vs30, z1pt0, z2pt5, self.strike, self.surface) self.target_sites = [Site(origin_location, vs30, vs30measured, z1pt0, z2pt5, backarc=backarc)] spacings = self._define_line_spacing(maximum_distance, spacing, as_log) for offset in spacings: target_loc= origin_location.point_at(offset, 0., azimuth) # Get Rupture distance temp_mesh = Mesh(np.array(target_loc.longitude), np.array(target_loc.latitude), np.array(target_loc.depth)) distance = self.surface.get_min_distance(temp_mesh) self.target_sites.append(Site(target_loc, vs30, vs30measured, z1pt0, z2pt5, backarc=backarc)) self.target_sites_config = { "TYPE": "Line", "RMAX": maximum_distance, "SPACING": spacing, "AZIMUTH": line_azimuth, "ORIGIN": origin_point, "AS_LOG": as_log, "VS30": vs30, "VS30MEASURED": vs30measured, "Z1.0": z1pt0, "Z2.5": z2pt5, "BACKARC": backarc} self.target_sites = SiteCollection(self.target_sites) return self.target_sites
def test_expand_2d(self): col = SiteCollection(self.SITES) col.indices = numpy.array([1, 3, 5, 6]) data_condensed = numpy.array([ [1, 2, 3], [5, 6, 7], [10, 11, 12], [15, 16, 17] ]) data_expanded = col.expand(data_condensed, total_sites=8, placeholder=-1) data_expanded_expected = numpy.array([ [-1, -1, -1], [1, 2, 3], [-1, -1, -1], [5, 6, 7], [-1, -1, -1], [10, 11, 12], [15, 16, 17], [-1, -1, -1] ]) numpy.testing.assert_array_equal(data_expanded, data_expanded_expected)
def test_filter(self): col = SiteCollection(self.SITES) filtered = col.filter(numpy.array([True, False, True, False])) self.assertIsInstance(filtered, FilteredSiteCollection) arreq = numpy.testing.assert_array_equal arreq(filtered.vs30, [1.2, 2]) arreq(filtered.vs30measured, [True, True]) arreq(filtered.z1pt0, [3, 9]) arreq(filtered.z2pt5, [5, 17]) arreq(filtered.mesh.lons, [10, 0]) arreq(filtered.mesh.lats, [20, 2]) self.assertIs(filtered.mesh.depths, None) filtered = col.filter(numpy.array([False, True, True, True])) self.assertIsInstance(filtered, FilteredSiteCollection) arreq(filtered.vs30, [55.4, 2, 4]) arreq(filtered.vs30measured, [False, True, False]) arreq(filtered.z1pt0, [6, 9, 22]) arreq(filtered.z2pt5, [8, 17, 11]) arreq(filtered.mesh.lons, [11, 0, 1]) arreq(filtered.mesh.lats, [12, 2, 1]) self.assertIs(filtered.mesh.depths, None)
def get_target_sites_mesh(self, maximum_distance, spacing, vs30, vs30measured=True, z1pt0=None, z2pt5=None, backarc=False): """ Renders a two dimensional mesh of points over the rupture surface """ # Get bounding box of dilated rupture lowx, highx, lowy, highy = self._get_limits_maximum_rjb( maximum_distance) # Create bounding box lines and then resample at spacing ewline = Line([Point(lowx, highy, 0.), Point(highx, highy, 0.)]) nsline = Line([Point(lowx, highy, 0.), Point(lowx, lowy, 0.)]) ewline = ewline.resample(spacing) nsline = nsline.resample(spacing) xvals = np.array([pnt.longitude for pnt in ewline.points]) yvals = np.array([pnt.latitude for pnt in nsline.points]) gridx, gridy = np.meshgrid(xvals, yvals) numx, numy = np.shape(gridx) npts = numx * numy gridx = (np.reshape(gridx, npts, 1)).flatten() gridy = (np.reshape(gridy, npts, 1)).flatten() site_list = [] if not z1pt0: # z1pt0 = vs30_to_z1pt0_as08(vs30) z1pt0 = vs30_to_z1pt0_cy14(vs30) if not z2pt5: # z2pt5 = z1pt0_to_z2pt5(z1pt0) z2pt5 = vs30_to_z2pt5_cb14(vs30) for iloc in range(0, npts): site_list.append(Site(Point(gridx[iloc], gridy[iloc], 0.), vs30, z1pt0, z2pt5, vs30measured=vs30measured, backarc=backarc)) self.target_sites = SiteCollection(site_list) self.target_sites_config = { "TYPE": "Mesh", "RMAX": maximum_distance, "SPACING": spacing, "VS30": vs30, "VS30MEASURED": vs30measured, "Z1.0": z1pt0, "Z2.5": z2pt5, "BACKARC": backarc} return self.target_sites
def test_sites_of_interest(self): calc = hazard_getters.GroundMotionValuesCalcGetter( self.imt, self.sites, self.sites_assets, 0, self.gsims, None) r = ProbabilisticRupture( mag=5.5, rake=123.45, tectonic_region_type=mock.Mock(), hypocenter=Point(5, 6, 7), surface=PlanarSurface(10, 11, 12, Point(0, 0, 1), Point(1, 0, 1), Point(1, 0, 2), Point(0, 0, 2) ), occurrence_rate=1, temporal_occurrence_model=mock.Mock(), source_typology=mock.Mock()) r.source_typology.filter_sites_by_distance_to_rupture = mock.Mock( return_value=None) sites, _idxs = calc.sites_of_interest(r, 0) self.assertEqual([], sites) ret = SiteCollection(list(iter(self.sites))) ret.indices = [1] r.source_typology.filter_sites_by_distance_to_rupture = mock.Mock( return_value=ret) sites, idxs = calc.sites_of_interest(r, 100) self.assertEqual(1, len(sites)) self.assertEqual(1, len(idxs)) self.assertEqual(1, idxs[0]) self.assertEqual(1, sites.get_by_id(1).id) ret.indices = [0, 2] r.source_typology.filter_sites_by_distance_to_rupture = mock.Mock( return_value=ret) sites, idxs = calc.sites_of_interest(r, 1000) self.assertEqual(2, len(sites)) self.assertEqual([0, 2], idxs)
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.parse( source_model, SourceConverter(investigation_time=50., rupture_mesh_spacing=2.)) site = Site(Point(0.1, 0.1), 800, True, 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_some_values(self): self.gsim_class.REQUIRES_DISTANCES = set('rjb rx'.split()) self.gsim_class.REQUIRES_RUPTURE_PARAMETERS = \ set('mag strike rake hypo_lon'.split()) self.gsim_class.REQUIRES_SITES_PARAMETERS = \ set('vs30 z1pt0 lons'.split()) sites = SiteCollection([self.site1, self.site2]) rctx, sctx, dctx = self.make_contexts(sites, self.rupture) self.assertEqual((rctx.mag, rctx.rake, rctx.strike, rctx.hypo_lon), (123.45, 123.56, 60.123, 2)) aac(sctx.vs30, (456, 1456)) aac(sctx.z1pt0, (12.1, 112.1)) aac(sctx.lons, [1, -2]) aac(dctx.rx, (4, 5)) self.assertEqual( self.fake_surface.call_counts, { 'get_min_distance': 1, 'get_joyner_boore_distance': 1, 'get_rx_distance': 1, 'get_strike': 1 })
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, filter_distance='rrup')
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 = [ 9.999978e-01, 9.084040e-01, 1.489753e-01, 3.690966e-03, 2.763261e-05 ] npt.assert_allclose(hcurves['PGA'][0], expected, rtol=1E-6, atol=1E-6) # splitting in point sources [[mps1, mps2]] = groups psources = list(mps1) + list(mps2) hcurves = calc_hazard_curves(psources, sitecol, imtls, gsim_by_trt) npt.assert_allclose(hcurves['PGA'][0], expected, rtol=1E-4, atol=1E-6)
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 point_at_distance(self, model, distance, vs30, line_azimuth=90., origin_point=(0.5, 0.), vs30measured=True, z1pt0=None, z2pt5=None, backarc=False): """ Generates a site given a specified rupture distance from the rupture surface """ azimuth, origin_location, z1pt0, z2pt5 = _setup_site_peripherals( line_azimuth, origin_point, vs30, z1pt0, z2pt5, model.strike, model.surface) selected_point = _rup_to_point(distance, model.surface, origin_location, azimuth, 'rjb') target_sites = SiteCollection([Site(selected_point, vs30, vs30measured, z1pt0, z2pt5, backarc=backarc)]) return target_sites
def site_array_to_collection(site_array): """ Converts a set of sites from a 2D numpy array to an instance of :class: openquake.hazardlib.site.SiteCollection :param np.ndarray site_array: Site parameters as [ID, Long, Lat, vs30, vs30measured, z1pt0, z2pt5, backarc] """ site_list = [] n_sites, n_param = np.shape(site_array) if n_param != 8: raise ValueError('Site array incorrectly formatted!') for iloc in range(0, n_sites): site = Site(Point(site_array[iloc, 1], site_array[iloc, 2]), # Location site_array[iloc, 3], # Vs30 site_array[iloc, 4].astype(bool), # vs30measured site_array[iloc, 5], # z1pt0 site_array[iloc, 6], # z2pt5 site_array[iloc, 7].astype(bool), # Backarc site_array[iloc, 0].astype(int)) # ID site_list.append(site) return SiteCollection(site_list)
def get_regular_site_collection(limits, vs30, z1pt0=100.0, z2pt5=1.0): """ Gets a collection of sites from a regularly spaced grid of points :param list limits: Limits of mesh as [lower_long, upper_long, long_spc, lower_lat, upper_lat, lat_spc] :param float vs30: Vs30 values :param float z1pt0: Depth (m) to the 1 km/s interface :param float z2pt5: Depth (km) to the 2.5 km/s interface """ xgrd = np.arange(limits[0], limits[1] + limits[2], limits[2]) ygrd = np.arange(limits[3], limits[4] + limits[5], limits[5]) gx, gy = np.meshgrid(xgrd, ygrd) nx, ny = np.shape(gx) ngp = nx * ny gx = np.reshape(gx, [ngp, 1]).flatten() gy = np.reshape(gy, [ngp, 1]).flatten() return SiteCollection( [Site(Point(gx[i], gy[i]), vs30, z1pt0, z2pt5) for i in range(0, ngp)])
def test_mearn_nearfault_distance_taper(self): rupture = self.make_rupture() site1 = Site(location=Point(27.9, 41), vs30=1200., vs30measured=True, z1pt0=2.36, z2pt5=2.) site2 = Site(location=Point(28.1, 41), vs30=1200., vs30measured=True, z1pt0=2.36, z2pt5=2.) sites = SiteCollection([site1, site2]) fields = ground_motion_fields(rupture, sites, [PGV()], ChiouYoungs2014NearFaultEffect(), truncation_level=0, realizations=1) gmf = fields[PGV()] self.assertAlmostEquals(2.27328758, gmf[0], delta=1e-4) self.assertAlmostEquals(3.38322998, gmf[1], delta=1e-4)
def test_all_values(self): self.gsim_class.REQUIRES_DISTANCES = set( 'rjb rx rrup repi rhypo ry0 azimuth'.split()) self.gsim_class.REQUIRES_RUPTURE_PARAMETERS = set( 'mag rake strike dip ztor hypo_lon hypo_lat hypo_depth width'. split()) self.gsim_class.REQUIRES_SITES_PARAMETERS = set( 'vs30 vs30measured z1pt0 z2pt5 lons lats'.split()) sites = SiteCollection([self.site1, self.site2]) sctx, dctx = self.make_contexts(sites, self.rupture) rctx = self.rupture self.assertEqual(rctx.mag, 123.45) self.assertEqual(rctx.rake, 123.56) self.assertEqual(rctx.strike, 60.123) self.assertEqual(rctx.dip, 45.4545) self.assertEqual(rctx.ztor, 30) self.assertEqual(rctx.hypo_lon, 2) self.assertEqual(rctx.hypo_lat, 3) self.assertEqual(rctx.hypo_depth, 40) self.assertEqual(rctx.width, 15) aac(sctx.vs30, [456, 1456]) aac(sctx.vs30measured, [False, True]) aac(sctx.z1pt0, [12.1, 112.1]) aac(sctx.z2pt5, [15.1, 115.1]) aac(sctx.lons, [1, -2]) aac(sctx.lats, [2, -3]) aac(dctx.rjb, [6, 7]) aac(dctx.rx, [4, 5]) aac(dctx.ry0, [8, 9]) aac(dctx.rrup, [10, 11]) aac(dctx.azimuth, [12, 34]) aac(dctx.rhypo, [162.18749272, 802.72247682]) aac(dctx.repi, [157.17755181, 801.72524895]) self.assertEqual(self.fake_surface.call_counts, {'get_top_edge_depth': 1, 'get_rx_distance': 1, 'get_joyner_boore_distance': 1, 'get_dip': 1, 'get_min_distance': 1, 'get_width': 1, 'get_strike': 1, 'get_ry0_distance': 1, 'get_azimuth': 1})
def get_target_sites_mesh(self, maximum_distance, spacing, vs30, vs30measured=True, z1pt0=None, z2pt5=None): """ Renders a two dimensional mesh of points over the rupture surface """ # Get bounding box of dilated rupture lowx, highx, lowy, highy = self._get_limits_maximum_rjb( maximum_distance) # Create bounding box lines and then resample at spacing ewline = Line([Point(lowx, highy, 0.), Point(highx, highy, 0.)]) nsline = Line([Point(lowx, highy, 0.), Point(lowx, lowy, 0.)]) ewline = ewline.resample(spacing) nsline = nsline.resample(spacing) xvals = np.array([pnt.longitude for pnt in ewline.points]) yvals = np.array([pnt.latitude for pnt in nsline.points]) gridx, gridy = np.meshgrid(xvals, yvals) numx, numy = np.shape(gridx) npts = numx * numy gridx = (np.reshape(gridx, npts, 1)).flatten() gridy = (np.reshape(gridy, npts, 1)).flatten() site_list = [] if not z1pt0: z1pt0 = vs30_to_z1pt0_as08(vs30) if not z2pt5: z2pt5 = z1pt0_to_z2pt5(z1pt0) for iloc in range(0, npts): site_list.append(Site(Point(gridx[iloc], gridy[iloc], 0.), vs30, vs30measured, z1pt0, z2pt5)) self.target_sites = SiteCollection(site_list) return self.target_sites
def test_from_sites(self): s1 = Site(location=Point(10, 20, 30), vs30=1.2, vs30measured=True, z1pt0=3.4, z2pt5=5.6) s2 = Site(location=Point(-1.2, -3.4, -5.6), vs30=55.4, vs30measured=False, z1pt0=66.7, z2pt5=88.9) cll = SiteCollection([s1, s2]) assert_eq(cll.vs30, [1.2, 55.4]) assert_eq(cll.vs30measured, [True, False]) assert_eq(cll.z1pt0, [3.4, 66.7]) assert_eq(cll.z2pt5, [5.6, 88.9]) assert_eq(cll.mesh.lons, [10, -1.2]) assert_eq(cll.mesh.lats, [20, -3.4]) assert_eq(cll.mesh.depths, [30, -5.6]) for arr in (cll.vs30, cll.z1pt0, cll.z2pt5): self.assertIsInstance(arr, numpy.ndarray) self.assertEqual(arr.flags.writeable, False) self.assertEqual(arr.dtype, float) for arr in (cll.vs30measured, ): self.assertIsInstance(arr, numpy.ndarray) self.assertEqual(arr.flags.writeable, False) self.assertEqual(arr.dtype, bool) self.assertEqual(len(cll), 2) # test serialization to hdf5 fd, fpath = tempfile.mkstemp(suffix='.hdf5') os.close(fd) with hdf5.File(fpath, 'w') as f: f['folder'] = dict(sitecol=cll, b=[2, 3]) newcll = f['folder/sitecol'] self.assertEqual(newcll, cll) self.assertEqual(list(f['folder/b']), [2, 3]) os.remove(fpath)
def test_nankai(self): # source model for the Nankai region provided by M. Pagani source_model = os.path.join(os.path.dirname(__file__), 'nankai.xml') # it has a single group containing 15 mutex sources [group] = nrml.to_python(source_model) aae(group.srcs_weights, [ 0.0125, 0.0125, 0.0125, 0.0125, 0.1625, 0.1625, 0.0125, 0.0125, 0.025, 0.025, 0.05, 0.05, 0.325, 0.025, 0.1 ]) rup_serial = numpy.arange(group.tot_ruptures, dtype=numpy.uint32) start = 0 for i, src in enumerate(group): src.id = i nr = src.num_ruptures src.serial = rup_serial[start:start + nr] start += nr group.samples = 1 lonlat = 135.68, 35.68 site = Site(geo.Point(*lonlat), 800, True, z1pt0=100., z2pt5=1.) s_filter = SourceFilter(SiteCollection([site]), {}) param = dict(ses_per_logic_tree_path=10, seed=42, filter_distance='rjb') gsims = [SiMidorikawa1999SInter()] dic = sample_ruptures(group, s_filter, gsims, param) self.assertEqual(dic['num_ruptures'], 19) # total ruptures self.assertEqual(dic['num_events'], 16) self.assertEqual(len(dic['eb_ruptures']), 8) self.assertEqual(len(dic['calc_times']), 15) # mutex sources # test export mesh = numpy.array([lonlat], [('lon', float), ('lat', float)]) ebr = dic['eb_ruptures'][0] ebr.export(mesh) # test no filtering ruptures = list(stochastic_event_set(group)) self.assertEqual(len(ruptures), 19)
def test_all_values(self): self.gsim_class.REQUIRES_DISTANCES = set( 'rjb rx rrup repi rhypo'.split()) self.gsim_class.REQUIRES_RUPTURE_PARAMETERS = set( 'mag rake dip ztor hypo_depth width'.split()) self.gsim_class.REQUIRES_SITES_PARAMETERS = set( 'vs30 vs30measured z1pt0 z2pt5'.split()) sites = SiteCollection([self.site1, self.site2]) sctx, rctx, dctx = self.gsim.make_contexts(sites, self.rupture) self.assertIsInstance(sctx, SitesContext) self.assertIsInstance(rctx, RuptureContext) self.assertIsInstance(dctx, DistancesContext) self.assertEqual(rctx.mag, 123.45) self.assertEqual(rctx.rake, 123.56) self.assertEqual(rctx.dip, 45.4545) self.assertEqual(rctx.ztor, 30) self.assertEqual(rctx.hypo_depth, 40) self.assertEqual(rctx.width, 15) self.assertTrue((sctx.vs30 == [456, 1456]).all()) self.assertTrue((sctx.vs30measured == [False, True]).all()) self.assertTrue((sctx.z1pt0 == [12.1, 112.1]).all()) self.assertTrue((sctx.z2pt5 == [15.1, 115.1]).all()) self.assertTrue((dctx.rjb == [6, 7]).all()) self.assertTrue((dctx.rx == [4, 5]).all()) self.assertTrue((dctx.rrup == [10, 11]).all()) numpy.testing.assert_almost_equal(dctx.rhypo, [162.18749272, 802.72247682]) numpy.testing.assert_almost_equal(dctx.repi, [157.17755181, 801.72524895]) self.assertEqual( self.fake_surface.call_counts, { 'get_top_edge_depth': 1, 'get_rx_distance': 1, 'get_joyner_boore_distance': 1, 'get_dip': 1, 'get_min_distance': 1, 'get_width': 1 })
class JB2009ApplyCorrelationTestCase(unittest.TestCase): SITECOL = SiteCollection([ Site(Point(2, -40), 1, True, 1, 1), Site(Point(2, -40.1), 1, True, 1, 1), Site(Point(2, -39.9), 1, True, 1, 1) ]) def test(self): numpy.random.seed(13) cormo = JB2009CorrelationModel(vs30_clustering=False) intra_residuals_sampled = numpy.random.normal(size=(3, 100000)) intra_residuals_correlated = cormo.apply_correlation( self.SITECOL, PGA(), intra_residuals_sampled) inferred_corrcoef = numpy.corrcoef(intra_residuals_correlated) mean = intra_residuals_correlated.mean() std = intra_residuals_correlated.std() self.assertAlmostEqual(mean, 0, delta=0.002) self.assertAlmostEqual(std, 1, delta=0.002) actual_corrcoef = cormo._get_correlation_matrix(self.SITECOL, PGA()) numpy.testing.assert_almost_equal(inferred_corrcoef, actual_corrcoef, decimal=2)
def _setup_sites_liquefaction_zhu(): """ Returns a collection of sites for liquefaction hazard analysis using the HAZUS method """ point_1 = Point(-64.98651, -0.15738) point_2 = Point(-64.77466, -0.45686) point_3 = Point(-64.92747, -0.38363) point_4 = Point(-65.05396, -0.17088) params = [[800., 0, 100., 0.0], [600., 1, 50., 1.0], [400., 2, 50., 2.0], [300., 3, 20., 5.0], [200., 4, 20., 7.0], [150., 5, 20., 10.0], [150., 5, 5., 15.0]] sites = [] for locn in [point_1, point_2, point_3, point_4]: for vs30, hazus_cat, dw, cti in params: sites.append({ "lon": locn.longitude, "lat": locn.latitude, "vs30": vs30, "vs30measured": False, "z1pt0": 48.0, "z2pt5": 0.607, "liquefaction_susceptibility": hazus_cat, "dw": dw, "cti": cti }) site_model_dt = np.dtype([(p, site_param_dt[p]) for p in sorted(sites[0])]) tuples = [ tuple(site[name] for name in site_model_dt.names) for site in sites ] sites = np.array(tuples, site_model_dt) req_site_params = ("vs30", "liquefaction_susceptibility", "dw", "cti") return SiteCollection.from_points(sites["lon"], sites["lat"], sitemodel=sites, req_site_params=req_site_params)
def test_case_10(self): hypocenter_pmf = PMF([(1, test_data.SET1_CASE10_HYPOCENTER_DEPTH)]) sources = [AreaSource( source_id='area', name='area', tectonic_region_type=const.TRT.ACTIVE_SHALLOW_CRUST, mfd=test_data.SET1_CASE10_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_CASE10_SOURCE_POLYGON, area_discretization=10.0, rupture_mesh_spacing=10.0 )] sites = SiteCollection([ test_data.SET1_CASE10_SITE1, test_data.SET1_CASE10_SITE2, test_data.SET1_CASE10_SITE3, test_data.SET1_CASE10_SITE4 ]) gsims = {const.TRT.ACTIVE_SHALLOW_CRUST: SadighEtAl1997()} truncation_level = 0 imts = {str(test_data.IMT): test_data.SET1_CASE10_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_CASE10_SITE1_POES, atol=1e-4, rtol=1e-1) assert_hazard_curve_is(self, s2hc, test_data.SET1_CASE10_SITE2_POES, atol=1e-4, rtol=1e-1) assert_hazard_curve_is(self, s3hc, test_data.SET1_CASE10_SITE3_POES, atol=1e-4, rtol=1e-1) assert_hazard_curve_is(self, s4hc, test_data.SET1_CASE10_SITE4_POES, atol=1e-4, rtol=1e-1)
def test_point_surface(self): sid = 0 name = 'test' trt = TRT.ACTIVE_SHALLOW_CRUST mfd = ArbitraryMFD([7.0], [1.]) rms = 2.5 msr = WC1994() rar = 1.0 tom = PoissonTOM(1.) usd = 0.0 lsd = 20.0 loc = Point(0.0, 0.0) npd = PMF([(1.0, NodalPlane(90., 90., 90.))]) hyd = PMF([(1.0, 10.)]) src = PointSource(sid, name, trt, mfd, rms, msr, rar, tom, usd, lsd, loc, npd, hyd) rups = [r for r in src.iter_ruptures()] # Compute distances param = 'closest_point' sites = SiteCollection( [Site(Point(0.0, 0.0, 0.0)), Site(Point(-0.2, 0.0, 0.0))]) dsts = get_distances(rups[0], sites, param) # Check first point msg = 'The longitude of the first point is wrong' self.assertTrue(abs(dsts[0, 0] - 0.0) < 1e-2, msg) msg = 'The latitude of the first point is wrong' self.assertTrue(abs(dsts[0, 1] - 0.0) < 1e-2, msg) # Check second point msg = 'The longitude of the second point is wrong' self.assertTrue(abs(dsts[1, 0] + 0.1666) < 1e-2, msg) msg = 'The latitude of the second point is wrong' self.assertTrue(abs(dsts[1, 1] - 0.0) < 1e-2, msg)
def test_international_date_line(self): maxdist = IntegrationDistance({ 'default': [(3, 30), (4, 40), (5, 100), (6, 200), (7, 300), (8, 400)] }) sitecol = SiteCollection([ Site(location=Point(179, 80), vs30=1.2, vs30measured=True, z1pt0=3.4, z2pt5=5.6, backarc=True), Site(location=Point(-179, 80), vs30=55.4, vs30measured=False, z1pt0=66.7, z2pt5=88.9, backarc=False) ]) srcfilter = SourceFilter(sitecol, maxdist) bb1, bb2 = srcfilter.get_bounding_boxes(mag=4.5) # bounding boxes in the form min_lon, min_lat, max_lon, max_lat aae(bb1, (173.8210225, 79.10068, 184.1789775, 80.89932)) aae(bb2, (-184.1789775, 79.10068, -173.8210225, 80.89932))
def test_get_bounding_boxes(self): maxdist = IntegrationDistance({ 'default': [(3, 30), (4, 40), (5, 100), (6, 200), (7, 300), (8, 400)] }) sitecol = SiteCollection([ Site(location=Point(10, 20, 30), vs30=1.2, vs30measured=True, z1pt0=3.4, z2pt5=5.6, backarc=True), Site(location=Point(-1.2, -3.4, -5.6), vs30=55.4, vs30measured=False, z1pt0=66.7, z2pt5=88.9, backarc=False) ]) srcfilter = SourceFilter(sitecol, maxdist) bb1, bb2 = srcfilter.get_bounding_boxes(mag=4.5) # bounding boxes in the form min_lon, min_lat, max_lon, max_lat aae(bb1, (9.0429636, 19.10068, 10.9570364, 20.89932)) aae(bb2, (-2.1009057, -4.29932, -0.2990943, -2.50068))
def point_at_distance(self, model, distance, vs30, line_azimuth=90., origin_point=(0.5, 0.), vs30measured=True, z1pt0=None, z2pt5=None, backarc=False): """ Generates a point at a given epicentral distance """ azimuth, origin_point, z1pt0, z2pt5 = _setup_site_peripherals( line_azimuth, origin_point, vs30, z1pt0, z2pt5, model.strike, model.surface) return SiteCollection([ Site(model.hypocentre.point_at(distance, 0., line_azimuth), vs30, vs30measured, z1pt0, z2pt5, backarc=backarc) ])
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 setUp(self): self.truncation_level = 3.4 self.imts = {imt.PGA(): [1, 2, 3], imt.PGD(): [2, 4]} self.time_span = 49.2 rup11 = self.FakeRupture(0.23, const.TRT.ACTIVE_SHALLOW_CRUST) rup12 = self.FakeRupture(0.15, const.TRT.ACTIVE_SHALLOW_CRUST) rup21 = self.FakeRupture(0.04, const.TRT.VOLCANIC) self.source1 = self.FakeSource(1, [rup11, rup12], time_span=self.time_span) self.source2 = self.FakeSource(2, [rup21], time_span=self.time_span) self.sources = iter([self.source1, self.source2]) site1 = Site(Point(10, 20), 1, True, 2, 3) site2 = Site(Point(20, 30), 2, False, 4, 5) self.sites = SiteCollection([site1, site2]) gsim1 = self.FakeGSIM(self.truncation_level, self.imts, poes={ (site1.location.latitude, rup11, imt.PGA()): [0.1, 0.05, 0.03], (site2.location.latitude, rup11, imt.PGA()): [0.11, 0.051, 0.034], (site1.location.latitude, rup12, imt.PGA()): [0.12, 0.052, 0.035], (site2.location.latitude, rup12, imt.PGA()): [0.13, 0.053, 0.036], (site1.location.latitude, rup11, imt.PGD()): [0.4, 0.33], (site2.location.latitude, rup11, imt.PGD()): [0.39, 0.331], (site1.location.latitude, rup12, imt.PGD()): [0.38, 0.332], (site2.location.latitude, rup12, imt.PGD()): [0.37, 0.333], }) gsim2 = self.FakeGSIM(self.truncation_level, self.imts, poes={ (site1.location.latitude, rup21, imt.PGA()): [0.5, 0.3, 0.2], (site2.location.latitude, rup21, imt.PGA()): [0.4, 0.2, 0.1], (site1.location.latitude, rup21, imt.PGD()): [0.24, 0.08], (site2.location.latitude, rup21, imt.PGD()): [0.14, 0.09], }) self.gsims = {const.TRT.ACTIVE_SHALLOW_CRUST: gsim1, const.TRT.VOLCANIC: gsim2}
def test_correlation_with_total_stddev(self): mean1 = 10 mean2 = 14 inter = 1e-300 intra1 = 0.2 intra2 = 1.6 p1 = Point(0, 0) p2 = Point(0, 0.3) sites = [ Site(p1, mean1, False, inter, intra1), Site(p2, mean2, False, inter, intra2) ] self.sites = SiteCollection(sites) numpy.random.seed(41) cormo = JB2009CorrelationModel(vs30_clustering=False) gsim = FakeGSIMTotalStdDev(self) with self.assertRaises(CorrelationButNoInterIntraStdDevs): ground_motion_fields(self.rupture, self.sites, [self.imt1], gsim, truncation_level=None, realizations=6000, correlation_model=cormo)
def test_get_bounding_boxes(self): maxdist = IntegrationDistance({ 'default': [(3, 30), (4, 40), (5, 100), (6, 200), (7, 300), (8, 400)] }) sitecol = SiteCollection([ Site(location=Point(10, 20, 30), vs30=1.2, vs30measured=True, z1pt0=3.4, z2pt5=5.6, backarc=True), Site(location=Point(-1.2, -3.4, -5.6), vs30=55.4, vs30measured=False, z1pt0=66.7, z2pt5=88.9, backarc=False) ]) srcfilter = SourceFilter(sitecol, maxdist) bb1, bb2 = srcfilter.get_bounding_boxes(mag=4) # bounding boxes in the form min_lon, min_lat, max_lon, max_lat aae(bb1, (9.6171855, 19.640272, 10.3828145, 20.359728)) aae(bb2, (-1.5603623, -3.759728, -0.8396377, -3.040272))
def setUpClass(cls): lons = numpy.array([-180, -178, 179, 180, 180], numpy.float32) lats = numpy.array([-27, -28, -26, -30, -28], numpy.float32) cls.sites = SiteCollection.from_points(lons, lats)
def test_filter_all_in(self): col = SiteCollection(self.SITES) filtered = col.filter(numpy.ones(len(self.SITES), bool)) self.assertIs(filtered, col)
def test_filter_all_out(self): col = SiteCollection(self.SITES) filtered = col.filter(numpy.zeros(len(self.SITES), bool)) self.assertIs(filtered, None)
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_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)
class GSIMRupture(object): """ Defines a rupture plane consistent with the properties specified for the trellis plotting. Also contains methods for configuring the site locations """ def __init__(self, magnitude, dip, aspect, tectonic_region='Active Shallow Crust', rake=0., ztor=0., strike=0., msr=WC1994(), initial_point=DEFAULT_POINT, hypocentre_location=None): """ Instantiate the rupture - requires a minimum of a magnitude, dip and aspect ratio """ self.magnitude = magnitude self.dip = dip self.aspect = aspect self.rake = rake self.strike = strike self.location = initial_point self.ztor = ztor self.trt = tectonic_region self.hypo_loc = hypocentre_location # If the top of rupture depth in the initial if fabs(self.location.depth - self.ztor) > 1E-9: self.location.depth = ztor self.msr = msr self.area = self.msr.get_median_area(self.magnitude, self.rake) self.surface = create_planar_surface(self.location, self.strike, self.dip, self.area, self.aspect) self.hypocentre = get_hypocentre_on_planar_surface(self.surface, self.hypo_loc) self.rupture = self.get_rupture() self.target_sites_config = None self.target_sites = None def get_rupture(self): """ Returns the rupture as an instance of the openquake.hazardlib.source.rupture.Rupture class """ return Rupture(self.magnitude, self.rake, self.trt, self.hypocentre, self.surface, PointSource) def get_gsim_contexts(self): """ Returns a comprehensive set of GMPE contecxt objects """ assert isinstance(self.rupture, Rupture) assert isinstance(self.target_sites, SiteCollection) # Distances dctx = DistancesContext() # Rupture distance setattr(dctx, 'rrup', self.rupture.surface.get_min_distance(self.target_sites.mesh)) # Rx setattr(dctx, 'rx', self.rupture.surface.get_rx_distance(self.target_sites.mesh)) # Rjb setattr(dctx, 'rjb', self.rupture.surface.get_joyner_boore_distance( self.target_sites.mesh)) # Rhypo setattr(dctx, 'rhypo', self.rupture.hypocenter.distance_to_mesh( self.target_sites.mesh)) # Repi setattr(dctx, 'repi', self.rupture.hypocenter.distance_to_mesh( self.target_sites.mesh, with_depths=False)) # Ry0 setattr(dctx, 'ry0', self.rupture.surface.get_ry0_distance(self.target_sites.mesh)) # Rcdpp - ignored at present setattr(dctx, 'rcdpp', None) # Azimuth setattr(dctx, 'azimuth', get_distances(self.rupture, self.target_sites.mesh, 'azimuth')) setattr(dctx, 'hanging_wall', None) # Rvolc setattr(dctx, "rvolc", np.zeros_like(self.target_sites.mesh.lons)) # Sites sctx = SitesContext(slots=self.target_sites.array.dtype.names) for key in sctx._slots_: setattr(sctx, key, self.target_sites.array[key]) # Rupture rctx = RuptureContext() setattr(rctx, 'mag', self.magnitude) setattr(rctx, 'strike', self.strike) setattr(rctx, 'dip', self.dip) setattr(rctx, 'rake', self.rake) setattr(rctx, 'ztor', self.ztor) setattr(rctx, 'hypo_depth', self.rupture.hypocenter.depth) setattr(rctx, 'hypo_lat', self.rupture.hypocenter.latitude) setattr(rctx, 'hypo_lon', self.rupture.hypocenter.longitude) setattr(rctx, 'hypo_loc', self.hypo_loc) setattr(rctx, 'width', self.rupture.surface.get_width()) return sctx, rctx, dctx def get_target_sites_mesh(self, maximum_distance, spacing, vs30, vs30measured=True, z1pt0=None, z2pt5=None, backarc=False): """ Renders a two dimensional mesh of points over the rupture surface """ # Get bounding box of dilated rupture lowx, highx, lowy, highy = self._get_limits_maximum_rjb( maximum_distance) # Create bounding box lines and then resample at spacing ewline = Line([Point(lowx, highy, 0.), Point(highx, highy, 0.)]) nsline = Line([Point(lowx, highy, 0.), Point(lowx, lowy, 0.)]) ewline = ewline.resample(spacing) nsline = nsline.resample(spacing) xvals = np.array([pnt.longitude for pnt in ewline.points]) yvals = np.array([pnt.latitude for pnt in nsline.points]) gridx, gridy = np.meshgrid(xvals, yvals) numx, numy = np.shape(gridx) npts = numx * numy gridx = (np.reshape(gridx, npts, 1)).flatten() gridy = (np.reshape(gridy, npts, 1)).flatten() site_list = [] if not z1pt0: # z1pt0 = vs30_to_z1pt0_as08(vs30) z1pt0 = vs30_to_z1pt0_cy14(vs30) if not z2pt5: # z2pt5 = z1pt0_to_z2pt5(z1pt0) z2pt5 = vs30_to_z2pt5_cb14(vs30) for iloc in range(0, npts): site_list.append(Site(Point(gridx[iloc], gridy[iloc], 0.), vs30, z1pt0, z2pt5, vs30measured=vs30measured, backarc=backarc)) self.target_sites = SiteCollection(site_list) self.target_sites_config = { "TYPE": "Mesh", "RMAX": maximum_distance, "SPACING": spacing, "VS30": vs30, "VS30MEASURED": vs30measured, "Z1.0": z1pt0, "Z2.5": z2pt5, "BACKARC": backarc} return self.target_sites def get_target_sites_line(self, maximum_distance, spacing, vs30, line_azimuth=90., origin_point=(0.5, 0.5), as_log=False, vs30measured=True, z1pt0=None, z2pt5=None, backarc=False): """ Defines the target sites along a line with respect to the rupture :param maximum_distance: Maximum distance to be considered [km] :param spacing: Sampling distance for the reference line [km] :param vs30: Time averaged shear wave velocity within the uppermost 30m [m/s] :param line_azimuth: Azimuth of the reference line [degrees] :param origin_point: Coordinates of the origin point of the reference line :param bool as_log: When True scales the distances logarithmically :param bool vs30measured: A boolean defining the method used to determine the vs30 value :param z1pt0: Depth to the 1km/s interface [km] :param z2pt5: Depth to the 2.5km/s interface [km] :param bool backarc: When True the sites are considered in the backarc region """ azimuth, origin_location, z1pt0, z2pt5 = \ self._define_origin_target_site(vs30, line_azimuth, origin_point, vs30measured, z1pt0, z2pt5, backarc) spacings = self._define_line_spacing(maximum_distance, spacing, as_log) target_sites = \ self._append_target_sites(spacings, azimuth, origin_location, vs30, line_azimuth, origin_point, as_log, vs30measured, z1pt0, z2pt5, backarc) # let's be picky and replace inferred values of # self.target_sites_config with the values provided here: self.target_sites_config.update({"RMAX": maximum_distance, "SPACING": spacing}) return target_sites def _define_line_spacing(self, maximum_distance, spacing, as_log=False): """ The user may wish to define the line spacing in either log or linear space """ nvals = int(maximum_distance / spacing) + 1 if as_log: spacings = np.logspace(-3., np.log10(maximum_distance), nvals) spacings[0] = 0.0 else: spacings = np.linspace(0.0, maximum_distance, nvals) if spacings[-1] < (maximum_distance - 1.0E-7): spacings = np.hstack([spacings, maximum_distance]) return spacings def get_target_sites_line_from_given_distances(self, distances, vs30, line_azimuth=90., origin_point=(0.5, 0.5), as_log=False, vs30measured=True, z1pt0=None, z2pt5=None, backarc=False): """ Defines the target sites along a line with respect to the rupture from a given numeric array of distances """ azimuth, origin_location, z1pt0, z2pt5 = \ self._define_origin_target_site(vs30, line_azimuth, origin_point, vs30measured, z1pt0, z2pt5, backarc) distances = self._convert_distances(distances, as_log) return self._append_target_sites(distances, azimuth, origin_location, vs30, line_azimuth, origin_point, as_log, vs30measured, z1pt0, z2pt5, backarc) @staticmethod def _convert_distances(distances, as_log=False): '''assures distances is a numpy numeric array, sorts it and converts its value to a logaritmic scale preserving the array bounds (min and max)''' dist = np.asarray(distances) dist.sort() if as_log: oldmin, oldmax = dist[0], dist[-1] dist = np.log1p(dist) # avoid -inf @ zero in case newmin, newmax = dist[0], dist[-1] # re-map the space to be logarithmic between oldmin and oldmax: dist = oldmin + (oldmax-oldmin)*(dist - newmin)/(newmax - newmin) return dist def _define_origin_target_site(self, vs30, line_azimuth=90., origin_point=(0.5, 0.5), vs30measured=True, z1pt0=None, z2pt5=None, backarc=False): """ Defines the target site from an origin point """ azimuth, origin_location, z1pt0, z2pt5 = _setup_site_peripherals( line_azimuth, origin_point, vs30, z1pt0, z2pt5, self.strike, self.surface) self.target_sites = [Site(origin_location, vs30, z1pt0, z2pt5, vs30measured=vs30measured, backarc=backarc)] return azimuth, origin_location, z1pt0, z2pt5 def _append_target_sites(self, distances, azimuth, origin_location, vs30, line_azimuth=90., origin_point=(0.5, 0.5), as_log=False, vs30measured=True, z1pt0=None, z2pt5=None, backarc=False): """ Appends the target sites along a line with respect to the rupture, given an already set origin target site """ for offset in distances: target_loc = origin_location.point_at(offset, 0., azimuth) self.target_sites.append(Site(target_loc, vs30, z1pt0, z2pt5, vs30measured=vs30measured, backarc=backarc)) self.target_sites_config = { "TYPE": "Line", "RMAX": distances[-1], "SPACING": np.nan if len(distances) < 2 else distances[1] - distances[0], # FIXME does it make sense? "AZIMUTH": line_azimuth, "ORIGIN": origin_point, "AS_LOG": as_log, "VS30": vs30, "VS30MEASURED": vs30measured, "Z1.0": z1pt0, "Z2.5": z2pt5, "BACKARC": backarc} self.target_sites = SiteCollection(self.target_sites) return self.target_sites def get_target_sites_point( self, distance, distance_type, vs30, line_azimuth=90, origin_point=(0.5, 0.5), vs30measured=True, z1pt0=None, z2pt5=None, backarc=False): """ Returns a single target site at a fixed distance from the source, with distance defined according to a specific typology :param float distance: Distance (km) from the point to the source :param str distance_type: Type of distance {'rrup', 'rjb', 'repi', 'rhyp'} :param float vs30: Vs30 (m / s) :param float line_azimuth: Aziumth of the source-to-site line :param tuple origin point: Location (along strike, down dip) of the origin of the source-site line within the rupture :param bool vs30measured: Is vs30 measured (True) or inferred (False) :param float z1pt0: Depth to 1 km/s interface :param floar z2pt5: Depth to 2.5 km/s interface """ if not distance_type in list(POINT_AT_MAPPING.keys()): raise ValueError("Distance type must be one of: Rupture ('rrup'), " "Joyner-Boore ('rjb'), Epicentral ('repi') or " "Hypocentral ('rhyp')") #input_origin_point = deepcopy(origin_point) azimuth, origin_location, z1pt0, z2pt5 = _setup_site_peripherals( line_azimuth, origin_point, vs30, z1pt0, z2pt5, self.strike, self.surface) self.target_sites_config = { "TYPE": "Point", "R": distance, "RTYPE": distance_type, "AZIMUTH": line_azimuth, "ORIGIN": origin_point, "VS30": vs30, "VS30MEASURED": vs30measured, "Z1.0": z1pt0, "Z2.5": z2pt5, "BACKARC": backarc} self.target_sites = POINT_AT_MAPPING[distance_type].point_at_distance( self, distance, vs30, line_azimuth, origin_point, vs30measured, z1pt0, z2pt5, backarc=backarc) 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 filter_hanging_wall(self, filter_type=None): """ Opt to consider only hanging wall or footwall sites """ if not filter_type: # Considers both footwall and hanging wall return self.target_sites elif not filter_type in ('HW', 'FW'): raise ValueError('Hanging wall filter must be either "HW" or "FW"') else: pass # Gets the Rx distance r_x = self.surface.get_rx_distance(self.target_sites.mesh) selected_sites = [] if filter_type == "HW": # Only hanging wall idx = np.where(r_x >= 0.)[0] else: # Only footwall idx = np.where(r_x < 0.)[0] for val in idx: selected_sites.append(self.target_sites.sites[val]) self.target_sites = SiteCollection(selected_sites) return self.target_sites def _site_collection_to_mesh(self): """ Returns a collection of sites as an instance of the :class: `openquake.hazardlib.geo.Mesh` """ if isinstance(self.target_sites, SiteCollection): locations = np.array([len(self.target_sites.sites), 3], dtype=float) for iloc, site in enumerate(self.target_sites.sites): locations[iloc, 0] = site.location.longitude locations[iloc, 1] = site.location.latitude locations[iloc, 2] = site.location.depth return Mesh(locations[:, 0], locations[:, 1], locations[:, 2]) else: raise ValueError('Target sites must be an instance of ' 'openquake.hazardlib.site.SiteCollection') def plot_distance_comparisons(self, distance1, distance2, logaxis=False, figure_size=(7, 5), filename=None, filetype="png", dpi=300): """ Creates a plot comparing different distance metrics for the specific rupture and target site combination """ xdist = self._calculate_distance(distance1) ydist = self._calculate_distance(distance2) plt.figure(figsize=figure_size) if logaxis: plt.loglog(xdist, ydist, color='b', marker='o', linestyle='None') else: plt.plot(xdist, ydist, color='b', marker='o', linestyle='None') plt.xlabel("%s (km)" % distance1, size='medium') plt.ylabel("%s (km)" % distance2, size='medium') plt.title('Rupture: M=%6.1f, Dip=%3.0f, Ztor=%4.1f, Aspect=%5.2f' % (self.magnitude, self.dip, self.ztor, self.aspect)) _save_image(filename, filetype, dpi) plt.show() def _calculate_distance(self, distance_type): """ Calculates the rupture to target site distances for the present rupture and target site configuration """ if distance_type == 'rrup': return self.surface.get_min_distance(self.target_sites.mesh) elif distance_type == 'rjb': return self.surface.get_joyner_boore_distance( self.target_sites.mesh) elif distance_type == 'rx': return self.surface.get_rx_distance(self.target_sites.mesh) elif distance_type == 'rhypo': return self.hypocentre.distance_to_mesh(self.target_sites.mesh) elif distance_type == 'repi': return self.hypocentre.distance_to_mesh(self.target_sites.mesh, with_depths=False) else: raise ValueError('Unsupported Distance Measure: %s' % distance_type) def plot_model_configuration(self, marker_style="o", figure_size=(7, 5), filename=None, filetype="png", dpi=300): """ Produces a 3D plot of the current model configuration """ fig = plt.figure(figsize=figure_size) ax = fig.add_subplot(111, projection='3d') # Wireframe rupture surface mesh lons = [] lats = [] depths = [] for pnt in [self.surface.top_left, self.surface.top_right, self.surface.bottom_right, self.surface.bottom_left, self.surface.top_left]: lons.append(pnt.longitude) lats.append(pnt.latitude) depths.append(-pnt.depth) ax.plot(lons, lats, depths, "k-", lw=2) # Scatter the target sites ax.scatter(self.target_sites.mesh.lons, self.target_sites.mesh.lats, np.ones_like(self.target_sites.mesh.lons), c='r', marker=marker_style) ax.set_xlabel('Longitude') ax.set_ylabel('Latitude') ax.set_zlabel('Depth (km)') ax.set_zlim(np.floor(min(depths)), 0.0) _save_image(filename, filetype, dpi) plt.show()
def test_unknown_distance_error(self): self.gsim_class.REQUIRES_DISTANCES.add('jump height') err = "Unknown distance measure 'jump height'" sites = SiteCollection([self.site1, self.site2]) self._assert_value_error(self.make_contexts, err, site_collection=sites, rupture=self.rupture)
class GSIMRupture(object): """ Creates a rupture plane consistent with the properties specified for the trellis plots """ def __init__(self, magnitude, dip, aspect, tectonic_region='Active Shallow Crust' , rake=0., ztor=0., strike=0., msr=WC1994(), initial_point=DEFAULT_POINT, hypocentre_location=None): """ Instantiate the rupture """ self.magnitude = magnitude self.dip = dip self.aspect = aspect self.rake = rake self.strike = strike self.location = initial_point self.ztor = ztor self.trt = tectonic_region # If the top of rupture depth in the initial if fabs(self.location.depth - self.ztor) > 1E-9: self.location.depth = ztor self.area = msr.get_median_area(self.magnitude, self.rake) self.surface = create_planar_surface(self.location, self.strike, self.dip, self.area, self.aspect) self.hypocentre = get_hypocentre_on_planar_surface(self.surface, hypocentre_location) self.rupture = self.get_rupture() self.target_sites = None def get_rupture(self): """ Returns the rupture as an instance of the openquake.hazardlib.source.rupture.Rupture class """ return Rupture(self.magnitude, self.rake, self.trt, self.hypocentre, self.surface, PointSource) def get_gsim_contexts(self): """ Returns a comprehensive set of GMPE contecxt objects """ assert isinstance(self.rupture, Rupture) assert isinstance(self.target_sites, SiteCollection) # Distances dctx = DistancesContext() # Rupture distance setattr(dctx, 'rrup', self.rupture.surface.get_min_distance(self.target_sites.mesh)) # Rx setattr(dctx, 'rx', self.rupture.surface.get_rx_distance(self.target_sites.mesh)) # Rjb setattr(dctx, 'rjb', self.rupture.surface.get_joyner_boore_distance( self.target_sites.mesh)) # Rhypo setattr(dctx, 'rhypo', self.rupture.hypocenter.distance_to_mesh( self.target_sites.mesh)) # Repi setattr(dctx, 'repi', self.rupture.hypocenter.distance_to_mesh( self.target_sites.mesh, with_depths=False)) # Sites sctx = SitesContext() key_list = ['_vs30', '_vs30measured', '_z1pt0', '_z2pt5'] for key in key_list: setattr(sctx, key[1:], getattr(self.target_sites, key)) # Rupture rctx = RuptureContext() setattr(rctx, 'mag', self.magnitude) setattr(rctx, 'dip', self.dip) setattr(rctx, 'rake', self.rake) setattr(rctx, 'ztor', self.ztor) setattr(rctx, 'hypo_depth', self.rupture.hypocenter.depth) setattr(rctx, 'width', self.rupture.surface.get_width()) return sctx, rctx, dctx def get_target_sites_mesh(self, maximum_distance, spacing, vs30, vs30measured=True, z1pt0=None, z2pt5=None): """ Renders a two dimensional mesh of points over the rupture surface """ # Get bounding box of dilated rupture lowx, highx, lowy, highy = self._get_limits_maximum_rjb( maximum_distance) # Create bounding box lines and then resample at spacing ewline = Line([Point(lowx, highy, 0.), Point(highx, highy, 0.)]) nsline = Line([Point(lowx, highy, 0.), Point(lowx, lowy, 0.)]) ewline = ewline.resample(spacing) nsline = nsline.resample(spacing) xvals = np.array([pnt.longitude for pnt in ewline.points]) yvals = np.array([pnt.latitude for pnt in nsline.points]) gridx, gridy = np.meshgrid(xvals, yvals) numx, numy = np.shape(gridx) npts = numx * numy gridx = (np.reshape(gridx, npts, 1)).flatten() gridy = (np.reshape(gridy, npts, 1)).flatten() site_list = [] if not z1pt0: z1pt0 = vs30_to_z1pt0_as08(vs30) if not z2pt5: z2pt5 = z1pt0_to_z2pt5(z1pt0) for iloc in range(0, npts): site_list.append(Site(Point(gridx[iloc], gridy[iloc], 0.), vs30, vs30measured, z1pt0, z2pt5)) self.target_sites = SiteCollection(site_list) return self.target_sites def get_target_sites_line(self, maximum_distance, spacing, vs30, line_azimuth=90., origin_point=(0.5, 0.5), vs30measured=True, z1pt0=None, z2pt5=None): """ Defines the target sites along a line with respect to the rupture """ azimuth, origin_point, z1pt0, z2pt5 = _setup_site_peripherals( line_azimuth, origin_point, vs30, z1pt0, z2pt5, self.strike, self.surface) targets = [origin_point] self.target_sites = [] distance = 0. cum_dist = distance + spacing while distance < maximum_distance: target_loc= origin_point.point_at(cum_dist, 0., azimuth) # Get Rupture distance temp_mesh = Mesh(np.array(target_loc.longitude), np.array(target_loc.latitude), np.array(target_loc.depth)) distance = self.surface.get_min_distance(temp_mesh) self.target_sites.append(Site(target_loc, vs30, vs30measured, z1pt0, z2pt5)) cum_dist += spacing self.target_sites = SiteCollection(self.target_sites) return self.target_sites def get_target_sites_point(self, distance, distance_type, vs30, line_azimuth=90, origin_point=(0.5, 0.5), vs30measured=True, z1pt0=None, z2pt5=None): """ Returns a single target site at a fixed distance from the source, with distance defined according to a specific typology :param float distance: Distance (km) from the point to the source :param str distance_type: Type of distance {'rrup', 'rjb', 'repi', 'rhyp'} :param float vs30: Vs30 (m / s) :param float line_azimuth: Aziumth of the source-to-site line :param tuple origin point: Location (along strike, down dip) of the origin of the source-site line within the rupture :param bool vs30measured: Is vs30 measured (True) or inferred (False) :param float z1pt0: Depth to 1 km/s interface :param floar z2pt5: Depth to 2.5 km/s interface """ if not distance_type in POINT_AT_MAPPING.keys(): raise ValueError("Distance type must be one of: Rupture ('rrup'), " "Joyner-Boore ('rjb'), Epicentral ('repi') or " "Hypocentral ('rhyp')") self.target_sites = POINT_AT_MAPPING[distance_type].point_at_distance( self, distance, vs30, line_azimuth, origin_point, vs30measured, z1pt0, z2pt5) 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 filter_hanging_wall(self, filter_type=None): """ Opt to consider only hanging wall or footwall sites """ if not filter_type: # Considers both footwall and hanging wall return self.target_sites elif not filter_type in ['HW', 'FW']: raise ValueError('Hanging wall filter must be either "HW" or "FW"') else: pass # Gets the Rx distance r_x = self.surface.get_rx_distance(self.target_sites.mesh) selected_sites = [] if filter_type == "HW": # Only hanging wall idx = np.where(r_x >= 0.)[0] else: # Only footwall idx = np.where(r_x < 0.)[0] for val in idx: selected_sites.append(self.target_sites.sites[val]) self.target_sites = SiteCollection(selected_sites) return self.target_sites def _site_collection_to_mesh(self): """ """ if isinstance(self.target_sites, SiteCollection): locations = np.array([len(self.target_sites.sites), 3], dtype=float) for iloc, site in enumerate(self.target_sites.sites): locations[i, 0] = site.location.longitude locations[i, 1] = site.location.latitude locations[i, 2] = site.location.depth return Mesh(locations[:, 0], locations[:, 1], locations[:, 2]) else: raise ValueError('Target sites must be an instance of ' 'openquake.hazardlib.site.SiteCollection') def plot_distance_comparisons(self, distance1, distance2, logaxis=False, figure_size=(7, 5), filename=None, filetype="png", dpi=300): """ Creates a plot comparing different distance metrics for the specific rupture and target site combination """ xdist = self._calculate_distance(distance1) ydist = self._calculate_distance(distance2) plt.figure(figsize=figure_size) if logaxis: plt.loglog(xdist, ydist, color='b', marker='o', linestyle='None') else: plt.plot(xdist, ydist, color='b', marker='o', linestyle='None') plt.xlabel("%s (km)" % distance1, size='medium') plt.ylabel("%s (km)" % distance2, size='medium') plt.title('Rupture: M=%6.1f, Dip=%3.0f, Ztor=%4.1f, Aspect=%5.2f' % (self.magnitude, self.dip, self.ztor, self.aspect)) _save_image(filename, filetype, dpi) plt.show() def _calculate_distance(self, distance_type): """ Calculates the rupture to target site distances for the present rupture and target site configuration """ if distance_type == 'rrup': return self.surface.get_min_distance(self.target_sites.mesh) elif distance_type == 'rjb': return self.surface.get_joyner_boore_distance( self.target_sites.mesh) elif distance_type == 'rx': return self.surface.get_rx_distance(self.target_sites.mesh) elif distance_type == 'rhypo': return self.hypocentre.distance_to_mesh(self.target_sites.mesh) elif distance_type == 'repi': return self.hypocentre.distance_to_mesh(self.target_sites.mesh, with_depths=False) else: raise ValueError('Unsupported Distance Measure: %s' % distance_type) def plot_model_configuration(self, marker_style="o", figure_size=(7, 5), filename=None, filetype="png", dpi=300): """ Produces a 3D plot of the current model configuration """ fig = plt.figure(figsize=figure_size) ax = fig.add_subplot(111, projection='3d') # Wireframe rupture surface mesh rupture_mesh = self.surface.get_mesh() ax.plot_wireframe(rupture_mesh.lons, rupture_mesh.lats, -rupture_mesh.depths, rstride=1, cstride=1) # Scatter the target sites ax.scatter(self.target_sites.mesh.lons, self.target_sites.mesh.lats, np.ones_like(self.target_sites.mesh.lons), c='r', marker=marker_style) ax.set_xlabel('Longitude') ax.set_ylabel('Latitude') ax.set_zlabel('Depth (km)') _save_image(filename, filetype, dpi) plt.show()