# -*- coding: utf-8 -*-# vim: tabstop=4 shiftwidth=4 softtabstop=4## Copyright (C) 2018-2023 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/>."""Module exports :class:`MultiGMPE`, which can create a composite ofmultiple GMPEs for different IMTs when passed a dictionary of ground motionmodels organised by IMT type or by a string describing the association"""importnumpyasnpfromopenquake.hazardlibimportconst,contextsfromopenquake.hazardlib.gsim.baseimportGMPE,registryfromopenquake.hazardlibimportimtasimt_moduleuppernames='''DEFINED_FOR_INTENSITY_MEASURE_TYPESDEFINED_FOR_STANDARD_DEVIATION_TYPESREQUIRES_SITES_PARAMETERSREQUIRES_RUPTURE_PARAMETERSREQUIRES_DISTANCES'''.split()
[docs]classMultiGMPE(GMPE):""" The MultiGMPE can call ground motions for various IMTs when instantiated with a dictionary of ground motion models organised by IMT or a string describing the association. In the case of spectral accelerations the period of the IMT must be defined explicitly and only SA for that period will be computed. """#: Supported tectonic region type is undefinedDEFINED_FOR_TECTONIC_REGION_TYPE=""#: Supported intensity measure types are not setDEFINED_FOR_INTENSITY_MEASURE_TYPES=set()#: Supported intensity measure component is horizontal#: :attr:`~openquake.hazardlib.const.IMC.HORIZONTAL`,DEFINED_FOR_INTENSITY_MEASURE_COMPONENT=const.IMC.HORIZONTAL#: Supported standard deviation typeDEFINED_FOR_STANDARD_DEVIATION_TYPES=set([const.StdDev.TOTAL])#: Required site parameters will be set be selected GMPESREQUIRES_SITES_PARAMETERS=set()#: Required rupture parameter is magnitude, others will be set laterREQUIRES_RUPTURE_PARAMETERS={'mag'}#: Required distance metrics will be set by the GMPEsREQUIRES_DISTANCES=set()def__init__(self,**kwargs):""" Instantiate with a dictionary of GMPEs organised by IMT """super().__init__(**kwargs)fornameinuppernames:setattr(self,name,set(getattr(self,name)))forimt,gsim_dicinself.kwargs.items():[(gsim_name,kw)]=gsim_dic.items()self.kwargs[imt]=gsim=registry[gsim_name](**kw)name="SA"ifimt.startswith("SA")elseimtimt_factory=getattr(imt_module,name)ifimt_factorynotingsim.DEFINED_FOR_INTENSITY_MEASURE_TYPES:raiseValueError("IMT %s not supported by %s"%(imt,gsim))fornameinuppernames:getattr(self,name).update(getattr(gsim,name))def__iter__(self):yield fromself.kwargsdef__getitem__(self,imt):returnself.kwargs[imt]def__len__(self):returnlen(self.kwargs)def__hash__(self):items=tuple((imt,str(gsim))forimt,gsiminsorted(self.kwargs.items()))returnhash(items)
[docs]defcompute(self,ctx:np.recarray,imts,mean,sig,tau,phi):""" Call the get mean and stddevs of the GMPE for the respective IMT """gsims=[self.kwargs[imt.string]forimtinimts]mean[:],sig[:],tau[:],phi[:]=contexts.get_mean_stds(gsims,ctx,imts)