def test_area_with_tgr_mfd(self): trunc_mfd = mfd.TruncatedGRMFD( a_val=2.1, b_val=4.2, bin_width=0.1, min_mag=6.55, max_mag=8.91 ) 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=trunc_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.)) actual = list(area) self.assertEqual(len(actual), 96) # expected 96 points self.assertAlmostEqual(actual[0].mfd.a_val, 0.1177287669604317)
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.)) return area
def _expected_point(self): tgr_mfd = mfd.TruncatedGRMFD( a_val=-3.5, b_val=1.0, min_mag=5.0, max_mag=6.5, bin_width=1.0) 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)]) point = source.PointSource( source_id="2", name="point", tectonic_region_type="Stable Continental Crust", mfd=tgr_mfd, rupture_mesh_spacing=self.rupture_mesh_spacing, magnitude_scaling_relationship=scalerel.WC1994(), rupture_aspect_ratio=0.5, upper_seismogenic_depth=0.0, lower_seismogenic_depth=10.0, location=geo.Point(-122.0, 38.0), nodal_plane_distribution=npd, hypocenter_distribution=hd, temporal_occurrence_model=PoissonTOM(50.)) point.num_ruptures = point.count_ruptures() return point
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 _area_to_hazardlib(src, mesh_spacing, bin_width, area_src_disc): """Convert a NRML area source to the HazardLib equivalent. See :mod:`openquake.nrmllib.models` and :mod:`openquake.hazardlib.source`. :param src: :class:`openquake.nrmllib.models.PointSource` instance. :param float mesh_spacing: Rupture mesh spacing, in km. :param float bin_width: Truncated Gutenberg-Richter MFD (Magnitude Frequency Distribution) bin width. :param float area_src_disc: Area source discretization, in km. Applies only to area sources. :returns: The HazardLib representation of the input source. """ shapely_polygon = wkt.loads(src.geometry.wkt) hazardlib_polygon = geo.Polygon( # We ignore the last coordinate in the sequence here, since it is a # duplicate of the first. hazardlib will close the loop for us. [geo.Point(*x) for x in list(shapely_polygon.exterior.coords)[:-1]]) mf_dist = _mfd_to_hazardlib(src.mfd, bin_width) # nodal plane distribution: npd = pmf.PMF([(x.probability, geo.NodalPlane(strike=x.strike, dip=x.dip, rake=x.rake)) for x in src.nodal_plane_dist]) # hypocentral depth distribution: hd = pmf.PMF([(x.probability, x.depth) for x in src.hypo_depth_dist]) msr = scalerel.get_available_magnitude_scalerel()[src.mag_scale_rel]() area = source.AreaSource( source_id=src.id, name=src.name, tectonic_region_type=src.trt, mfd=mf_dist, rupture_mesh_spacing=mesh_spacing, magnitude_scaling_relationship=msr, rupture_aspect_ratio=src.rupt_aspect_ratio, upper_seismogenic_depth=src.geometry.upper_seismo_depth, lower_seismogenic_depth=src.geometry.lower_seismo_depth, nodal_plane_distribution=npd, hypocenter_distribution=hd, polygon=hazardlib_polygon, area_discretization=area_src_disc) return area
def convert_nonParametricSeismicSource(self, node): """ Convert the given node into a non parametric source object. :param node: a node with tag areaGeometry :returns: a :class:`openquake.hazardlib.source.NonParametricSeismicSource` instance """ trt = node.attrib.get('tectonicRegion') rup_pmf_data = [] rups_weights = None if 'rup_weights' in node.attrib: rups_weights = F64(node['rup_weights'].split()) num_probs = None for i, rupnode in enumerate(node): po = rupnode['probs_occur'] probs = pmf.PMF(valid.pmf(po)) if num_probs is None: # first time num_probs = len(probs.data) elif len(probs.data) != num_probs: # probs_occur must have uniform length for all ruptures raise ValueError( 'prob_occurs=%s has %d elements, expected %s' % (po, len(probs.data), num_probs)) rup = RuptureConverter.convert_node(self, rupnode) rup.tectonic_region_type = trt rup_pmf_data.append((rup, probs)) nps = source.NonParametricSeismicSource(node['id'], node['name'], trt, rup_pmf_data, rups_weights) nps.splittable = 'rup_weights' not in node.attrib return nps
def convert_nonParametricSeismicSource(self, node): """ Convert the given node into a non parametric source object. :param node: a node with tag areaGeometry :returns: a :class:`openquake.hazardlib.source.NonParametricSeismicSource` instance """ trt = node.attrib.get('tectonicRegion') rup_pmf_data = [] rups_weights = None if 'rup_weights' in node.attrib: tmp = node.attrib.get('rup_weights') rups_weights = numpy.array([float(s) for s in tmp.split()]) for i, rupnode in enumerate(node): probs = pmf.PMF(valid.pmf(rupnode['probs_occur'])) rup = RuptureConverter.convert_node(self, rupnode) rup.tectonic_region_type = trt rup.weight = None if rups_weights is None else rups_weights[i] rup_pmf_data.append((rup, probs)) nps = source.NonParametricSeismicSource(node['id'], node['name'], trt, rup_pmf_data) nps.splittable = 'rup_weights' not in node.attrib return nps
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 _point_to_hazardlib(src, mesh_spacing, bin_width): """Convert a NRML point source to the HazardLib equivalent. See :mod:`openquake.nrmllib.models` and :mod:`openquake.hazardlib.source`. :param src: :class:`openquake.nrmllib.models.PointSource` instance. :param float mesh_spacing: Rupture mesh spacing, in km. :param float bin_width: Truncated Gutenberg-Richter MFD (Magnitude Frequency Distribution) bin width. :returns: The HazardLib representation of the input source. """ shapely_pt = wkt.loads(src.geometry.wkt) mf_dist = _mfd_to_hazardlib(src.mfd, bin_width) # nodal plane distribution: npd = pmf.PMF([(x.probability, geo.NodalPlane(strike=x.strike, dip=x.dip, rake=x.rake)) for x in src.nodal_plane_dist]) # hypocentral depth distribution: hd = pmf.PMF([(x.probability, x.depth) for x in src.hypo_depth_dist]) msr = scalerel.get_available_magnitude_scalerel()[src.mag_scale_rel]() point = source.PointSource( source_id=src.id, name=src.name, tectonic_region_type=src.trt, mfd=mf_dist, rupture_mesh_spacing=mesh_spacing, magnitude_scaling_relationship=msr, rupture_aspect_ratio=src.rupt_aspect_ratio, upper_seismogenic_depth=src.geometry.upper_seismo_depth, lower_seismogenic_depth=src.geometry.lower_seismo_depth, location=geo.Point(shapely_pt.x, shapely_pt.y), nodal_plane_distribution=npd, hypocenter_distribution=hd) return point
def convert_hpdist(self, node): """ Convert the given node into a probability mass function for the hypo depth distribution. :param node: a hypoDepthDist node :returns: a :class:`openquake.hazardlib.pmf.PMF` instance """ with context(self.fname, node): return pmf.PMF([~hd for hd in node.hypoDepthDist])
def convert_npdist(self, node): """ Convert the given node into a Nodal Plane Distribution. :param node: a nodalPlaneDist node :returns: a :class:`openquake.hazardlib.geo.NodalPlane` instance """ with context(self.fname, node): npdist = [] for np in node.nodalPlaneDist: prob, strike, dip, rake = ~np npdist.append((prob, geo.NodalPlane(strike, dip, rake))) return pmf.PMF(npdist)
def convert_hpdist(self, node): """ Convert the given node into a probability mass function for the hypo depth distribution. :param node: a hypoDepthDist node :returns: a :class:`openquake.hazardlib.pmf.PMF` instance """ with context(self.fname, node): hcdist = [(hd['probability'], hd['depth']) for hd in node.hypoDepthDist] if os.environ.get('OQ_FLOATING') == 'no': hcdist = [(1, hcdist[0][1])] return pmf.PMF(hcdist)
def convert_hpdist(self, node): """ Convert the given node into a probability mass function for the hypo depth distribution. :param node: a hypoDepthDist node :returns: a :class:`openquake.hazardlib.pmf.PMF` instance """ with context(self.fname, node): hcdist = [(hd['probability'], hd['depth']) for hd in node.hypoDepthDist] if not self.spinning_floating: # consider the first hypocenter hcdist = [(1, hcdist[0][1])] return pmf.PMF(hcdist)
def convert_npdist(self, node): """ Convert the given node into a Nodal Plane Distribution. :param node: a nodalPlaneDist node :returns: a :class:`openquake.hazardlib.geo.NodalPlane` instance """ with context(self.fname, node): npdist = [] for np in node.nodalPlaneDist: prob, strike, dip, rake = (np['probability'], np['strike'], np['dip'], np['rake']) npdist.append((prob, geo.NodalPlane(strike, dip, rake))) if os.environ.get('OQ_SPINNING') == 'no': npdist = [(1, npdist[0][1])] # consider the first nodal plane return pmf.PMF(npdist)
def convert_nonParametricSeismicSource(fname, node): """ Convert the given node into a non parametric source object. :param fname: full pathname to the XML file associated to the node :param node: a Node object coming from an XML file :returns: a :class:`openquake.hazardlib.source.NonParametricSeismicSource` instance """ trt = node.attrib.get('tectonicRegion') rups_weights = None if 'rup_weights' in node.attrib: rups_weights = F64(node['rup_weights'].split()) nps = source.NonParametricSeismicSource(node['id'], node['name'], trt, [], []) nps.splittable = 'rup_weights' not in node.attrib path = os.path.splitext(fname)[0] + '.hdf5' hdf5_fname = path if os.path.exists(path) else None if hdf5_fname: # read the rupture data from the HDF5 file assert node.text is None, node.text with hdf5.File(hdf5_fname, 'r') as h: dic = {k: d[:] for k, d in h[node['id']].items()} nps.fromdict(dic, rups_weights) num_probs = len(dic['probs_occur']) else: # read the rupture data from the XML nodes num_probs = None for i, rupnode in enumerate(node): po = rupnode['probs_occur'] probs = pmf.PMF(valid.pmf(po)) if num_probs is None: # first time num_probs = len(probs.data) elif len(probs.data) != num_probs: # probs_occur must have uniform length for all ruptures raise ValueError( 'prob_occurs=%s has %d elements, expected %s' % (po, len(probs.data), num_probs)) rup = RuptureConverter(5.).convert_node(rupnode) rup.tectonic_region_type = trt rup.weight = None if rups_weights is None else rups_weights[i] nps.data.append((rup, probs)) nps.num_probs_occur = num_probs return nps
def convert_nonParametricSeismicSource(self, node): """ Convert the given node into a non parametric source object. :param node: a node with tag areaGeometry :returns: a :class:`openquake.hazardlib.source.NonParametricSeismicSource` instance """ trt = node['tectonicRegion'] rup_pmf_data = [] for rupnode in node: probs = pmf.PMF(rupnode['probs_occur']) rup = RuptureConverter.convert_node(self, rupnode) rup.tectonic_region_type = trt rup_pmf_data.append((rup, probs)) nps = source.NonParametricSeismicSource(node['id'], node['name'], trt, rup_pmf_data) return nps
def convert_npdist(self, node): """ Convert the given node into a Nodal Plane Distribution. :param node: a nodalPlaneDist node :returns: a :class:`openquake.hazardlib.geo.NodalPlane` instance """ with context(self.fname, node): npnode = node.nodalPlaneDist npdist = [] for np in npnode: prob, strike, dip, rake = (np['probability'], np['strike'], np['dip'], np['rake']) npdist.append((prob, geo.NodalPlane(strike, dip, rake))) with context(self.fname, npnode): fix_dupl(npdist, self.fname, npnode.lineno) if not self.spinning_floating: npdist = [(1, npdist[0][1])] # consider the first nodal plane return pmf.PMF(npdist)