diff --git a/src/main/java/gov/usgs/earthquake/nshmp/gmm/CombinedGmm.java b/src/main/java/gov/usgs/earthquake/nshmp/gmm/CombinedGmm.java index b1e300473ec537dcba674fcd941fd6ff65182153..c790609e65dda6a164e0ac5bb044a1b2efda6bd3 100644 --- a/src/main/java/gov/usgs/earthquake/nshmp/gmm/CombinedGmm.java +++ b/src/main/java/gov/usgs/earthquake/nshmp/gmm/CombinedGmm.java @@ -76,12 +76,12 @@ import static gov.usgs.earthquake.nshmp.gmm.Gmm.ZHAO_06_INTERFACE_BASIN_M9; import static gov.usgs.earthquake.nshmp.gmm.Gmm.ZHAO_06_SLAB_BASIN; import java.util.Map; -import java.util.Map.Entry; -import java.util.stream.Collectors; +import java.util.Optional; import gov.usgs.earthquake.nshmp.data.DoubleData; import gov.usgs.earthquake.nshmp.gmm.GmmInput.Constraints; import gov.usgs.earthquake.nshmp.tree.LogicTree; +import gov.usgs.earthquake.nshmp.tree.Trees; /** * Convenience class for combined GMM implementations that compute weight @@ -92,12 +92,11 @@ import gov.usgs.earthquake.nshmp.tree.LogicTree; class CombinedGmm implements GroundMotionModel { private static final String NAME = "Combined: "; - private final Map<Gmm, Double> gmms; + private final LogicTree<GroundMotionModel> gmmTree; private final Imt imt; - /* Supply map of ground motion models initialized to the required IMT. */ private CombinedGmm(Imt imt, Map<Gmm, Double> gmms) { - this.gmms = gmms; + this.gmmTree = GmmUtils.weightMapToInstanceTree(gmms, imt); this.imt = imt; double[] weights = gmms.values().stream() @@ -113,23 +112,10 @@ class CombinedGmm implements GroundMotionModel { @Override public LogicTree<GroundMotion> calc(GmmInput in) { - - LogicTree.Builder<GroundMotion> builder = LogicTree.builder(NAME); - gmms.keySet().forEach(key -> builder.addBranch( - key.name(), - GroundMotions.combine(key.instance(imt).calc(in)), - gmms.get(key))); - return builder.build(); - } - - static Map<Gmm, GroundMotionModel> instancesForImt( - Imt imt, - Map<Gmm, Double> gmms) { - - return gmms.entrySet().stream() - .collect(Collectors.toMap( - Entry::getKey, - entry -> entry.getKey().instance(imt))); + return Trees.transform( + gmmTree, + gmm -> GroundMotions.combine(gmm.calc(in)), + Optional.of(GroundMotions.TREE_NAME)); } /* diff --git a/src/main/java/gov/usgs/earthquake/nshmp/gmm/ConusStableCrust_2014.java b/src/main/java/gov/usgs/earthquake/nshmp/gmm/ConusStableCrust_2014.java new file mode 100644 index 0000000000000000000000000000000000000000..b31893efa2e920744c2cd46b47c409f43e21185c --- /dev/null +++ b/src/main/java/gov/usgs/earthquake/nshmp/gmm/ConusStableCrust_2014.java @@ -0,0 +1,108 @@ +package gov.usgs.earthquake.nshmp.gmm; + +import static gov.usgs.earthquake.nshmp.gmm.Gmm.AB_06_PRIME; +import static gov.usgs.earthquake.nshmp.gmm.Gmm.ATKINSON_08_PRIME; +import static gov.usgs.earthquake.nshmp.gmm.Gmm.CAMPBELL_03; +import static gov.usgs.earthquake.nshmp.gmm.Gmm.FRANKEL_96; +import static gov.usgs.earthquake.nshmp.gmm.Gmm.PEZESHK_11; +import static gov.usgs.earthquake.nshmp.gmm.Gmm.SILVA_02; +import static gov.usgs.earthquake.nshmp.gmm.Gmm.SOMERVILLE_01; +import static gov.usgs.earthquake.nshmp.gmm.Gmm.TORO_97_MW; +import static gov.usgs.earthquake.nshmp.gmm.Gmm.TP_05; + +import java.util.Map; +import java.util.Optional; + +import gov.usgs.earthquake.nshmp.tree.LogicTree; +import gov.usgs.earthquake.nshmp.tree.Trees; + +/** + * Implementation of GMMs for the stable crust used in the 2014 CONUS NSHM. The + * 2014 NSHM included distance-dependent variations in the GMM logic trees. + * Support was removed for this feature with the switch to <i>nshmp-haz-v2</i> + * Because the individual GMMs all produce single branch logic trees of ground + * motion, legacy distance dependence is now supported via wrapping the 2014 + * stable crust GMM logic trees into a single GMM. + * + * @author U.S. Geological Survey + * @see Gmm#CONUS_STABLE_CRUST_2014_FAULT + * @see Gmm#CONUS_STABLE_CRUST_2014_GRID + */ +public class ConusStableCrust_2014 implements GroundMotionModel { + + static final String NAME = "CONUS Stable Crst (2014)"; + + private final LogicTree<GroundMotionModel> gmmTree500; + private final LogicTree<GroundMotionModel> gmmTree1000; + + private final Imt imt; + + ConusStableCrust_2014( + Imt imt, + Map<Gmm, Double> gmms500, + Map<Gmm, Double> gmms1000) { + + this.gmmTree500 = GmmUtils.weightMapToInstanceTree(gmms500, imt); + this.gmmTree1000 = GmmUtils.weightMapToInstanceTree(gmms1000, imt); + this.imt = imt; + } + + @Override + public Imt imt() { + return imt; + } + + @Override + public LogicTree<GroundMotion> calc(GmmInput in) { + return Trees.transform( + (in.rRup <= 500.0) ? gmmTree500 : gmmTree1000, + gmm -> gmm.calc(in).get(0).value(), // we know all GMs are singletons + Optional.empty()); + } + + private static final Map<Gmm, Double> GMMS_FAULT_500_KM = Map.of( + AB_06_PRIME, 0.22, + ATKINSON_08_PRIME, 0.08, + CAMPBELL_03, 0.11, + FRANKEL_96, 0.06, + PEZESHK_11, 0.15, + SILVA_02, 0.06, + SOMERVILLE_01, 0.1, + TP_05, 0.11, + TORO_97_MW, 0.11); + + private static final Map<Gmm, Double> GMMS_GRID_500_KM = Map.of( + AB_06_PRIME, 0.25, + ATKINSON_08_PRIME, 0.08, + CAMPBELL_03, 0.13, + FRANKEL_96, 0.06, + PEZESHK_11, 0.16, + SILVA_02, 0.06, + TP_05, 0.13, + TORO_97_MW, 0.13); + + private static final Map<Gmm, Double> GMMS_1000_KM = Map.of( + AB_06_PRIME, 0.3, + CAMPBELL_03, 0.17, + FRANKEL_96, 0.16, + PEZESHK_11, 0.2, + TP_05, 0.17); + + static final class Fault extends ConusStableCrust_2014 { + + static final String NAME = ConusStableCrust_2014.NAME + " : Fault"; + + Fault(Imt imt) { + super(imt, GMMS_FAULT_500_KM, GMMS_1000_KM); + } + } + + static final class Grid extends ConusStableCrust_2014 { + + static final String NAME = ConusStableCrust_2014.NAME + " : Grid"; + + Grid(Imt imt) { + super(imt, GMMS_GRID_500_KM, GMMS_1000_KM); + } + } +} 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 7717957c9994099caf603f5703c07342821da95c..33b893b1b72d3f3a3d480c425394de8ce937e33d 100644 --- a/src/main/java/gov/usgs/earthquake/nshmp/gmm/Gmm.java +++ b/src/main/java/gov/usgs/earthquake/nshmp/gmm/Gmm.java @@ -967,6 +967,22 @@ public enum Gmm { ToroEtAl_1997.COEFFS_MW, ToroEtAl_1997.CONSTRAINTS), + /* Combined GMMs for CEUS 2014 distance dependence */ + + /** @see ConusStableCrust_2014 */ + CONUS_STABLE_CRUST_2014_FAULT( + ConusStableCrust_2014.Fault.class, + ConusStableCrust_2014.Fault.NAME, + FrankelEtAl_1996.COEFFS, // 7 common periods + FrankelEtAl_1996.CONSTRAINTS), + + /** @see ConusStableCrust_2014 */ + CONUS_STABLE_CRUST_2014_GRID( + ConusStableCrust_2014.Grid.class, + ConusStableCrust_2014.Grid.NAME, + FrankelEtAl_1996.COEFFS, // 7 common periods + FrankelEtAl_1996.CONSTRAINTS), + /* Johnston mag converting flavors of CEUS 2008 */ /** @see AtkinsonBoore_2006 */ diff --git a/src/main/java/gov/usgs/earthquake/nshmp/gmm/GmmUtils.java b/src/main/java/gov/usgs/earthquake/nshmp/gmm/GmmUtils.java index d32b1b01e7885304a8e9ef5fe9cb1b08139e9963..d8e8b76dfb003dace9da329da24f921fbd0ae3e6 100644 --- a/src/main/java/gov/usgs/earthquake/nshmp/gmm/GmmUtils.java +++ b/src/main/java/gov/usgs/earthquake/nshmp/gmm/GmmUtils.java @@ -8,9 +8,12 @@ import static gov.usgs.earthquake.nshmp.gmm.Imt.PGA; import static gov.usgs.earthquake.nshmp.gmm.Imt.SA0P02; import static java.lang.Math.log; +import java.util.Map; + import com.google.common.primitives.Doubles; import gov.usgs.earthquake.nshmp.gmm.GroundMotionTables.GroundMotionTable; +import gov.usgs.earthquake.nshmp.tree.LogicTree; /** * Ground motion model (Gmm) utilities. @@ -18,6 +21,9 @@ import gov.usgs.earthquake.nshmp.gmm.GroundMotionTables.GroundMotionTable; */ public final class GmmUtils { + /* Name for gmm logic tree; same as in Deserialize. */ + private static final String TREE_NAME = "gmm-tree"; + /* * Base-10 to base-e conversion factor commonly used with ground motion lookup * tables that supply log10 instead of natural log values. This conversion @@ -54,6 +60,22 @@ public final class GmmUtils { : (rake >= -135 && rake <= -45) ? NORMAL : STRIKE_SLIP; } + /** + * Convert a map of GMMs and weights to a logic tree of instances for the + * supplied IMT. + */ + static LogicTree<GroundMotionModel> weightMapToInstanceTree( + Map<Gmm, Double> gmms, + Imt imt) { + + LogicTree.EnumBuilder<Gmm, GroundMotionModel> tree = LogicTree.enumBuilder(TREE_NAME); + gmms.entrySet().forEach(e -> tree.addBranch( + e.getKey(), + e.getKey().instance(imt), + e.getValue())); + return tree.build(); + } + /* Derived from z2p5 via mmoschetti's 2018 ngaw2 db regressions */ static final double BASIN_Z1P0_UPPER = 0.3; static final double BASIN_Z1P0_LOWER = 0.5; diff --git a/src/main/java/gov/usgs/earthquake/nshmp/gmm/GroundMotions.java b/src/main/java/gov/usgs/earthquake/nshmp/gmm/GroundMotions.java index 0ce4dc9eb318a1acc047c8d7585e37690026e30c..690fa33ab4f1e863bc98b547c6a056bfda968842 100644 --- a/src/main/java/gov/usgs/earthquake/nshmp/gmm/GroundMotions.java +++ b/src/main/java/gov/usgs/earthquake/nshmp/gmm/GroundMotions.java @@ -80,7 +80,7 @@ public class GroundMotions { return new MultiMeanMultiSigma(μIds, μs, μWts, σIds, σs, σWts); } - private static final String TREE_NAME = "ground-motion-tree"; + static final String TREE_NAME = "ground-motion-tree"; public static final String EPI_LO = "epi-lo"; public static final String EPI_OFF = "epi-off"; public static final String EPI_HI = "epi-hi";