From 7aaee54f66167dbb5074ceb76c1287a97dc61651 Mon Sep 17 00:00:00 2001
From: Peter Powers <pmpowers@usgs.gov>
Date: Thu, 21 Nov 2024 15:34:13 -0700
Subject: [PATCH 1/3] added static gmm weight map to instance logic tree method

---
 .../usgs/earthquake/nshmp/gmm/GmmUtils.java   | 22 +++++++++++++++++++
 1 file changed, 22 insertions(+)

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 d32b1b01..d8e8b76d 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;
-- 
GitLab


From a38116d172e220452372a129513130d0b22e692d Mon Sep 17 00:00:00 2001
From: Peter Powers <pmpowers@usgs.gov>
Date: Thu, 21 Nov 2024 15:35:41 -0700
Subject: [PATCH 2/3] updated combined gmm implementation

---
 .../earthquake/nshmp/gmm/CombinedGmm.java     | 30 +++++--------------
 .../earthquake/nshmp/gmm/GroundMotions.java   |  2 +-
 2 files changed, 9 insertions(+), 23 deletions(-)

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 b1e30047..c790609e 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/GroundMotions.java b/src/main/java/gov/usgs/earthquake/nshmp/gmm/GroundMotions.java
index 0ce4dc9e..690fa33a 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";
-- 
GitLab


From 3f8468926dbb734aba39b481998607ba763ccee0 Mon Sep 17 00:00:00 2001
From: Peter Powers <pmpowers@usgs.gov>
Date: Thu, 21 Nov 2024 16:41:18 -0700
Subject: [PATCH 3/3] added combined 2018 ceus r-dependent gmms

---
 .../nshmp/gmm/ConusStableCrust_2014.java      | 108 ++++++++++++++++++
 .../gov/usgs/earthquake/nshmp/gmm/Gmm.java    |  16 +++
 2 files changed, 124 insertions(+)
 create mode 100644 src/main/java/gov/usgs/earthquake/nshmp/gmm/ConusStableCrust_2014.java

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 00000000..b31893ef
--- /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 7717957c..33b893b1 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 */
-- 
GitLab