From fca41cbaff6e7b369f8c95850a0846cc9e442c81 Mon Sep 17 00:00:00 2001 From: Peter Powers <pmpowers@usgs.gov> Date: Mon, 21 Oct 2024 15:24:20 -0600 Subject: [PATCH] added GMMs for PRVI sensitivities --- .../gov/usgs/earthquake/nshmp/gmm/Gmm.java | 72 ++++ .../nshmp/gmm/UsgsPrviBackbone2025.java | 310 +++++++++++++++--- 2 files changed, 335 insertions(+), 47 deletions(-) diff --git a/src/main/java/gov/usgs/earthquake/nshmp/gmm/Gmm.java b/src/main/java/gov/usgs/earthquake/nshmp/gmm/Gmm.java index fcf7395c..ef81df50 100644 --- a/src/main/java/gov/usgs/earthquake/nshmp/gmm/Gmm.java +++ b/src/main/java/gov/usgs/earthquake/nshmp/gmm/Gmm.java @@ -1307,6 +1307,30 @@ public enum Gmm { UsgsPrviBackbone2025.COEFFS_DATA_ADJUSTMENT, UsgsPrviBackbone2025.ActiveCrust.CONSTRAINTS), + USGS_PRVI_ACTIVE_CRUST_ADJUSTED_NO_EPI_SIGMA_NGA( + UsgsPrviBackbone2025.ActiveCrustAdjustedNoEpiSigmaNga.class, + UsgsPrviBackbone2025.ActiveCrustAdjustedNoEpiSigmaNga.NAME, + UsgsPrviBackbone2025.COEFFS_DATA_ADJUSTMENT, + UsgsPrviBackbone2025.ActiveCrust.CONSTRAINTS), + + USGS_PRVI_ACTIVE_CRUST_SIGMA_NGA( + UsgsPrviBackbone2025.ActiveCrustSigmaNga.class, + UsgsPrviBackbone2025.ActiveCrustSigmaNga.NAME, + UsgsPrviBackbone2025.COEFFS_DATA_ADJUSTMENT, + UsgsPrviBackbone2025.ActiveCrust.CONSTRAINTS), + + USGS_PRVI_ACTIVE_CRUST_NO_EPI_SIGMA_NGA( + UsgsPrviBackbone2025.ActiveCrustNoEpiSigmaNga.class, + UsgsPrviBackbone2025.ActiveCrustNoEpiSigmaNga.NAME, + UsgsPrviBackbone2025.COEFFS_DATA_ADJUSTMENT, + UsgsPrviBackbone2025.ActiveCrust.CONSTRAINTS), + + USGS_PRVI_ACTIVE_CRUST_NO_EPI_SIGMA_PRVI( + UsgsPrviBackbone2025.ActiveCrustNoEpiSigmaPrvi.class, + UsgsPrviBackbone2025.ActiveCrustNoEpiSigmaPrvi.NAME, + UsgsPrviBackbone2025.COEFFS_DATA_ADJUSTMENT, + UsgsPrviBackbone2025.ActiveCrust.CONSTRAINTS), + USGS_PRVI_ACTIVE_CRUST_COMBINED_TREE( UsgsPrviBackbone2025.ActiveCrustTotal.class, UsgsPrviBackbone2025.ActiveCrustTotal.NAME, @@ -1325,6 +1349,30 @@ public enum Gmm { UsgsPrviBackbone2025.COEFFS_DATA_ADJUSTMENT, UsgsPrviBackbone2025.Interface.CONSTRAINTS), + USGS_PRVI_INTERFACE_ADJUSTED_NO_EPI_SIGMA_NGA( + UsgsPrviBackbone2025.InterfaceAdjustedNoEpiSigmaNga.class, + UsgsPrviBackbone2025.InterfaceAdjustedNoEpiSigmaNga.NAME, + UsgsPrviBackbone2025.COEFFS_DATA_ADJUSTMENT, + UsgsPrviBackbone2025.Interface.CONSTRAINTS), + + USGS_PRVI_INTERFACE_SIGMA_NGA( + UsgsPrviBackbone2025.InterfaceSigmaNga.class, + UsgsPrviBackbone2025.InterfaceSigmaNga.NAME, + UsgsPrviBackbone2025.COEFFS_DATA_ADJUSTMENT, + UsgsPrviBackbone2025.Interface.CONSTRAINTS), + + USGS_PRVI_INTERFACE_NO_EPI_SIGMA_NGA( + UsgsPrviBackbone2025.InterfaceNoEpiSigmaNga.class, + UsgsPrviBackbone2025.InterfaceNoEpiSigmaNga.NAME, + UsgsPrviBackbone2025.COEFFS_DATA_ADJUSTMENT, + UsgsPrviBackbone2025.Interface.CONSTRAINTS), + + USGS_PRVI_INTERFACE_NO_EPI_SIGMA_PRVI( + UsgsPrviBackbone2025.InterfaceNoEpiSigmaPrvi.class, + UsgsPrviBackbone2025.InterfaceNoEpiSigmaPrvi.NAME, + UsgsPrviBackbone2025.COEFFS_DATA_ADJUSTMENT, + UsgsPrviBackbone2025.Interface.CONSTRAINTS), + USGS_PRVI_INTERFACE_COMBINED_TREE( UsgsPrviBackbone2025.InterfaceTotal.class, UsgsPrviBackbone2025.InterfaceTotal.NAME, @@ -1343,6 +1391,30 @@ public enum Gmm { UsgsPrviBackbone2025.COEFFS_DATA_ADJUSTMENT, UsgsPrviBackbone2025.Slab.CONSTRAINTS), + USGS_PRVI_INTRASLAB_ADJUSTED_NO_EPI_SIGMA_NGA( + UsgsPrviBackbone2025.SlabAdjustedNoEpiSigmaNga.class, + UsgsPrviBackbone2025.SlabAdjustedNoEpiSigmaNga.NAME, + UsgsPrviBackbone2025.COEFFS_DATA_ADJUSTMENT, + UsgsPrviBackbone2025.Slab.CONSTRAINTS), + + USGS_PRVI_INTRASLAB_SIGMA_NGA( + UsgsPrviBackbone2025.SlabSigmaNga.class, + UsgsPrviBackbone2025.SlabSigmaNga.NAME, + UsgsPrviBackbone2025.COEFFS_DATA_ADJUSTMENT, + UsgsPrviBackbone2025.Slab.CONSTRAINTS), + + USGS_PRVI_INTRASLAB_NO_EPI_SIGMA_NGA( + UsgsPrviBackbone2025.SlabNoEpiSigmaNga.class, + UsgsPrviBackbone2025.SlabNoEpiSigmaNga.NAME, + UsgsPrviBackbone2025.COEFFS_DATA_ADJUSTMENT, + UsgsPrviBackbone2025.Slab.CONSTRAINTS), + + USGS_PRVI_INTRASLAB_NO_EPI_SIGMA_PRVI( + UsgsPrviBackbone2025.SlabNoEpiSigmaPrvi.class, + UsgsPrviBackbone2025.SlabNoEpiSigmaPrvi.NAME, + UsgsPrviBackbone2025.COEFFS_DATA_ADJUSTMENT, + UsgsPrviBackbone2025.Slab.CONSTRAINTS), + USGS_PRVI_INTRASLAB_COMBINED_TREE( UsgsPrviBackbone2025.SlabTotal.class, UsgsPrviBackbone2025.SlabTotal.NAME, diff --git a/src/main/java/gov/usgs/earthquake/nshmp/gmm/UsgsPrviBackbone2025.java b/src/main/java/gov/usgs/earthquake/nshmp/gmm/UsgsPrviBackbone2025.java index bfd23a59..8cb0141e 100644 --- a/src/main/java/gov/usgs/earthquake/nshmp/gmm/UsgsPrviBackbone2025.java +++ b/src/main/java/gov/usgs/earthquake/nshmp/gmm/UsgsPrviBackbone2025.java @@ -1,5 +1,6 @@ package gov.usgs.earthquake.nshmp.gmm; +import static com.google.common.base.Preconditions.checkArgument; import static gov.usgs.earthquake.nshmp.gmm.Gmm.AG_20_GLOBAL_INTERFACE; import static gov.usgs.earthquake.nshmp.gmm.Gmm.AG_20_GLOBAL_SLAB; import static gov.usgs.earthquake.nshmp.gmm.Gmm.ASK_14_BASE; @@ -14,6 +15,8 @@ import static gov.usgs.earthquake.nshmp.gmm.Gmm.Type.ACTIVE_CRUST; import static gov.usgs.earthquake.nshmp.gmm.Gmm.Type.SUBDUCTION_INTERFACE; import static gov.usgs.earthquake.nshmp.gmm.Gmm.Type.SUBDUCTION_SLAB; import static gov.usgs.earthquake.nshmp.gmm.GroundMotionTables.getPrviEpi; +import static gov.usgs.earthquake.nshmp.gmm.GroundMotions.EPI_IDS; +import static gov.usgs.earthquake.nshmp.gmm.GroundMotions.EPI_WTS; import static gov.usgs.earthquake.nshmp.gmm.SubductionZone.Type.INTERFACE; import static gov.usgs.earthquake.nshmp.gmm.SubductionZone.Type.SLAB; import static java.lang.Math.exp; @@ -64,6 +67,9 @@ public abstract class UsgsPrviBackbone2025 implements GroundMotionModel { static final CoefficientContainer COEFFS_DATA_ADJUSTMENT = new CoefficientContainer("prvi-25-backbone-adjustments.csv"); + public static final double DATA_ADJUST_CRUSTAL = -0.3; + public static final double DATA_ADJUST_SUBDUCTION = -0.4; + public static final String MODEL_BASE_ID = "base"; public static final String MODEL_ADJUST_ID = "adjust"; @@ -114,15 +120,18 @@ public abstract class UsgsPrviBackbone2025 implements GroundMotionModel { private final LogicTree<GroundMotionModel> tree; private final Imt imt; private final GroundMotionTable[] epiTables; // 0=lower, 1=upper + private final double dataAdjust; /* Supply map of ground motion models initialized to the required IMT. */ UsgsPrviBackbone2025( Imt imt, String name, Map<Gmm, Double> gmms, - GroundMotionTable[] epiTables) { + GroundMotionTable[] epiTables, + double dataAdjust) { this.imt = imt; this.epiTables = epiTables; + this.dataAdjust = dataAdjust; LogicTree.Builder<GroundMotionModel> b = LogicTree.builder(name); gmms.entrySet().stream().forEach(e -> b.addBranch( e.getKey().name(), @@ -145,18 +154,37 @@ public abstract class UsgsPrviBackbone2025 implements GroundMotionModel { @Override public LogicTree<GroundMotion> calc(GmmInput in) { + return calc(in, true, SigmaType.TREE); + } + + LogicTree<GroundMotion> calc(GmmInput in, boolean epi, SigmaType σType) { + + GroundMotion bgm = calcBackboneGroundMotion(in); + double μ = bgm.mean() + dataAdjust; + double[] σs = calcSigmas(in); // NGA=0, PRVI=1 - double μ = calcMean(in); - double[] μs = applyEpistemic(μ, in.Mw, in.rRup); - double[] σs = calcSigmas(in); + if (epi) { + double[] μs = applyEpistemic(μ, in.Mw, in.rRup); + if (σType == SigmaType.TREE) { + return GroundMotions.createTree( + EPI_IDS, μs, EPI_WTS, + SIGMA_IDS, σs, SIGMA_WTS); + } else { + double σ = (σType == SigmaType.NGA) ? σs[0] : σs[1]; + return GroundMotions.createTree(EPI_IDS, μs, EPI_WTS, σ); + } + } - return GroundMotions.createTree( - GroundMotions.EPI_IDS, μs, GroundMotions.EPI_WTS, - SIGMA_IDS, σs, SIGMA_WTS); + // single mean with multi sigma not supported + checkArgument(σType != SigmaType.TREE); + double σ = (σType == SigmaType.NGA) ? σs[0] : σs[1]; + return GroundMotions.createTree(μ, σ); } - double calcMean(GmmInput in) { + /* Compute backbone ground motions. */ + GroundMotion calcBackboneGroundMotion(GmmInput in) { double median = 0.0; + double sigmaSq = 0.0; for (Branch<GroundMotionModel> b : tree) { // NGA GMMs currently returning mix of singleton trees and epi branches // TODO would be preferable to get the mean directly w/o epi branches @@ -165,8 +193,10 @@ public abstract class UsgsPrviBackbone2025 implements GroundMotionModel { ? gmTree.get(0).value() : gmTree.get(1).value(); median += exp(gm.mean()) * b.weight(); + sigmaSq += gm.sigma() * gm.sigma() * b.weight(); } - return log(median); + return GroundMotion.create(log(median), sqrt(sigmaSq)); + } double[] applyEpistemic(double μ, double Mw, double rRup) { @@ -175,6 +205,12 @@ public abstract class UsgsPrviBackbone2025 implements GroundMotionModel { return new double[] { μ + εLo, μ, μ + εHi }; } + static enum SigmaType { + NGA, + PRVI, + TREE; + } + abstract double[] calcSigmas(GmmInput in); /* @@ -196,11 +232,11 @@ public abstract class UsgsPrviBackbone2025 implements GroundMotionModel { CY_14_BASE, 0.25); ActiveCrust(Imt imt) { - this(imt, NAME); + this(imt, NAME, 0.0); } - ActiveCrust(Imt imt, String name) { - super(imt, name, GMM_MAP, getPrviEpi(ACTIVE_CRUST, imt)); + ActiveCrust(Imt imt, String name, double dataAdjust) { + super(imt, name, GMM_MAP, getPrviEpi(ACTIVE_CRUST, imt), dataAdjust); } @Override @@ -234,26 +270,86 @@ public abstract class UsgsPrviBackbone2025 implements GroundMotionModel { } } - /* PRVI 2025 Active Crust Data Adjusted */ + /* PRVI 2025 Active Crust - sigma NGA */ + @Deprecated + static final class ActiveCrustSigmaNga extends ActiveCrust { + + static final String NAME = ActiveCrust.NAME + " (NGA sigma)"; + + ActiveCrustSigmaNga(Imt imt) { + super(imt, NAME, 0.0); + } + + @Override + public LogicTree<GroundMotion> calc(GmmInput in) { + return calc(in, true, SigmaType.NGA); + } + } + + /* PRVI 2025 Active Crust - data adjusted */ static final class ActiveCrustAdjusted extends ActiveCrust { static final String NAME = ActiveCrust.NAME + " (adjusted)"; - final double bias; - ActiveCrustAdjusted(Imt imt) { - super(imt, NAME); - // bias = COEFFS_DATA_ADJUSTMENT.get(imt, "active_crust"); - bias = -0.3; + super(imt, NAME, DATA_ADJUST_CRUSTAL); + } + + @Override + public LogicTree<GroundMotion> calc(GmmInput in) { + return calc(in, true, SigmaType.TREE); + } + } + + /* PRVI 2025 Active Crust - data adjusted, no epi, sigma NGA */ + @Deprecated + static final class ActiveCrustAdjustedNoEpiSigmaNga extends ActiveCrust { + + static final String NAME = ActiveCrust.NAME + " (adjusted, no epi, NGA sigma)"; + + ActiveCrustAdjustedNoEpiSigmaNga(Imt imt) { + super(imt, NAME, DATA_ADJUST_CRUSTAL); + } + + @Override + public LogicTree<GroundMotion> calc(GmmInput in) { + return calc(in, false, SigmaType.NGA); + } + } + + /* PRVI 2025 Active Crust - no epi, sigma NGA */ + @Deprecated + static final class ActiveCrustNoEpiSigmaNga extends ActiveCrust { + + static final String NAME = ActiveCrust.NAME + " (no epi, NGA sigma)"; + + ActiveCrustNoEpiSigmaNga(Imt imt) { + super(imt, NAME, 0.0); } @Override - double calcMean(GmmInput in) { - return super.calcMean(in) + bias; + public LogicTree<GroundMotion> calc(GmmInput in) { + return calc(in, false, SigmaType.NGA); } } - /* TODO Deprecate */ + /* PRVI 2025 Active Crust - no epi, sigma PRVI */ + @Deprecated + static final class ActiveCrustNoEpiSigmaPrvi extends ActiveCrust { + + static final String NAME = ActiveCrust.NAME + " (no epi, PRVI sigma)"; + + ActiveCrustNoEpiSigmaPrvi(Imt imt) { + super(imt, NAME, 0.0); + } + + @Override + public LogicTree<GroundMotion> calc(GmmInput in) { + return calc(in, false, SigmaType.PRVI); + } + } + + @Deprecated static final class ActiveCrustTotal implements GroundMotionModel { static final String NAME = ActiveCrust.NAME + " (total tree)"; static final Constraints CONSTRAINTS = AbrahamsonEtAl_2014.CONSTRAINTS; @@ -281,7 +377,7 @@ public abstract class UsgsPrviBackbone2025 implements GroundMotionModel { } } - /* PRVI 2025 Subduction Interface */ + /* PRVI 2025 Interface */ static class Interface extends UsgsPrviBackbone2025 { static final String NAME = UsgsPrviBackbone2025.NAME + " : " + INTERFACE; @@ -293,11 +389,11 @@ public abstract class UsgsPrviBackbone2025 implements GroundMotionModel { PSBAH_20_GLOBAL_INTERFACE, 0.3334); Interface(Imt imt) { - this(imt, NAME); + this(imt, NAME, 0.0); } - Interface(Imt imt, String name) { - super(imt, name, GMM_MAP, getPrviEpi(SUBDUCTION_INTERFACE, imt)); + Interface(Imt imt, String name, double dataAdjust) { + super(imt, name, GMM_MAP, getPrviEpi(SUBDUCTION_INTERFACE, imt), dataAdjust); } @@ -310,26 +406,86 @@ public abstract class UsgsPrviBackbone2025 implements GroundMotionModel { } } - /* PRVI 2025 Interface Data Adjusted */ + /* PRVI 2025 Interface - NGA sigma */ + @Deprecated + static final class InterfaceSigmaNga extends Interface { + + static final String NAME = Interface.NAME + " (NGA sigma)"; + + InterfaceSigmaNga(Imt imt) { + super(imt, NAME, 0.0); + } + + @Override + public LogicTree<GroundMotion> calc(GmmInput in) { + return calc(in, true, SigmaType.NGA); + } + } + + /* PRVI 2025 Interface - data adjusted */ static final class InterfaceAdjusted extends Interface { static final String NAME = Interface.NAME + " (adjusted)"; - final double bias; - InterfaceAdjusted(Imt imt) { - super(imt, NAME); - // bias = COEFFS_DATA_ADJUSTMENT.get(imt, "interface"); - bias = -0.4; + super(imt, NAME, DATA_ADJUST_SUBDUCTION); + } + + @Override + public LogicTree<GroundMotion> calc(GmmInput in) { + return calc(in, true, SigmaType.TREE); + } + } + + /* PRVI 2025 Interface - data adjusted, no epi, NGA sigma */ + @Deprecated + static final class InterfaceAdjustedNoEpiSigmaNga extends Interface { + + static final String NAME = Interface.NAME + " (adjusted, no epi, NGA sigma)"; + + InterfaceAdjustedNoEpiSigmaNga(Imt imt) { + super(imt, NAME, DATA_ADJUST_SUBDUCTION); + } + + @Override + public LogicTree<GroundMotion> calc(GmmInput in) { + return calc(in, false, SigmaType.NGA); + } + } + + /* PRVI 2025 Interface - no epi, NGA sigma */ + @Deprecated + static final class InterfaceNoEpiSigmaNga extends Interface { + + static final String NAME = Interface.NAME + " (no epi, NGA sigma)"; + + InterfaceNoEpiSigmaNga(Imt imt) { + super(imt, NAME, 0.0); } @Override - double calcMean(GmmInput in) { - return super.calcMean(in) + bias; + public LogicTree<GroundMotion> calc(GmmInput in) { + return calc(in, false, SigmaType.NGA); } } - /* TODO Deprecate */ + /* PRVI 2025 Interface - no epi, PRVI sigma */ + @Deprecated + static final class InterfaceNoEpiSigmaPrvi extends Interface { + + static final String NAME = Interface.NAME + " (no epi, PRVI sigma)"; + + InterfaceNoEpiSigmaPrvi(Imt imt) { + super(imt, NAME, 0.0); + } + + @Override + public LogicTree<GroundMotion> calc(GmmInput in) { + return calc(in, false, SigmaType.PRVI); + } + } + + @Deprecated static final class InterfaceTotal implements GroundMotionModel { static final String NAME = Interface.NAME + " (total tree)"; static final Constraints CONSTRAINTS = AbrahamsonGulerce_2020.CONSTRAINTS_INTERFACE; @@ -357,7 +513,7 @@ public abstract class UsgsPrviBackbone2025 implements GroundMotionModel { } } - /* PRVI 2025 Subduction Intraslab */ + /* PRVI 2025 Intraslab */ static class Slab extends UsgsPrviBackbone2025 { static final String NAME = UsgsPrviBackbone2025.NAME + " : " + SLAB; @@ -369,11 +525,11 @@ public abstract class UsgsPrviBackbone2025 implements GroundMotionModel { PSBAH_20_GLOBAL_SLAB, 0.3334); Slab(Imt imt) { - this(imt, NAME); + this(imt, NAME, 0.0); } - Slab(Imt imt, String name) { - super(imt, name, GMM_MAP, getPrviEpi(SUBDUCTION_SLAB, imt)); + Slab(Imt imt, String name, double dataAdjust) { + super(imt, name, GMM_MAP, getPrviEpi(SUBDUCTION_SLAB, imt), dataAdjust); } @Override @@ -385,26 +541,86 @@ public abstract class UsgsPrviBackbone2025 implements GroundMotionModel { } } - /* PRVI 2025 Interface Data Adjusted */ + /* PRVI 2025 Intraslab - NGA sigma */ + @Deprecated + static final class SlabSigmaNga extends Slab { + + static final String NAME = Slab.NAME + " (NGA sigma)"; + + SlabSigmaNga(Imt imt) { + super(imt, NAME, 0.0); + } + + @Override + public LogicTree<GroundMotion> calc(GmmInput in) { + return calc(in, true, SigmaType.TREE); + } + } + + /* PRVI 2025 Intraslab - data adjusted */ static final class SlabAdjusted extends Slab { static final String NAME = Slab.NAME + " (adjusted)"; - final double bias; - SlabAdjusted(Imt imt) { - super(imt, NAME); - // bias = COEFFS_DATA_ADJUSTMENT.get(imt, "intraslab"); - bias = -0.4; + super(imt, NAME, DATA_ADJUST_SUBDUCTION); + } + + @Override + public LogicTree<GroundMotion> calc(GmmInput in) { + return calc(in, true, SigmaType.TREE); + } + } + + /* PRVI 2025 Intraslab - data adjusted, no epi, NGA sigma */ + @Deprecated + static final class SlabAdjustedNoEpiSigmaNga extends Slab { + + static final String NAME = Slab.NAME + " (adjusted, no epi, NGA sigma)"; + + SlabAdjustedNoEpiSigmaNga(Imt imt) { + super(imt, NAME, DATA_ADJUST_SUBDUCTION); } @Override - double calcMean(GmmInput in) { - return super.calcMean(in) + bias; + public LogicTree<GroundMotion> calc(GmmInput in) { + return calc(in, false, SigmaType.NGA); + } + } + + /* PRVI 2025 Intraslab - no epi, NGA sigma */ + @Deprecated + static final class SlabNoEpiSigmaNga extends Slab { + + static final String NAME = Slab.NAME + " (no epi, NGA sigma)"; + + SlabNoEpiSigmaNga(Imt imt) { + super(imt, NAME, 0.0); + } + + @Override + public LogicTree<GroundMotion> calc(GmmInput in) { + return calc(in, false, SigmaType.NGA); + } + } + + /* PRVI 2025 Intraslab - no epi, PRVI sigma */ + @Deprecated + static final class SlabNoEpiSigmaPrvi extends Slab { + + static final String NAME = Slab.NAME + " (no epi, PRVI sigma)"; + + SlabNoEpiSigmaPrvi(Imt imt) { + super(imt, NAME, 0.0); + } + + @Override + public LogicTree<GroundMotion> calc(GmmInput in) { + return calc(in, false, SigmaType.PRVI); } } - /* TODO Deprecate */ + @Deprecated static final class SlabTotal implements GroundMotionModel { static final String NAME = Slab.NAME + " (total tree)"; static final Constraints CONSTRAINTS = AbrahamsonGulerce_2020.CONSTRAINTS_SLAB; -- GitLab