Source code for openquake.engine.tools.correct_complex_sources

# -*- coding: utf-8 -*-
# vim: tabstop=4 shiftwidth=4 softtabstop=4
#
# Copyright (C) 2014-2020 GEM Foundation
#
# OpenQuake is free software: you can redistribute it and/or modify it
# under the terms of the GNU Affero General Public License as published
# by the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# OpenQuake is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with OpenQuake. If not, see <http://www.gnu.org/licenses/>.

"""
Correct complex fault sources to comply with Aki and Richards convention.
"""
import sys
import numpy

from openquake.hazardlib import nrml

from openquake.hazardlib.geo.line import Line
from openquake.hazardlib.geo.point import Point
from openquake.hazardlib.geo.surface import ComplexFaultSurface

AKI_RICH_ERR_MSG = 'Surface does not conform with Aki & Richards convention'
WRONG_ORDER_ERR_MSG = 'Edges points are not in the right order'


[docs]def make_edge(edge): ls = ~edge.LineString.posList coords = numpy.array(ls).reshape(-1, 3) return Line([Point(*coord) for coord in coords])
[docs]def reverse(edge): poslist = ~edge.LineString.posList coords = numpy.array(poslist).reshape(-1, 3)[::-1] # reversing text = '\n'.join('%s %s %s' % tuple(coord) for coord in coords) edge.LineString.posList.text = text
[docs]def fix_source_node(node): if node.tag.endswith('complexFaultSource'): geom = node.complexFaultGeometry top = geom.faultTopEdge intermediate = [edge for edge in geom.getnodes('intermediateEdge')] bottom = geom.faultBottomEdge edges = list(map(make_edge, [top] + intermediate + [bottom])) try: ComplexFaultSurface.from_fault_data(edges, mesh_spacing=4.) except ValueError as excp: if AKI_RICH_ERR_MSG in str(excp): print(excp) print('Reverting edges ...') reverse(geom.faultTopEdge) reverse(geom.faultBottomEdge) elif WRONG_ORDER_ERR_MSG in str(excp): print(excp) print('reverting bottom edge ...') reverse(geom.faultBottomEdge) else: raise
[docs]def fix(fname, outname=None): root = nrml.read(fname) xmlns = root['xmlns'] if xmlns == u'http://openquake.org/xmlns/nrml/0.4': for src_node in root.sourceModel: fix_source_node(src_node) else: # nrml/0.5+ for src_grp in root.sourceModel: for src_node in src_grp: fix_source_node(src_node) with open(outname or fname, 'wb') as out: nrml.write([root.sourceModel], out, xmlns=xmlns)
if __name__ == '__main__': fname = sys.argv[1] fix(fname)