From fad01e61669e429772415133512fca978a6e63a0 Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 4 Nov 2024 14:51:50 +0100 Subject: [PATCH 01/28] first commit --- openquake/hazardlib/contexts.py | 10 +-- .../hazardlib/gsim/mgmpe/cy14_site_term.py | 4 +- .../hazardlib/gsim/mgmpe/m9_basin_term.py | 74 ++++++++++++++++ .../hazardlib/gsim/mgmpe/modifiable_gmpe.py | 15 +++- .../tests/gsim/mgmpe/m9_basin_term_test.py | 86 +++++++++++++++++++ 5 files changed, 179 insertions(+), 10 deletions(-) create mode 100644 openquake/hazardlib/gsim/mgmpe/m9_basin_term.py create mode 100644 openquake/hazardlib/tests/gsim/mgmpe/m9_basin_term_test.py diff --git a/openquake/hazardlib/contexts.py b/openquake/hazardlib/contexts.py index 2da36291eab7..a5b66f36a2cf 100644 --- a/openquake/hazardlib/contexts.py +++ b/openquake/hazardlib/contexts.py @@ -1640,7 +1640,7 @@ def __eq__(self, other): return False -# mock of a site collection used in the tests and in the SMTK +# mock of a site collection used in the tests and in the SMT class SitesContext(BaseContext): """ Sites calculation context for ground shaking intensity models. @@ -1653,7 +1653,7 @@ class SitesContext(BaseContext): Only those required parameters are made available in a result context object. """ - # _slots_ is used in hazardlib check_gsim and in the SMTK + # _slots_ is used in hazardlib check_gsim and in the SMT def __init__(self, slots='vs30 vs30measured z1pt0 z2pt5'.split(), sitecol=None): self._slots_ = slots @@ -1662,7 +1662,7 @@ def __init__(self, slots='vs30 vs30measured z1pt0 z2pt5'.split(), for slot in slots: setattr(self, slot, getattr(sitecol, slot)) - # used in the SMTK + # used in the SMT def __len__(self): return len(self.sids) @@ -1699,7 +1699,7 @@ def get_dists(ctx): # used to produce a RuptureContext suitable for legacy code, i.e. for calls -# to .get_mean_and_stddevs, like for instance in the SMTK +# to .get_mean_and_stddevs, like for instance in the SMT def full_context(sites, rup, dctx=None): """ :returns: a full RuptureContext with all the relevant attributes @@ -1739,7 +1739,7 @@ def get_mean_stds(gsim, ctx, imts, **kw): return out[:, 0] if single else out -# mock of a rupture used in the tests and in the SMTK +# mock of a rupture used in the tests and in the SMT class RuptureContext(BaseContext): """ Rupture calculation context for ground shaking intensity models. diff --git a/openquake/hazardlib/gsim/mgmpe/cy14_site_term.py b/openquake/hazardlib/gsim/mgmpe/cy14_site_term.py index c13f4bd6e455..cd73fbff459b 100644 --- a/openquake/hazardlib/gsim/mgmpe/cy14_site_term.py +++ b/openquake/hazardlib/gsim/mgmpe/cy14_site_term.py @@ -26,7 +26,7 @@ from openquake.hazardlib.gsim.chiou_youngs_2014 import ChiouYoungs2014 -def _get_site_term(C, vs30, ln_y_ref): +def _get_cy14_site_term(C, vs30, ln_y_ref): """ Applies the linear and nonlinear site amplification term of Chiou & Youngs (2014) (excluding the basin amplification term) @@ -104,4 +104,4 @@ def compute(self, ctx: np.recarray, imts, mean, sig, tau, phi): vs30 = ctx.vs30.copy() for m, imt in enumerate(imts): C = ChiouYoungs2014.COEFFS[imt] - mean[m] += _get_site_term(C, vs30, mean[m]) + mean[m] += _get_cy14_site_term(C, vs30, mean[m]) diff --git a/openquake/hazardlib/gsim/mgmpe/m9_basin_term.py b/openquake/hazardlib/gsim/mgmpe/m9_basin_term.py new file mode 100644 index 000000000000..f309121757dd --- /dev/null +++ b/openquake/hazardlib/gsim/mgmpe/m9_basin_term.py @@ -0,0 +1,74 @@ +# The Hazard Library +# Copyright (C) 2012-2023 GEM Foundation +# +# This program 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. +# +# This program 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 this program. If not, see . + +""" +Module :mod:`openquake.hazardlib.mgmpe.m9_basin_term` implements +:class:`~openquake.hazardlib.mgmpe.M9BasinTerm` +""" +import numpy as np + +from openquake.hazardlib import const +from openquake.hazardlib.gsim.base import GMPE, registry + + +def _get_m9_basin_term(ctx, imt, mean): + if imt.period > 1.9: # Only apply to long-period SA + fb_m9 = np.log(2.0) + idx = ctx.z2pt5 > 6.0 # Apply only if z2pt5 > 6 + mean[idx] += fb_m9 + + return mean + + +class M9BasinTerm(GMPE): + """ + Implements a modified GMPE class that can be used to account for basin + amplification of long period ground-motions within the Seattle Basin + through the use of the M9 basin amplification model (Frankel et al. 2018, + Wirth et al. 2018). + + The amplification of the mean ground-motion is uniformly modelled across + the Seattle Basin as an additive factor of log(2.0) for long period + ground-motions with a z2pt5 greater than 6.0 km. + + :param gmpe_name: + The name of a GMPE class + """ + # Req Params + REQUIRES_SITES_PARAMETERS = {} + + # Others are set from underlying GMM + REQUIRES_DISTANCES = set() + REQUIRES_RUPTURE_PARAMETERS = set() + DEFINED_FOR_INTENSITY_MEASURE_COMPONENT = "" + DEFINED_FOR_INTENSITY_MEASURE_TYPES = set() + DEFINED_FOR_STANDARD_DEVIATION_TYPES = {const.StdDev.TOTAL} + DEFINED_FOR_TECTONIC_REGION_TYPE = "" + DEFINED_FOR_REFERENCE_VELOCITY = None + + def __init__(self, gmpe_name, **kwargs): + self.gmpe = registry[gmpe_name]() + self.set_parameters() + + def compute(self, ctx: np.recarray, imts, mean, sig, tau, phi): + """ + See :meth:`superclass method + <.base.GroundShakingIntensityModel.compute>` + for spec of input and result values. + """ + self.gmpe.compute(ctx, imts, mean, sig, tau, phi) + for m, imt in enumerate(imts): + mean[m] += _get_m9_basin_term(ctx, imt, mean[m]) \ No newline at end of file diff --git a/openquake/hazardlib/gsim/mgmpe/modifiable_gmpe.py b/openquake/hazardlib/gsim/mgmpe/modifiable_gmpe.py index c3f431ce3b55..977056d0207c 100644 --- a/openquake/hazardlib/gsim/mgmpe/modifiable_gmpe.py +++ b/openquake/hazardlib/gsim/mgmpe/modifiable_gmpe.py @@ -26,8 +26,9 @@ from openquake.hazardlib.imt import from_string from openquake.hazardlib.gsim.mgmpe.nrcan15_site_term import ( NRCan15SiteTerm, BA08_AB06) -from openquake.hazardlib.gsim.mgmpe.cy14_site_term import _get_site_term +from openquake.hazardlib.gsim.mgmpe.cy14_site_term import _get_cy14_site_term from openquake.hazardlib.gsim.chiou_youngs_2014 import ChiouYoungs2014 +from openquake.hazardlib.gsim.mgmpe.m9_basin_term import _get_m9_basin_term from openquake.hazardlib.gsim.nga_east import ( TAU_EXECUTION, get_phi_ss, TAU_SETUP, PHI_SETUP, get_tau_at_quantile, @@ -73,10 +74,17 @@ def cy14_site_term(ctx, imt, me, si, ta, phi): This function adds the CY14 site term to GMMs requiring it """ C = ChiouYoungs2014.COEFFS[imt] - fa = _get_site_term(C, ctx.vs30, me) # ref mean must be in natural log + fa = _get_cy14_site_term(C, ctx.vs30, me) # ref mean must be in natural log me[:] += fa +def m9_basin_term(ctx, imt, me): + """ + This function adds the M9 basin amplification term + """ + me += _get_m9_basin_term(ctx, imt, me) + + def add_between_within_stds(ctx, imt, me, si, ta, ph, with_betw_ratio): """ This adds the between and within standard deviations to a model which has @@ -301,6 +309,7 @@ def compute(self, ctx: np.recarray, imts, mean, sig, tau, phi): <.base.GroundShakingIntensityModel.compute>` for spec of input and result values. """ + # Set reference Vs30 if required if ('nrcan15_site_term' in self.params or 'cy14_site_term' in self.params): ctx_copy = ctx.copy() @@ -308,7 +317,7 @@ def compute(self, ctx: np.recarray, imts, mean, sig, tau, phi): rock_vs30 = 760. elif 'cy14_site_term' in self.params: rock_vs30 = 1130. - ctx_copy.vs30 = np.full_like(ctx.vs30, rock_vs30) # rock + ctx_copy.vs30 = np.full_like(ctx.vs30, rock_vs30) # rock else: ctx_copy = ctx g = globals() diff --git a/openquake/hazardlib/tests/gsim/mgmpe/m9_basin_term_test.py b/openquake/hazardlib/tests/gsim/mgmpe/m9_basin_term_test.py new file mode 100644 index 000000000000..27a81e1c9f73 --- /dev/null +++ b/openquake/hazardlib/tests/gsim/mgmpe/m9_basin_term_test.py @@ -0,0 +1,86 @@ +# The Hazard Library +# Copyright (C) 2012-2023 GEM Foundation +# +# This program 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. +# +# This program 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 this program. If not, see . + +import numpy as np +import unittest + +from openquake.hazardlib.tests.gsim.mgmpe.dummy import new_ctx +from openquake.hazardlib.contexts import simple_cmaker +from openquake.hazardlib.imt import PGA, PGV, SA +from openquake.hazardlib.const import TRT, IMC +from openquake.hazardlib.gsim.mgmpe.m9_basin_term import M9BasinTerm +from openquake.hazardlib.gsim.mgmpe.modifiable_gmpe import ModifiableGMPE +from openquake.hazardlib.gsim.kuehn_2020 import KuehnEtAl2020SInter + +aae = np.testing.assert_almost_equal + + +class M9BasinTermTestCase(unittest.TestCase): + + def test_instantiation(self): + mgmpe = M9BasinTerm(gmpe_name='KuehnEtAl2020SInter') + + # Check the assigned IMTs + expected = set([PGA, SA, PGV]) + self.assertTrue(mgmpe.DEFINED_FOR_INTENSITY_MEASURE_TYPES == expected, + msg='The assigned IMTs are incorrect') + # Check the TR + expected = TRT.SUBDUCTION_INTERFACE + self.assertTrue(mgmpe.DEFINED_FOR_TECTONIC_REGION_TYPE == expected, + msg='The assigned TRT is incorrect') + # Check the IM component + expected = IMC.RotD50 + self.assertTrue(mgmpe.DEFINED_FOR_INTENSITY_MEASURE_COMPONENT == + expected, msg='The IM component is wrong') + # Check the required distances + expected = {'rrup'} + self.assertTrue(mgmpe.REQUIRES_DISTANCES == expected, + msg='The assigned distance types are wrong') + + + def test_all(self): + """ + Test that the M9 basin term applied to Kuehn et al. (2020) + provides the expected values (using sites with z2pt5 above + and below 6 km threshold and considering SAs with periods + above and below 1.9 s) + """ + # Make base GMM + gmpe = KuehnEtAl2020SInter() + + # Make GMM with basin term using the mgmpe class directly + mgmpe_cls = M9BasinTerm(gmpe_name='KuehnEtAl2020SInter') + + # Make GMM with basin term using ModifiableGMPE and kwargs + kwargs = {'gmpe': {'KuehnEtAl2020SInter': {}}, + 'm9_basin_term': {}} + mgmpe_kws = ModifiableGMPE(**kwargs) + + # Make the ctx + cmaker = simple_cmaker([gmpe, mgmpe_cls, mgmpe_kws], + ['PGA', 'SA(1.0)', 'SA(2.0)']) + + ctx = new_ctx(cmaker, 6) + ctx.dip = 60. + ctx.rake = 90. + ctx.z1pt0 = np.array([522.32, 516.98, 522.32, 516.98, 522.32]) + ctx.z2pt5 = np.array([6.32, 3.53, 6.32, 3.53, 6.32]) + ctx.rrup = np.array([1., 10., 30., 70., 200., 500.]) + ctx.vs30 = 1100. + ctx.vs30measured = 1 + mea, sig, _, _ = cmaker.get_mean_stds([ctx]) + aae(mea[0], mea[1]) + aae(sig[0], sig[1]) \ No newline at end of file From 89d1c93fe97be44230335727856719e749ebf2e3 Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 4 Nov 2024 14:53:26 +0100 Subject: [PATCH 02/28] first commit --- openquake/hazardlib/gsim/mgmpe/m9_basin_term.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openquake/hazardlib/gsim/mgmpe/m9_basin_term.py b/openquake/hazardlib/gsim/mgmpe/m9_basin_term.py index f309121757dd..49fdb998fc17 100644 --- a/openquake/hazardlib/gsim/mgmpe/m9_basin_term.py +++ b/openquake/hazardlib/gsim/mgmpe/m9_basin_term.py @@ -48,7 +48,7 @@ class M9BasinTerm(GMPE): The name of a GMPE class """ # Req Params - REQUIRES_SITES_PARAMETERS = {} + REQUIRES_SITES_PARAMETERS = {'z2pt5'} # Others are set from underlying GMM REQUIRES_DISTANCES = set() From d841eb5aaf8a746b52c30a0e954481514d5be677 Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 4 Nov 2024 17:24:43 +0100 Subject: [PATCH 03/28] adding tests --- .../hazardlib/gsim/mgmpe/m9_basin_term.py | 7 ++- .../hazardlib/gsim/mgmpe/modifiable_gmpe.py | 10 ++- .../tests/gsim/mgmpe/m9_basin_term_test.py | 61 +++++++++++++------ 3 files changed, 57 insertions(+), 21 deletions(-) diff --git a/openquake/hazardlib/gsim/mgmpe/m9_basin_term.py b/openquake/hazardlib/gsim/mgmpe/m9_basin_term.py index 49fdb998fc17..21d4eba37532 100644 --- a/openquake/hazardlib/gsim/mgmpe/m9_basin_term.py +++ b/openquake/hazardlib/gsim/mgmpe/m9_basin_term.py @@ -62,6 +62,11 @@ class M9BasinTerm(GMPE): def __init__(self, gmpe_name, **kwargs): self.gmpe = registry[gmpe_name]() self.set_parameters() + + # Need z2pt5 in req site params to ensure in ctx site col + if 'z2pt5' not in self.gmpe.REQUIRES_SITES_PARAMETERS: + self.REQUIRES_SITES_PARAMETERS = frozenset( + self.gmpe.REQUIRES_SITES_PARAMETERS | {'z2pt5'}) def compute(self, ctx: np.recarray, imts, mean, sig, tau, phi): """ @@ -71,4 +76,4 @@ def compute(self, ctx: np.recarray, imts, mean, sig, tau, phi): """ self.gmpe.compute(ctx, imts, mean, sig, tau, phi) for m, imt in enumerate(imts): - mean[m] += _get_m9_basin_term(ctx, imt, mean[m]) \ No newline at end of file + mean[m] = _get_m9_basin_term(ctx, imt, mean[m]) \ No newline at end of file diff --git a/openquake/hazardlib/gsim/mgmpe/modifiable_gmpe.py b/openquake/hazardlib/gsim/mgmpe/modifiable_gmpe.py index 977056d0207c..2fd8aa50568d 100644 --- a/openquake/hazardlib/gsim/mgmpe/modifiable_gmpe.py +++ b/openquake/hazardlib/gsim/mgmpe/modifiable_gmpe.py @@ -78,11 +78,11 @@ def cy14_site_term(ctx, imt, me, si, ta, phi): me[:] += fa -def m9_basin_term(ctx, imt, me): +def m9_basin_term(ctx, imt, me, si, ta, phi): """ This function adds the M9 basin amplification term """ - me += _get_m9_basin_term(ctx, imt, me) + me = _get_m9_basin_term(ctx, imt, me) def add_between_within_stds(ctx, imt, me, si, ta, ph, with_betw_ratio): @@ -256,6 +256,12 @@ def __init__(self, **kwargs): setattr(self, 'DEFINED_FOR_STANDARD_DEVIATION_TYPES', {StdDev.TOTAL, StdDev.INTRA_EVENT, StdDev.INTER_EVENT}) + if ('m9_basin_term' in self.params) and ( + 'z2pt5' not in self.gmpe.REQUIRES_SITES_PARAMETERS): + tmp = list(self.gmpe.REQUIRES_SITES_PARAMETERS) + tmp.append('z2pt5') + self.gmpe.REQUIRES_SITES_PARAMETERS = frozenset(tmp) + # This is required by the `sigma_model_alatik2015` function key = 'sigma_model_alatik2015' if key in self.params: diff --git a/openquake/hazardlib/tests/gsim/mgmpe/m9_basin_term_test.py b/openquake/hazardlib/tests/gsim/mgmpe/m9_basin_term_test.py index 27a81e1c9f73..49a01ccfc292 100644 --- a/openquake/hazardlib/tests/gsim/mgmpe/m9_basin_term_test.py +++ b/openquake/hazardlib/tests/gsim/mgmpe/m9_basin_term_test.py @@ -19,12 +19,13 @@ from openquake.hazardlib.tests.gsim.mgmpe.dummy import new_ctx from openquake.hazardlib.contexts import simple_cmaker +from openquake.hazardlib import valid from openquake.hazardlib.imt import PGA, PGV, SA from openquake.hazardlib.const import TRT, IMC from openquake.hazardlib.gsim.mgmpe.m9_basin_term import M9BasinTerm -from openquake.hazardlib.gsim.mgmpe.modifiable_gmpe import ModifiableGMPE from openquake.hazardlib.gsim.kuehn_2020 import KuehnEtAl2020SInter +ae = np.testing.assert_equal aae = np.testing.assert_almost_equal @@ -58,29 +59,53 @@ def test_all(self): and below 6 km threshold and considering SAs with periods above and below 1.9 s) """ - # Make base GMM - gmpe = KuehnEtAl2020SInter() + k20 = valid.gsim('KuehnEtAl2020SInter') + # Make original GMM + gmpe = valid.modified_gsim(k20) + # Make GMM with basin term using the mgmpe class directly mgmpe_cls = M9BasinTerm(gmpe_name='KuehnEtAl2020SInter') - - # Make GMM with basin term using ModifiableGMPE and kwargs - kwargs = {'gmpe': {'KuehnEtAl2020SInter': {}}, - 'm9_basin_term': {}} - mgmpe_kws = ModifiableGMPE(**kwargs) + # Make GMM with basin term using ModifiableGMPE and kwargs + mgmpe_val = valid.modified_gsim(k20, m9_basin_term={}) + # Make the ctx - cmaker = simple_cmaker([gmpe, mgmpe_cls, mgmpe_kws], - ['PGA', 'SA(1.0)', 'SA(2.0)']) - - ctx = new_ctx(cmaker, 6) + imts = ['PGA', 'SA(1.0)', 'SA(2.0)'] + cmaker = simple_cmaker([gmpe, mgmpe_cls, mgmpe_val], imts) + ctx = new_ctx(cmaker, 3) ctx.dip = 60. ctx.rake = 90. - ctx.z1pt0 = np.array([522.32, 516.98, 522.32, 516.98, 522.32]) - ctx.z2pt5 = np.array([6.32, 3.53, 6.32, 3.53, 6.32]) - ctx.rrup = np.array([1., 10., 30., 70., 200., 500.]) + ctx.z1pt0 = np.array([522.32, 516.98, 522.32]) + ctx.z2pt5 = np.array([6.32, 3.53, 6.32]) + ctx.rrup = np.array([50., 200., 500.]) ctx.vs30 = 1100. ctx.vs30measured = 1 - mea, sig, _, _ = cmaker.get_mean_stds([ctx]) - aae(mea[0], mea[1]) - aae(sig[0], sig[1]) \ No newline at end of file + mea, _, _, _ = cmaker.get_mean_stds([ctx]) + + # For SA with period less than 2 all means should be + # the same (amp term only applied for long periods) + ori_mea_pga = mea[0][0] + cls_mea_pga = mea[1][0] + val_mea_pga = mea[2][0] + ae(ori_mea_pga, cls_mea_pga, val_mea_pga) + ori_mea_sa1pt0 = mea[0][1] + cls_mea_sa1pt0 = mea[1][1] + val_mea_sa1pt0 = mea[2][1] + ae(ori_mea_sa1pt0, cls_mea_sa1pt0, val_mea_sa1pt0) + + # Check means using m9 term from mgmpe cls and + # valid.modifiable_gmpe are the same + ae(mea[1], mea[2]) + + # For SA(2.0) basin amplification should be added + # unmodified + np.log(2.0) + ori_sa2pt0 = mea[0][2] + cls_sa2pt0 = mea[1][2] + val_sa2pt0 = mea[2][2] + exp_diff = np.array([np.log(2.0), 0., np.log(2.0)]) + for idx_v, v in enumerate(exp_diff): + diff_cls = cls_sa2pt0[idx_v] - ori_sa2pt0[idx_v] + diff_val = val_sa2pt0[idx_v] - ori_sa2pt0[idx_v] + aae(diff_cls, exp_diff[idx_v]) + aae(diff_val, exp_diff[idx_v]) \ No newline at end of file From dacc496956cd2891a5c8ea783e0c7b0e353fe5e0 Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 4 Nov 2024 17:41:00 +0100 Subject: [PATCH 04/28] removing unused import --- openquake/hazardlib/tests/gsim/mgmpe/m9_basin_term_test.py | 1 - 1 file changed, 1 deletion(-) diff --git a/openquake/hazardlib/tests/gsim/mgmpe/m9_basin_term_test.py b/openquake/hazardlib/tests/gsim/mgmpe/m9_basin_term_test.py index 49a01ccfc292..2556bd642c6a 100644 --- a/openquake/hazardlib/tests/gsim/mgmpe/m9_basin_term_test.py +++ b/openquake/hazardlib/tests/gsim/mgmpe/m9_basin_term_test.py @@ -23,7 +23,6 @@ from openquake.hazardlib.imt import PGA, PGV, SA from openquake.hazardlib.const import TRT, IMC from openquake.hazardlib.gsim.mgmpe.m9_basin_term import M9BasinTerm -from openquake.hazardlib.gsim.kuehn_2020 import KuehnEtAl2020SInter ae = np.testing.assert_equal aae = np.testing.assert_almost_equal From 2ed19c1bd62f915901162a9b3753ef6e4ab0b05c Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 4 Nov 2024 17:42:49 +0100 Subject: [PATCH 05/28] upd changelog --- debian/changelog | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/debian/changelog b/debian/changelog index 00499633430f..409b6daad6fe 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,7 @@ + [Christopher Brooks] + * Adding M9 (Seattle) Basin amplification term for ModifiableGMPE + and assoc unit tests + [Michele Simionato] * Internal: changed the ordering in the composite risk model from (loss_type, riskid) -> (riskid, loss_type) From e76cc316bfada34036592d8091ca9f743299f243 Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 5 Nov 2024 11:32:29 +0100 Subject: [PATCH 06/28] req changes --- openquake/hazardlib/gsim/mgmpe/m9_basin_term.py | 4 ++-- openquake/hazardlib/gsim/mgmpe/modifiable_gmpe.py | 4 ++-- .../hazardlib/tests/gsim/mgmpe/m9_basin_term_test.py | 12 ++++-------- 3 files changed, 8 insertions(+), 12 deletions(-) diff --git a/openquake/hazardlib/gsim/mgmpe/m9_basin_term.py b/openquake/hazardlib/gsim/mgmpe/m9_basin_term.py index 21d4eba37532..133f12ed678a 100644 --- a/openquake/hazardlib/gsim/mgmpe/m9_basin_term.py +++ b/openquake/hazardlib/gsim/mgmpe/m9_basin_term.py @@ -24,7 +24,7 @@ from openquake.hazardlib.gsim.base import GMPE, registry -def _get_m9_basin_term(ctx, imt, mean): +def _apply_m9_basin_term(ctx, imt, mean): if imt.period > 1.9: # Only apply to long-period SA fb_m9 = np.log(2.0) idx = ctx.z2pt5 > 6.0 # Apply only if z2pt5 > 6 @@ -76,4 +76,4 @@ def compute(self, ctx: np.recarray, imts, mean, sig, tau, phi): """ self.gmpe.compute(ctx, imts, mean, sig, tau, phi) for m, imt in enumerate(imts): - mean[m] = _get_m9_basin_term(ctx, imt, mean[m]) \ No newline at end of file + mean[m] = _apply_m9_basin_term(ctx, imt, mean[m]) \ No newline at end of file diff --git a/openquake/hazardlib/gsim/mgmpe/modifiable_gmpe.py b/openquake/hazardlib/gsim/mgmpe/modifiable_gmpe.py index 2fd8aa50568d..480768e27c22 100644 --- a/openquake/hazardlib/gsim/mgmpe/modifiable_gmpe.py +++ b/openquake/hazardlib/gsim/mgmpe/modifiable_gmpe.py @@ -28,7 +28,7 @@ NRCan15SiteTerm, BA08_AB06) from openquake.hazardlib.gsim.mgmpe.cy14_site_term import _get_cy14_site_term from openquake.hazardlib.gsim.chiou_youngs_2014 import ChiouYoungs2014 -from openquake.hazardlib.gsim.mgmpe.m9_basin_term import _get_m9_basin_term +from openquake.hazardlib.gsim.mgmpe.m9_basin_term import _apply_m9_basin_term from openquake.hazardlib.gsim.nga_east import ( TAU_EXECUTION, get_phi_ss, TAU_SETUP, PHI_SETUP, get_tau_at_quantile, @@ -82,7 +82,7 @@ def m9_basin_term(ctx, imt, me, si, ta, phi): """ This function adds the M9 basin amplification term """ - me = _get_m9_basin_term(ctx, imt, me) + me = _apply_m9_basin_term(ctx, imt, me) def add_between_within_stds(ctx, imt, me, si, ta, ph, with_betw_ratio): diff --git a/openquake/hazardlib/tests/gsim/mgmpe/m9_basin_term_test.py b/openquake/hazardlib/tests/gsim/mgmpe/m9_basin_term_test.py index 2556bd642c6a..7f773cdbdade 100644 --- a/openquake/hazardlib/tests/gsim/mgmpe/m9_basin_term_test.py +++ b/openquake/hazardlib/tests/gsim/mgmpe/m9_basin_term_test.py @@ -35,20 +35,16 @@ def test_instantiation(self): # Check the assigned IMTs expected = set([PGA, SA, PGV]) - self.assertTrue(mgmpe.DEFINED_FOR_INTENSITY_MEASURE_TYPES == expected, - msg='The assigned IMTs are incorrect') + ae(mgmpe.DEFINED_FOR_INTENSITY_MEASURE_TYPES, expected) # Check the TR expected = TRT.SUBDUCTION_INTERFACE - self.assertTrue(mgmpe.DEFINED_FOR_TECTONIC_REGION_TYPE == expected, - msg='The assigned TRT is incorrect') + ae(mgmpe.DEFINED_FOR_TECTONIC_REGION_TYPE, expected) # Check the IM component expected = IMC.RotD50 - self.assertTrue(mgmpe.DEFINED_FOR_INTENSITY_MEASURE_COMPONENT == - expected, msg='The IM component is wrong') + ae(mgmpe.DEFINED_FOR_INTENSITY_MEASURE_COMPONENT, expected) # Check the required distances expected = {'rrup'} - self.assertTrue(mgmpe.REQUIRES_DISTANCES == expected, - msg='The assigned distance types are wrong') + ae(mgmpe.REQUIRES_DISTANCES, expected) def test_all(self): From 51b3d89164719db110078bfb7760df5dcc1eb3b8 Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 5 Nov 2024 12:15:36 +0100 Subject: [PATCH 07/28] update --- .../hazardlib/gsim/mgmpe/m9_basin_term.py | 20 +++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/openquake/hazardlib/gsim/mgmpe/m9_basin_term.py b/openquake/hazardlib/gsim/mgmpe/m9_basin_term.py index 133f12ed678a..65bd661b33f3 100644 --- a/openquake/hazardlib/gsim/mgmpe/m9_basin_term.py +++ b/openquake/hazardlib/gsim/mgmpe/m9_basin_term.py @@ -25,10 +25,9 @@ def _apply_m9_basin_term(ctx, imt, mean): - if imt.period > 1.9: # Only apply to long-period SA - fb_m9 = np.log(2.0) - idx = ctx.z2pt5 > 6.0 # Apply only if z2pt5 > 6 - mean[idx] += fb_m9 + fb_m9 = np.log(2.0) + idx = ctx.z2pt5 >= 6.0 + mean[idx] += fb_m9 return mean @@ -36,13 +35,14 @@ def _apply_m9_basin_term(ctx, imt, mean): class M9BasinTerm(GMPE): """ Implements a modified GMPE class that can be used to account for basin - amplification of long period ground-motions within the Seattle Basin - through the use of the M9 basin amplification model (Frankel et al. 2018, - Wirth et al. 2018). + amplification of ground-motions within the Seattle Basin through the use + of the M9 basin amplification model. Implementation is as described on + pp. 1178-1179 of the Moschetti et al. 2024 EQ Spectra article for US 2023 + conterminous model GMC. - The amplification of the mean ground-motion is uniformly modelled across - the Seattle Basin as an additive factor of log(2.0) for long period - ground-motions with a z2pt5 greater than 6.0 km. + The amplification of the mean ground-motion is uniformly modelled as an + additive factor of log(2.0) for sites with a z2pt5 greater than or equal + to 6.0 km. :param gmpe_name: The name of a GMPE class From 70a99ed92ec718b17be54355347b123836f9b5f9 Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 5 Nov 2024 13:15:44 +0100 Subject: [PATCH 08/28] fix tests --- .../hazardlib/gsim/mgmpe/m9_basin_term.py | 21 ++++++++++--------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/openquake/hazardlib/gsim/mgmpe/m9_basin_term.py b/openquake/hazardlib/gsim/mgmpe/m9_basin_term.py index 65bd661b33f3..64ec8409bc72 100644 --- a/openquake/hazardlib/gsim/mgmpe/m9_basin_term.py +++ b/openquake/hazardlib/gsim/mgmpe/m9_basin_term.py @@ -25,9 +25,10 @@ def _apply_m9_basin_term(ctx, imt, mean): - fb_m9 = np.log(2.0) - idx = ctx.z2pt5 >= 6.0 - mean[idx] += fb_m9 + if imt.period > 1.9: # Only apply to long-period SA + fb_m9 = np.log(2.0) + idx = ctx.z2pt5 >= 6.0 # Apply only to sites with z2pt5 >= 6 + mean[idx] += fb_m9 return mean @@ -35,14 +36,14 @@ def _apply_m9_basin_term(ctx, imt, mean): class M9BasinTerm(GMPE): """ Implements a modified GMPE class that can be used to account for basin - amplification of ground-motions within the Seattle Basin through the use - of the M9 basin amplification model. Implementation is as described on - pp. 1178-1179 of the Moschetti et al. 2024 EQ Spectra article for US 2023 - conterminous model GMC. + amplification of long period ground-motions within the Seattle Basin + through the use of the M9 basin amplification model as described within + Moschetti et al. (2024) EQ spectra article on conterminous US 2023 NSHM + GMC. - The amplification of the mean ground-motion is uniformly modelled as an - additive factor of log(2.0) for sites with a z2pt5 greater than or equal - to 6.0 km. + The amplification of the mean ground-motion is uniformly modelled across + the Seattle Basin as an additive factor of log(2.0) for long period + ground-motions with a z2pt5 greater than 6.0 km. :param gmpe_name: The name of a GMPE class From 579d1cfb9530f005e9d238f36111d870c78e698e Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 5 Nov 2024 13:32:59 +0100 Subject: [PATCH 09/28] tidying --- openquake/hazardlib/tests/gsim/mgmpe/m9_basin_term_test.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/openquake/hazardlib/tests/gsim/mgmpe/m9_basin_term_test.py b/openquake/hazardlib/tests/gsim/mgmpe/m9_basin_term_test.py index 7f773cdbdade..449c24a4708c 100644 --- a/openquake/hazardlib/tests/gsim/mgmpe/m9_basin_term_test.py +++ b/openquake/hazardlib/tests/gsim/mgmpe/m9_basin_term_test.py @@ -94,12 +94,11 @@ def test_all(self): ae(mea[1], mea[2]) # For SA(2.0) basin amplification should be added - # unmodified + np.log(2.0) ori_sa2pt0 = mea[0][2] cls_sa2pt0 = mea[1][2] val_sa2pt0 = mea[2][2] - exp_diff = np.array([np.log(2.0), 0., np.log(2.0)]) - for idx_v, v in enumerate(exp_diff): + exp_diff = np.array([np.log(2.0), 0., np.log(2.0)]) # Site 1 intensities + for idx_v, v in enumerate(exp_diff): # note be changed diff_cls = cls_sa2pt0[idx_v] - ori_sa2pt0[idx_v] diff_val = val_sa2pt0[idx_v] - ori_sa2pt0[idx_v] aae(diff_cls, exp_diff[idx_v]) From 75b92f4db43596f74528103ce9ac9ae5b9ef8d3f Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 5 Nov 2024 15:22:12 +0100 Subject: [PATCH 10/28] changelog --- debian/changelog | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/debian/changelog b/debian/changelog index 409b6daad6fe..a81c1744c739 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,6 +1,6 @@ [Christopher Brooks] - * Adding M9 (Seattle) Basin amplification term for ModifiableGMPE - and assoc unit tests + * Adding M9 Basin amplification term for ModifiableGMPE + and assoc. unit tests [Michele Simionato] * Internal: changed the ordering in the composite risk model from From 52e71dffdb43bf957ce881f0d420e50d1299ed16 Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 5 Nov 2024 16:52:14 +0100 Subject: [PATCH 11/28] update doctstring --- openquake/hazardlib/gsim/mgmpe/m9_basin_term.py | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/openquake/hazardlib/gsim/mgmpe/m9_basin_term.py b/openquake/hazardlib/gsim/mgmpe/m9_basin_term.py index 64ec8409bc72..b74518abf35c 100644 --- a/openquake/hazardlib/gsim/mgmpe/m9_basin_term.py +++ b/openquake/hazardlib/gsim/mgmpe/m9_basin_term.py @@ -35,15 +35,13 @@ def _apply_m9_basin_term(ctx, imt, mean): class M9BasinTerm(GMPE): """ - Implements a modified GMPE class that can be used to account for basin + Implements a modified GMPE class that can be used to account for amplification of long period ground-motions within the Seattle Basin - through the use of the M9 basin amplification model as described within - Moschetti et al. (2024) EQ spectra article on conterminous US 2023 NSHM - GMC. - - The amplification of the mean ground-motion is uniformly modelled across - the Seattle Basin as an additive factor of log(2.0) for long period - ground-motions with a z2pt5 greater than 6.0 km. + through the use of the M9 project-based basin adjustment term. + + This implementation is based on the description of the M9 adjustment as + provided by the Moschetti et al. (2024) EQ Spectra article on the + conterminous US 2023 NSHM GMC. :param gmpe_name: The name of a GMPE class From 2173ee59c594f8c28691047d140dbe640dd77b77 Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 5 Nov 2024 17:04:01 +0100 Subject: [PATCH 12/28] more docstring refinement --- openquake/hazardlib/gsim/mgmpe/m9_basin_term.py | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/openquake/hazardlib/gsim/mgmpe/m9_basin_term.py b/openquake/hazardlib/gsim/mgmpe/m9_basin_term.py index b74518abf35c..0d1b0da2eebf 100644 --- a/openquake/hazardlib/gsim/mgmpe/m9_basin_term.py +++ b/openquake/hazardlib/gsim/mgmpe/m9_basin_term.py @@ -35,13 +35,12 @@ def _apply_m9_basin_term(ctx, imt, mean): class M9BasinTerm(GMPE): """ - Implements a modified GMPE class that can be used to account for - amplification of long period ground-motions within the Seattle Basin - through the use of the M9 project-based basin adjustment term. + Implements a modified GMPE class that can be used to implement the "M9" + US 2023 NSHM basin amplification adjustment. - This implementation is based on the description of the M9 adjustment as - provided by the Moschetti et al. (2024) EQ Spectra article on the - conterminous US 2023 NSHM GMC. + This implementation is based on the description of the M9 adjustment + within the Moschetti et al. (2024) EQ Spectra article on the conterminous + US 2023 NSHM GMC. :param gmpe_name: The name of a GMPE class From 9fe083d1d8910f6d71854b045a4999dd3854d24a Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 6 Nov 2024 10:27:18 +0100 Subject: [PATCH 13/28] upd --- openquake/hazardlib/gsim/mgmpe/modifiable_gmpe.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openquake/hazardlib/gsim/mgmpe/modifiable_gmpe.py b/openquake/hazardlib/gsim/mgmpe/modifiable_gmpe.py index 480768e27c22..11e1d8d48d9a 100644 --- a/openquake/hazardlib/gsim/mgmpe/modifiable_gmpe.py +++ b/openquake/hazardlib/gsim/mgmpe/modifiable_gmpe.py @@ -80,7 +80,7 @@ def cy14_site_term(ctx, imt, me, si, ta, phi): def m9_basin_term(ctx, imt, me, si, ta, phi): """ - This function adds the M9 basin amplification term + This function applies the M9 basin adjustment """ me = _apply_m9_basin_term(ctx, imt, me) From faeb51a2ce798595385f929f0950d81dc5c1fccd Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 6 Nov 2024 14:31:47 +0100 Subject: [PATCH 14/28] adding AG2020 with m9 basin term --- .../hazardlib/gsim/abrahamson_gulerce_2020.py | 42 ++++++++++++++----- 1 file changed, 31 insertions(+), 11 deletions(-) diff --git a/openquake/hazardlib/gsim/abrahamson_gulerce_2020.py b/openquake/hazardlib/gsim/abrahamson_gulerce_2020.py index 6c922a986ab6..1dd08febdb17 100644 --- a/openquake/hazardlib/gsim/abrahamson_gulerce_2020.py +++ b/openquake/hazardlib/gsim/abrahamson_gulerce_2020.py @@ -25,6 +25,7 @@ from openquake.hazardlib.gsim.base import GMPE, CoeffsTable, add_alias from openquake.hazardlib import const from openquake.hazardlib.imt import PGA, SA +from openquake.hazardlib.gsim.mgmpe.m9_basin_term import _apply_m9_basin_term # The regions for which the model is supported. If not listed then the @@ -312,6 +313,7 @@ def get_basin_depth_scaling(C, region, vs30, z25): # Cascadia Basin (Equation 3.11) idx = ln_z25_prime > 0.0 f_basin[idx] = C["a39"] * ln_z25_prime[idx] + return f_basin @@ -335,7 +337,7 @@ def get_acceleration_on_reference_rock(C, trt, region, ctx, apply_adjustment): get_site_amplification_term(C, region, vs30, null_pga1000)) -def get_mean_acceleration(C, trt, region, ctx, pga1000, apply_adjustment): +def get_mean_acceleration(C, trt, region, ctx, pga1000, apply_adjustment, imt, m9): """ Returns the mean acceleration on soil """ @@ -346,14 +348,28 @@ def get_mean_acceleration(C, trt, region, ctx, pga1000, apply_adjustment): # Basin depths will be ignored, so set zeros z25 = np.zeros(ctx.vs30.shape) - return (get_base_term(C, region, apply_adjustment) + - get_magnitude_scaling_term(C, trt, region, ctx.mag) + - get_geometric_spreading_term(C, region, ctx.mag, ctx.rrup) + - get_anelastic_attenuation_term(C, region, ctx.rrup) + - get_rupture_depth_scaling_term(C, trt, ctx) + - get_inslab_scaling_term(C, trt, region, ctx.mag, ctx.rrup) + - get_site_amplification_term(C, region, ctx.vs30, pga1000) + - get_basin_depth_scaling(C, region, ctx.vs30, z25)) + # First get mean prior to basin amplification + u_gmm = (get_base_term(C, region, apply_adjustment) + + get_magnitude_scaling_term(C, trt, region, ctx.mag) + + get_geometric_spreading_term(C, region, ctx.mag, ctx.rrup) + + get_anelastic_attenuation_term(C, region, ctx.rrup) + + get_rupture_depth_scaling_term(C, trt, ctx) + + get_inslab_scaling_term(C, trt, region, ctx.mag, ctx.rrup) + + get_site_amplification_term(C, region, ctx.vs30, pga1000)) + + # Add basin amplification + f_bas = get_basin_depth_scaling(C, region, ctx.vs30, z25) + means = u_gmm + f_bas + + # If m9 basin adjustment + if m9: + # Applied to basin sites (z2pt5 >= 6 km) for SA with T >= 1.9 s only + means_m9 = _apply_m9_basin_term(ctx, imt, u_gmm) + # And only to sites where means are greater than if using GMM basin amp. + idx = means_m9 > means + means[idx] = means_m9[idx] + + return means def _get_f2(t1, t2, t3, t4, alpha, period): @@ -589,6 +605,8 @@ class AbrahamsonGulerce2020SInter(GMPE): apply_usa_adjustment (bool): Apply the modeller designated Alaska or Cascadia adjustments (available only for the regions "USA-AK" or "CAS") + m9_basin_adjustment (bool): Apply the M9 basin adjustment as defined + for US 2023 interface GMMs sigma_mu_epsilon (float): Number of standard deviations to multiply sigma mu (the standard deviation of the median) for the epistemic uncertainty model @@ -624,13 +642,14 @@ class AbrahamsonGulerce2020SInter(GMPE): DEFINED_FOR_REFERENCE_VELOCITY = 1000.0 def __init__(self, region="GLO", ergodic=True, apply_usa_adjustment=False, - sigma_mu_epsilon=0.0): + m9_basin_adjustment=False, sigma_mu_epsilon=0.0): assert region in SUPPORTED_REGIONS, "Region %s not supported by %s" \ % (region, self.__class__.__name__) self.region = region self.ergodic = ergodic self.apply_usa_adjustment = apply_usa_adjustment self.sigma_mu_epsilon = sigma_mu_epsilon + self.m9_basin_adjustment = m9_basin_adjustment # If running for Cascadia or Japan then z2.5 is needed if region in ("CAS", "JPN"): self.REQUIRES_SITES_PARAMETERS = \ @@ -652,7 +671,8 @@ def compute(self, ctx: np.recarray, imts, mean, sig, tau, phi): for m, imt in enumerate(imts): C = self.COEFFS[imt] mean[m] = get_mean_acceleration(C, trt, self.region, ctx, pga1000, - self.apply_usa_adjustment) + self.apply_usa_adjustment, imt, + self.m9_basin_adjustment) if self.sigma_mu_epsilon: # Apply an epistmic adjustment factor mean[m] += (self.sigma_mu_epsilon * From d29c398f6cfbe3dfcb84b424771d705603cdf4ad Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 6 Nov 2024 14:34:15 +0100 Subject: [PATCH 15/28] update --- openquake/hazardlib/gsim/abrahamson_gulerce_2020.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openquake/hazardlib/gsim/abrahamson_gulerce_2020.py b/openquake/hazardlib/gsim/abrahamson_gulerce_2020.py index 1dd08febdb17..06835edbbfb9 100644 --- a/openquake/hazardlib/gsim/abrahamson_gulerce_2020.py +++ b/openquake/hazardlib/gsim/abrahamson_gulerce_2020.py @@ -367,7 +367,7 @@ def get_mean_acceleration(C, trt, region, ctx, pga1000, apply_adjustment, imt, m means_m9 = _apply_m9_basin_term(ctx, imt, u_gmm) # And only to sites where means are greater than if using GMM basin amp. idx = means_m9 > means - means[idx] = means_m9[idx] + means[idx] = means_m9[idx] # pp. 1178 of Moschetti et al. 2024 EQ Spectra return means From bb72a14774af535ce122aa0381d5f718d29ca8ef Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 6 Nov 2024 14:47:58 +0100 Subject: [PATCH 16/28] update --- debian/changelog | 7 +++++-- openquake/hazardlib/gsim/abrahamson_gulerce_2020.py | 2 +- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/debian/changelog b/debian/changelog index e3f19fbb026d..f4c3fdb646fe 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,8 +1,11 @@ [Christopher Brooks] - * Adding M9 Basin amplification term for ModifiableGMPE + * Added M9 Basin amplification term for ModifiableGMPE and assoc. unit tests - + * Added ability to specify M9 basin term as an argument + within US 2023 NSHM interface GMMs + [Michele Simionato] + * Added command `oq info peril` * Extended consequences to perils * Replaced taxonomy mapping by loss type with taxonomy mapping by peril * Internal: changed the ordering in the composite risk model from diff --git a/openquake/hazardlib/gsim/abrahamson_gulerce_2020.py b/openquake/hazardlib/gsim/abrahamson_gulerce_2020.py index 06835edbbfb9..9c2ea4b334d5 100644 --- a/openquake/hazardlib/gsim/abrahamson_gulerce_2020.py +++ b/openquake/hazardlib/gsim/abrahamson_gulerce_2020.py @@ -367,7 +367,7 @@ def get_mean_acceleration(C, trt, region, ctx, pga1000, apply_adjustment, imt, m means_m9 = _apply_m9_basin_term(ctx, imt, u_gmm) # And only to sites where means are greater than if using GMM basin amp. idx = means_m9 > means - means[idx] = means_m9[idx] # pp. 1178 of Moschetti et al. 2024 EQ Spectra + means[idx] = means_m9[idx] # pp. 1178 of Moschetti et al. 2024 EQ Spec. return means From 9a7d6f63463a9a3846b453155f24cf853e4a8f7a Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 6 Nov 2024 15:18:06 +0100 Subject: [PATCH 17/28] fixing nz22 test --- openquake/hazardlib/gsim/abrahamson_gulerce_2020.py | 3 ++- .../hazardlib/gsim/nz22/nz_nshm2022_abrahamson_gulerce_2020.py | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/openquake/hazardlib/gsim/abrahamson_gulerce_2020.py b/openquake/hazardlib/gsim/abrahamson_gulerce_2020.py index 9c2ea4b334d5..f8e4dd743188 100644 --- a/openquake/hazardlib/gsim/abrahamson_gulerce_2020.py +++ b/openquake/hazardlib/gsim/abrahamson_gulerce_2020.py @@ -337,7 +337,8 @@ def get_acceleration_on_reference_rock(C, trt, region, ctx, apply_adjustment): get_site_amplification_term(C, region, vs30, null_pga1000)) -def get_mean_acceleration(C, trt, region, ctx, pga1000, apply_adjustment, imt, m9): +def get_mean_acceleration(C, trt, region, ctx, pga1000, apply_adjustment, imt, + m9=None): """ Returns the mean acceleration on soil """ diff --git a/openquake/hazardlib/gsim/nz22/nz_nshm2022_abrahamson_gulerce_2020.py b/openquake/hazardlib/gsim/nz22/nz_nshm2022_abrahamson_gulerce_2020.py index 4f0e9244bd46..0dc7aec4f60c 100644 --- a/openquake/hazardlib/gsim/nz22/nz_nshm2022_abrahamson_gulerce_2020.py +++ b/openquake/hazardlib/gsim/nz22/nz_nshm2022_abrahamson_gulerce_2020.py @@ -95,7 +95,7 @@ def get_mean_acceleration_ba( C, trt, region, ctx, pga1000, apply_adjustment, imt ): return get_mean_acceleration( - C, trt, region, ctx, pga1000, apply_adjustment + C, trt, region, ctx, pga1000, apply_adjustment, imt ) + get_backarc_term(trt, imt, ctx) From 68d3e1fb7d71e78bc973e07052957548cdb5416d Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 6 Nov 2024 17:27:59 +0100 Subject: [PATCH 18/28] k20 --- .../hazardlib/gsim/abrahamson_gulerce_2020.py | 8 +-- openquake/hazardlib/gsim/kuehn_2020.py | 49 ++++++++++++++----- .../hazardlib/gsim/mgmpe/m9_basin_term.py | 2 +- 3 files changed, 41 insertions(+), 18 deletions(-) diff --git a/openquake/hazardlib/gsim/abrahamson_gulerce_2020.py b/openquake/hazardlib/gsim/abrahamson_gulerce_2020.py index f8e4dd743188..23ccaefa6a13 100644 --- a/openquake/hazardlib/gsim/abrahamson_gulerce_2020.py +++ b/openquake/hazardlib/gsim/abrahamson_gulerce_2020.py @@ -338,7 +338,7 @@ def get_acceleration_on_reference_rock(C, trt, region, ctx, apply_adjustment): def get_mean_acceleration(C, trt, region, ctx, pga1000, apply_adjustment, imt, - m9=None): + m9): """ Returns the mean acceleration on soil """ @@ -364,11 +364,11 @@ def get_mean_acceleration(C, trt, region, ctx, pga1000, apply_adjustment, imt, # If m9 basin adjustment if m9: - # Applied to basin sites (z2pt5 >= 6 km) for SA with T >= 1.9 s only + # Apply to basin sites for SA with T >= 1.9 s only means_m9 = _apply_m9_basin_term(ctx, imt, u_gmm) - # And only to sites where means are greater than if using GMM basin amp. + # And only when greater than if using GMM basin amp. factor idx = means_m9 > means - means[idx] = means_m9[idx] # pp. 1178 of Moschetti et al. 2024 EQ Spec. + means[idx] = means_m9[idx] return means diff --git a/openquake/hazardlib/gsim/kuehn_2020.py b/openquake/hazardlib/gsim/kuehn_2020.py index 0416ae5f454b..f92804bebfd2 100644 --- a/openquake/hazardlib/gsim/kuehn_2020.py +++ b/openquake/hazardlib/gsim/kuehn_2020.py @@ -42,6 +42,7 @@ from openquake.hazardlib.gsim.base import GMPE, CoeffsTable, add_alias from openquake.hazardlib import const from openquake.hazardlib.imt import PGA, PGV, SA +from openquake.hazardlib.gsim.mgmpe.m9_basin_term import _apply_m9_basin_term # Path to the within-model epistemic adjustment tables @@ -426,7 +427,7 @@ def get_basin_response_term(C, region, vs30, z_value): return brt -def get_mean_values(C, region, trt, m_b, ctx, a1100=None): +def get_mean_values(C, region, trt, m_b, ctx, a1100=None, imt=None, m9=None): """ Returns the mean ground values for a specific IMT @@ -448,24 +449,36 @@ def get_mean_values(C, region, trt, m_b, ctx, a1100=None): else: z_values = np.zeros(vs30.shape) # Get the mean ground motions - mean = (get_base_term(C, trt, region) + - get_magnitude_scaling_term(C, trt, m_b, ctx.mag) + - get_geometric_attenuation_term(C, trt, ctx.mag, ctx.rrup) + - get_anelastic_attenuation_term(C, trt, region, ctx.rrup) + - get_depth_term(C, trt, ctx.ztor) + - get_shallow_site_response_term(C, region, vs30, a1100)) + u_gmm = (get_base_term(C, trt, region) + + get_magnitude_scaling_term(C, trt, m_b, ctx.mag) + + get_geometric_attenuation_term(C, trt, ctx.mag, ctx.rrup) + + get_anelastic_attenuation_term(C, trt, region, ctx.rrup) + + get_depth_term(C, trt, ctx.ztor) + + get_shallow_site_response_term(C, region, vs30, a1100)) # For Cascadia, Japan, New Zealand and Taiwan a basin depth term # is included if region in ("CAS", "JPN"): + # m9 adjustment only applicable for Cascadia region (Seattle Basin) + if region == "JPN" and m9: + raise ValueError("M9 basin adjustment is only for Cascadia region") # For Cascadia and Japan Z2.5 is used as the basin parameter (in m # rather than km) - mean += get_basin_response_term(C, region, vs30, z_values) + mean = u_gmm + get_basin_response_term(C, region, vs30, z_values) + # If m9 adjustment + if m9: + # Apply to basin sites for SA with T >= 1.9 s only + mean_m9 = _apply_m9_basin_term(ctx, imt, u_gmm) + # And only when greater than if using GMM basin amp. factor + idx = mean_m9 > mean + mean[idx] = mean_m9[idx] + elif region in ("NZL", "TWN"): # For New Zealand and Taiwan Z1.0 (m) is used as the basin parameter - mean += get_basin_response_term(C, region, vs30, z_values) + mean = u_gmm + get_basin_response_term(C, region, vs30, z_values) else: - pass + mean = u_gmm # No basin term added if region is global + return mean @@ -629,6 +642,9 @@ class KuehnEtAl2020SInter(GMPE): m_b: The magnitude scaling breakpoint. This term is defined for each region and tectonic region type, but this can also be over-ridden by the user + m9_basin_adjustment (bool): Apply the M9 basin adjustment as defined + for US 2023 interface GMMs + sigma_mu_epsilon: Within-model epistemic uncertainty (sigma_mu) is described in Chapter 6 of the report by the authors. This uncertainty is region specific and is described by a @@ -670,7 +686,8 @@ class KuehnEtAl2020SInter(GMPE): #: Defined for a reference velocity of 1100 m/s DEFINED_FOR_REFERENCE_VELOCITY = 1100.0 - def __init__(self, region="GLO", m_b=None, sigma_mu_epsilon=0.0): + def __init__(self, region="GLO", m_b=None, m9_basin_adjustment=False, + sigma_mu_epsilon=0.0): # Check that if a region is input that it is one of the ones # supported by the model assert region in SUPPORTED_REGIONS, "Region %s not defined for %s" %\ @@ -688,7 +705,12 @@ def __init__(self, region="GLO", m_b=None, sigma_mu_epsilon=0.0): else: pass + # Mag-scaling breakpoint self.m_b = m_b + + # M9 basin adjustment + self.m9_basin_adjustment = m9_basin_adjustment + # epsilon for epistemic uncertainty self.sigma_mu_epsilon = sigma_mu_epsilon if self.sigma_mu_epsilon: @@ -713,11 +735,12 @@ def compute(self, ctx: np.recarray, imts, mean, sig, tau, phi): m_b = REGION_TERMS_IF[self.region]["mb"] \ if trt == const.TRT.SUBDUCTION_INTERFACE else \ REGION_TERMS_SLAB[self.region]["mb"] + m9 = self.m9_basin_adjustment C_PGA = self.COEFFS[PGA()] # Get PGA on rock pga1100 = np.exp(get_mean_values( - C_PGA, self.region, trt, m_b, ctx, None)) + C_PGA, self.region, trt, m_b, ctx)) # For PGA and SA ( T <= 0.1 ) we need to define PGA on soil to # ensure that SA ( T ) does not fall below PGA on soil pga_soil = None @@ -745,7 +768,7 @@ def compute(self, ctx: np.recarray, imts, mean, sig, tau, phi): else: # For PGV and Sa (T > 0.1 s) mean[m] = get_mean_values(C, self.region, trt, m_break, - ctx, pga1100) + ctx, pga1100, imt, m9) # Apply the sigma mu adjustment if necessary if self.sigma_mu_epsilon: sigma_mu_adjust = get_sigma_mu_adjustment( diff --git a/openquake/hazardlib/gsim/mgmpe/m9_basin_term.py b/openquake/hazardlib/gsim/mgmpe/m9_basin_term.py index 0d1b0da2eebf..1e146ec1a315 100644 --- a/openquake/hazardlib/gsim/mgmpe/m9_basin_term.py +++ b/openquake/hazardlib/gsim/mgmpe/m9_basin_term.py @@ -29,7 +29,7 @@ def _apply_m9_basin_term(ctx, imt, mean): fb_m9 = np.log(2.0) idx = ctx.z2pt5 >= 6.0 # Apply only to sites with z2pt5 >= 6 mean[idx] += fb_m9 - + return mean From c20d19066a04dcca37cafae591f290cd16bc63e8 Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 6 Nov 2024 18:31:36 +0100 Subject: [PATCH 19/28] p20 --- .../hazardlib/gsim/abrahamson_gulerce_2020.py | 2 +- openquake/hazardlib/gsim/kuehn_2020.py | 2 +- openquake/hazardlib/gsim/parker_2020.py | 18 +++++++++++++++--- 3 files changed, 17 insertions(+), 5 deletions(-) diff --git a/openquake/hazardlib/gsim/abrahamson_gulerce_2020.py b/openquake/hazardlib/gsim/abrahamson_gulerce_2020.py index 23ccaefa6a13..a2e12fb1012c 100644 --- a/openquake/hazardlib/gsim/abrahamson_gulerce_2020.py +++ b/openquake/hazardlib/gsim/abrahamson_gulerce_2020.py @@ -362,7 +362,7 @@ def get_mean_acceleration(C, trt, region, ctx, pga1000, apply_adjustment, imt, f_bas = get_basin_depth_scaling(C, region, ctx.vs30, z25) means = u_gmm + f_bas - # If m9 basin adjustment + # If M9 basin adjustment if m9: # Apply to basin sites for SA with T >= 1.9 s only means_m9 = _apply_m9_basin_term(ctx, imt, u_gmm) diff --git a/openquake/hazardlib/gsim/kuehn_2020.py b/openquake/hazardlib/gsim/kuehn_2020.py index f92804bebfd2..93bf19ca1a20 100644 --- a/openquake/hazardlib/gsim/kuehn_2020.py +++ b/openquake/hazardlib/gsim/kuehn_2020.py @@ -465,7 +465,7 @@ def get_mean_values(C, region, trt, m_b, ctx, a1100=None, imt=None, m9=None): # For Cascadia and Japan Z2.5 is used as the basin parameter (in m # rather than km) mean = u_gmm + get_basin_response_term(C, region, vs30, z_values) - # If m9 adjustment + # If M9 adjustment specified if m9: # Apply to basin sites for SA with T >= 1.9 s only mean_m9 = _apply_m9_basin_term(ctx, imt, u_gmm) diff --git a/openquake/hazardlib/gsim/parker_2020.py b/openquake/hazardlib/gsim/parker_2020.py index 6fc22e33cb34..24a81f7be5d9 100644 --- a/openquake/hazardlib/gsim/parker_2020.py +++ b/openquake/hazardlib/gsim/parker_2020.py @@ -31,6 +31,7 @@ from openquake.hazardlib import const from openquake.hazardlib.gsim.base import GMPE, CoeffsTable, add_alias from openquake.hazardlib.imt import PGA, SA, PGV +from openquake.hazardlib.gsim.mgmpe.m9_basin_term import _apply_m9_basin_term CONSTANTS = {"b4": 0.1, "f3": 0.05, "Vb": 200, "vref_fnl": 760, "V1": 270, "vref": 760} @@ -311,7 +312,6 @@ class ParkerEtAl2020SInter(GMPE): """ Implements Parker et al. (2020) for subduction interface. """ - DEFINED_FOR_TECTONIC_REGION_TYPE = const.TRT.SUBDUCTION_INTERFACE #: Supported intensity measure types are spectral acceleration, @@ -335,7 +335,8 @@ class ParkerEtAl2020SInter(GMPE): REQUIRES_DISTANCES = {'rrup'} REQUIRES_ATTRIBUTES = {'region', 'saturation_region', 'basin'} - def __init__(self, region=None, saturation_region=None, basin=None): + def __init__(self, region=None, saturation_region=None, basin=None, + m9_basin_adjustment=None): """ Enable setting regions to prevent messy overriding and code duplication. @@ -346,6 +347,7 @@ def __init__(self, region=None, saturation_region=None, basin=None): else: self.saturation_region = saturation_region self.basin = basin + self.m9_basin_adjustment = m9_basin_adjustment def compute(self, ctx: np.recarray, imts, mean, sig, tau, phi): """ @@ -355,6 +357,7 @@ def compute(self, ctx: np.recarray, imts, mean, sig, tau, phi): """ trt = self.DEFINED_FOR_TECTONIC_REGION_TYPE C_PGA = self.COEFFS[PGA()] + m9 = self.m9_basin_adjustment for m, imt in enumerate(imts): C = self.COEFFS[imt] @@ -379,7 +382,16 @@ def compute(self, ctx: np.recarray, imts, mean, sig, tau, phi): # The output is the desired median model prediction in LN units # Take the exponential to get PGA, PSA in g or the PGV in cm/s - mean[m] = fp + fnl + fb + flin + fm + c0 + fd + u_gmm = fp + fnl + flin + fm + c0 + fd + means = u_gmm + fb + # If M9 basin adjustment + if m9: + # Apply to basin sites for SA with T >= 1.9 s only + means_m9 = _apply_m9_basin_term(ctx, imt, u_gmm) + # And only when greater than if using GMM basin amp. factor + idx = means_m9 > means + means[idx] = means_m9[idx] + mean[m] = means sig[m], tau[m], phi[m] = get_stddevs(C, ctx.rrup, ctx.vs30) From 3052e44dd6c2670dad698dd9e1751e4c5d6f509e Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 6 Nov 2024 19:49:29 +0100 Subject: [PATCH 20/28] fix nz22 test for ag20 --- openquake/hazardlib/gsim/abrahamson_gulerce_2020.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openquake/hazardlib/gsim/abrahamson_gulerce_2020.py b/openquake/hazardlib/gsim/abrahamson_gulerce_2020.py index a2e12fb1012c..f33835f316a4 100644 --- a/openquake/hazardlib/gsim/abrahamson_gulerce_2020.py +++ b/openquake/hazardlib/gsim/abrahamson_gulerce_2020.py @@ -338,7 +338,7 @@ def get_acceleration_on_reference_rock(C, trt, region, ctx, apply_adjustment): def get_mean_acceleration(C, trt, region, ctx, pga1000, apply_adjustment, imt, - m9): + m9=None): """ Returns the mean acceleration on soil """ From 1f045f7e6788fc9a3764f1b7ea2978fbb8590d10 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 7 Nov 2024 10:03:37 +0100 Subject: [PATCH 21/28] restoring AG2020 --- .../hazardlib/gsim/abrahamson_gulerce_2020.py | 43 +++++-------------- .../nz_nshm2022_abrahamson_gulerce_2020.py | 2 +- 2 files changed, 12 insertions(+), 33 deletions(-) diff --git a/openquake/hazardlib/gsim/abrahamson_gulerce_2020.py b/openquake/hazardlib/gsim/abrahamson_gulerce_2020.py index f33835f316a4..6c922a986ab6 100644 --- a/openquake/hazardlib/gsim/abrahamson_gulerce_2020.py +++ b/openquake/hazardlib/gsim/abrahamson_gulerce_2020.py @@ -25,7 +25,6 @@ from openquake.hazardlib.gsim.base import GMPE, CoeffsTable, add_alias from openquake.hazardlib import const from openquake.hazardlib.imt import PGA, SA -from openquake.hazardlib.gsim.mgmpe.m9_basin_term import _apply_m9_basin_term # The regions for which the model is supported. If not listed then the @@ -313,7 +312,6 @@ def get_basin_depth_scaling(C, region, vs30, z25): # Cascadia Basin (Equation 3.11) idx = ln_z25_prime > 0.0 f_basin[idx] = C["a39"] * ln_z25_prime[idx] - return f_basin @@ -337,8 +335,7 @@ def get_acceleration_on_reference_rock(C, trt, region, ctx, apply_adjustment): get_site_amplification_term(C, region, vs30, null_pga1000)) -def get_mean_acceleration(C, trt, region, ctx, pga1000, apply_adjustment, imt, - m9=None): +def get_mean_acceleration(C, trt, region, ctx, pga1000, apply_adjustment): """ Returns the mean acceleration on soil """ @@ -349,28 +346,14 @@ def get_mean_acceleration(C, trt, region, ctx, pga1000, apply_adjustment, imt, # Basin depths will be ignored, so set zeros z25 = np.zeros(ctx.vs30.shape) - # First get mean prior to basin amplification - u_gmm = (get_base_term(C, region, apply_adjustment) + - get_magnitude_scaling_term(C, trt, region, ctx.mag) + - get_geometric_spreading_term(C, region, ctx.mag, ctx.rrup) + - get_anelastic_attenuation_term(C, region, ctx.rrup) + - get_rupture_depth_scaling_term(C, trt, ctx) + - get_inslab_scaling_term(C, trt, region, ctx.mag, ctx.rrup) + - get_site_amplification_term(C, region, ctx.vs30, pga1000)) - - # Add basin amplification - f_bas = get_basin_depth_scaling(C, region, ctx.vs30, z25) - means = u_gmm + f_bas - - # If M9 basin adjustment - if m9: - # Apply to basin sites for SA with T >= 1.9 s only - means_m9 = _apply_m9_basin_term(ctx, imt, u_gmm) - # And only when greater than if using GMM basin amp. factor - idx = means_m9 > means - means[idx] = means_m9[idx] - - return means + return (get_base_term(C, region, apply_adjustment) + + get_magnitude_scaling_term(C, trt, region, ctx.mag) + + get_geometric_spreading_term(C, region, ctx.mag, ctx.rrup) + + get_anelastic_attenuation_term(C, region, ctx.rrup) + + get_rupture_depth_scaling_term(C, trt, ctx) + + get_inslab_scaling_term(C, trt, region, ctx.mag, ctx.rrup) + + get_site_amplification_term(C, region, ctx.vs30, pga1000) + + get_basin_depth_scaling(C, region, ctx.vs30, z25)) def _get_f2(t1, t2, t3, t4, alpha, period): @@ -606,8 +589,6 @@ class AbrahamsonGulerce2020SInter(GMPE): apply_usa_adjustment (bool): Apply the modeller designated Alaska or Cascadia adjustments (available only for the regions "USA-AK" or "CAS") - m9_basin_adjustment (bool): Apply the M9 basin adjustment as defined - for US 2023 interface GMMs sigma_mu_epsilon (float): Number of standard deviations to multiply sigma mu (the standard deviation of the median) for the epistemic uncertainty model @@ -643,14 +624,13 @@ class AbrahamsonGulerce2020SInter(GMPE): DEFINED_FOR_REFERENCE_VELOCITY = 1000.0 def __init__(self, region="GLO", ergodic=True, apply_usa_adjustment=False, - m9_basin_adjustment=False, sigma_mu_epsilon=0.0): + sigma_mu_epsilon=0.0): assert region in SUPPORTED_REGIONS, "Region %s not supported by %s" \ % (region, self.__class__.__name__) self.region = region self.ergodic = ergodic self.apply_usa_adjustment = apply_usa_adjustment self.sigma_mu_epsilon = sigma_mu_epsilon - self.m9_basin_adjustment = m9_basin_adjustment # If running for Cascadia or Japan then z2.5 is needed if region in ("CAS", "JPN"): self.REQUIRES_SITES_PARAMETERS = \ @@ -672,8 +652,7 @@ def compute(self, ctx: np.recarray, imts, mean, sig, tau, phi): for m, imt in enumerate(imts): C = self.COEFFS[imt] mean[m] = get_mean_acceleration(C, trt, self.region, ctx, pga1000, - self.apply_usa_adjustment, imt, - self.m9_basin_adjustment) + self.apply_usa_adjustment) if self.sigma_mu_epsilon: # Apply an epistmic adjustment factor mean[m] += (self.sigma_mu_epsilon * diff --git a/openquake/hazardlib/gsim/nz22/nz_nshm2022_abrahamson_gulerce_2020.py b/openquake/hazardlib/gsim/nz22/nz_nshm2022_abrahamson_gulerce_2020.py index 0dc7aec4f60c..4f0e9244bd46 100644 --- a/openquake/hazardlib/gsim/nz22/nz_nshm2022_abrahamson_gulerce_2020.py +++ b/openquake/hazardlib/gsim/nz22/nz_nshm2022_abrahamson_gulerce_2020.py @@ -95,7 +95,7 @@ def get_mean_acceleration_ba( C, trt, region, ctx, pga1000, apply_adjustment, imt ): return get_mean_acceleration( - C, trt, region, ctx, pga1000, apply_adjustment, imt + C, trt, region, ctx, pga1000, apply_adjustment ) + get_backarc_term(trt, imt, ctx) From 99420b7ce29384d811694c65cf10e80c3eaceff4 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 7 Nov 2024 10:20:47 +0100 Subject: [PATCH 22/28] only permit if interface and has z2pt5 --- openquake/hazardlib/gsim/kuehn_2020.py | 4 ++-- openquake/hazardlib/gsim/parker_2020.py | 9 +++++++-- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/openquake/hazardlib/gsim/kuehn_2020.py b/openquake/hazardlib/gsim/kuehn_2020.py index 93bf19ca1a20..536a4e03df5e 100644 --- a/openquake/hazardlib/gsim/kuehn_2020.py +++ b/openquake/hazardlib/gsim/kuehn_2020.py @@ -465,8 +465,8 @@ def get_mean_values(C, region, trt, m_b, ctx, a1100=None, imt=None, m9=None): # For Cascadia and Japan Z2.5 is used as the basin parameter (in m # rather than km) mean = u_gmm + get_basin_response_term(C, region, vs30, z_values) - # If M9 adjustment specified - if m9: + # If M9 adjustment specified and trt is interface + if m9 and trt == const.TRT.SUBDUCTION_INTERFACE: # Apply to basin sites for SA with T >= 1.9 s only mean_m9 = _apply_m9_basin_term(ctx, imt, u_gmm) # And only when greater than if using GMM basin amp. factor diff --git a/openquake/hazardlib/gsim/parker_2020.py b/openquake/hazardlib/gsim/parker_2020.py index 24a81f7be5d9..08bdc39b60a9 100644 --- a/openquake/hazardlib/gsim/parker_2020.py +++ b/openquake/hazardlib/gsim/parker_2020.py @@ -384,8 +384,13 @@ def compute(self, ctx: np.recarray, imts, mean, sig, tau, phi): # Take the exponential to get PGA, PSA in g or the PGV in cm/s u_gmm = fp + fnl + flin + fm + c0 + fd means = u_gmm + fb - # If M9 basin adjustment - if m9: + # If M9 basin adjustment and trt is interface + if m9 and trt == const.TRT.SUBDUCTION_INTERFACE: + # Can only use with the ParkerEtAl2020SInterB (basin version) + if 'z2pt5' not in self.REQUIRES_SITES_PARAMETERS: + raise ValueError("To apply the M9 adjustment the " + "ParkerEtAl2020SInterB gsim must " + "be selected (uses z2pt5 for basin amp.)") # Apply to basin sites for SA with T >= 1.9 s only means_m9 = _apply_m9_basin_term(ctx, imt, u_gmm) # And only when greater than if using GMM basin amp. factor From 9179feb3b9b3d30539eaf74fa362694e4b065c92 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 7 Nov 2024 14:13:11 +0100 Subject: [PATCH 23/28] restoring k20 and p20 + adding cb14 basin term to mgmpe --- openquake/hazardlib/gsim/kuehn_2020.py | 49 +++-------- .../hazardlib/gsim/mgmpe/cb14_basin_term.py | 85 +++++++++++++++++++ .../hazardlib/gsim/mgmpe/modifiable_gmpe.py | 16 +++- openquake/hazardlib/gsim/parker_2020.py | 23 +---- 4 files changed, 114 insertions(+), 59 deletions(-) create mode 100644 openquake/hazardlib/gsim/mgmpe/cb14_basin_term.py diff --git a/openquake/hazardlib/gsim/kuehn_2020.py b/openquake/hazardlib/gsim/kuehn_2020.py index 536a4e03df5e..0416ae5f454b 100644 --- a/openquake/hazardlib/gsim/kuehn_2020.py +++ b/openquake/hazardlib/gsim/kuehn_2020.py @@ -42,7 +42,6 @@ from openquake.hazardlib.gsim.base import GMPE, CoeffsTable, add_alias from openquake.hazardlib import const from openquake.hazardlib.imt import PGA, PGV, SA -from openquake.hazardlib.gsim.mgmpe.m9_basin_term import _apply_m9_basin_term # Path to the within-model epistemic adjustment tables @@ -427,7 +426,7 @@ def get_basin_response_term(C, region, vs30, z_value): return brt -def get_mean_values(C, region, trt, m_b, ctx, a1100=None, imt=None, m9=None): +def get_mean_values(C, region, trt, m_b, ctx, a1100=None): """ Returns the mean ground values for a specific IMT @@ -449,36 +448,24 @@ def get_mean_values(C, region, trt, m_b, ctx, a1100=None, imt=None, m9=None): else: z_values = np.zeros(vs30.shape) # Get the mean ground motions - u_gmm = (get_base_term(C, trt, region) + - get_magnitude_scaling_term(C, trt, m_b, ctx.mag) + - get_geometric_attenuation_term(C, trt, ctx.mag, ctx.rrup) + - get_anelastic_attenuation_term(C, trt, region, ctx.rrup) + - get_depth_term(C, trt, ctx.ztor) + - get_shallow_site_response_term(C, region, vs30, a1100)) + mean = (get_base_term(C, trt, region) + + get_magnitude_scaling_term(C, trt, m_b, ctx.mag) + + get_geometric_attenuation_term(C, trt, ctx.mag, ctx.rrup) + + get_anelastic_attenuation_term(C, trt, region, ctx.rrup) + + get_depth_term(C, trt, ctx.ztor) + + get_shallow_site_response_term(C, region, vs30, a1100)) # For Cascadia, Japan, New Zealand and Taiwan a basin depth term # is included if region in ("CAS", "JPN"): - # m9 adjustment only applicable for Cascadia region (Seattle Basin) - if region == "JPN" and m9: - raise ValueError("M9 basin adjustment is only for Cascadia region") # For Cascadia and Japan Z2.5 is used as the basin parameter (in m # rather than km) - mean = u_gmm + get_basin_response_term(C, region, vs30, z_values) - # If M9 adjustment specified and trt is interface - if m9 and trt == const.TRT.SUBDUCTION_INTERFACE: - # Apply to basin sites for SA with T >= 1.9 s only - mean_m9 = _apply_m9_basin_term(ctx, imt, u_gmm) - # And only when greater than if using GMM basin amp. factor - idx = mean_m9 > mean - mean[idx] = mean_m9[idx] - + mean += get_basin_response_term(C, region, vs30, z_values) elif region in ("NZL", "TWN"): # For New Zealand and Taiwan Z1.0 (m) is used as the basin parameter - mean = u_gmm + get_basin_response_term(C, region, vs30, z_values) + mean += get_basin_response_term(C, region, vs30, z_values) else: - mean = u_gmm # No basin term added if region is global - + pass return mean @@ -642,9 +629,6 @@ class KuehnEtAl2020SInter(GMPE): m_b: The magnitude scaling breakpoint. This term is defined for each region and tectonic region type, but this can also be over-ridden by the user - m9_basin_adjustment (bool): Apply the M9 basin adjustment as defined - for US 2023 interface GMMs - sigma_mu_epsilon: Within-model epistemic uncertainty (sigma_mu) is described in Chapter 6 of the report by the authors. This uncertainty is region specific and is described by a @@ -686,8 +670,7 @@ class KuehnEtAl2020SInter(GMPE): #: Defined for a reference velocity of 1100 m/s DEFINED_FOR_REFERENCE_VELOCITY = 1100.0 - def __init__(self, region="GLO", m_b=None, m9_basin_adjustment=False, - sigma_mu_epsilon=0.0): + def __init__(self, region="GLO", m_b=None, sigma_mu_epsilon=0.0): # Check that if a region is input that it is one of the ones # supported by the model assert region in SUPPORTED_REGIONS, "Region %s not defined for %s" %\ @@ -705,12 +688,7 @@ def __init__(self, region="GLO", m_b=None, m9_basin_adjustment=False, else: pass - # Mag-scaling breakpoint self.m_b = m_b - - # M9 basin adjustment - self.m9_basin_adjustment = m9_basin_adjustment - # epsilon for epistemic uncertainty self.sigma_mu_epsilon = sigma_mu_epsilon if self.sigma_mu_epsilon: @@ -735,12 +713,11 @@ def compute(self, ctx: np.recarray, imts, mean, sig, tau, phi): m_b = REGION_TERMS_IF[self.region]["mb"] \ if trt == const.TRT.SUBDUCTION_INTERFACE else \ REGION_TERMS_SLAB[self.region]["mb"] - m9 = self.m9_basin_adjustment C_PGA = self.COEFFS[PGA()] # Get PGA on rock pga1100 = np.exp(get_mean_values( - C_PGA, self.region, trt, m_b, ctx)) + C_PGA, self.region, trt, m_b, ctx, None)) # For PGA and SA ( T <= 0.1 ) we need to define PGA on soil to # ensure that SA ( T ) does not fall below PGA on soil pga_soil = None @@ -768,7 +745,7 @@ def compute(self, ctx: np.recarray, imts, mean, sig, tau, phi): else: # For PGV and Sa (T > 0.1 s) mean[m] = get_mean_values(C, self.region, trt, m_break, - ctx, pga1100, imt, m9) + ctx, pga1100) # Apply the sigma mu adjustment if necessary if self.sigma_mu_epsilon: sigma_mu_adjust = get_sigma_mu_adjustment( diff --git a/openquake/hazardlib/gsim/mgmpe/cb14_basin_term.py b/openquake/hazardlib/gsim/mgmpe/cb14_basin_term.py new file mode 100644 index 000000000000..acad2d59e72f --- /dev/null +++ b/openquake/hazardlib/gsim/mgmpe/cb14_basin_term.py @@ -0,0 +1,85 @@ +# The Hazard Library +# Copyright (C) 2012-2023 GEM Foundation +# +# This program 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. +# +# This program 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 this program. If not, see . + +""" +Module :mod:`openquake.hazardlib.mgmpe.cb14_basin_term` implements +:class:`~openquake.hazardlib.mgmpe.CB14BasinTerm` +""" +import numpy as np + +from openquake.hazardlib import const +from openquake.hazardlib.gsim.base import GMPE, registry +from openquake.hazardlib.gsim.campbell_bozorgnia_2014 import CampbellBozorgnia2014 + + +def _get_cb14_basin_term(ctx, C, jpn_flag=False): + """ + Get the basin response term defined in equation 20 of the Campbell and + Bozorgnia (2014) GMM paper. + + Currently the global basin term is provided (i.e. the Japan-regionalised + basin term is for now turned off). + """ + z2pt5 = ctx.z2pt5 + fb = np.zeros(len(z2pt5)) + idx = z2pt5 < 1.0 + fb[idx] = (C["c14"] + C["c15"] * jpn_flag) * (z2pt5[idx] - 1.0) + idx = z2pt5 > 3.0 + fb[idx] = C["c16"] * C["k3"] * np.exp(-0.75) * ( + 1. - np.exp(-0.25 * (z2pt5[idx] - 3.))) + + return fb + + +class CB14BasinTerm(GMPE): + """ + Implements a modified GMPE class that can be used to implement the Campbell + and Bozorgnia (2014) GMM's basin term + + :param gmpe_name: + The name of a GMPE class + """ + # Req Params + REQUIRES_SITES_PARAMETERS = {'z2pt5'} + + # Others are set from underlying GMM + REQUIRES_DISTANCES = set() + REQUIRES_RUPTURE_PARAMETERS = set() + DEFINED_FOR_INTENSITY_MEASURE_COMPONENT = "" + DEFINED_FOR_INTENSITY_MEASURE_TYPES = set() + DEFINED_FOR_STANDARD_DEVIATION_TYPES = {const.StdDev.TOTAL} + DEFINED_FOR_TECTONIC_REGION_TYPE = "" + DEFINED_FOR_REFERENCE_VELOCITY = None + + def __init__(self, gmpe_name, **kwargs): + self.gmpe = registry[gmpe_name]() + self.set_parameters() + + # Need z2pt5 in req site params to ensure in ctx site col + if 'z2pt5' not in self.gmpe.REQUIRES_SITES_PARAMETERS: + self.REQUIRES_SITES_PARAMETERS = frozenset( + self.gmpe.REQUIRES_SITES_PARAMETERS | {'z2pt5'}) + + def compute(self, ctx: np.recarray, imts, mean, sig, tau, phi): + """ + See :meth:`superclass method + <.base.GroundShakingIntensityModel.compute>` + for spec of input and result values. + """ + self.gmpe.compute(ctx, imts, mean, sig, tau, phi) + for m, imt in enumerate(imts): + C = CampbellBozorgnia2014.COEFFS[imt] + mean[m] += _get_cb14_basin_term(ctx, C) \ No newline at end of file diff --git a/openquake/hazardlib/gsim/mgmpe/modifiable_gmpe.py b/openquake/hazardlib/gsim/mgmpe/modifiable_gmpe.py index 11e1d8d48d9a..9d5cf525be6f 100644 --- a/openquake/hazardlib/gsim/mgmpe/modifiable_gmpe.py +++ b/openquake/hazardlib/gsim/mgmpe/modifiable_gmpe.py @@ -28,6 +28,8 @@ NRCan15SiteTerm, BA08_AB06) from openquake.hazardlib.gsim.mgmpe.cy14_site_term import _get_cy14_site_term from openquake.hazardlib.gsim.chiou_youngs_2014 import ChiouYoungs2014 +from openquake.hazardlib.gsim.mgmpe.cb14_basin_term import _get_cb14_basin_term +from openquake.hazardlib.gsim.campbell_bozorgnia_2014 import CampbellBozorgnia2014 from openquake.hazardlib.gsim.mgmpe.m9_basin_term import _apply_m9_basin_term from openquake.hazardlib.gsim.nga_east import ( @@ -74,10 +76,18 @@ def cy14_site_term(ctx, imt, me, si, ta, phi): This function adds the CY14 site term to GMMs requiring it """ C = ChiouYoungs2014.COEFFS[imt] - fa = _get_cy14_site_term(C, ctx.vs30, me) # ref mean must be in natural log + fa = _get_cy14_site_term(C, ctx.vs30, me) # Ref mean must be in natural log me[:] += fa +def cb14_basin_term(ctx, imt, me, si, ta, phi): + """ + This function adds the CB14 basin term to GMMs requiring it. + """ + C = CampbellBozorgnia2014.COEFFS[imt] + me[:] += _get_cb14_basin_term(ctx, C) + + def m9_basin_term(ctx, imt, me, si, ta, phi): """ This function applies the M9 basin adjustment @@ -256,8 +266,8 @@ def __init__(self, **kwargs): setattr(self, 'DEFINED_FOR_STANDARD_DEVIATION_TYPES', {StdDev.TOTAL, StdDev.INTRA_EVENT, StdDev.INTER_EVENT}) - if ('m9_basin_term' in self.params) and ( - 'z2pt5' not in self.gmpe.REQUIRES_SITES_PARAMETERS): + if ('cb14_basin_term' in self.params or 'm9_basin_term' in self.params + ) and ( 'z2pt5' not in self.gmpe.REQUIRES_SITES_PARAMETERS): tmp = list(self.gmpe.REQUIRES_SITES_PARAMETERS) tmp.append('z2pt5') self.gmpe.REQUIRES_SITES_PARAMETERS = frozenset(tmp) diff --git a/openquake/hazardlib/gsim/parker_2020.py b/openquake/hazardlib/gsim/parker_2020.py index 08bdc39b60a9..6fc22e33cb34 100644 --- a/openquake/hazardlib/gsim/parker_2020.py +++ b/openquake/hazardlib/gsim/parker_2020.py @@ -31,7 +31,6 @@ from openquake.hazardlib import const from openquake.hazardlib.gsim.base import GMPE, CoeffsTable, add_alias from openquake.hazardlib.imt import PGA, SA, PGV -from openquake.hazardlib.gsim.mgmpe.m9_basin_term import _apply_m9_basin_term CONSTANTS = {"b4": 0.1, "f3": 0.05, "Vb": 200, "vref_fnl": 760, "V1": 270, "vref": 760} @@ -312,6 +311,7 @@ class ParkerEtAl2020SInter(GMPE): """ Implements Parker et al. (2020) for subduction interface. """ + DEFINED_FOR_TECTONIC_REGION_TYPE = const.TRT.SUBDUCTION_INTERFACE #: Supported intensity measure types are spectral acceleration, @@ -335,8 +335,7 @@ class ParkerEtAl2020SInter(GMPE): REQUIRES_DISTANCES = {'rrup'} REQUIRES_ATTRIBUTES = {'region', 'saturation_region', 'basin'} - def __init__(self, region=None, saturation_region=None, basin=None, - m9_basin_adjustment=None): + def __init__(self, region=None, saturation_region=None, basin=None): """ Enable setting regions to prevent messy overriding and code duplication. @@ -347,7 +346,6 @@ def __init__(self, region=None, saturation_region=None, basin=None, else: self.saturation_region = saturation_region self.basin = basin - self.m9_basin_adjustment = m9_basin_adjustment def compute(self, ctx: np.recarray, imts, mean, sig, tau, phi): """ @@ -357,7 +355,6 @@ def compute(self, ctx: np.recarray, imts, mean, sig, tau, phi): """ trt = self.DEFINED_FOR_TECTONIC_REGION_TYPE C_PGA = self.COEFFS[PGA()] - m9 = self.m9_basin_adjustment for m, imt in enumerate(imts): C = self.COEFFS[imt] @@ -382,21 +379,7 @@ def compute(self, ctx: np.recarray, imts, mean, sig, tau, phi): # The output is the desired median model prediction in LN units # Take the exponential to get PGA, PSA in g or the PGV in cm/s - u_gmm = fp + fnl + flin + fm + c0 + fd - means = u_gmm + fb - # If M9 basin adjustment and trt is interface - if m9 and trt == const.TRT.SUBDUCTION_INTERFACE: - # Can only use with the ParkerEtAl2020SInterB (basin version) - if 'z2pt5' not in self.REQUIRES_SITES_PARAMETERS: - raise ValueError("To apply the M9 adjustment the " - "ParkerEtAl2020SInterB gsim must " - "be selected (uses z2pt5 for basin amp.)") - # Apply to basin sites for SA with T >= 1.9 s only - means_m9 = _apply_m9_basin_term(ctx, imt, u_gmm) - # And only when greater than if using GMM basin amp. factor - idx = means_m9 > means - means[idx] = means_m9[idx] - mean[m] = means + mean[m] = fp + fnl + fb + flin + fm + c0 + fd sig[m], tau[m], phi[m] = get_stddevs(C, ctx.rrup, ctx.vs30) From 5f53a8627957df21ec8b0e82aa75759960599518 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 7 Nov 2024 14:31:36 +0100 Subject: [PATCH 24/28] update changelog --- debian/changelog | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/debian/changelog b/debian/changelog index f4c3fdb646fe..9984069a3f2d 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,8 +1,8 @@ [Christopher Brooks] * Added M9 Basin amplification term for ModifiableGMPE and assoc. unit tests - * Added ability to specify M9 basin term as an argument - within US 2023 NSHM interface GMMs + * Added the CB14 basin amplification term for + ModifiableGMPE and assoc. unit tests [Michele Simionato] * Added command `oq info peril` From d5b7de354538e176996d311d5e500940cfc91e37 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 7 Nov 2024 14:52:17 +0100 Subject: [PATCH 25/28] add cb14 basin term mgmpe test --- .../tests/gsim/mgmpe/cb14_basin_term_test.py | 89 +++++++++++++++++++ 1 file changed, 89 insertions(+) create mode 100644 openquake/hazardlib/tests/gsim/mgmpe/cb14_basin_term_test.py diff --git a/openquake/hazardlib/tests/gsim/mgmpe/cb14_basin_term_test.py b/openquake/hazardlib/tests/gsim/mgmpe/cb14_basin_term_test.py new file mode 100644 index 000000000000..014cc9fd391c --- /dev/null +++ b/openquake/hazardlib/tests/gsim/mgmpe/cb14_basin_term_test.py @@ -0,0 +1,89 @@ +# The Hazard Library +# Copyright (C) 2012-2023 GEM Foundation +# +# This program 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. +# +# This program 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 this program. If not, see . + +import numpy as np +import unittest + +from openquake.hazardlib.tests.gsim.mgmpe.dummy import new_ctx +from openquake.hazardlib.contexts import simple_cmaker +from openquake.hazardlib import valid +from openquake.hazardlib.imt import PGA, PGV, SA +from openquake.hazardlib.const import TRT, IMC +from openquake.hazardlib.gsim.mgmpe.cb14_basin_term import CB14BasinTerm + +ae = np.testing.assert_equal +aae = np.testing.assert_almost_equal + +exp_gmm_origin = np.array([[-1.55067862, -3.8245714 , -5.48623229], + [-2.25723424, -3.72056054, -5.28051045], + [-3.45764676, -4.67077352, -5.84789307]]) + +exp_with_basin = np.array([[-1.35815033, -3.78220564, -5.293704 ], + [-1.86104115, -3.63337845, -4.88431736], + [-3.04727152, -4.58047065, -5.43751783]]) + +class M9BasinTermTestCase(unittest.TestCase): + + def test_instantiation(self): + mgmpe = CB14BasinTerm(gmpe_name='AtkinsonMacias2009') + + # Check the assigned IMTs + expected = set([PGA, SA]) + ae(mgmpe.DEFINED_FOR_INTENSITY_MEASURE_TYPES, expected) + # Check the TR + expected = TRT.SUBDUCTION_INTERFACE + ae(mgmpe.DEFINED_FOR_TECTONIC_REGION_TYPE, expected) + # Check the IM component + expected = IMC.RANDOM_HORIZONTAL + ae(mgmpe.DEFINED_FOR_INTENSITY_MEASURE_COMPONENT, expected) + # Check the required distances + expected = {'rrup'} + ae(mgmpe.REQUIRES_DISTANCES, expected) + + def test_all(self): + """ + Test that the M9 basin term applied to Kuehn et al. (2020) + provides the expected values (using sites with z2pt5 above + and below 6 km threshold and considering SAs with periods + above and below 1.9 s) + """ + am09 = valid.gsim('AtkinsonMacias2009') + + # Make original GMM + gmpe = valid.modified_gsim(am09) + + # Make GMM with basin term using the mgmpe class directly + mgmpe_cls = CB14BasinTerm(gmpe_name='AtkinsonMacias2009') + + # Make GMM with basin term using ModifiableGMPE and kwargs + mgmpe_val = valid.modified_gsim(am09, cb14_basin_term={}) + # Make the ctx + imts = ['PGA', 'SA(1.0)', 'SA(2.0)'] + cmaker = simple_cmaker([gmpe, mgmpe_cls, mgmpe_val], imts) + ctx = new_ctx(cmaker, 3) + ctx.dip = 60. + ctx.rake = 90. + ctx.z1pt0 = np.array([522.32, 516.98, 522.32]) + ctx.z2pt5 = np.array([6.32, 3.53, 6.32]) + ctx.rrup = np.array([50., 200., 500.]) + ctx.vs30 = 1100. + ctx.vs30measured = 1 + mea, _, _, _ = cmaker.get_mean_stds([ctx]) + + # Check expected is observed (original vs modified with basin term) + aae(mea[0], exp_gmm_origin) + aae(mea[1], exp_with_basin) + aae(mea[2], exp_with_basin) \ No newline at end of file From dd366bbbce5cb3173f070728973257aec46905ce Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 7 Nov 2024 14:58:04 +0100 Subject: [PATCH 26/28] remove unused import --- openquake/hazardlib/tests/gsim/mgmpe/cb14_basin_term_test.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openquake/hazardlib/tests/gsim/mgmpe/cb14_basin_term_test.py b/openquake/hazardlib/tests/gsim/mgmpe/cb14_basin_term_test.py index 014cc9fd391c..717343816af2 100644 --- a/openquake/hazardlib/tests/gsim/mgmpe/cb14_basin_term_test.py +++ b/openquake/hazardlib/tests/gsim/mgmpe/cb14_basin_term_test.py @@ -20,7 +20,7 @@ from openquake.hazardlib.tests.gsim.mgmpe.dummy import new_ctx from openquake.hazardlib.contexts import simple_cmaker from openquake.hazardlib import valid -from openquake.hazardlib.imt import PGA, PGV, SA +from openquake.hazardlib.imt import PGA, SA from openquake.hazardlib.const import TRT, IMC from openquake.hazardlib.gsim.mgmpe.cb14_basin_term import CB14BasinTerm From 16ac617e05cff037641e19e434cac2a165614388 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 7 Nov 2024 15:32:03 +0100 Subject: [PATCH 27/28] docstring --- openquake/hazardlib/gsim/mgmpe/m9_basin_term.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openquake/hazardlib/gsim/mgmpe/m9_basin_term.py b/openquake/hazardlib/gsim/mgmpe/m9_basin_term.py index 1e146ec1a315..e2df2291e25a 100644 --- a/openquake/hazardlib/gsim/mgmpe/m9_basin_term.py +++ b/openquake/hazardlib/gsim/mgmpe/m9_basin_term.py @@ -40,7 +40,7 @@ class M9BasinTerm(GMPE): This implementation is based on the description of the M9 adjustment within the Moschetti et al. (2024) EQ Spectra article on the conterminous - US 2023 NSHM GMC. + US 2023 NSHM GMC (pp. 1178). :param gmpe_name: The name of a GMPE class From f0482dd7b9549cae61bec3499a1c18d620ddaec1 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 7 Nov 2024 15:40:41 +0100 Subject: [PATCH 28/28] update changelog --- debian/changelog | 1 - 1 file changed, 1 deletion(-) diff --git a/debian/changelog b/debian/changelog index 9984069a3f2d..8cc52bdefb97 100644 --- a/debian/changelog +++ b/debian/changelog @@ -20,7 +20,6 @@ * Raised an error in case of non-invertible hazard curves, affecting disaggregation and site-specific hazard spectrum calculations * Changed the ruptures.csv exporter to also export the source IDs - * Restricted damage calculations to a single loss type * Added support for consequence=losses for liquefaction and landslides * Added a check for missing secondary perils * Added loss types liquefaction and landslide