Source code for openquake.hmtk.parsers.faults.fault_yaml_parser
# -*- coding: utf-8 -*-# vim: tabstop=4 shiftwidth=4 softtabstop=4## LICENSE## Copyright (C) 2010-2025 GEM Foundation, G. Weatherill, M. Pagani,# D. Monelli.## The Hazard Modeller's Toolkit 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.## You should have received a copy of the GNU Affero General Public License# along with OpenQuake. If not, see <http://www.gnu.org/licenses/>## DISCLAIMER## The software Hazard Modeller's Toolkit (openquake.hmtk) provided herein# is released as a prototype implementation on behalf of# scientists and engineers working within the GEM Foundation (Global# Earthquake Model).## It is distributed for the purpose of open collaboration and in the# hope that it will be useful to the scientific, engineering, disaster# risk and software design communities.## The software is NOT distributed as part of GEM's OpenQuake suite# (https://www.globalquakemodel.org/tools-products) and must be considered as a# separate entity. The software provided herein is designed and implemented# by scientific staff. It is not developed to the design standards, nor# subject to same level of critical review by professional software# developers, as GEM's OpenQuake software suite.## Feedback and contribution to the software is welcome, and can be# directed to the hazard scientific staff of the GEM Model Facility# (hazard@globalquakemodel.org).## The Hazard Modeller's Toolkit (openquake.hmtk) is therefore distributed WITHOUT# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License# for more details.## The GEM Foundation, and the authors of the software, assume no# liability for use of the software."""Module: openquake.hmtk.parsers.fault.fault_yaml_parser implements parser of a faultmodel from the TOML format"""importtomlimportnumpyasnpfrommathimportfabsfromopenquake.hazardlib.geo.pointimportPointfromopenquake.hazardlib.geo.lineimportLinefromopenquake.hazardlib.scalerelimportget_available_scalerelfromopenquake.hmtk.faults.fault_geometriesimport(SimpleFaultGeometry,ComplexFaultGeometry,)fromopenquake.hmtk.faults.fault_modelsimportmtkActiveFaultfromopenquake.hmtk.faults.active_fault_modelimportmtkActiveFaultModelfromopenquake.hmtk.faults.tectonic_regionalisationimport(TectonicRegionalisation,)SCALE_REL_MAP=get_available_scalerel()
[docs]defweight_list_to_tuple(data,attr_name):""" Converts a list of values and corresponding weights to a tuple of values """iflen(data["Value"])!=len(data["Weight"]):raiseValueError("Number of weights do not correspond to number of ""attributes in %s"%attr_name)weight=np.array(data["Weight"])iffabs(np.sum(weight)-1.0)>1e-7:raiseValueError("Weights do not sum to 1.0 in %s"%attr_name)data_tuple=[]foriloc,valueinenumerate(data["Value"]):data_tuple.append((value,weight[iloc]))returndata_tuple
[docs]defparse_tect_region_dict_to_tuples(region_dict):""" Parses the tectonic regionalisation dictionary attributes to tuples """output_region_dict=[]tuple_keys=["Displacement_Length_Ratio","Shear_Modulus"]# Convert MSR string name to openquake.hazardlib.scalerel objectforregioninregion_dict:forval_nameintuple_keys:region[val_name]=weight_list_to_tuple(region[val_name],val_name)# MSR works differently - so call get_scaling_relation_tupleregion["Magnitude_Scaling_Relation"]=weight_list_to_tuple(region["Magnitude_Scaling_Relation"],"Magnitude Scaling Relation")output_region_dict.append(region)returnoutput_region_dict
[docs]defget_scaling_relation_tuple(msr_dict):""" For a dictionary of scaling relation values convert string list to object list and then to tuple """# Convert MSR string name to openquake.hazardlib.scalerel objectforiloc,valueinenumerate(msr_dict["Value"]):ifvaluenotinSCALE_REL_MAP:raiseValueError("Scaling relation %s not supported!"%value)msr_dict["Value"][iloc]=SCALE_REL_MAP[value]()returnweight_list_to_tuple(msr_dict,"Magnitude Scaling Relation")
[docs]classFaultYmltoSource(object):""" Class to parse a fault model definition from TOML format to a fault model class """def__init__(self,filename):""" :param str filename: Name of input file (in yml format) """self.data=toml.load(open(filename,"rt"))if"Fault_Model"notinself.data:raiseValueError("Fault Model not defined in input file!")
[docs]defread_file(self,mesh_spacing=1.0):""" Reads the file and returns an instance of the FaultSource class. :param float mesh_spacing: Fault mesh spacing (km) """# Process the tectonic regionalisationtectonic_reg=self.process_tectonic_regionalisation()model=mtkActiveFaultModel(self.data["Fault_Model_ID"],self.data["Fault_Model_Name"])forfaultinself.data["Fault_Model"]:fault_geometry=self.read_fault_geometry(fault["Fault_Geometry"],mesh_spacing)iffault["Shear_Modulus"]:fault["Shear_Modulus"]=weight_list_to_tuple(fault["Shear_Modulus"],"%s Shear Modulus"%fault["ID"])iffault["Displacement_Length_Ratio"]:fault["Displacement_Length_Ratio"]=weight_list_to_tuple(fault["Displacement_Length_Ratio"],"%s Displacement to Length Ratio"%fault["ID"],)fault_source=mtkActiveFault(fault["ID"],fault["Fault_Name"],fault_geometry,weight_list_to_tuple(fault["Slip"],"%s - Slip"%fault["ID"]),float(fault["Rake"]),fault["Tectonic_Region"],float(fault["Aseismic"]),weight_list_to_tuple(fault["Scaling_Relation_Sigma"],"%s Scaling_Relation_Sigma"%fault["ID"],),neotectonic_fault=None,scale_rel=get_scaling_relation_tuple(fault["Magnitude_Scaling_Relation"]),aspect_ratio=fault["Aspect_Ratio"],shear_modulus=fault["Shear_Modulus"],disp_length_ratio=fault["Displacement_Length_Ratio"],)iftectonic_reg:fault_source.get_tectonic_regionalisation(tectonic_reg,fault["Tectonic_Region"])assertisinstance(fault["MFD_Model"],list)fault_source.generate_config_set(fault["MFD_Model"])model.faults.append(fault_source)returnmodel,tectonic_reg
[docs]defprocess_tectonic_regionalisation(self):""" Processes the tectonic regionalisation from the TOML file """if"tectonic_regionalisation"inself.data:tectonic_reg=TectonicRegionalisation()tectonic_reg.populate_regions(parse_tect_region_dict_to_tuples(self.data["tectonic_regionalisation"]))else:tectonic_reg=Nonereturntectonic_reg
[docs]defread_fault_geometry(self,geo_dict,mesh_spacing=1.0):""" Creates the fault geometry from the parameters specified in the dictionary. :param dict geo_dict: Sub-dictionary of main fault dictionary containing only the geometry attributes :param float mesh_spacing: Fault mesh spacing (km) :returns: Instance of SimpleFaultGeometry or ComplexFaultGeometry, depending on typology """ifgeo_dict["Fault_Typology"]=="Simple":# Simple fault geometryraw_trace=geo_dict["Fault_Trace"]trace=Line([Point(raw_trace[ival],raw_trace[ival+1])forivalinrange(0,len(raw_trace),2)])geometry=SimpleFaultGeometry(trace,geo_dict["Dip"],geo_dict["Upper_Depth"],geo_dict["Lower_Depth"],mesh_spacing,)elifgeo_dict["Fault_Typology"]=="Complex":# Complex Fault Typologytrace=[]forraw_traceingeo_dict["Fault_Trace"]:fault_edge=Line([Point(raw_trace[ival],raw_trace[ival+1],raw_trace[ival+2],)forivalinrange(0,len(raw_trace),3)])trace.append(fault_edge)geometry=ComplexFaultGeometry(trace,mesh_spacing)else:raiseValueError("Unrecognised or unsupported fault geometry!")returngeometry