def _expected_simple(self): incr_mfd = mfd.EvenlyDiscretizedMFD(min_mag=5.0, bin_width=0.1, occurrence_rates=[ 0.0010614989, 8.8291627E-4, 7.3437777E-4, 6.108288E-4, 5.080653E-4, ]) simple = source.SimpleFaultSource( source_id="3", name="Mount Diablo Thrust", tectonic_region_type="Active Shallow Crust", mfd=incr_mfd, rupture_mesh_spacing=MESH_SPACING, magnitude_scaling_relationship=scalerel.WC1994(), rupture_aspect_ratio=1.5, upper_seismogenic_depth=10.0, lower_seismogenic_depth=20.0, fault_trace=geo.Line([ geo.Point(-121.82290, 37.73010), geo.Point(-122.03880, 37.87710) ]), dip=45.0, rake=30.0) return simple
def test_area_with_incr_mfd(self): incr_mfd = mfd.EvenlyDiscretizedMFD( min_mag=6.55, bin_width=0.1, occurrence_rates=[ 0.0010614989, 8.8291627E-4, 7.3437777E-4, 6.108288E-4, 5.080653E-4]) np1 = geo.NodalPlane(strike=0.0, dip=90.0, rake=0.0) np2 = geo.NodalPlane(strike=90.0, dip=45.0, rake=90.0) npd = pmf.PMF([(0.3, np1), (0.7, np2)]) hd = pmf.PMF([(0.5, 4.0), (0.5, 8.0)]) polygon = geo.Polygon( [geo.Point(-122.5, 37.5), geo.Point(-121.5, 37.5), geo.Point(-121.5, 38.5), geo.Point(-122.5, 38.5)]) area = source.AreaSource( source_id="1", name="source A", tectonic_region_type="Active Shallow Crust", mfd=incr_mfd, rupture_mesh_spacing=self.rupture_mesh_spacing, magnitude_scaling_relationship=scalerel.PeerMSR(), rupture_aspect_ratio=1.0, upper_seismogenic_depth=0.0, lower_seismogenic_depth=10.0, nodal_plane_distribution=npd, hypocenter_distribution=hd, polygon=polygon, area_discretization=10, temporal_occurrence_model=PoissonTOM(50.0), ) actual = list(area) self.assertEqual(len(actual), 96) # expected 96 points assert_allclose( actual[0].mfd.occurrence_rates, [1.10572802083e-05, 9.197044479166666e-06, 7.6497684375e-06, 6.3627999999999995e-06, 5.292346875e-06])
def convert_mfdist(self, node): """ Convert the given node into a Magnitude-Frequency Distribution object. :param node: a node of kind incrementalMFD or truncGutenbergRichterMFD :returns: a :class:`openquake.hazardlib.mdf.EvenlyDiscretizedMFD.` or :class:`openquake.hazardlib.mdf.TruncatedGRMFD` instance """ with context(self.fname, node): [mfd_node] = [ subnode for subnode in node if subnode.tag.endswith(('incrementalMFD', 'truncGutenbergRichterMFD')) ] if mfd_node.tag.endswith('incrementalMFD'): return mfd.EvenlyDiscretizedMFD( min_mag=mfd_node['minMag'], bin_width=mfd_node['binWidth'], occurrence_rates=~mfd_node.occurRates) elif mfd_node.tag.endswith('truncGutenbergRichterMFD'): return mfd.TruncatedGRMFD(a_val=mfd_node['aValue'], b_val=mfd_node['bValue'], min_mag=mfd_node['minMag'], max_mag=mfd_node['maxMag'], bin_width=self.width_of_mfd_bin)
def _expected_area(self): incr_mfd = mfd.EvenlyDiscretizedMFD( min_mag=6.55, bin_width=0.1, occurrence_rates=[ 0.0010614989, 8.8291627E-4, 7.3437777E-4, 6.108288E-4, 5.080653E-4]) np1 = geo.NodalPlane(strike=0.0, dip=90.0, rake=0.0) np2 = geo.NodalPlane(strike=90.0, dip=45.0, rake=90.0) npd = pmf.PMF([(0.3, np1), (0.7, np2)]) hd = pmf.PMF([(0.5, 4.0), (0.5, 8.0)]) polygon = geo.Polygon( [geo.Point(-122.5, 37.5), geo.Point(-121.5, 37.5), geo.Point(-121.5, 38.5), geo.Point(-122.5, 38.5)]) area = source.AreaSource( source_id="1", name="Quito", tectonic_region_type="Active Shallow Crust", mfd=incr_mfd, rupture_mesh_spacing=self.rupture_mesh_spacing, magnitude_scaling_relationship=scalerel.PeerMSR(), rupture_aspect_ratio=1.5, upper_seismogenic_depth=0.0, lower_seismogenic_depth=10.0, nodal_plane_distribution=npd, hypocenter_distribution=hd, polygon=polygon, area_discretization=2, temporal_occurrence_model=PoissonTOM(50.)) area.num_ruptures = area.count_ruptures() return area
def _expected_simple(self): incr_mfd = mfd.EvenlyDiscretizedMFD( min_mag=5.0, bin_width=0.1, occurrence_rates=[ 0.0010614989, 8.8291627E-4, 7.3437777E-4, 6.108288E-4, 5.080653E-4]) simple = source.SimpleFaultSource( source_id="3", name="Mount Diablo Thrust", tectonic_region_type="Active Shallow Crust", mfd=incr_mfd, rupture_mesh_spacing=self.rupture_mesh_spacing, magnitude_scaling_relationship=scalerel.WC1994(), rupture_aspect_ratio=1.5, upper_seismogenic_depth=10.0, lower_seismogenic_depth=20.0, fault_trace=geo.Line( [geo.Point(-121.82290, 37.73010), geo.Point(-122.03880, 37.87710)]), dip=45.0, rake=30.0, temporal_occurrence_model=PoissonTOM(50.), hypo_list=numpy.array([[0.25, 0.25, 0.3], [0.75, 0.75, 0.7]]), slip_list=numpy.array([[90, 0.7], [135, 0.3]])) simple.num_ruptures = simple.count_ruptures() return simple
def __iter__(self): """ Split an area source into a generator of point sources. MFDs will be rescaled appropriately for the number of points in the area mesh. """ mesh = self.polygon.discretize(self.area_discretization) num_points = len(mesh) area_mfd = self.mfd if isinstance(area_mfd, mfd.TruncatedGRMFD): new_mfd = mfd.TruncatedGRMFD(a_val=area_mfd.a_val - math.log10(num_points), b_val=area_mfd.b_val, bin_width=area_mfd.bin_width, min_mag=area_mfd.min_mag, max_mag=area_mfd.max_mag) elif isinstance(area_mfd, mfd.EvenlyDiscretizedMFD): new_occur_rates = [ x / num_points for x in area_mfd.occurrence_rates ] new_mfd = mfd.EvenlyDiscretizedMFD( min_mag=area_mfd.min_mag, bin_width=area_mfd.bin_width, occurrence_rates=new_occur_rates) elif isinstance(area_mfd, mfd.ArbitraryMFD): new_occur_rates = [ x / num_points for x in area_mfd.occurrence_rates ] new_mfd = mfd.ArbitraryMFD(magnitudes=area_mfd.magnitudes, occurrence_rates=new_occur_rates) elif isinstance(area_mfd, mfd.YoungsCoppersmith1985MFD): new_mfd = mfd.YoungsCoppersmith1985MFD.from_characteristic_rate( area_mfd.min_mag, area_mfd.b_val, area_mfd.char_mag, area_mfd.char_rate / num_points, area_mfd.bin_width) else: raise TypeError('Unknown MFD: %s' % area_mfd) for i, (lon, lat) in enumerate(zip(mesh.lons, mesh.lats)): pt = PointSource( # Generate a new ID and name source_id='%s:%s' % (self.source_id, i), name=self.name, tectonic_region_type=self.tectonic_region_type, mfd=new_mfd, rupture_mesh_spacing=self.rupture_mesh_spacing, magnitude_scaling_relationship=self. magnitude_scaling_relationship, rupture_aspect_ratio=self.rupture_aspect_ratio, upper_seismogenic_depth=self.upper_seismogenic_depth, lower_seismogenic_depth=self.lower_seismogenic_depth, location=geo.Point(lon, lat), nodal_plane_distribution=self.nodal_plane_distribution, hypocenter_distribution=self.hypocenter_distribution, temporal_occurrence_model=self.temporal_occurrence_model) pt.num_ruptures = pt.count_ruptures() yield pt
def area_to_point_sources(area_src): """ Split an area source into a generator of point sources. MFDs will be rescaled appropriately for the number of points in the area mesh. :param area_src: :class:`openquake.hazardlib.source.AreaSource` """ mesh = area_src.polygon.discretize(area_src.area_discretization) num_points = len(mesh) area_mfd = area_src.mfd if isinstance(area_mfd, mfd.TruncatedGRMFD): new_a_val = math.log10(10 ** area_mfd.a_val / float(num_points)) new_mfd = mfd.TruncatedGRMFD( a_val=new_a_val, b_val=area_mfd.b_val, bin_width=area_mfd.bin_width, min_mag=area_mfd.min_mag, max_mag=area_mfd.max_mag) elif isinstance(area_mfd, mfd.EvenlyDiscretizedMFD): new_occur_rates = [float(x) / num_points for x in area_mfd.occurrence_rates] new_mfd = mfd.EvenlyDiscretizedMFD( min_mag=area_mfd.min_mag, bin_width=area_mfd.bin_width, occurrence_rates=new_occur_rates) elif isinstance(area_mfd, mfd.ArbitraryMFD): new_occur_rates = [float(x) / num_points for x in area_mfd.occurrence_rates] new_mfd = mfd.ArbitraryMFD( magnitudes=area_mfd.magnitudes, occurrence_rates=new_occur_rates) for i, (lon, lat) in enumerate(zip(mesh.lons, mesh.lats)): pt = source.PointSource( # Generate a new ID and name source_id='%s-%s' % (area_src.source_id, i), name='%s-%s' % (area_src.name, i), tectonic_region_type=area_src.tectonic_region_type, mfd=new_mfd, rupture_mesh_spacing=area_src.rupture_mesh_spacing, magnitude_scaling_relationship= area_src.magnitude_scaling_relationship, rupture_aspect_ratio=area_src.rupture_aspect_ratio, upper_seismogenic_depth=area_src.upper_seismogenic_depth, lower_seismogenic_depth=area_src.lower_seismogenic_depth, location=geo.Point(lon, lat), nodal_plane_distribution=area_src.nodal_plane_distribution, hypocenter_distribution=area_src.hypocenter_distribution, temporal_occurrence_model=area_src.temporal_occurrence_model) pt.trt_model_id = area_src.trt_model_id pt.num_ruptures = pt.count_ruptures() yield pt
def convert_mfdist(self, node): """ Convert the given node into a Magnitude-Frequency Distribution object. :param node: a node of kind incrementalMFD or truncGutenbergRichterMFD :returns: a :class:`openquake.hazardlib.mfd.EvenlyDiscretizedMFD.` or :class:`openquake.hazardlib.mfd.TruncatedGRMFD` instance """ with context(self.fname, node): [mfd_node] = [ subnode for subnode in node if subnode.tag.endswith(('incrementalMFD', 'truncGutenbergRichterMFD', 'arbitraryMFD', 'YoungsCoppersmithMFD', 'multiMFD')) ] if mfd_node.tag.endswith('incrementalMFD'): return mfd.EvenlyDiscretizedMFD( min_mag=mfd_node['minMag'], bin_width=mfd_node['binWidth'], occurrence_rates=~mfd_node.occurRates) elif mfd_node.tag.endswith('truncGutenbergRichterMFD'): return mfd.TruncatedGRMFD(a_val=mfd_node['aValue'], b_val=mfd_node['bValue'], min_mag=mfd_node['minMag'], max_mag=mfd_node['maxMag'], bin_width=self.width_of_mfd_bin) elif mfd_node.tag.endswith('arbitraryMFD'): return mfd.ArbitraryMFD(magnitudes=~mfd_node.magnitudes, occurrence_rates=~mfd_node.occurRates) elif mfd_node.tag.endswith('YoungsCoppersmithMFD'): if "totalMomentRate" in mfd_node.attrib.keys(): # Return Youngs & Coppersmith from the total moment rate return mfd.YoungsCoppersmith1985MFD.from_total_moment_rate( min_mag=mfd_node["minMag"], b_val=mfd_node["bValue"], char_mag=mfd_node["characteristicMag"], total_moment_rate=mfd_node["totalMomentRate"], bin_width=mfd_node["binWidth"]) elif "characteristicRate" in mfd_node.attrib.keys(): # Return Youngs & Coppersmith from the total moment rate return mfd.YoungsCoppersmith1985MFD.\ from_characteristic_rate( min_mag=mfd_node["minMag"], b_val=mfd_node["bValue"], char_mag=mfd_node["characteristicMag"], char_rate=mfd_node["characteristicRate"], bin_width=mfd_node["binWidth"]) elif mfd_node.tag.endswith('multiMFD'): return mfd.multi_mfd.MultiMFD.from_node( mfd_node, self.width_of_mfd_bin)
def _expected_char_complex(self): incr_mfd = mfd.EvenlyDiscretizedMFD(min_mag=5.0, bin_width=0.1, occurrence_rates=[ 0.0010614989, 8.8291627E-4, 7.3437777E-4, 6.108288E-4, 5.080653E-4, ]) edges = [ geo.Line([ geo.Point(-124.704, 40.363, 0.5493260E+01), geo.Point(-124.977, 41.214, 0.4988560E+01), geo.Point(-125.140, 42.096, 0.4897340E+01), ]), geo.Line([ geo.Point(-124.704, 40.363, 0.5593260E+01), geo.Point(-124.977, 41.214, 0.5088560E+01), geo.Point(-125.140, 42.096, 0.4997340E+01), ]), geo.Line([ geo.Point(-124.704, 40.363, 0.5693260E+01), geo.Point(-124.977, 41.214, 0.5188560E+01), geo.Point(-125.140, 42.096, 0.5097340E+01), ]), geo.Line([ geo.Point(-123.829, 40.347, 0.2038490E+02), geo.Point(-124.137, 41.218, 0.1741390E+02), geo.Point(-124.252, 42.115, 0.1752740E+02), ]), ] complex_surface = geo.ComplexFaultSurface.from_fault_data( edges, self.complex_fault_mesh_spacing) char = source.CharacteristicFaultSource( source_id="6", name="characteristic source, complex fault", tectonic_region_type="Volcanic", mfd=incr_mfd, surface=complex_surface, rake=60.0, temporal_occurrence_model=PoissonTOM(50.0), ) return char
def make_source(series, source_class, mag_bin_width=0.1): ''' Make a source from a pandas Series. ''' if source_class is mtkPointSource: geometry = geo.point.Point(series.longitude, series.latitude) elif source_class is mtkAreaSource: if isinstance(series.geometry, str): series.geometry = loads(series.geometry) coords = list(zip(*series.geometry.exterior.coords.xy)) points = [geo.point.Point(lon, lat) for lon, lat in coords] geometry = geo.polygon.Polygon(points + [points[0]]) else: raise ValueError('Source class %s not supported' % source_class.__name__) if 'occurRates' in series: mag_freq_dist = mfd.EvenlyDiscretizedMFD( series.mmin + series.magBin / 2, series.magBin, series.occurRates.tolist()) else: mag_freq_dist = mfd.TruncatedGRMFD(series.mmin, series.mmax, mag_bin_width, series.a, series.b) nodal_plane_pmf = pmf.PMF([(1.0, geo.NodalPlane(series.strike, series.dip, series.rake))]) try: hypo_depth_pmf = pmf.PMF([(1.0, series.hypo_depth)]) except AttributeError: hypo_depth_pmf = pmf.PMF([(1.0, (series.zmin + series.zmax) / 2.0)]) return source_class(series.id, series.source_name, geometry=geometry, trt=series['tectonic subregion'], upper_depth=series.zmin, lower_depth=series.zmax, rupt_aspect_ratio=series['aspect ratio'], mag_scale_rel=series.msr, mfd=mag_freq_dist, nodal_plane_dist=nodal_plane_pmf, hypo_depth_dist=hypo_depth_pmf)
def split_fault_source(src): """ Generator splitting a fault source into several fault sources, one for each magnitude. :param src: an instance of :class:`openquake.hazardlib.source.base.SeismicSource` """ i = 0 # split source index for mag, rate in src.mfd.get_annual_occurrence_rates(): if rate: # ignore zero occurency rate new_src = copy.copy(src) new_src.source_id = '%s-%s' % (src.source_id, i) new_src.mfd = mfd.EvenlyDiscretizedMFD(min_mag=mag, bin_width=src.mfd.bin_width, occurrence_rates=[rate]) i += 1 yield new_src
def split_fault_source_by_magnitude(src): """ Utility splitting a fault source into fault sources with a single magnitude bin. :param src: an instance of :class:`openquake.hazardlib.source.base.SeismicSource` """ splitlist = [] i = 0 for mag, rate in src.mfd.get_annual_occurrence_rates(): if not rate: # ignore zero occurency rate continue new_src = copy.copy(src) new_src.source_id = '%s-%s' % (src.source_id, i) new_src.mfd = mfd.EvenlyDiscretizedMFD(min_mag=mag, bin_width=src.mfd.bin_width, occurrence_rates=[rate]) i += 1 splitlist.append(new_src) return splitlist
def _mfd_to_hazardlib(src_mfd, bin_width): """Convert a NRML MFD to an HazardLib MFD. :param src_mfd: :class:`openquake.nrmllib.models.IncrementalMFD` or :class:`openquake.nrmllib.models.TGRMFD` instance. :param float bin_width: Optional. Required only for Truncated Gutenberg-Richter MFDs. :returns: The HazardLib representation of the MFD. See :mod:`openquake.hazardlib.mfd`. """ if isinstance(src_mfd, nrml_models.TGRMFD): assert bin_width is not None return mfd.TruncatedGRMFD(a_val=src_mfd.a_val, b_val=src_mfd.b_val, min_mag=src_mfd.min_mag, max_mag=src_mfd.max_mag, bin_width=bin_width) elif isinstance(src_mfd, nrml_models.IncrementalMFD): return mfd.EvenlyDiscretizedMFD(min_mag=src_mfd.min_mag, bin_width=src_mfd.bin_width, occurrence_rates=src_mfd.occur_rates)