Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improving extensibility of NGA-West2 and NGA-Sub ground-motion model implementations #10011

Closed
baagaard-usgs opened this issue Oct 2, 2024 · 5 comments

Comments

@baagaard-usgs
Copy link

Shortcoming of current implementation

For the 2025 USGS NSHM update for Puerto Rico we are creating local (regional) adjustment to the NGA-West2 (AbrahamsonEtAl2014, BooreEtAl2014, CampbellBozorgnia2014, and ChiouYoungs2014) and NGA-Sub (AbrahamsonGulerce2020, KuehnEtAl2020, and ParkerEtAl2020) ground-motion models. The existing implementations in OQ for the NGA-Sub models account for regional variations with regions hardwired in the code and all of the region-specific coeffients included in a single coefficients table. As a result , it is difficult to extend the implementation to other regions without modifying the existing files. Similar issues will likely come up more frequently as the community moves towards non-ergodic models.

Potential solution

  • Refactor the code for these GMMs so that region-specific parameters and coefficients are set during initialization to eliminate hardcoding region-specific code in the functions computing the GMM terms.
  • Use one coefficients table for the region-independent coefficients and a separate coefficients table for the region-specific coefficients, so that region-specific models provide a small coefficients table with the region-specific vales.
  • I strongly prefer a solution that allows someone to extend a ground-motion model with region-specific coefficients and adjustments by adding a new module/file without modifying any other files.

We are interested in contributing this change in the coming months. We would appreciate comments on whether this general direction makes sense or if you have an alternative approach in mind for making the ground-motion model implementations more extensible.

This is somewhat related to #9894. The ModifiableGMPE approach seems limited because the class includes logic related to the modifications. I strongly prefer that the extension be completely self-contained.

@micheles
Copy link
Contributor

micheles commented Oct 3, 2024

There is nothing forbidding passing the CoeffsTable at instantiation time, i.e. it is possible to override a default table with code like the following:

from openquake.hazardlib import const
from openquake.hazardlib.gsim.base import GMPE
from openquake.hazardlib.imt import PGA, SA
from openquake.hazardlib.gsim.coeffs_table import CoeffsTable

class Example(GMPE):
    DEFINED_FOR_TECTONIC_REGION_TYPE = const.TRT.STABLE_CONTINENTAL
    DEFINED_FOR_INTENSITY_MEASURE_TYPES = {PGA, SA}
    DEFINED_FOR_INTENSITY_MEASURE_COMPONENT = const.IMC.GEOMETRIC_MEAN
    DEFINED_FOR_STANDARD_DEVIATION_TYPES = {const.StdDev.TOTAL}
    REQUIRES_SITES_PARAMETERS = set()
    REQUIRES_RUPTURE_PARAMETERS = {'mag'}
    REQUIRES_DISTANCES = {'rjb'}
    COEFFS = CoeffsTable(sa_damping=5, table="""\
imt a1 a2 a3
PGA 0.1 0.2 0.3
0.01 0.4 0.5 0.6
0.05 0.7 0.8 0.9""")
    def __init__(self, coeffs=None):
        if coeffs is not None:
            self.COEFFS = coeffs


if __name__ == '__main__':
    region_coeffs = CoeffsTable("""
imt a1 a2 a3
PGA 0.11 0.22 0.33
0.01 0.43 0.54 0.66
0.05 0.7 0.8 0.9""")
    example_original = Example()  # default COEFFS
    example_regional = Example(coeffs=region_coeffs)  # overridden COEFFS

It is just a matter of adding a few aliases and introducing a TOML representation for the CoeffsTable.

@baagaard-usgs
Copy link
Author

For a region-specific ground-motion model that needs to override many of the coefficients, your approach works well. This is what I am currently doing. In my case, I am only changing 2-3 out of 20+ coefficients; for the NGA-West2 and NGA-Sub ground-motion models, there are generally only 2-3 region-specific coefficients but 20+ coefficients that are not region-specific. I would rather override just the region-specific coefficients rather than 20+ coefficients when most of the coefficients don't change. This seems like a much cleaner implementation. Additionally, overriding all of the coefficients it makes it difficult for a user of the new region-specific ground-motion model to understand what coefficients were actually changed.

@micheles
Copy link
Contributor

micheles commented Oct 4, 2024

What about

    def __init__(self, coeffs_toml=''):
        if coeffs_toml:
            self.COEFFS = self.COEFFS | CoeffsTable.fromtoml(coeffs_toml)

where coeffs_toml is a string containing the coefficients to update in TOML format? This is possible after #10022. For instance, here is how to create a table updating a single coefficient:

CoeffsTable.fromtoml('''
["SA(0.01)"]
a1 = 0.11
''')

I am working on this idea to refactor the CampbellBozorgnia GMPEs, see #10024.

@baagaard-usgs
Copy link
Author

self.COEFFS = self.COEFFS | CoeffsTable.fromtoml(coeffs_toml)

This looks like an excellent solution!

@micheles micheles added this to the Engine 3.22.0 milestone Oct 5, 2024
@micheles
Copy link
Contributor

micheles commented Oct 5, 2024

I got the CampbellBozorgnia classes working with a few minor tweaks and you can look at those for inspiration (see https://github.com/gem/oq-engine/blob/master/openquake/hazardlib/gsim/campbell_bozorgnia_2014.py#L412)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants