def _parse_complex_geometry(cls, src_elem): """ :param src_elem: :class:`lxml.etree._Element` instance representing a geometry. :returns: Fully populated :class:`openquake.nrmllib.models.ComplexFaultGeometry` object. """ complex_geom = models.ComplexFaultGeometry() [top_edge] = _xpath(src_elem, './/nrml:faultTopEdge//gml:posList') top_coords = top_edge.text.split() complex_geom.top_edge_wkt = utils.coords_to_linestr_wkt(top_coords, 3) [bottom_edge] = _xpath(src_elem, './/nrml:faultBottomEdge//gml:posList') bottom_coords = bottom_edge.text.split() complex_geom.bottom_edge_wkt = utils.coords_to_linestr_wkt( bottom_coords, 3) # Optional itermediate edges: int_edges = _xpath(src_elem, './/nrml:intermediateEdge//gml:posList') for edge in int_edges: coords = edge.text.split() complex_geom.int_edges.append( utils.coords_to_linestr_wkt(coords, 3)) return complex_geom
def complex_trace_to_wkt_linestring(edges): ''' Converts a set of complex fault edges to an instance of the :class: openquake.nrmllib.models.ComplexFaultGeometry :param list edges: Edges of the fault as a list of instances of the :class: openquake.hazardlib.geo.line.Line :returns: Complex fault geometry as instance of the :class: openquake.nrmllib.models.ComplexFaultGeometry ''' int_edges = [] for iloc, edge in enumerate(edges): if iloc == 0: top_edge = simple_edge_to_wkt_linestring(edge) elif iloc == len(edges) - 1: bottom_edge = simple_edge_to_wkt_linestring(edge) else: int_edges.append(simple_edge_to_wkt_linestring(edge)) if len(int_edges) == 0: int_edges = None return models.ComplexFaultGeometry(top_edge, bottom_edge, int_edges)
def test_create_oqnmrl_complex_fault_source(self): ''' Tests the conversion of a point source to an instance of the :class: oqnrmllib.models.AreaSource ''' # Define a complete source complex_edges = [ line.Line([point.Point(10., 10., 0.), point.Point(11., 10., 0.)]), line.Line( [point.Point(10., 10., 20.), point.Point(11.5, 10., 21.)]) ] self.fault_source = mtkComplexFaultSource('001', 'A Fault Source', trt='Active Shallow Crust', geometry=None, mag_scale_rel=None, rupt_aspect_ratio=1.0, mfd=models.TGRMFD( a_val=3., b_val=1.0, min_mag=5.0, max_mag=8.0), rake=0.) self.fault_source.create_geometry(complex_edges, 2.0) expected_geometry = models.ComplexFaultGeometry( top_edge_wkt='LINESTRING (10.0 10.0 0.0, 11.0 10.0 0.0)', bottom_edge_wkt='LINESTRING (10.0 10.0 20.0, 11.5 10.0 21.0)') expected_source = models.ComplexFaultSource('001', 'A Fault Source', trt='Active Shallow Crust', geometry=expected_geometry, mag_scale_rel='WC1994', rupt_aspect_ratio=1.0, mfd=models.TGRMFD( a_val=3., b_val=1.0, min_mag=5.0, max_mag=8.0), rake=90.) test_source = self.fault_source.create_oqnrml_source(use_defaults=True) self.assertTrue(isinstance(test_source, models.ComplexFaultSource)) self.assertEqual(test_source.id, expected_source.id) self.assertEqual(test_source.name, expected_source.name) self.assertAlmostEqual(test_source.mfd.b_val, expected_source.mfd.b_val)
def _expected_source_model(cls): # Area: area_geom = models.AreaGeometry( wkt=('POLYGON((-122.5 37.5, -121.5 37.5, -121.5 38.5, -122.5 38.5,' ' -122.5 37.5))'), upper_seismo_depth=0.0, lower_seismo_depth=10.0, ) area_mfd = models.IncrementalMFD( min_mag=6.55, bin_width=0.1, occur_rates=[ 0.0010614989, 8.8291627E-4, 7.3437777E-4, 6.108288E-4, 5.080653E-4 ], ) area_npd = [ models.NodalPlane(probability=decimal.Decimal("0.3"), strike=0.0, dip=90.0, rake=0.0), models.NodalPlane(probability=decimal.Decimal("0.7"), strike=90.0, dip=45.0, rake=90.0), ] area_hdd = [ models.HypocentralDepth(probability=decimal.Decimal("0.5"), depth=4.0), models.HypocentralDepth(probability=decimal.Decimal("0.5"), depth=8.0), ] area_src = models.AreaSource( id='1', name='Quito', trt='Active Shallow Crust', geometry=area_geom, mag_scale_rel='PeerMSR', rupt_aspect_ratio=1.5, mfd=area_mfd, nodal_plane_dist=area_npd, hypo_depth_dist=area_hdd, ) # Point: point_geom = models.PointGeometry( wkt='POINT(-122.0 38.0)', upper_seismo_depth=0.0, lower_seismo_depth=10.0, ) point_mfd = models.TGRMFD( a_val=-3.5, b_val=1.0, min_mag=5.0, max_mag=6.5, ) point_npd = [ models.NodalPlane(probability=decimal.Decimal("0.3"), strike=0.0, dip=90.0, rake=0.0), models.NodalPlane(probability=decimal.Decimal("0.7"), strike=90.0, dip=45.0, rake=90.0), ] point_hdd = [ models.HypocentralDepth(probability=decimal.Decimal("0.5"), depth=4.0), models.HypocentralDepth(probability=decimal.Decimal("0.5"), depth=8.0), ] point_src = models.PointSource( id='2', name='point', trt='Stable Continental Crust', geometry=point_geom, mag_scale_rel='WC1994', rupt_aspect_ratio=0.5, mfd=point_mfd, nodal_plane_dist=point_npd, hypo_depth_dist=point_hdd, ) # Simple: simple_geom = models.SimpleFaultGeometry( wkt='LINESTRING(-121.82290 37.73010, -122.03880 37.87710)', dip=45.0, upper_seismo_depth=10.0, lower_seismo_depth=20.0, ) simple_mfd = models.IncrementalMFD( min_mag=5.0, bin_width=0.1, occur_rates=[ 0.0010614989, 8.8291627E-4, 7.3437777E-4, 6.108288E-4, 5.080653E-4 ], ) simple_src = models.SimpleFaultSource( id='3', name='Mount Diablo Thrust', trt='Active Shallow Crust', geometry=simple_geom, mag_scale_rel='WC1994', rupt_aspect_ratio=1.5, mfd=simple_mfd, rake=30.0, ) # Complex: complex_geom = models.ComplexFaultGeometry( top_edge_wkt=('LINESTRING(-124.704 40.363 0.5493260E+01, ' '-124.977 41.214 0.4988560E+01, ' '-125.140 42.096 0.4897340E+01)'), bottom_edge_wkt=('LINESTRING(-123.829 40.347 0.2038490E+02, ' '-124.137 41.218 0.1741390E+02, ' '-124.252 42.115 0.1752740E+02)'), int_edges=[ ('LINESTRING(-124.704 40.363 0.5593260E+01, ' '-124.977 41.214 0.5088560E+01, ' '-125.140 42.096 0.4997340E+01)'), ('LINESTRING(-124.704 40.363 0.5693260E+01, ' '-124.977 41.214 0.5188560E+01, ' '-125.140 42.096 0.5097340E+01)'), ]) complex_mfd = models.TGRMFD(a_val=-3.5, b_val=1.0, min_mag=5.0, max_mag=6.5) complex_src = models.ComplexFaultSource( id='4', name='Cascadia Megathrust', trt='Subduction Interface', geometry=complex_geom, mag_scale_rel='WC1994', rupt_aspect_ratio=2.0, mfd=complex_mfd, rake=30.0, ) # 3 Characteristic Sources: char_src_simple = models.CharacteristicSource( id='5', name='characteristic source, simple fault', trt='Volcanic', mfd=models.TGRMFD(a_val=-3.5, b_val=1.0, min_mag=5.0, max_mag=6.5), rake=30.0, surface=simple_geom) char_src_complex = models.CharacteristicSource( id='6', name='characteristic source, complex fault', trt='Volcanic', mfd=models.IncrementalMFD( min_mag=5.0, bin_width=0.1, occur_rates=[ 0.0010614989, 8.8291627E-4, 7.3437777E-4, 6.108288E-4, 5.080653E-4 ], ), rake=60.0, surface=complex_geom) char_src_multi = models.CharacteristicSource( id='7', name='characteristic source, multi surface', trt='Volcanic', mfd=models.TGRMFD(a_val=-3.6, b_val=1.0, min_mag=5.2, max_mag=6.4), rake=90.0) psurface_1 = models.PlanarSurface( strike=0.0, dip=90.0, top_left=models.Point(longitude=-1.0, latitude=1.0, depth=21.0), top_right=models.Point(longitude=1.0, latitude=1.0, depth=21.0), bottom_left=models.Point(longitude=-1.0, latitude=-1.0, depth=59.0), bottom_right=models.Point(longitude=1.0, latitude=-1.0, depth=59.0), ) psurface_2 = models.PlanarSurface( strike=20.0, dip=45.0, top_left=models.Point(longitude=1.0, latitude=1.0, depth=20.0), top_right=models.Point(longitude=3.0, latitude=1.0, depth=20.0), bottom_left=models.Point(longitude=1.0, latitude=-1.0, depth=80.0), bottom_right=models.Point(longitude=3.0, latitude=-1.0, depth=80.0), ) char_src_multi.surface = [psurface_1, psurface_2] source_model = models.SourceModel() source_model.name = 'Some Source Model' # Generator: source_model.sources = (x for x in [ area_src, point_src, simple_src, complex_src, char_src_simple, char_src_complex, char_src_multi ]) return source_model
class RuptureModelParserTestCase(unittest.TestCase): SAMPLE_FILES = [ 'examples/simple-fault-rupture.xml', 'examples/complex-fault-rupture.xml' ] EXPECTED_MODELS = [ models.SimpleFaultRuptureModel( magnitude=7.65, rake=15.0, hypocenter=[0.0, 0.0, 15.0], geometry=models.SimpleFaultGeometry( wkt= 'LINESTRING(-124.704 40.363, -124.977 41.214, -125.140 42.096)', dip=50.0, upper_seismo_depth=12.5, lower_seismo_depth=19.5)), models.ComplexFaultRuptureModel( magnitude=9.0, rake=0.0, hypocenter=[-124.977, 41.214, 0.5088560E+01], geometry=models.ComplexFaultGeometry( top_edge_wkt= 'LINESTRING(-124.704 40.363 0.5493260E+01, -124.977 41.214 0.4988560E+01, -125.140 42.096 0.4897340E+01)', bottom_edge_wkt= 'LINESTRING(-123.829 40.347 0.2038490E+02, -124.137 41.218 0.1741390E+02, -124.252 42.115 0.1752740E+02)', int_edges=[ 'LINESTRING(-124.704 40.363 0.5593260E+01, -124.977 41.214 0.5088560E+01, -125.140 42.096 0.4997340E+01)', 'LINESTRING(-124.704 40.363 0.5693260E+01, -124.977 41.214 0.5188560E+01, -125.140 42.096 0.5097340E+01)' ])), ] INVALID_1 = '''<?xml version='1.0' encoding='utf-8'?> <nrml xmlns:gml="http://www.opengis.net/gml" xmlns="http://openquake.org/xmlns/nrml/0.4"> <simpeFaultRupture> <magnitude type="Mw">7.65</magnitude> <rake>15.0</rake> <simpleFaultGeometry> <faultTrace> <gml:LineString srsName="urn:ogc:def:crs:EPSG::4326"> <gml:posList> -124.704 40.363 0.1 -124.977 41.214 0.1 -125.140 42.096 0.1 </gml:posList> </gml:LineString> </faultTrace> <dip>50.0</dip> <upperSeismoDepth>12.5</upperSeismoDepth> <lowerSeismoDepth>19.5</lowerSeismoDepth> </simpleFaultGeometry> </simpleFaultRupture> </nrml> ''' # there is a mispelled simpeFaultRupture here INVALID_2 = '''<?xml version='1.0' encoding='utf-8'?> <nrml xmlns:gml="http://www.opengis.net/gml" xmlns="http://openquake.org/xmlns/nrml/0.4"> <bcrMap sourceModelTreePath="b1|b2" gsimTreePath="b1|b2" lossCategory="economic_loss" unit="EUR" interestRate="1.0" assetLifeExpectancy="20"> <node> <gml:Point> <gml:pos>-116.0 41.0</gml:pos> </gml:Point> <bcr assetRef="asset_1" ratio="15.23" aalOrig="1.1" aalRetr="1.0" /> <bcr assetRef="asset_2" ratio="25.23" aalOrig="2.1" aalRetr="2.0" /> </node> <node> <gml:Point> <gml:pos>-116.0 42.0</gml:pos> </gml:Point> <bcr assetRef="asset_3" ratio="64.23" aalOrig="2.1" aalRetr="2.0" /> </node> </bcrMap> </nrml> ''' # you are trying to parse a bcrMap with a RuptureParser! def test_parse(self): for fname, expected_model in zip(self.SAMPLE_FILES, self.EXPECTED_MODELS): parser = parsers.RuptureModelParser(fname) model = parser.parse() self.assertTrue(*_utils.deep_eq(model, expected_model)) def test_invalid(self): inv1 = StringIO.StringIO(self.INVALID_1) self.assertRaises(etree.XMLSyntaxError, parsers.RuptureModelParser(inv1).parse) inv2 = StringIO.StringIO(self.INVALID_2) self.assertRaises(ValueError, parsers.RuptureModelParser(inv2).parse)