class ConcordantSurfaceTestCase(unittest.TestCase): """ Tests the verification of the GC2 module for the Concordant Test case """ def setUp(self): self.data = numpy.genfromtxt(CONCORDANT_FILE, delimiter=",") self.mesh = Mesh(self.data[:, 0], self.data[:, 1], self.data[:, 2]) self.model = MultiSurface(FRANK1.surfaces) def test_gc2_coords(self): """ Verifies the GC2U, GC2T coordinate for the concordant case """ expected_t = self.data[:, 3] expected_u = self.data[:, 4] gc2t, gc2u = self.model.get_generalised_coordinates( self.mesh.lons, self.mesh.lats) numpy.testing.assert_array_almost_equal(expected_t, gc2t) numpy.testing.assert_array_almost_equal(expected_u, gc2u) def test_gc2_rx(self): """ Verifies Rx for the concordant case """ expected_rx = self.data[:, 5] r_x = self.model.get_rx_distance(self.mesh) numpy.testing.assert_array_almost_equal(expected_rx, r_x) def test_gc2_ry0(self): """ Verifies Ry0 for the concordant case """ expected_ry0 = self.data[:, 6] ry0 = self.model.get_ry0_distance(self.mesh) numpy.testing.assert_array_almost_equal(expected_ry0, ry0)
class ConcordantSurfaceTestCase(unittest.TestCase): """ Tests the verification of the GC2 module for the Concordant Test case """ def setUp(self): self.data = numpy.genfromtxt(CONCORDANT_FILE, delimiter=",") self.mesh = Mesh(self.data[:, 0], self.data[:, 1], self.data[:, 2]) self.model = MultiSurface(FRANK1.surfaces) def test_gc2_coords(self): """ Verifies the GC2U, GC2T coordinate for the concordant case """ expected_t = self.data[:, 3] expected_u = self.data[:, 4] gc2t, gc2u = self.model.get_generalised_coordinates(self.mesh.lons, self.mesh.lats) numpy.testing.assert_array_almost_equal(expected_t, gc2t) numpy.testing.assert_array_almost_equal(expected_u, gc2u) def test_gc2_rx(self): """ Verifies Rx for the concordant case """ expected_rx = self.data[:, 5] r_x = self.model.get_rx_distance(self.mesh) numpy.testing.assert_array_almost_equal(expected_rx, r_x) def test_gc2_ry0(self): """ Verifies Ry0 for the concordant case """ expected_ry0 = self.data[:, 6] ry0 = self.model.get_ry0_distance(self.mesh) numpy.testing.assert_array_almost_equal(expected_ry0, ry0)
def test_bounding_box(self): surf = MultiSurface(self.surfaces_mesh2D) west, east, north, south = surf.get_bounding_box() self.assertEqual(0.1, west) self.assertEqual(4.6, east) self.assertEqual(5.6, north) self.assertEqual(1.1, south)
def get_rupture_enclosing_polygon(self, dilation=0): """ Create instance of :class:`openquake.hazardlib.geo.surface.multi.MultiSurface` from all ruptures' surfaces and compute its bounding box. Calculate convex hull of bounding box, and return it dilated by ``dilation``. :param dilation: A buffer distance in km to extend the polygon borders to. :returns: Instance of :class:`openquake.hazardlib.geo.polygon.Polygon`. """ surfaces = [] for rup, _ in self.data: if isinstance(rup.surface, MultiSurface): for s in rup.surface.surfaces: surfaces.append(s) else: surfaces.append(rup.surface) multi_surf = MultiSurface(surfaces) west, east, north, south = multi_surf.get_bounding_box() mesh = RectangularMesh(numpy.array([[west, east], [west, east]]), numpy.array([[north, north], [south, south]]), None) poly = mesh.get_convex_hull() return poly if dilation == 0 else poly.dilate(dilation)
def setUp(self): # First surface - Almost vertical dipping to south prf1 = Line([Point(0, 0, 0), Point(0, -0.00001, 20.)]) prf2 = Line([Point(0.15, 0, 0), Point(0.15, -0.00001, 20.)]) prf3 = Line([Point(0.3, 0, 0), Point(0.3, -0.00001, 20.)]) sfca = KiteSurface.from_profiles([prf1, prf2, prf3], 1., 1.) self.msrf = MultiSurface([sfca])
def test_middle_point_multi_surfaces(self): surf = MultiSurface( [ PlanarSurface( 1.0, 0.0, 90.0, Point(0.0, -1.0, 0.0), Point(0.0, 1.0, 0.0), Point(0.0, 1.0, 10.0), Point(0.0, -1.0, 10.0), ), PlanarSurface( 1.0, 135.0, 90.0, Point(0.0, -1.0, 0.0), Point(1.0, 1.0, 0.0), Point(1.0, 1.0, 10.0), Point(0.0, -1.0, 10.0), ), ] ) middle_point = surf.get_middle_point() self.assertTrue(Point(0.5, 0.0, 5.0) == middle_point)
def test_get_closest_points_mesh1D(self): surf = MultiSurface(self.surfaces_mesh1D) closest_points = surf.get_closest_points(self.mesh1D) numpy.testing.assert_equal(closest_points.lons, numpy.array([0.1, 0.2, 2.3])) numpy.testing.assert_equal(closest_points.lats, numpy.array([1.1, 1.2, 3.3])) numpy.testing.assert_equal(closest_points.depths, numpy.array([1.1, 1.2, 2.3]))
def test_middle_point_multi_surfaces(self): surf = MultiSurface([ PlanarSurface(1.0, 0.0, 90.0, Point(0.0, -1.0, 0.0), Point(0.0, 1.0, 0.0), Point(0.0, 1.0, 10.0), Point(0.0, -1.0, 10.0)), PlanarSurface(1.0, 135.0, 90.0, Point(0.0, -1.0, 0.0), Point(1.0, 1.0, 0.0), Point(1.0, 1.0, 10.0), Point(0.0, -1.0, 10.0)) ]) middle_point = surf.get_middle_point() self.assertTrue(Point(0.5, 0.0, 5.0) == middle_point)
def test_get_closest_points_mesh1D(self): surf = MultiSurface(self.surfaces_mesh1D) closest_points = surf.get_closest_points(self.mesh1D) numpy.testing.assert_equal( closest_points.lons, numpy.array([0.1, 0.2, 2.3]) ) numpy.testing.assert_equal( closest_points.lats, numpy.array([1.1, 1.2, 3.3]) ) numpy.testing.assert_equal( closest_points.depths, numpy.array([1.1, 1.2, 2.3]) )
def get_bounding_box(self, maxdist): """ Bounding box containing all surfaces, enlarged by the maximum distance """ surfaces = [] for rup, _ in self.data: if isinstance(rup.surface, MultiSurface): for s in rup.surface.surfaces: surfaces.append(s) else: surfaces.append(rup.surface) multi_surf = MultiSurface(surfaces) west, east, north, south = multi_surf.get_bounding_box() a1 = maxdist * KM_TO_DEGREES a2 = angular_distance(maxdist, north, south) return west - a2, south - a1, east + a2, north + a1
def iter_ruptures(self, fromidx=0, untilidx=None, **kwargs): """ An iterator for the ruptures. :param fromidx: start :param untilidx: stop """ # check if 'sections' not in self.__dict__: raise RuntimeError('You forgot to call set_sections in %s!' % self) # iter on the ruptures untilidx = len(self.mags) if untilidx is None else untilidx s = self.sections for i in range(fromidx, untilidx): idxs = self.rupture_idxs[i] if len(idxs) == 1: sfc = self.sections[idxs[0]].surface else: sfc = MultiSurface([s[idx].surface for idx in idxs]) rake = self.rakes[i] hypo = self.sections[idxs[0]].surface.get_middle_point() yield NonParametricProbabilisticRupture(self.mags[i], rake, self.tectonic_region_type, hypo, sfc, self.pmfs[i])
class MultiSurfaceTestCase(unittest.TestCase): def setUp(self): # First surface prf1 = Line([Point(0, 0, 0), Point(0, -0.001, 20.)]) prf2 = Line([Point(0.15, 0, 0), Point(0.15, -0.001, 20.)]) prf3 = Line([Point(0.3, 0, 0), Point(0.3, -0.001, 20.)]) sfcA = KiteSurface.from_profiles([prf1, prf2, prf3], 5., 5.) # Second surface prf3 = Line([Point(0.32, 0, 0), Point(0.32, 0.001, 20.)]) prf4 = Line([Point(0.45, 0.15, 0), Point(0.45, 0.1501, 20.)]) sfcB = KiteSurface.from_profiles([prf3, prf4], 5., 5.) self.msrf = MultiSurface([sfcA, sfcB]) coo = np.array([[-0.1, 0.0], [0.0, 0.1]]) self.mesh = Mesh(coo[:, 0], coo[:, 1]) def test_rx(self): # Test Rx expected = np.array([-3.492642, -13.384149]) computed = self.msrf.get_rx_distance(self.mesh) np.testing.assert_allclose(computed, expected)
def setUp(self): path = os.path.join(BASE_DATA_PATH, 'profiles08') hsmpl = 2 vsmpl = 2 idl = False alg = False # Read the profiles with prefix cs_50. These profiles dip toward # north prf, _ = _read_profiles(path, 'cs_50') srfc50 = KiteSurface.from_profiles(prf, vsmpl, hsmpl, idl, alg) # Read the profiles with prefix cs_52. These profiles dip toward # north. This section is west to the section defined by cs_50 prf, _ = _read_profiles(path, 'cs_51') srfc51 = KiteSurface.from_profiles(prf, vsmpl, hsmpl, idl, alg) clo = [] cla = [] step = 0.01 for lo in np.arange(-71.8, -69, step): tlo = [] tla = [] for la in np.arange(19.25, 20.25, step): tlo.append(lo) tla.append(la) clo.append(tlo) cla.append(tla) self.clo = np.array(clo) self.cla = np.array(cla) mesh = Mesh(lons=self.clo.flatten(), lats=self.cla.flatten()) # Define multisurface and mesh of sites self.srfc50 = srfc50 self.srfc51 = srfc51 self.msrf = MultiSurface([srfc50, srfc51]) self.mesh = mesh self.los = [ self.msrf.surfaces[0].mesh.lons, self.msrf.surfaces[1].mesh.lons ] self.las = [ self.msrf.surfaces[0].mesh.lats, self.msrf.surfaces[1].mesh.lats ]
def setUp(self): # First surface prf1 = Line([Point(0, 0, 0), Point(0, -0.001, 20.)]) prf2 = Line([Point(0.15, 0, 0), Point(0.15, -0.001, 20.)]) prf3 = Line([Point(0.3, 0, 0), Point(0.3, -0.001, 20.)]) sfcA = KiteSurface.from_profiles([prf1, prf2, prf3], 5., 5.) # Second surface prf3 = Line([Point(0.32, 0, 0), Point(0.32, 0.001, 20.)]) prf4 = Line([Point(0.45, 0.15, 0), Point(0.45, 0.1501, 20.)]) sfcB = KiteSurface.from_profiles([prf3, prf4], 5., 5.) self.msrf = MultiSurface([sfcA, sfcB]) coo = np.array([[-0.1, 0.0], [0.0, 0.1]]) self.mesh = Mesh(coo[:, 0], coo[:, 1])
def test_rx(self): mesh = Mesh(numpy.array([-118.]), numpy.array([33])) # 1 point surf18 = MultiSurface.from_csv(cd / 'msurface18.csv') # 2 planes surf19 = MultiSurface.from_csv(cd / 'msurface19.csv') # 2 planes surf20 = MultiSurface.from_csv(cd / 'msurface20.csv') # 1 plane rx18 = surf18.get_rx_distance(mesh)[0] rx19 = surf19.get_rx_distance(mesh)[0] rx20 = surf20.get_rx_distance(mesh)[0] aac([rx18, rx19, rx20], [51.610675, 54.441119, -60.205692]) surfa = MultiSurface(surf18.surfaces + surf19.surfaces) surfb = MultiSurface(surf19.surfaces + surf20.surfaces) rxa = surfa.get_rx_distance(mesh)[0] rxb = surfb.get_rx_distance(mesh)[0] aac([rxa, rxb], [53.034889, -56.064366])
def test_rjb(self): mesh = Mesh(numpy.array([-118.]), numpy.array([33])) # 1 point surf18 = MultiSurface.from_csv(cd / 'msurface18.csv') # 2 planes surf19 = MultiSurface.from_csv(cd / 'msurface19.csv') # 2 planes surf20 = MultiSurface.from_csv(cd / 'msurface20.csv') # 1 plane rjb18 = surf18.get_joyner_boore_distance(mesh)[0] rjb19 = surf19.get_joyner_boore_distance(mesh)[0] rjb20 = surf20.get_joyner_boore_distance(mesh)[0] aac([rjb18, rjb19, rjb20], [85.676294, 89.225542, 92.937021]) surfa = MultiSurface(surf18.surfaces + surf19.surfaces) surfb = MultiSurface(surf19.surfaces + surf20.surfaces) rjba = surfa.get_joyner_boore_distance(mesh)[0] rjbb = surfb.get_joyner_boore_distance(mesh)[0] aac([rjba, rjbb], [85.676294, 89.225542])
def test_rx_kite(self): spc = 2.0 pro1 = Line([Point(0.2, 0.0, 0.0), Point(0.2, 0.05, 15.0)]) pro2 = Line([Point(0.0, 0.0, 0.0), Point(0.0, 0.05, 15.0)]) sfc1 = KiteSurface.from_profiles([pro1, pro2], spc, spc) msurf = MultiSurface([sfc1]) pcoo = numpy.array([[0.2, 0.1], [0.0, -0.1]]) mesh = Mesh(pcoo[:, 0], pcoo[:, 1]) # Compute expected distances lo = pro1.points[0].longitude la = pro1.points[0].longitude tmp0 = geodetic_distance(lo, la, pcoo[0, 0], pcoo[0, 1]) lo = pro2.points[0].longitude la = pro2.points[0].longitude tmp1 = geodetic_distance(lo, la, pcoo[1, 0], pcoo[1, 1]) # Checking rx = msurf.get_rx_distance(mesh) expected = numpy.array([tmp0, -tmp1]) numpy.testing.assert_almost_equal(expected, rx, decimal=5)
def setUp(self): # First surface - Almost vertical dipping to south prf1 = Line([Point(0, 0, 0), Point(0, -0.00001, 20.)]) prf2 = Line([Point(0.15, 0, 0), Point(0.15, -0.00001, 20.)]) prf3 = Line([Point(0.3, 0, 0), Point(0.3, -0.00001, 20.)]) sfca = KiteSurface.from_profiles([prf1, prf2, prf3], 1., 1.) # Second surface - Strike to NE and dip to SE pntsa = npoints_towards(lon=0.32, lat=0.0, depth=0.0, azimuth=45, hdist=10.0, vdist=0.0, npoints=2) pntsb = npoints_towards(lon=pntsa[0][1], lat=pntsa[1][1], depth=pntsa[2][1], azimuth=45 + 90, hdist=10.0, vdist=10.0, npoints=2) pntsc = npoints_towards(lon=0.32, lat=0.0, depth=0.0, azimuth=45 + 90, hdist=10.0, vdist=10.0, npoints=2) tmp = Point(pntsc[0][1], pntsc[1][1], pntsc[2][1]) prf3 = Line([Point(0.32, 0, 0), tmp]) tmp1 = Point(pntsa[0][1], pntsa[1][1], pntsa[2][1]) tmp2 = Point(pntsb[0][1], pntsb[1][1], pntsb[2][1]) prf4 = Line([tmp1, tmp2]) sfcb = KiteSurface.from_profiles([prf3, prf4], 0.2, 0.2) # Create surface and mesh needed for the test self.msrf = MultiSurface([sfca, sfcb]) self.coo = np.array([[-0.1, 0.0], [0.0, 0.1]]) self.mesh = Mesh(self.coo[:, 0], self.coo[:, 1])
def get_rupture_enclosing_polygon(self, dilation=0): """ Create instance of :class:`openquake.hazardlib.geo.surface.multi.MultiSurface` from all ruptures' surfaces and compute its bounding box. Calculate convex hull of bounding box, and return it dilated by ``dilation``. :param dilation: A buffer distance in km to extend the polygon borders to. :returns: Instance of :class:`openquake.hazardlib.geo.polygon.Polygon`. """ surfaces = [rup.surface for (rup, _) in self.data] multi_surf = MultiSurface(surfaces) west, east, north, south = multi_surf.get_bounding_box() mesh = RectangularMesh(numpy.array([[west, east], [west, east]]), numpy.array([[north, north], [south, south]]), None) poly = mesh.get_convex_hull() return poly if dilation == 0 else poly.dilate(dilation)
def get_ucerf_rupture(self, hdf5, iloc, src_filter): """ :param hdf5: Source Model hdf5 object as instance of :class: h5py.File :param int iloc: Location of the rupture plane in the hdf5 file :param src_filter: Sites for consideration and maximum distance """ ctl = self.control mesh_spacing = ctl.mesh_spacing trt = ctl.tectonic_region_type ridx = hdf5[self.idx_set["geol_idx"] + "/RuptureIndex"][iloc] mag = hdf5[self.idx_set["mag_idx"]][iloc] surface_set = [] r_sites = self.get_rupture_sites(hdf5, ridx, src_filter, mag) if r_sites is None: return None, None for idx in ridx: # Build simple fault surface trace_idx = "{:s}/{:s}".format(self.idx_set["sec_idx"], str(idx)) rup_plane = hdf5[trace_idx + "/RupturePlanes"][:].astype("float64") for jloc in range(0, rup_plane.shape[2]): top_left = Point(rup_plane[0, 0, jloc], rup_plane[0, 1, jloc], rup_plane[0, 2, jloc]) top_right = Point(rup_plane[1, 0, jloc], rup_plane[1, 1, jloc], rup_plane[1, 2, jloc]) bottom_right = Point(rup_plane[2, 0, jloc], rup_plane[2, 1, jloc], rup_plane[2, 2, jloc]) bottom_left = Point(rup_plane[3, 0, jloc], rup_plane[3, 1, jloc], rup_plane[3, 2, jloc]) try: surface_set.append( ImperfectPlanarSurface.from_corner_points( mesh_spacing, top_left, top_right, bottom_right, bottom_left)) except ValueError as evl: raise ValueError(evl, trace_idx, top_left, top_right, bottom_right, bottom_left) rupture = ParametricProbabilisticRupture( mag, hdf5[self.idx_set["rake_idx"]][iloc], trt, surface_set[len(surface_set) // 2].get_middle_point(), MultiSurface(surface_set), CharacteristicFaultSource, hdf5[self.idx_set["rate_idx"]][iloc], ctl.tom) # Get rupture index code string ridx_string = "-".join(str(val) for val in ridx) return rupture, ridx_string
def setUp(self): path = os.path.join(BASE_DATA_PATH, 'profiles08') hsmpl = 5 vsmpl = 5 idl = False alg = False prf, _ = _read_profiles(path, 'cs_50') srfc50 = KiteSurface.from_profiles(prf, vsmpl, hsmpl, idl, alg) prf, _ = _read_profiles(path, 'cs_51') srfc51 = KiteSurface.from_profiles(prf, vsmpl, hsmpl, idl, alg) coo = [] step = 0.5 for lo in np.arange(-74, -68, step): for la in np.arange(17, 20, step): coo.append([lo, la]) coo = np.array(coo) mesh = Mesh(coo[:, 0], coo[:, 1]) # Define multisurface and mesh of sites self.msrf = MultiSurface([srfc50, srfc51]) self.mesh = mesh
def few_ruptures(self): """ Fast version of iter_ruptures used in estimate_weight """ s = self.sections for i in range(0, len(self.mags), BLOCKSIZE // 5): idxs = self.rupture_idxs[i] if len(idxs) == 1: sfc = self.sections[idxs[0]].surface else: sfc = MultiSurface([s[idx].surface for idx in idxs]) rake = self.rakes[i] hypo = self.sections[idxs[0]].surface.get_middle_point() yield NonParametricProbabilisticRupture( self.mags[i], rake, self.tectonic_region_type, hypo, sfc, self.pmfs[i])
def get_ucerf_rupture(self, iloc): """ :param iloc: Location of the rupture plane in the hdf5 file """ trt = self.tectonic_region_type if hasattr(self, 'all_ridx'): # already computed by the UcerfFilter ridx = self.all_ridx[iloc - self.start] else: ridx = self.get_ridx(iloc) mag = self.mags[iloc - self.start] if mag < self.min_mag: return surface_set = [] indices = self.src_filter.get_indices(self, ridx, mag) if len(indices) == 0: return for trace, plane in self.gen_trace_planes(ridx): # build simple fault surface for jloc in range(0, plane.shape[2]): top_left = Point( plane[0, 0, jloc], plane[0, 1, jloc], plane[0, 2, jloc]) top_right = Point( plane[1, 0, jloc], plane[1, 1, jloc], plane[1, 2, jloc]) bottom_right = Point( plane[2, 0, jloc], plane[2, 1, jloc], plane[2, 2, jloc]) bottom_left = Point( plane[3, 0, jloc], plane[3, 1, jloc], plane[3, 2, jloc]) try: surface_set.append( ImperfectPlanarSurface.from_corner_points( top_left, top_right, bottom_right, bottom_left)) except ValueError as err: raise ValueError(err, trace, top_left, top_right, bottom_right, bottom_left) rupture = ParametricProbabilisticRupture( mag, self.rake[iloc - self.start], trt, surface_set[len(surface_set) // 2].get_middle_point(), MultiSurface(surface_set), self.rate[iloc - self.start], self.tom) return rupture
def get_ucerf_rupture(self, iloc, src_filter): """ :param iloc: Location of the rupture plane in the hdf5 file :param src_filter: Sites for consideration and maximum distance """ mesh_spacing = self.mesh_spacing trt = self.tectonic_region_type ridx = self.get_ridx(iloc) mag = self.mags[iloc] surface_set = [] r_sites = self.get_rupture_sites(ridx, src_filter, mag) if r_sites is None: return None for trace, plane in self.gen_trace_planes(ridx): # build simple fault surface for jloc in range(0, plane.shape[2]): top_left = Point(plane[0, 0, jloc], plane[0, 1, jloc], plane[0, 2, jloc]) top_right = Point(plane[1, 0, jloc], plane[1, 1, jloc], plane[1, 2, jloc]) bottom_right = Point(plane[2, 0, jloc], plane[2, 1, jloc], plane[2, 2, jloc]) bottom_left = Point(plane[3, 0, jloc], plane[3, 1, jloc], plane[3, 2, jloc]) try: surface_set.append( ImperfectPlanarSurface.from_corner_points( mesh_spacing, top_left, top_right, bottom_right, bottom_left)) except ValueError as err: raise ValueError(err, trace, top_left, top_right, bottom_right, bottom_left) rupture = ParametricProbabilisticRupture( mag, self.rake[iloc], trt, surface_set[len(surface_set) // 2].get_middle_point(), MultiSurface(surface_set), CharacteristicFaultSource, self.rate[iloc], self.tom) return rupture
def get_ucerf_rupture(self, ridx): """ :param ridx: rupture index """ sections = self.sections[ridx] mag = self.mags[ridx] if mag < self.min_mag: return surface_set = [] for sec in sections: plane = self.planes[sec] for p in range(plane.shape[2]): surface_set.append(PlanarSurface.from_ucerf(plane[:, :, p])) rupture = ParametricProbabilisticRupture( mag, self.rake[ridx], self.tectonic_region_type, surface_set[len(surface_set) // 2].get_middle_point(), MultiSurface(surface_set), self.rate[ridx], self.tom) rupture.rup_id = self.start + ridx return rupture
class MultiSurfaceTwoTestCase(unittest.TestCase): def setUp(self): # First surface - Almost vertical dipping to south prf1 = Line([Point(0, 0, 0), Point(0, -0.00001, 20.)]) prf2 = Line([Point(0.15, 0, 0), Point(0.15, -0.00001, 20.)]) prf3 = Line([Point(0.3, 0, 0), Point(0.3, -0.00001, 20.)]) sfca = KiteSurface.from_profiles([prf1, prf2, prf3], 1., 1.) # Second surface - Strike to NE and dip to SE pntsa = npoints_towards(lon=0.32, lat=0.0, depth=0.0, azimuth=45, hdist=10.0, vdist=0.0, npoints=2) pntsb = npoints_towards(lon=pntsa[0][1], lat=pntsa[1][1], depth=pntsa[2][1], azimuth=45 + 90, hdist=10.0, vdist=10.0, npoints=2) pntsc = npoints_towards(lon=0.32, lat=0.0, depth=0.0, azimuth=45 + 90, hdist=10.0, vdist=10.0, npoints=2) tmp = Point(pntsc[0][1], pntsc[1][1], pntsc[2][1]) prf3 = Line([Point(0.32, 0, 0), tmp]) tmp1 = Point(pntsa[0][1], pntsa[1][1], pntsa[2][1]) tmp2 = Point(pntsb[0][1], pntsb[1][1], pntsb[2][1]) prf4 = Line([tmp1, tmp2]) sfcb = KiteSurface.from_profiles([prf3, prf4], 0.2, 0.2) # Create surface and mesh needed for the test self.msrf = MultiSurface([sfca, sfcb]) self.coo = np.array([[-0.1, 0.0], [0.0, 0.1]]) self.mesh = Mesh(self.coo[:, 0], self.coo[:, 1]) def test_areas(self): """ Compute the areas of surfaces """ length = geodetic_distance(0.0, 0.0, 0.3, 0.0) expected = np.array([length * 20.0, 10 * 14.14]) computed = self.msrf._get_areas() msg = 'Multi fault surface: areas are wrong' np.testing.assert_almost_equal(expected, computed, err_msg=msg, decimal=-1) def test_width(self): """ Compute the width of a multifault surface with 2 sections""" computed = self.msrf.get_width() # The width of the first surface is about 20 km while the second one # is about 14 km. The total width is the weighted mean of the width of # each section (weight proportional to the area) smm = np.sum(self.msrf.areas) expected = (20.0 * self.msrf.areas[0] + 14.14 * self.msrf.areas[1]) / smm perc_diff = abs(computed - expected) / computed * 100 msg = f'Multi fault surface: width is wrong. % diff {perc_diff}' self.assertTrue(perc_diff < 0.2, msg=msg) def test_get_area(self): computed = self.msrf.get_area() length = geodetic_distance(0.0, 0.0, 0.3, 0.0) expected = length * 20.0 + 100 perc_diff = abs(computed - expected) / computed msg = 'Multi fault surface: area is wrong' self.assertTrue(perc_diff < 0.1, msg=msg)
def _setup_peer_test_bending_fault_config(): """ The GC2 tests will be based on variations of the PEER bending fault test case: (Fault is dipping east north east Point 5 (-65.0, 0.0, 0.0) o | | | o Point 4 (-65.0, -0.16188, 0) \ \ \ \ \ o Point 3 (-64.90498, -0.36564, 0.0) \__ \__ \__ \__ \__Point 2 (-64.80164, -0.45236, 0.0) \o---o Point 1 (-64.78365, -0.45236, 0.0) """ # Build separate faults # Get down-dip points - dipping east-noth-east strike1 = PNT1.azimuth(PNT2) dipdir1 = (strike1 + 90.) % 360.0 strike2 = PNT2.azimuth(PNT3) dipdir2 = (strike2 + 90.) % 360.0 strike3 = PNT3.azimuth(PNT4) dipdir3 = (strike3 + 90.) % 360.0 strike4 = PNT4.azimuth(PNT5) dipdir4 = (strike4 + 90.) % 360.0 global_strike = PNT1.azimuth(PNT5) global_dipdir = (global_strike + 90.) % 360.0 # Get lower trace usd = 0.0 lsd = 12.0 dip = 60.0 as_length = lsd / numpy.tan(numpy.radians(dip)) PNT1b = PNT1.point_at(as_length, lsd, global_dipdir) PNT2b = PNT2.point_at(as_length, lsd, global_dipdir) PNT3b = PNT3.point_at(as_length, lsd, global_dipdir) PNT4b = PNT4.point_at(as_length, lsd, global_dipdir) PNT5b = PNT5.point_at(as_length, lsd, global_dipdir) # As simple fault dipping east mesh_spacing = 0.5 simple_fault1 = SimpleFaultSurface.from_fault_data( Line([PNT1, PNT2, PNT3, PNT4, PNT5]), usd, lsd, dip, mesh_spacing) # As a set of planes describing a concordant "Stirling fault" stirling_planes = [ PlanarSurface.from_corner_points(PNT1, PNT2, PNT2b, PNT1b), PlanarSurface.from_corner_points(PNT2, PNT3, PNT3b, PNT2b), PlanarSurface.from_corner_points(PNT3, PNT4, PNT4b, PNT3b), PlanarSurface.from_corner_points(PNT4, PNT5, PNT5b, PNT4b) ] stirling_fault1 = MultiSurface(stirling_planes) # As a set of planes describing a concordant "Frankel Fault" # In the Frankel fault each segment is projected to the local dip direction dipdir2b = (dipdir2 + 180.) % 360.0 frankel_planes = [ PlanarSurface.from_corner_points( PNT1, PNT2, PNT2.point_at(as_length, lsd, dipdir1), PNT1.point_at(as_length, lsd, dipdir1)), PlanarSurface.from_corner_points( PNT2, PNT3, PNT3.point_at(as_length, lsd, dipdir2), PNT2.point_at(as_length, lsd, dipdir2)), PlanarSurface.from_corner_points( PNT3, PNT4, PNT4.point_at(as_length, lsd, dipdir3), PNT3.point_at(as_length, lsd, dipdir3)), PlanarSurface.from_corner_points( PNT4, PNT5, PNT5.point_at(as_length, lsd, dipdir4), PNT4.point_at(as_length, lsd, dipdir4)) ] frankel_fault1 = MultiSurface(frankel_planes) # Test the case of a discordant Frankel plane # Swapping the strike of the second segment to change the dip direction # Also increasing the dip from 60 degrees to 75 degrees as_length_alt = lsd / numpy.tan(numpy.radians(75.0)) frankel_discordant = [ PlanarSurface.from_corner_points( PNT1, PNT2, PNT2.point_at(as_length, lsd, dipdir1), PNT1.point_at(as_length, lsd, dipdir1)), PlanarSurface.from_corner_points( PNT3, PNT2, PNT2.point_at(as_length_alt, lsd, dipdir2b), PNT3.point_at(as_length_alt, lsd, dipdir2b)), PlanarSurface.from_corner_points( PNT3, PNT4, PNT4.point_at(as_length, lsd, dipdir3), PNT3.point_at(as_length, lsd, dipdir3)), PlanarSurface.from_corner_points( PNT4, PNT5, PNT5.point_at(as_length, lsd, dipdir4), PNT4.point_at(as_length, lsd, dipdir4)) ] frankel_fault2 = MultiSurface(frankel_discordant) return simple_fault1, stirling_fault1, frankel_fault1, frankel_fault2
def setUp(self): self.data = numpy.genfromtxt(DISCORDANT_FILE, delimiter=",") self.mesh = Mesh(self.data[:, 0], self.data[:, 1], self.data[:, 2]) self.model = MultiSurface(FRANK2.surfaces)
def test_area(self): surf = MultiSurface(self.surfaces_mesh2D) self.assertAlmostEqual(90.0, surf.get_area())
def test_joyner_boore_distance_mesh1D(self): surf = MultiSurface(self.surfaces_mesh1D) numpy.testing.assert_equal(surf.get_joyner_boore_distance(self.mesh1D), numpy.array([-1.0, 2.0, 2.0]))
def test_get_width(self): surf = MultiSurface(self.surfaces_mesh2D) self.assertAlmostEqual(12.88888888, surf.get_width())
def test_get_dip(self): surf = MultiSurface(self.surfaces_mesh2D) self.assertAlmostEqual(53.33333333, surf.get_dip())
def test_get_strike(self): surf = MultiSurface(self.surfaces_mesh2D) self.assertAlmostEqual(87.64579754, surf.get_strike())
def test_top_edge_depth(self): surf = MultiSurface(self.surfaces_mesh2D) self.assertAlmostEqual(8.22222222, surf.get_top_edge_depth())
def test_rx_distance_mesh1D(self): surf = MultiSurface(self.surfaces_mesh1D) numpy.testing.assert_equal(surf.get_rx_distance(self.mesh1D), numpy.array([-1., 2., 2.]))
def test_joyner_boore_distance_mesh2D(self): surf = MultiSurface(self.surfaces_mesh2D) numpy.testing.assert_equal(surf.get_joyner_boore_distance(self.mesh2D), numpy.array([[-1., 2., 2.], [4., 4., 5.]]))
class MultiSurfaceWithNaNsTestCase(unittest.TestCase): NAME = 'MultiSurfaceWithNaNsTestCase' def setUp(self): path = os.path.join(BASE_DATA_PATH, 'profiles08') hsmpl = 2 vsmpl = 2 idl = False alg = False # Read the profiles with prefix cs_50. These profiles dip toward # north prf, _ = _read_profiles(path, 'cs_50') srfc50 = KiteSurface.from_profiles(prf, vsmpl, hsmpl, idl, alg) # Read the profiles with prefix cs_52. These profiles dip toward # north. This section is west to the section defined by cs_50 prf, _ = _read_profiles(path, 'cs_51') srfc51 = KiteSurface.from_profiles(prf, vsmpl, hsmpl, idl, alg) clo = [] cla = [] step = 0.01 for lo in np.arange(-71.8, -69, step): tlo = [] tla = [] for la in np.arange(19.25, 20.25, step): tlo.append(lo) tla.append(la) clo.append(tlo) cla.append(tla) self.clo = np.array(clo) self.cla = np.array(cla) mesh = Mesh(lons=self.clo.flatten(), lats=self.cla.flatten()) # Define multisurface and mesh of sites self.srfc50 = srfc50 self.srfc51 = srfc51 self.msrf = MultiSurface([srfc50, srfc51]) self.mesh = mesh self.los = [ self.msrf.surfaces[0].mesh.lons, self.msrf.surfaces[1].mesh.lons ] self.las = [ self.msrf.surfaces[0].mesh.lats, self.msrf.surfaces[1].mesh.lats ] def test_get_edge_set(self): # The vertexes of the expected edges are the first and last vertexes of # the topmost row of the mesh expected = [ np.array([[-70.33, 19.65, 0.], [-70.57722702, 19.6697801, 0.0]]), np.array([[-70.10327766, 19.67957463, 0.0], [-70.33, 19.65, 0.0]]) ] if PLOTTING: _, ax = plt.subplots(1, 1) for sfc in self.msrf.surfaces: col = np.random.rand(3) mesh = sfc.mesh ax.plot(mesh.lons, mesh.lats, '.', color=col) ax.plot(mesh.lons[0, :], mesh.lats[0, :], lw=3) for edge in self.msrf.edge_set: ax.plot(edge[:, 0], edge[:, 1], 'x-r') plt.show() # Note that method is executed when the object is initialized ess = self.msrf.edge_set for es, expct in zip(ess, expected): np.testing.assert_array_almost_equal(es, expct, decimal=2) def test_get_strike(self): # Since the two surfaces dip to the north, we expect the strike to # point toward W msg = 'Multi fault surface: strike is wrong' strike = self.msrf.get_strike() self.assertAlmostEqual(268.867, strike, places=2, msg=msg) def test_get_dip(self): dip = self.msrf.get_dip() expected = 69.649 msg = 'Multi fault surface: dip is wrong' aae(dip, expected, err_msg=msg, decimal=2) def test_get_width(self): """ check the width """ # Measuring the width width = self.msrf.get_width() np.testing.assert_allclose(width, 20.44854) def test_get_area(self): # The area is computed by summing the areas of each section. a1 = self.msrf.surfaces[0].get_area() a2 = self.msrf.surfaces[1].get_area() area = self.msrf.get_area() aae(a1 + a2, area) def test_get_bounding_box(self): bb = self.msrf.get_bounding_box() if PLOTTING: _, ax = plt.subplots(1, 1) ax.plot([bb.west, bb.east, bb.east, bb.west], [bb.south, bb.south, bb.north, bb.north], '-') ax.plot(self.los[0], self.las[0], '.') ax.plot(self.los[1], self.las[1], '.') plt.show() aae([bb.west, bb.east, bb.south, bb.north], [-70.5772, -70.1032, 19.650, 19.7405], decimal=2) def test_get_middle_point(self): # The computed middle point is the mid point of the first surface midp = self.msrf.get_middle_point() expected = [-70.453372, 19.695377, 10.2703] computed = [midp.longitude, midp.latitude, midp.depth] aae(expected, computed, decimal=4) def test_get_surface_boundaries01(self): # This checks the boundary of the first surface. The result is checked # visually blo, bla = self.srfc50.get_surface_boundaries() # Saving data fname = os.path.join(BASE_PATH, 'results', 'results_t01.npz') if OVERWRITE: np.savez_compressed(fname, blo=blo, bla=bla) # Load expected results er = np.load(fname) if PLOTTING: _, ax = plt.subplots(1, 1) ax.plot(er['blo'], er['bla'], '-r') plt.show() # Testing aae(er['blo'], blo, decimal=1) aae(er['bla'], bla, decimal=1) @unittest.skip("skipping due to differences betweeen various architectures" ) def test_get_surface_boundaries(self): # The result is checked visually blo, bla = self.msrf.get_surface_boundaries() # Saving data fname = os.path.join(BASE_PATH, 'results', 'results_t02.npz') if OVERWRITE: np.savez_compressed(fname, blo=blo, bla=bla) # Load expected results er = np.load(fname) if PLOTTING: _, ax = plt.subplots(1, 1) ax.plot(blo, bla, '-r') ax.plot(self.los[0], self.las[0], '.') ax.plot(self.los[1], self.las[1], '.') plt.show() # Testing aae(er['blo'], blo, decimal=2) aae(er['bla'], bla, decimal=2) def test_get_rx(self): # Results visually inspected dst = self.msrf.get_rx_distance(self.mesh) if PLOTTING: title = f'{self.NAME} - Rx' _plt_results(self.clo, self.cla, dst, self.msrf, title) def test_get_ry0(self): # Results visually inspected dst = self.msrf.get_ry0_distance(self.mesh) if PLOTTING: title = f'{self.NAME} - Rx' _plt_results(self.clo, self.cla, dst, self.msrf, title)
def test_middle_point_single_surface(self): surf = MultiSurface([self.surfaces_mesh2D[0]]) middle_point = surf.get_middle_point() self.assertTrue(Point(0.1, 1.1, 1.1) == middle_point)
class MultiSurfaceOneTestCase(unittest.TestCase): def setUp(self): # First surface - Almost vertical dipping to south prf1 = Line([Point(0, 0, 0), Point(0, -0.00001, 20.)]) prf2 = Line([Point(0.15, 0, 0), Point(0.15, -0.00001, 20.)]) prf3 = Line([Point(0.3, 0, 0), Point(0.3, -0.00001, 20.)]) sfca = KiteSurface.from_profiles([prf1, prf2, prf3], 1., 1.) self.msrf = MultiSurface([sfca]) def test_get_width(self): # Surface is almost vertical. The width must be equal to the depth # difference between the points at the top and bottom width = self.msrf.get_width() msg = 'Multi fault surface: width is wrong' self.assertAlmostEqual(20.0, width, places=2, msg=msg) def test_get_dip(self): # Surface is almost vertical. The dip must be equal to 90 dip = self.msrf.get_dip() msg = 'Multi fault surface: dip is wrong' self.assertAlmostEqual(90.0, dip, places=2, msg=msg) def test_get_area(self): computed = self.msrf.get_area() length = geodetic_distance(0.0, 0.0, 0.3, 0.0) expected = length * 20.0 perc_diff = abs(computed - expected) / computed * 100 msg = 'Multi fault surface: area is wrong' self.assertTrue(perc_diff < 2, msg=msg) def test_get_area1(self): pntsa = npoints_towards(lon=0.32, lat=0.0, depth=0.0, azimuth=45, hdist=10.0, vdist=0.0, npoints=2) pntsb = npoints_towards(lon=pntsa[0][1], lat=pntsa[1][1], depth=pntsa[2][1], azimuth=45 + 90, hdist=10.0, vdist=10.0, npoints=2) pntsc = npoints_towards(lon=0.32, lat=0.0, depth=0.0, azimuth=45 + 90, hdist=10.0, vdist=10.0, npoints=2) tmp = Point(pntsc[0][1], pntsc[1][1], pntsc[2][1]) prf3 = Line([Point(0.32, 0, 0), tmp]) tmp1 = Point(pntsa[0][1], pntsa[1][1], pntsa[2][1]) tmp2 = Point(pntsb[0][1], pntsb[1][1], pntsb[2][1]) prf4 = Line([tmp1, tmp2]) sfcb = KiteSurface.from_profiles([prf3, prf4], 0.2, 0.2) computed = sfcb.get_area() expected = 10.0 * 14.14 msg = 'Multi fault surface: area is wrong' aae(expected, computed, decimal=-1, err_msg=msg)
def test_rx_distance_mesh2D(self): surf = MultiSurface(self.surfaces_mesh2D) numpy.testing.assert_equal(surf.get_rx_distance(self.mesh2D), numpy.array([[-1.0, 2.0, 2.0], [4.0, 4.0, 5.0]]))
def setUp(self): self.data = numpy.genfromtxt(CONCORDANT_FILE, delimiter=",") self.mesh = Mesh(self.data[:, 0], self.data[:, 1], self.data[:, 2]) self.model = MultiSurface(FRANK1.surfaces)