def test_build_fault_model(self): # Tests the constuction of a fault model with two faults (1 simple, # 1 complex) each with two mfd rates - should produce four sources self.model = mtkActiveFaultModel('001', 'A Fault Model', faults=[]) x0 = Point(30., 30., 0.) x1 = x0.point_at(30., 0., 30.) x2 = x1.point_at(30., 0., 60.) # Total length is 60 km trace = Line([x0, x1, x2]) simple_fault = SimpleFaultGeometry(trace, 90., 0., 20.) # Creates a trace ~60 km long made of 3 points upper_edge = Line([x0, x1, x2]) lower_edge = Line([ x0.point_at(40., 20., 130.), x1.point_at(42., 25., 130.), x2.point_at(41., 22., 130.) ]) complex_fault = ComplexFaultGeometry([upper_edge, lower_edge], 2.0) config = [{ 'MFD_spacing': 0.1, 'Maximum_Magnitude': 7.0, 'Maximum_Uncertainty': None, 'Model_Name': 'Characteristic', 'Model_Weight': 0.5, 'Sigma': 0.1, 'Lower_Bound': -1., 'Upper_Bound': 1. }, { 'MFD_spacing': 0.1, 'Maximum_Magnitude': 7.5, 'Maximum_Uncertainty': None, 'Model_Name': 'Characteristic', 'Model_Weight': 0.5, 'Sigma': 0.1, 'Lower_Bound': -1., 'Upper_Bound': 1. }] fault1 = mtkActiveFault('001', 'Simple Fault 1', simple_fault, [(10.0, 1.0)], -90., None, aspect_ratio=1.0, scale_rel=[(WC1994(), 1.0)], shear_modulus=[(30.0, 1.0)], disp_length_ratio=[(1E-5, 1.0)]) fault1.generate_config_set(config) fault2 = mtkActiveFault('002', 'Complex Fault 1', complex_fault, [(10.0, 1.0)], -90., None, aspect_ratio=1.0, scale_rel=[(WC1994(), 1.0)], shear_modulus=[(30.0, 1.0)], disp_length_ratio=[(1E-5, 1.0)]) fault2.generate_config_set(config) self.model.faults = [fault1, fault2] # Generate source model self.model.build_fault_model() self.assertEqual(len(self.model.source_model.sources), 4) # First source should be an instance of a mtkSimpleFaultSource model1 = self.model.source_model.sources[0] self.assertTrue(isinstance(model1, mtkSimpleFaultSource)) self.assertEqual(model1.id, '001_1') self.assertAlmostEqual(model1.mfd.min_mag, 6.9) np.testing.assert_array_almost_equal( np.log10(np.array(model1.mfd.occurrence_rates)), np.array([-2.95320041, -2.54583708, -2.953200413])) # Second source should be an instance of a mtkSimpleFaultSource model2 = self.model.source_model.sources[1] self.assertTrue(isinstance(model2, mtkSimpleFaultSource)) self.assertEqual(model2.id, '001_2') self.assertAlmostEqual(model2.mfd.min_mag, 7.4) np.testing.assert_array_almost_equal( np.log10(np.array(model2.mfd.occurrence_rates)), np.array([-3.70320041, -3.29583708, -3.70320041])) # Third source should be an instance of a mtkComplexFaultSource model3 = self.model.source_model.sources[2] self.assertTrue(isinstance(model3, mtkComplexFaultSource)) self.assertEqual(model3.id, '002_1') self.assertAlmostEqual(model3.mfd.min_mag, 6.9) np.testing.assert_array_almost_equal( np.log10(np.array(model3.mfd.occurrence_rates)), np.array([-2.59033387, -2.18297054, -2.59033387])) # Fourth source should be an instance of a mtkComplexFaultSource model4 = self.model.source_model.sources[3] self.assertTrue(isinstance(model4, mtkComplexFaultSource)) self.assertEqual(model4.id, '002_2') self.assertAlmostEqual(model4.mfd.min_mag, 7.4) np.testing.assert_array_almost_equal( np.log10(np.array(model4.mfd.occurrence_rates)), np.array([-3.34033387, -2.93297054, -3.34033387]))
def test_fault_trace_on_surface(self): fault_trace = Line([Point(0.0, 0.0, 1.0), Point(1.0, 1.0, 0.0)]) self.assertRaises(ValueError, SimpleFaultSurface.check_fault_data, fault_trace, 0.0, 1.0, 90.0, 1.0)
def _parse_distance_data(self, event, site, metadata): """ Read in the distance related metadata and return an instance of the :class: smtk.sm_database.RecordDistance """ # Compute various distance metrics # Add calculation of Repi, Rhypo from event and station localizations # (latitudes, longitudes, depth, elevation)? target_site = Mesh(np.array([site.longitude]), np.array([site.latitude]), np.array([-site.altitude / 1000.0])) # Warning ratio fixed to 1.5 ratio = 1.5 surface_modeled = rcfg.create_planar_surface( Point(event.longitude, event.latitude, event.depth), event.mechanism.nodal_planes.nodal_plane_1['strike'], event.mechanism.nodal_planes.nodal_plane_1['dip'], event.rupture.area, ratio) hypocenter = rcfg.get_hypocentre_on_planar_surface( surface_modeled, event.rupture.hypo_loc) try: surface_modeled._create_mesh() except: dip = surface_modeled.get_dip() dip_dir = (surface_modeled.get_strike() - 90.) % 360. ztor = surface_modeled.top_left.depth d_x = ztor * np.tan(np.radians(90.0 - dip)) top_left_surface = surface_modeled.top_left.point_at( d_x, -ztor, dip_dir) top_left_surface.depth = 0. top_right_surface = surface_modeled.top_right.point_at( d_x, -ztor, dip_dir) top_right_surface.depth = 0. surface_modeled = SimpleFaultSurface.from_fault_data( Line([top_left_surface, top_right_surface]), surface_modeled.top_left.depth, surface_modeled.bottom_left.depth, surface_modeled.get_dip(), 1.0) # Rhypo Rhypo = get_float(metadata["Hypocentral Distance (km)"]) if Rhypo is None: Rhypo = hypocenter.distance_to_mesh(target_site) # Repi Repi = get_float(metadata["Epicentral Distance (km)"]) if Repi is None: Repi = hypocenter.distance_to_mesh(target_site, with_depths=False) # Rrup Rrup = get_float(metadata["Rupture Distance (km)"]) if Rrup is None: Rrup = surface_modeled.get_min_distance(target_site) # Rjb Rjb = get_float(metadata["Joyner-Boore Distance (km)"]) if Rjb is None: Rjb = surface_modeled.get_joyner_boore_distance(target_site) # Rcdpp Rcdpp = get_float(metadata["Rcdpp"]) if Rcdpp is None: Rcdpp = surface_modeled.get_cdppvalue(target_site) # Need to check if Rx and Ry0 are consistant with the other metrics # when those are coming from the flatfile? # Rx Rx = surface_modeled.get_rx_distance(target_site) # Ry0 Ry0 = surface_modeled.get_ry0_distance(target_site) distance = RecordDistance(repi=float(Repi), rhypo=float(Rhypo), rjb=float(Rjb), rrup=float(Rrup), r_x=float(Rx), ry0=float(Ry0), rcdpp=float(Rcdpp)) distance.azimuth = get_float(metadata["Source to Site Azimuth (deg)"]) #distance.hanging_wall = get_float(metadata["FW/HW Indicator"]) if metadata["FW/HW Indicator"] == "HW": distance.hanging_wall = True elif metadata["FW/HW Indicator"] == "FW": distance.hanging_wall = False else: pass return distance
def test_vertical_planar_surface(self): p1 = Point(0.1, 0.1, 0.0) p2 = Point(0.1, 0.126979648178, 0.0) surface = SimpleFaultSurface.from_fault_data(Line([p1, p2]), 2.0, 4.0, 90.0, 1.0) self.assertAlmostEqual(surface.get_width(), 2.0)
def setUp(self): self.fault_trace = Line([Point(0.0, 0.0), Point(1.0, 1.0)])
def test_get_strike_along_meridian(self): line = Line([Point(0, 0), Point(1e-5, 1e-3), Point(0, 2e-3)]) surface = SimpleFaultSurface.from_fault_data(line, 1.0, 6.0, 89.9, 0.1) self.assertAlmostEquals(0, surface.get_strike(), delta=6e-2)
def test_one_edge(self): edges = [Line([Point(0, 0), Point(0, 1)])] self.assertRaises(ValueError, ComplexFaultSurface.from_fault_data, edges, mesh_spacing=1)
def make_edge(edge): ls = ~edge.LineString.posList coords = numpy.array(ls).reshape(-1, 3) return Line([Point(*coord) for coord in coords])
def _parse_distance_data(self, event, site, metadata): """ Read in the distance related metadata and return an instance of the :class: smtk.sm_database.RecordDistance """ # Compute various distance metrics # Add calculation of Repi, Rhypo from event and station localizations # (latitudes, longitudes, depth, elevation)? target_site = Mesh(np.array([site.longitude]), np.array([site.latitude]), np.array([-site.altitude / 1000.0])) # Warning ratio fixed to 1.5 ratio = 1.5 if not event.rupture.area: event.rupture.area = WC1994().get_median_area( event.magnitude.value, None) surface_modeled = rcfg.create_planar_surface( Point(event.longitude, event.latitude, event.depth), event.mechanism.nodal_planes.nodal_plane_1['strike'], event.mechanism.nodal_planes.nodal_plane_1['dip'], event.rupture.area, ratio) hypocenter = rcfg.get_hypocentre_on_planar_surface( surface_modeled, event.rupture.hypo_loc) try: surface_modeled._create_mesh() except: dip = surface_modeled.get_dip() dip_dir = (surface_modeled.get_strike() - 90.) % 360. ztor = surface_modeled.top_left.depth d_x = ztor * np.tan(np.radians(90.0 - dip)) top_left_surface = surface_modeled.top_left.point_at( d_x, -ztor, dip_dir) top_left_surface.depth = 0. top_right_surface = surface_modeled.top_right.point_at( d_x, -ztor, dip_dir) top_right_surface.depth = 0. surface_modeled = SimpleFaultSurface.from_fault_data( Line([top_left_surface, top_right_surface]), surface_modeled.top_left.depth, surface_modeled.bottom_left.depth, surface_modeled.get_dip(), 1.0) # Rhypo Rhypo, Repi, Rrup, Rjb, Ry0 = tuple( map(get_positive_float, [ metadata[key] for key in [ "Hypocentral Distance (km)", "Epicentral Distance (km)", "Rupture Distance (km)", "Joyner-Boore Distance (km)", "Ry0 (km)" ] ])) Rx = get_float(metadata["Rx (km)"]) # Rx can be negative #Rhypo = get_float(metadata["Hypocentral Distance (km)"]) if Rhypo is None or Rhypo < 0.0: Rhypo = hypocenter.distance_to_mesh(target_site) # Repi #Repi = get_float(metadata["Epicentral Distance (km)"]) if Repi is None or Repi < 0.0: Repi = hypocenter.distance_to_mesh(target_site, with_depths=False) # Rrup #Rrup = get_float(metadata["Rupture Distance (km)"]) if Rrup is None or Rrup < 0.0: Rrup = surface_modeled.get_min_distance(target_site)[0] # Rjb #Rjb = get_float(metadata["Joyner-Boore Distance (km)"]) if Rjb is None or Rjb < 0.0: Rjb = surface_modeled.get_joyner_boore_distance(target_site)[0] # Need to check if Rx and Ry0 are consistant with the other metrics # when those are coming from the flatfile? # Rx #Rx = get_float(metadata["Rx (km)"]) if Rx is None or Rx < 0.0: Rx = surface_modeled.get_rx_distance(target_site)[0] # Ry0 Ry0 = get_float(metadata["Ry0 (km)"]) if Ry0 is None or Ry0 < 0.0: Ry0 = surface_modeled.get_ry0_distance(target_site)[0] distance = RecordDistance(repi=Repi, rhypo=Rhypo, rjb=Rjb, rrup=Rrup, r_x=Rx, ry0=Ry0) distance.azimuth = get_float(metadata["Source to Site Azimuth (deg)"]) #distance.hanging_wall = get_float(metadata["FW/HW Indicator"]) if metadata["FW/HW Indicator"] == "HW": distance.hanging_wall = True elif metadata["FW/HW Indicator"] == "FW": distance.hanging_wall = False else: pass return distance return
PMF([(1.0, 5.0)])) AREA_POLY = Polygon([ Point(14.95, 15.05), Point(15.05, 15.05), Point(15.05, 14.95), Point(14.95, 14.95) ]) AREA_SOURCE = AreaSource("AREA000", "Area 000", "Active Shallow Crust", EvenlyDiscretizedMFD(5.0, 0.1, [1.0]), 1.0, PointMSR(), 1.0, PoissonTOM(1.0), 0., 40., PMF([(1.0, NodalPlane(0.0, 90.0, 0.0))]), PMF([(0.5, 5.0), (0.5, 15.0)]), AREA_POLY, 4.0) SIMPLE_TRACE = Line([Point(14.975, 15.0, 0.0), Point(15.025, 15.0, 0.0)]) SIMPLE_FAULT = SimpleFaultSource("SFLT000", "Simple Fault Source", "Active Shallow Crust", EvenlyDiscretizedMFD(7.0, 0.1, [1.0]), 1.0, PeerMSR(), 1.0, PoissonTOM(1.0), 0.0, 20.0, SIMPLE_TRACE, 90., 0.0) COMPLEX_EDGES = [ SIMPLE_TRACE, Line([Point(14.975, 15.0, 20.0), Point(15.025, 15.0, 20.0)]) ] COMPLEX_FAULT = ComplexFaultSource("CFLT000", "Complex Fault Source", "Active Shallow Crust",