def test_within_rupture_distance(self): """ Tests the function to select within Joyner-Boore distance """ self.catalogue.data["longitude"] = np.arange(4.0, 7.5, 0.5) self.catalogue.data["latitude"] = np.arange(4.0, 7.5, 0.5) self.catalogue.data["depth"] = np.ones(7, dtype=float) selector0 = CatalogueSelector(self.catalogue) # Construct Fault trace0 = np.array([[5.5, 6.0], [5.5, 5.0]]) fault_trace = Line([Point(trace0[i, 0], trace0[i, 1]) for i in range(0, 2)]) # Simple fault with vertical dip fault0 = SimpleFaultSurface.from_fault_data(fault_trace, 0.0, 20.0, 90.0, 1.0) # Within 100 km test_cat_100 = selector0.within_rupture_distance(fault0, 100.0) np.testing.assert_array_almost_equal(test_cat_100.data["longitude"], np.array([5.0, 5.5, 6.0])) np.testing.assert_array_almost_equal(test_cat_100.data["latitude"], np.array([5.0, 5.5, 6.0])) np.testing.assert_array_almost_equal(test_cat_100.data["depth"], np.array([1.0, 1.0, 1.0])) # Simple fault with 30 degree dip fault0 = SimpleFaultSurface.from_fault_data(fault_trace, 0.0, 20.0, 30.0, 1.0) # Within 100 km test_cat_100 = selector0.within_rupture_distance(fault0, 100.0) np.testing.assert_array_almost_equal(test_cat_100.data["longitude"], np.array([4.5, 5.0, 5.5, 6.0])) np.testing.assert_array_almost_equal(test_cat_100.data["latitude"], np.array([4.5, 5.0, 5.5, 6.0])) np.testing.assert_array_almost_equal(test_cat_100.data["depth"], np.array([1.0, 1.0, 1.0, 1.0]))
def count_ruptures(self): """ See :meth: `openquake.hazardlib.source.base.BaseSeismicSource.count_ruptures`. """ whole_fault_surface = SimpleFaultSurface.from_fault_data( self.fault_trace, self.upper_seismogenic_depth, self.lower_seismogenic_depth, self.dip, self.rupture_mesh_spacing) whole_fault_mesh = whole_fault_surface.mesh mesh_rows, mesh_cols = whole_fault_mesh.shape fault_length = float((mesh_cols - 1) * self.rupture_mesh_spacing) fault_width = float((mesh_rows - 1) * self.rupture_mesh_spacing) self._nr = [] n_hypo = len(self.hypo_list) or 1 n_slip = len(self.slip_list) or 1 for (mag, mag_occ_rate) in self.get_annual_occurrence_rates(): if mag_occ_rate == 0: continue rup_cols, rup_rows = self._get_rupture_dimensions( fault_length, fault_width, mag) num_rup_along_length = mesh_cols - rup_cols + 1 num_rup_along_width = mesh_rows - rup_rows + 1 self._nr.append(num_rup_along_length * num_rup_along_width * n_hypo * n_slip) counts = sum(self._nr) return counts
def make_rupture_fordpp(self, rupture_class, **kwargs): # Create the rupture surface. upper_seismogenic_depth = 0. lower_seismogenic_depth = 15. dip = 90. mesh_spacing = 1. fault_trace_start = Point(10., 45.2) fault_trace_end = Point(10., 45.919457) fault_trace = Line([fault_trace_start, fault_trace_end]) default_arguments = { 'mag': 7.2, 'rake': 0., 'tectonic_region_type': const.TRT.STABLE_CONTINENTAL, 'hypocenter': Point(10.0, 45.334898, 10), 'surface': SimpleFaultSurface.from_fault_data( fault_trace, upper_seismogenic_depth, lower_seismogenic_depth, dip=dip, mesh_spacing=mesh_spacing), 'source_typology': object(), 'rupture_slip_direction': 0. } default_arguments.update(kwargs) kwargs = default_arguments rupture = rupture_class(**kwargs) for key in kwargs: assert getattr(rupture, key) is kwargs[key] return rupture
def iter_ruptures(self): """ See :meth: `openquake.hazardlib.source.base.BaseSeismicSource.iter_ruptures`. Generates a ruptures using the "floating" algorithm: for all the magnitude values of assigned MFD calculates the rupture size with respect to MSR and aspect ratio and then places ruptures of that size on the surface of the whole fault source. The occurrence rate of each of those ruptures is the magnitude occurrence rate divided by the number of ruptures that can be placed in a fault. """ whole_fault_surface = SimpleFaultSurface.from_fault_data( self.fault_trace, self.upper_seismogenic_depth, self.lower_seismogenic_depth, self.dip, self.rupture_mesh_spacing) whole_fault_mesh = whole_fault_surface.mesh mesh_rows, mesh_cols = whole_fault_mesh.shape fault_length = float((mesh_cols - 1) * self.rupture_mesh_spacing) fault_width = float((mesh_rows - 1) * self.rupture_mesh_spacing) for mag, mag_occ_rate in self.get_annual_occurrence_rates(): rup_cols, rup_rows = self._get_rupture_dimensions( fault_length, fault_width, mag) num_rup_along_length = mesh_cols - rup_cols + 1 num_rup_along_width = mesh_rows - rup_rows + 1 num_rup = num_rup_along_length * num_rup_along_width occurrence_rate = mag_occ_rate / float(num_rup) for first_row in range(num_rup_along_width): for first_col in range(num_rup_along_length): mesh = whole_fault_mesh[first_row: first_row + rup_rows, first_col: first_col + rup_cols] if not len(self.hypo_list) and not len(self.slip_list): hypocenter = mesh.get_middle_point() occurrence_rate_hypo = occurrence_rate surface = SimpleFaultSurface(mesh) yield ParametricProbabilisticRupture( mag, self.rake, self.tectonic_region_type, hypocenter, surface, occurrence_rate_hypo, self.temporal_occurrence_model) else: for hypo in self.hypo_list: for slip in self.slip_list: surface = SimpleFaultSurface(mesh) hypocenter = surface.get_hypo_location( self.rupture_mesh_spacing, hypo[:2]) occurrence_rate_hypo = occurrence_rate * \ hypo[2] * slip[1] rupture_slip_direction = slip[0] yield ParametricProbabilisticRupture( mag, self.rake, self.tectonic_region_type, hypocenter, surface, occurrence_rate_hypo, self.temporal_occurrence_model, rupture_slip_direction)
def test_get_strike_1(self): p1 = Point(0.0, 0.0) p2 = Point(0.0635916966572, 0.0635916574897) surface = SimpleFaultSurface.from_fault_data(Line([p1, p2]), 1.0, 6.0, 89.9, 1.0) self.assertAlmostEquals(45.0, surface.get_strike(), delta=1e-4)
def test_get_dip_2(self): p1 = Point(0.0, 0.0) p2 = Point(0.0635916966572, 0.0635916574897) surface = SimpleFaultSurface.from_fault_data(Line([p1, p2]), 1.0, 6.0, 30.0, 1.0) self.assertAlmostEquals(30.0, surface.get_dip(), 1)
def test_inclined_non_planar_surface(self): p1 = Point(0.1, 0.1, 0.0) p2 = Point(0.1, 0.117986432118, 0.0) p3 = Point(0.117986470254, 0.117986426305, 0.0) p4 = Point(0.117986470254, 0.0999999941864, 0.0) surface = SimpleFaultSurface.from_fault_data(Line([p1, p2, p3, p4]), 2.0, 4.0, 30.0, 1.0) self.assertAlmostEqual(surface.get_width(), 4.0, places=2)
def test_get_mesh_5(self): p1 = Point(179.9, 0.0) p2 = Point(180.0, 0.0) p3 = Point(-179.9, 0.0) fault = SimpleFaultSurface.from_fault_data(Line([p1, p2, p3]), 1.0, 6.0, 90.0, 1.0) self.assert_mesh_is(fault, test_data.TEST_5_MESH)
def test_get_dip_1(self): p1 = Point(0.0, 0.0) p2 = Point(0.0635916966572, 0.0635916574897) p3 = Point(0.0860747816618, 0.102533437776) surface = SimpleFaultSurface.from_fault_data(Line([p1, p2, p3]), 1.0, 6.0, 90.0, 1.0) self.assertAlmostEquals(90.0, surface.get_dip(), delta=1e-6)
def test_get_mesh_topo(self): p1 = Point(0.0, 0.0, -2.0) p2 = Point(0.0, 0.0359728811759, -2.0) p3 = Point(0.0190775080917, 0.0550503815182, -2.0) p4 = Point(0.03974514139, 0.0723925718856, -2.0) fault = SimpleFaultSurface.from_fault_data(Line([p1, p2, p3, p4]), -2.0, 2.0, 90.0, 1.0) self.assert_mesh_is(fault, test_data.TEST_TOPO_MESH)
def test_get_mesh_1(self): p1 = Point(0.0, 0.0, 0.0) p2 = Point(0.0, 0.0359728811759, 0.0) p3 = Point(0.0190775080917, 0.0550503815182, 0.0) p4 = Point(0.03974514139, 0.0723925718856, 0.0) fault = SimpleFaultSurface.from_fault_data( Line([p1, p2, p3, p4]), 0.0, 4.2426406871192848, 45.0, 1.0) self.assert_mesh_is(fault, test_data.TEST_1_MESH)
def _make_source(self, *args, **kwargs): source = super(ComplexFaultSourceSimpleGeometryIterRupturesTestCase, self)._make_source(*args, **kwargs) surface = SimpleFaultSurface.from_fault_data( source.fault_trace, source.upper_seismogenic_depth, source.lower_seismogenic_depth, source.dip, source.rupture_mesh_spacing ) mesh = surface.get_mesh() top_edge = Line(list(mesh[0:1])) bottom_edge = Line(list(mesh[-1:])) return ComplexFaultSource( source.source_id, source.name, source.tectonic_region_type, source.mfd, source.rupture_mesh_spacing, source.magnitude_scaling_relationship, source.rupture_aspect_ratio, [top_edge, bottom_edge], source.rake )
def create_geometry(self, input_geometry, dip, upper_depth, lower_depth, mesh_spacing=1.0): ''' If geometry is defined as a numpy array then create instance of nhlib.geo.line.Line class, otherwise if already instance of class accept class :param input_geometry: Trace (line) of the fault source as either i) instance of nhlib.geo.line.Line class ii) numpy.ndarray [Longitude, Latitude] :param float dip: Dip of fault surface (in degrees) :param float upper_depth: Upper seismogenic depth (km) :param float lower_depth: Lower seismogenic depth (km) :param float mesh_spacing: Spacing of the fault mesh (km) {default = 1.0} ''' assert((dip > 0.) and (dip <= 90.)) self.dip = dip self._check_seismogenic_depths(upper_depth, lower_depth) if not isinstance(input_geometry, Line): if not isinstance(input_geometry, np.ndarray): raise ValueError('Unrecognised or unsupported geometry ' 'definition') else: self.fault_trace = Line([Point(row[0], row[1]) for row in input_geometry]) else: self.fault_trace = input_geometry # Build fault surface self.geometry = SimpleFaultSurface.from_fault_data(self.fault_trace, self.upper_depth, self.lower_depth, self.dip, mesh_spacing)
def test_hypocentre_index_multi_segments(self): hypocentre = Point(0.588100, 0.479057, 7.1711) upper_seismogenic_depth = 0.5 lower_seismogenic_depth = 15. dip = 56.5 mesh_spacing = 2. fault_trace = Line([Point(0., 0.), Point(0.55, 0.5), Point(1.2, 1.2)]) whole_fault_surface = SimpleFaultSurface.from_fault_data( fault_trace, upper_seismogenic_depth, lower_seismogenic_depth, dip, mesh_spacing ) target_rupture_surface = whole_fault_surface.get_resampled_top_edge() index = SimpleFaultSurface.hypocentre_patch_index( hypocentre, target_rupture_surface, upper_seismogenic_depth, lower_seismogenic_depth, dip) # The value used for this test is by hand calculation self.assertEqual(index, 2)
def _make_source(self, *args, **kwargs): source = super()._make_source(*args, **kwargs) surface = SimpleFaultSurface.from_fault_data( source.fault_trace, source.upper_seismogenic_depth, source.lower_seismogenic_depth, source.dip, source.rupture_mesh_spacing ) mesh = surface.mesh top_edge = Line(list(mesh[0:1])) bottom_edge = Line(list(mesh[-1:])) cfs = ComplexFaultSource( source.source_id, source.name, source.tectonic_region_type, source.mfd, source.rupture_mesh_spacing, source.magnitude_scaling_relationship, source.rupture_aspect_ratio, source.temporal_occurrence_model, [top_edge, bottom_edge], source.rake ) assert_pickleable(cfs) return cfs
def test_hypocentre_index_large_mesh_spacing(self): hypocentre = Point(10.443522, 45.379006, 20.0) upper_seismogenic_depth = 10. lower_seismogenic_depth = 28. dip = 30. mesh_spacing = 10. fault_trace = Line([Point(10., 45.2), Point(10., 45.487783)]) whole_fault_surface = SimpleFaultSurface.from_fault_data( fault_trace, upper_seismogenic_depth, lower_seismogenic_depth, dip, mesh_spacing ) target_rupture_surface = whole_fault_surface.get_resampled_top_edge() index = SimpleFaultSurface.hypocentre_patch_index( hypocentre, target_rupture_surface, upper_seismogenic_depth, lower_seismogenic_depth, dip) # The value used for this test is by hand calculation self.assertEqual(index, 1)
def __init__(self, trace, dip, upper_depth, lower_depth, mesh_spacing=1.0): ''' Sets up the fault geometry parameters from the input fault definitions :param float mesh_spacing: Spacing (km) of the fault surface mesh ''' self.typology = 'Simple' self.trace = trace self.dip = dip self.upper_depth = upper_depth self.lower_depth = lower_depth self.surface = SimpleFaultSurface.from_fault_data(self.trace, self.upper_depth, self.lower_depth, self.dip, mesh_spacing) self.length = trace.get_length() self.downdip_width = None self.surface_width = None self.area = None
def count_ruptures(self): """ See :meth: `openquake.hazardlib.source.base.BaseSeismicSource.count_ruptures`. """ whole_fault_surface = SimpleFaultSurface.from_fault_data( self.fault_trace, self.upper_seismogenic_depth, self.lower_seismogenic_depth, self.dip, self.rupture_mesh_spacing ) whole_fault_mesh = whole_fault_surface.get_mesh() mesh_rows, mesh_cols = whole_fault_mesh.shape fault_length = float((mesh_cols - 1) * self.rupture_mesh_spacing) fault_width = float((mesh_rows - 1) * self.rupture_mesh_spacing) counts = 0 for (mag, mag_occ_rate) in self.get_annual_occurrence_rates(): rup_cols, rup_rows = self._get_rupture_dimensions( fault_length, fault_width, mag) num_rup_along_length = mesh_cols - rup_cols + 1 num_rup_along_width = mesh_rows - rup_rows + 1 counts += num_rup_along_length * num_rup_along_width return counts
def test_hypocentre_index_2ndpatch(self): hypocentre = Point(10.237155, 45.562761, 8.0) upper_seismogenic_depth = 0. lower_seismogenic_depth = 15. dip = 30. mesh_spacing = 1. fault_trace = Line([Point(10., 45.2), Point(10.0, 45.559729), Point(10.365145, 45.813659)]) whole_fault_surface = SimpleFaultSurface.from_fault_data( fault_trace, upper_seismogenic_depth, lower_seismogenic_depth, dip, mesh_spacing ) target_rupture_surface = whole_fault_surface.get_resampled_top_edge() index = SimpleFaultSurface.hypocentre_patch_index( hypocentre, target_rupture_surface, upper_seismogenic_depth, lower_seismogenic_depth, dip) # The value used for this test is by hand calculation self.assertEqual(index, 2)
def test_get_resampled_top_edge_non_planar(self): upper_seismogenic_depth = 0. lower_seismogenic_depth = 40. dip = 90. mesh_spacing = 10. fault_trace = Line([Point(0.0, 0.0), Point(0.5, 0.5), Point(1.5, 1.0)]) whole_fault_surface = SimpleFaultSurface.from_fault_data( fault_trace, upper_seismogenic_depth, lower_seismogenic_depth, dip, mesh_spacing ) ref = Line([Point(0., 0.), Point(0.5, 0.5), Point(1.5, 1.0)]) result = whole_fault_surface.get_resampled_top_edge() for ref_point, result_point in zip(ref.points, result.points): self.assertAlmostEqual(ref_point.longitude, result_point.longitude, delta=0.1) self.assertAlmostEqual(ref_point.latitude, result_point.latitude, delta=0.1) self.assertAlmostEqual(ref_point.depth, result_point.depth, delta=0.1)
def test_get_dip_5(self): p1 = Point(0.0, 0.0) p2 = Point(0.0, 0.0899322029395) p3 = Point(0.0899323137217, 0.0899320921571) p4 = Point(0.0899323137217, -1.10782376538e-07) surface = SimpleFaultSurface.from_fault_data(Line([p1, p2, p3, p4]), 0.0, 10.0, 45.0, 1.0) # fault contains three segments. the one in the middle is inclined # with dip of 45 degrees. other two are purely vertical (they are # perpendicular to the middle one). the middle segment is rectangle # and the side ones are parallelograms. area of those parallelograms # is area of middle segment times sine of their acute angle. mid_area = 1.0 mid_dip = pi / 4 # 45 degree side_area = sin(mid_dip) * mid_area side_dip = pi / 2 # 90 degree expected_dip = degrees(atan2( (mid_area * sin(mid_dip) + 2 * (side_area * sin(side_dip))) / 3.0, (mid_area * cos(mid_dip) + 2 * (side_area * cos(side_dip))) / 3.0 )) self.assertAlmostEquals(surface.get_dip(), expected_dip, delta=1e-3)
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", EvenlyDiscretizedMFD(7.0, 0.1, [1.0]), 1.0, PeerMSR(), 1.0, PoissonTOM(1.0), COMPLEX_EDGES, 0.0) SIMPLE_FAULT_SURFACE = SimpleFaultSurface.from_fault_data(SIMPLE_TRACE, 0.0, 20.0, 90.0, 1.0) CHARACTERISTIC_FAULT = CharacteristicFaultSource( "CHRFLT000", "Characteristic 000", "Active Shallow Crust", EvenlyDiscretizedMFD(7.0, 0.1, [1.0]), PoissonTOM(1.0), SIMPLE_FAULT_SURFACE, 0.0) class RateGridTestCase(unittest.TestCase): """
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
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_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 _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
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", EvenlyDiscretizedMFD(7.0, 0.1, [1.0]), 1.0, PeerMSR(), 1.0, PoissonTOM(1.0), COMPLEX_EDGES, 0.0) SIMPLE_FAULT_SURFACE = SimpleFaultSurface.from_fault_data( SIMPLE_TRACE, 0.0, 20.0, 90.0, 1.0) CHARACTERISTIC_FAULT = CharacteristicFaultSource( "CHRFLT000", "Characteristic 000", "Active Shallow Crust", EvenlyDiscretizedMFD(7.0, 0.1, [1.0]), PoissonTOM(1.0), SIMPLE_FAULT_SURFACE, 0.0) class RateGridTestCase(unittest.TestCase): """ General test class for Rate Grid calculation """ def setUp(self): """ Set up limits """
def iter_ruptures(self): """ See :meth: `openquake.hazardlib.source.base.BaseSeismicSource.iter_ruptures`. Generates a ruptures using the "floating" algorithm: for all the magnitude values of assigned MFD calculates the rupture size with respect to MSR and aspect ratio and then places ruptures of that size on the surface of the whole fault source. The occurrence rate of each of those ruptures is the magnitude occurrence rate divided by the number of ruptures that can be placed in a fault. """ whole_fault_surface = SimpleFaultSurface.from_fault_data( self.fault_trace, self.upper_seismogenic_depth, self.lower_seismogenic_depth, self.dip, self.rupture_mesh_spacing) whole_fault_mesh = whole_fault_surface.get_mesh() mesh_rows, mesh_cols = whole_fault_mesh.shape fault_length = float((mesh_cols - 1) * self.rupture_mesh_spacing) fault_width = float((mesh_rows - 1) * self.rupture_mesh_spacing) for (mag, mag_occ_rate) in self.get_annual_occurrence_rates(): rup_cols, rup_rows = self._get_rupture_dimensions( fault_length, fault_width, mag) num_rup_along_length = mesh_cols - rup_cols + 1 num_rup_along_width = mesh_rows - rup_rows + 1 num_rup = num_rup_along_length * num_rup_along_width occurrence_rate = mag_occ_rate / float(num_rup) for first_row in range(num_rup_along_width): for first_col in range(num_rup_along_length): mesh = whole_fault_mesh[first_row:first_row + rup_rows, first_col:first_col + rup_cols] if not len(self.hypo_list) and not len(self.slip_list): hypocenter = mesh.get_middle_point() occurrence_rate_hypo = occurrence_rate surface = SimpleFaultSurface(mesh) yield ParametricProbabilisticRupture( mag, self.rake, self.tectonic_region_type, hypocenter, surface, type(self), occurrence_rate_hypo, self.temporal_occurrence_model) else: for hypo in self.hypo_list: for slip in self.slip_list: surface = SimpleFaultSurface(mesh) hypocenter = surface.get_hypo_location( self.rupture_mesh_spacing, hypo[:2]) occurrence_rate_hypo = occurrence_rate * \ hypo[2] * slip[1] rupture_slip_direction = slip[0] yield ParametricProbabilisticRupture( mag, self.rake, self.tectonic_region_type, hypocenter, surface, type(self), occurrence_rate_hypo, self.temporal_occurrence_model, rupture_slip_direction)
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 _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