diff --git a/src/main/java/gov/usgs/earthquake/nshmp/gmm/ChapmanGuo_2021.java b/src/main/java/gov/usgs/earthquake/nshmp/gmm/ChapmanGuo_2021.java
index 1ad3e040fa76df06303f99315c473f04f6309cda..bc4ddc13426fcc495cd113f091db9f80eb9d202d 100644
--- a/src/main/java/gov/usgs/earthquake/nshmp/gmm/ChapmanGuo_2021.java
+++ b/src/main/java/gov/usgs/earthquake/nshmp/gmm/ChapmanGuo_2021.java
@@ -14,18 +14,16 @@ import java.util.Map;
 import com.google.common.io.Resources;
 
 /**
- * Implementation support for Guo & Chapman (2019) gulf coastal plain
+ * Implementation support for Chapman & Guo (2021) Gulf coastal plain
  * spectral ratio amplification model. This class is not a GMM, it provides
- * utility methods lookup spectral ratios based on sediment depth, source
+ * utility methods to lookup spectral ratios based on sediment depth, source
  * magnitude, and epicentral distance.
  *
  * <p><b>Reference:</b> Chapman, M.C. and Guo, Z., 2021, A response spectral
  * ratio model to account for amplification and attenuation effects in the
  * Atlantic and Gulf coastal plain: Bulletin of the Seismological Society of
- * America, v. 111, n. 4, p. 1849-1867. doi: https://doi.org/10.1785/0120200322
- *
- * <p><b>doi:</b><a href="https://doi.org/10.1785/0120200322">
- * 10.1785/0120200322</a>
+ * America, v. 111, n. 4, p. 1849-1867, doi: <a
+ * href="https://doi.org/10.1785/0120200322"> 10.1785/0120200322</a>.
  *
  * @author U.S. Geological Survey
  */
@@ -35,6 +33,8 @@ class ChapmanGuo_2021 {
       PGV,
       Imt.mprsImts().toArray(new Imt[0]));
 
+  static final double VS_REF = 590.0;
+
   private static final double[] Z = {
       0.0, 0.1, 0.2, 0.3, 0.4, 0.6, 0.8,
       1.0, 1.5, 2.5, 3.5, 4.5, 5.5, 6.5, 7.5, 8.5, 9.5, 10.5, 11.5, 12.5 };
@@ -117,12 +117,6 @@ class ChapmanGuo_2021 {
     return interpolate(z1, z2, zf);
   }
 
-  // public static void main(String[] args) {
-  // // 0.74631047
-  // double scale = cpaPsaRatio(Imt.PGA, 0.8, 8.2, 100);
-  // System.out.println(scale);
-  // }
-
   private static double interpolate(double lo, double hi, double fraction) {
     return lo + fraction * (hi - lo);
   }
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 375f7e2208fa066151fca1e12e4258e7d2b2fab5..a56e96dd569f12d81c407aaa94068c51c859167a 100644
--- a/src/main/java/gov/usgs/earthquake/nshmp/gmm/CombinedGmm.java
+++ b/src/main/java/gov/usgs/earthquake/nshmp/gmm/CombinedGmm.java
@@ -155,8 +155,8 @@ class CombinedGmm implements GroundMotionModel {
   static final class Ceus2018 extends CombinedGmm {
 
     static final String NAME = CombinedGmm.NAME + "CEUS 2018 (5.0)";
-    static final Constraints CONSTRAINTS = NgaEast_2018.CONSTRAINTS;
-    static final CoefficientContainer COEFFS = NgaEast_2018.COEFFS_SIGMA_PANEL;
+    static final Constraints CONSTRAINTS = NgaEast.CONSTRAINTS;
+    static final CoefficientContainer COEFFS = NgaEast.COEFFS_SIGMA_PANEL;
 
     Ceus2018(Imt imt) {
       super(imt, CEUS_2018);
@@ -171,8 +171,8 @@ class CombinedGmm implements GroundMotionModel {
   static final class Ceus2018Cpa extends CombinedGmm {
 
     static final String NAME = CombinedGmm.NAME + "CEUS 2018 (Gulf Coast)";
-    static final Constraints CONSTRAINTS = NgaEast_2018.CONSTRAINTS;
-    static final CoefficientContainer COEFFS = NgaEast_2018.COEFFS_SIGMA_PANEL;
+    static final Constraints CONSTRAINTS = NgaEast.CONSTRAINTS;
+    static final CoefficientContainer COEFFS = NgaEast.COEFFS_SIGMA_PANEL;
 
     Ceus2018Cpa(Imt imt) {
       super(imt, CEUS_2018_CPA);
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 7c8e78ab856c4e4852cc44ba730448eeb4e656e6..022aa2a2eb88bfcd44149db6aee8461bc5852132 100644
--- a/src/main/java/gov/usgs/earthquake/nshmp/gmm/Gmm.java
+++ b/src/main/java/gov/usgs/earthquake/nshmp/gmm/Gmm.java
@@ -32,6 +32,7 @@ import gov.usgs.earthquake.nshmp.gmm.CeusMb.SilvaEtAl_2002_J;
 import gov.usgs.earthquake.nshmp.gmm.CeusMb.TavakoliPezeshk_2005_AB;
 import gov.usgs.earthquake.nshmp.gmm.CeusMb.TavakoliPezeshk_2005_J;
 import gov.usgs.earthquake.nshmp.gmm.GmmInput.Constraints;
+import gov.usgs.earthquake.nshmp.gmm.NgaEast.NgaEast_2018;
 
 /**
  * {@link GroundMotionModel} (Gmm) identifiers. Use these to generate
@@ -852,191 +853,191 @@ public enum Gmm {
 
   /* NGA-East for USGS */
 
-  /** @see NgaEast_2018 */
+  /** @see NgaEast */
   NGA_EAST_2018(
-      NgaEast_2018.NgaEastBase.class,
-      NgaEast_2018.NgaEastBase.NAME,
-      NgaEast_2018.COEFFS_SIGMA_PANEL,
-      NgaEast_2018.CONSTRAINTS),
+      NgaEast.NgaEast_2018.class,
+      NgaEast.NgaEast_2018.NAME,
+      NgaEast.COEFFS_SIGMA_PANEL,
+      NgaEast.CONSTRAINTS),
 
-  /** NGA-East for USGS with Guo &amp; Chapman Gulf CPA **/
+  /** @see NgaEast */
   NGA_EAST_2023(
-      NgaEast_2018.Usgs17Cpa.class,
-      NgaEast_2018.Usgs17Cpa.NAME,
-      NgaEast_2018.COEFFS_SIGMA_PANEL,
-      NgaEast_2018.CONSTRAINTS),
+      NgaEast.NgaEast_2023.class,
+      NgaEast.NgaEast_2023.NAME,
+      NgaEast.COEFFS_SIGMA_PANEL,
+      NgaEast.CONSTRAINTS),
 
   /* NGA-East USGS Seed Tree */
 
-  /** @see NgaEast_2018 */
+  /** @see NgaEast */
   NGA_EAST_SEEDS_2018(
-      NgaEast_2018.UsgsSeeds.class,
-      NgaEast_2018.UsgsSeeds.NAME,
-      NgaEast_2018.COEFFS_SIGMA_PANEL,
-      NgaEast_2018.CONSTRAINTS),
+      NgaEast.UsgsSeeds_2018.class,
+      NgaEast.UsgsSeeds_2018.NAME,
+      NgaEast.COEFFS_SIGMA_PANEL,
+      NgaEast.CONSTRAINTS),
 
-  /** NGA-East for USGS Seed Models with Guo &amp; Chapman Gulf CPA **/
+  /** @see NgaEast */
   NGA_EAST_SEEDS_2023(
-      NgaEast_2018.UsgsSeedsCpa.class,
-      NgaEast_2018.UsgsSeedsCpa.NAME,
-      NgaEast_2018.COEFFS_SIGMA_PANEL,
-      NgaEast_2018.CONSTRAINTS),
+      NgaEast.UsgsSeeds_2023.class,
+      NgaEast.UsgsSeeds_2023.NAME,
+      NgaEast.COEFFS_SIGMA_PANEL,
+      NgaEast.CONSTRAINTS),
 
   /* NGA-East Seed Models */
 
   /** @see NgaEast_2018 */
   NGA_EAST_SEED_1CCSP(
-      NgaEast_2018.Seed_1CCSP.class,
-      NgaEast_2018.Seed_1CCSP.NAME,
-      NgaEast_2018.COEFFS_SIGMA_PANEL,
-      NgaEast_2018.CONSTRAINTS),
+      NgaEast.Seed_1CCSP.class,
+      NgaEast.Seed_1CCSP.NAME,
+      NgaEast.COEFFS_SIGMA_PANEL,
+      NgaEast.CONSTRAINTS),
 
   /** @see NgaEast_2018 */
   NGA_EAST_SEED_1CVSP(
-      NgaEast_2018.Seed_1CVSP.class,
-      NgaEast_2018.Seed_1CVSP.NAME,
-      NgaEast_2018.COEFFS_SIGMA_PANEL,
-      NgaEast_2018.CONSTRAINTS),
+      NgaEast.Seed_1CVSP.class,
+      NgaEast.Seed_1CVSP.NAME,
+      NgaEast.COEFFS_SIGMA_PANEL,
+      NgaEast.CONSTRAINTS),
 
   /** @see NgaEast_2018 */
   NGA_EAST_SEED_2CCSP(
-      NgaEast_2018.Seed_2CCSP.class,
-      NgaEast_2018.Seed_2CCSP.NAME,
-      NgaEast_2018.COEFFS_SIGMA_PANEL,
-      NgaEast_2018.CONSTRAINTS),
+      NgaEast.Seed_2CCSP.class,
+      NgaEast.Seed_2CCSP.NAME,
+      NgaEast.COEFFS_SIGMA_PANEL,
+      NgaEast.CONSTRAINTS),
 
   /** @see NgaEast_2018 */
   NGA_EAST_SEED_2CVSP(
-      NgaEast_2018.Seed_2CVSP.class,
-      NgaEast_2018.Seed_2CVSP.NAME,
-      NgaEast_2018.COEFFS_SIGMA_PANEL,
-      NgaEast_2018.CONSTRAINTS),
+      NgaEast.Seed_2CVSP.class,
+      NgaEast.Seed_2CVSP.NAME,
+      NgaEast.COEFFS_SIGMA_PANEL,
+      NgaEast.CONSTRAINTS),
 
   /** @see NgaEast_2018 */
   NGA_EAST_SEED_B_A04(
-      NgaEast_2018.Seed_B_a04.class,
-      NgaEast_2018.Seed_B_a04.NAME,
-      NgaEast_2018.COEFFS_SIGMA_PANEL,
-      NgaEast_2018.CONSTRAINTS),
+      NgaEast.Seed_B_a04.class,
+      NgaEast.Seed_B_a04.NAME,
+      NgaEast.COEFFS_SIGMA_PANEL,
+      NgaEast.CONSTRAINTS),
 
   /** @see NgaEast_2018 */
   NGA_EAST_SEED_B_AB14(
-      NgaEast_2018.Seed_B_ab14.class,
-      NgaEast_2018.Seed_B_ab14.NAME,
-      NgaEast_2018.COEFFS_SIGMA_PANEL,
-      NgaEast_2018.CONSTRAINTS),
+      NgaEast.Seed_B_ab14.class,
+      NgaEast.Seed_B_ab14.NAME,
+      NgaEast.COEFFS_SIGMA_PANEL,
+      NgaEast.CONSTRAINTS),
 
   /** @see NgaEast_2018 */
   NGA_EAST_SEED_B_AB95(
-      NgaEast_2018.Seed_B_ab95.class,
-      NgaEast_2018.Seed_B_ab95.NAME,
-      NgaEast_2018.COEFFS_SIGMA_PANEL,
-      NgaEast_2018.CONSTRAINTS),
+      NgaEast.Seed_B_ab95.class,
+      NgaEast.Seed_B_ab95.NAME,
+      NgaEast.COEFFS_SIGMA_PANEL,
+      NgaEast.CONSTRAINTS),
 
   /** @see NgaEast_2018 */
   NGA_EAST_SEED_B_BCA10D(
-      NgaEast_2018.Seed_B_bca10d.class,
-      NgaEast_2018.Seed_B_bca10d.NAME,
-      NgaEast_2018.COEFFS_SIGMA_PANEL,
-      NgaEast_2018.CONSTRAINTS),
+      NgaEast.Seed_B_bca10d.class,
+      NgaEast.Seed_B_bca10d.NAME,
+      NgaEast.COEFFS_SIGMA_PANEL,
+      NgaEast.CONSTRAINTS),
 
   /** @see NgaEast_2018 */
   NGA_EAST_SEED_B_BS11(
-      NgaEast_2018.Seed_B_bs11.class,
-      NgaEast_2018.Seed_B_bs11.NAME,
-      NgaEast_2018.COEFFS_SIGMA_PANEL,
-      NgaEast_2018.CONSTRAINTS),
+      NgaEast.Seed_B_bs11.class,
+      NgaEast.Seed_B_bs11.NAME,
+      NgaEast.COEFFS_SIGMA_PANEL,
+      NgaEast.CONSTRAINTS),
 
   /** @see NgaEast_2018 */
   NGA_EAST_SEED_B_SGD02(
-      NgaEast_2018.Seed_B_sgd02.class,
-      NgaEast_2018.Seed_B_sgd02.NAME,
-      NgaEast_2018.COEFFS_SIGMA_PANEL,
-      NgaEast_2018.CONSTRAINTS),
+      NgaEast.Seed_B_sgd02.class,
+      NgaEast.Seed_B_sgd02.NAME,
+      NgaEast.COEFFS_SIGMA_PANEL,
+      NgaEast.CONSTRAINTS),
 
   /** @see NgaEast_2018 */
   NGA_EAST_SEED_B20_AB14MOD1(
-      NgaEast_2018.Seed_B20_ab14mod1.class,
-      NgaEast_2018.Seed_B20_ab14mod1.NAME,
-      NgaEast_2018.COEFFS_SIGMA_PANEL,
-      NgaEast_2018.CONSTRAINTS),
+      NgaEast.Seed_B20_ab14mod1.class,
+      NgaEast.Seed_B20_ab14mod1.NAME,
+      NgaEast.COEFFS_SIGMA_PANEL,
+      NgaEast.CONSTRAINTS),
 
   /** @see NgaEast_2018 */
   NGA_EAST_SEED_B20_AB14MOD2(
-      NgaEast_2018.Seed_B20_ab14mod2.class,
-      NgaEast_2018.Seed_B20_ab14mod2.NAME,
-      NgaEast_2018.COEFFS_SIGMA_PANEL,
-      NgaEast_2018.CONSTRAINTS),
+      NgaEast.Seed_B20_ab14mod2.class,
+      NgaEast.Seed_B20_ab14mod2.NAME,
+      NgaEast.COEFFS_SIGMA_PANEL,
+      NgaEast.CONSTRAINTS),
 
   /** @see NgaEast_2018 */
   NGA_EAST_SEED_B20_BCA10D(
-      NgaEast_2018.Seed_B20_bca10d.class,
-      NgaEast_2018.Seed_B20_bca10d.NAME,
-      NgaEast_2018.COEFFS_SIGMA_PANEL,
-      NgaEast_2018.CONSTRAINTS),
+      NgaEast.Seed_B20_bca10d.class,
+      NgaEast.Seed_B20_bca10d.NAME,
+      NgaEast.COEFFS_SIGMA_PANEL,
+      NgaEast.CONSTRAINTS),
 
   /** @see NgaEast_2018 */
   NGA_EAST_SEED_FRANKEL(
-      NgaEast_2018.Seed_Frankel.class,
-      NgaEast_2018.Seed_Frankel.NAME,
-      NgaEast_2018.COEFFS_SIGMA_PANEL,
-      NgaEast_2018.CONSTRAINTS),
+      NgaEast.Seed_Frankel.class,
+      NgaEast.Seed_Frankel.NAME,
+      NgaEast.COEFFS_SIGMA_PANEL,
+      NgaEast.CONSTRAINTS),
 
   /** @see NgaEast_2018 */
   NGA_EAST_SEED_GRAIZER(
-      NgaEast_2018.Seed_Graizer.class,
-      NgaEast_2018.Seed_Graizer.NAME,
-      NgaEast_2018.COEFFS_SIGMA_PANEL,
-      NgaEast_2018.CONSTRAINTS),
+      NgaEast.Seed_Graizer.class,
+      NgaEast.Seed_Graizer.NAME,
+      NgaEast.COEFFS_SIGMA_PANEL,
+      NgaEast.CONSTRAINTS),
 
   /** @see NgaEast_2018 */
   NGA_EAST_SEED_GRAIZER16(
-      NgaEast_2018.Seed_Graizer16.class,
-      NgaEast_2018.Seed_Graizer16.NAME,
-      NgaEast_2018.COEFFS_SIGMA_PANEL,
-      NgaEast_2018.CONSTRAINTS),
+      NgaEast.Seed_Graizer16.class,
+      NgaEast.Seed_Graizer16.NAME,
+      NgaEast.COEFFS_SIGMA_PANEL,
+      NgaEast.CONSTRAINTS),
 
   /** @see NgaEast_2018 */
   NGA_EAST_SEED_GRAIZER17(
-      NgaEast_2018.Seed_Graizer17.class,
-      NgaEast_2018.Seed_Graizer17.NAME,
-      NgaEast_2018.COEFFS_SIGMA_PANEL,
-      NgaEast_2018.CONSTRAINTS),
+      NgaEast.Seed_Graizer17.class,
+      NgaEast.Seed_Graizer17.NAME,
+      NgaEast.COEFFS_SIGMA_PANEL,
+      NgaEast.CONSTRAINTS),
 
   /** @see NgaEast_2018 */
   NGA_EAST_SEED_HA15(
-      NgaEast_2018.Seed_HA15.class,
-      NgaEast_2018.Seed_HA15.NAME,
-      NgaEast_2018.COEFFS_SIGMA_PANEL,
-      NgaEast_2018.CONSTRAINTS),
+      NgaEast.Seed_HA15.class,
+      NgaEast.Seed_HA15.NAME,
+      NgaEast.COEFFS_SIGMA_PANEL,
+      NgaEast.CONSTRAINTS),
 
   /** @see NgaEast_2018 */
   NGA_EAST_SEED_PEER_EX(
-      NgaEast_2018.Seed_PEER_EX.class,
-      NgaEast_2018.Seed_PEER_EX.NAME,
-      NgaEast_2018.COEFFS_SIGMA_PANEL,
-      NgaEast_2018.CONSTRAINTS),
+      NgaEast.Seed_PEER_EX.class,
+      NgaEast.Seed_PEER_EX.NAME,
+      NgaEast.COEFFS_SIGMA_PANEL,
+      NgaEast.CONSTRAINTS),
 
   /** @see NgaEast_2018 */
   NGA_EAST_SEED_PEER_GP(
-      NgaEast_2018.Seed_PEER_GP.class,
-      NgaEast_2018.Seed_PEER_GP.NAME,
-      NgaEast_2018.COEFFS_SIGMA_PANEL,
-      NgaEast_2018.CONSTRAINTS),
+      NgaEast.Seed_PEER_GP.class,
+      NgaEast.Seed_PEER_GP.NAME,
+      NgaEast.COEFFS_SIGMA_PANEL,
+      NgaEast.CONSTRAINTS),
 
   /** @see NgaEast_2018 */
   NGA_EAST_SEED_PZCT15_M1SS(
-      NgaEast_2018.Seed_PZCT15_M1SS.class,
-      NgaEast_2018.Seed_PZCT15_M1SS.NAME,
-      NgaEast_2018.COEFFS_SIGMA_PANEL,
-      NgaEast_2018.CONSTRAINTS),
+      NgaEast.Seed_PZCT15_M1SS.class,
+      NgaEast.Seed_PZCT15_M1SS.NAME,
+      NgaEast.COEFFS_SIGMA_PANEL,
+      NgaEast.CONSTRAINTS),
 
   /** @see NgaEast_2018 */
   NGA_EAST_SEED_PZCT15_M2ES(
-      NgaEast_2018.Seed_PZCT15_M2ES.class,
-      NgaEast_2018.Seed_PZCT15_M2ES.NAME,
-      NgaEast_2018.COEFFS_SIGMA_PANEL,
-      NgaEast_2018.CONSTRAINTS),
+      NgaEast.Seed_PZCT15_M2ES.class,
+      NgaEast.Seed_PZCT15_M2ES.NAME,
+      NgaEast.COEFFS_SIGMA_PANEL,
+      NgaEast.CONSTRAINTS),
 
   /** @see NgaEast_2018 @see PezeshkEtAl_2018 */
   NGA_EAST_SEED_PZCT18_M1SS(
@@ -1054,10 +1055,10 @@ public enum Gmm {
 
   /** @see NgaEast_2018 */
   NGA_EAST_SEED_SP15(
-      NgaEast_2018.Seed_SP15.class,
-      NgaEast_2018.Seed_SP15.NAME,
-      NgaEast_2018.COEFFS_SIGMA_PANEL,
-      NgaEast_2018.CONSTRAINTS),
+      NgaEast.Seed_SP15.class,
+      NgaEast.Seed_SP15.NAME,
+      NgaEast.COEFFS_SIGMA_PANEL,
+      NgaEast.CONSTRAINTS),
 
   /** @see NgaEast_2018 @see ShahjoueiPezeshk_2016 */
   NGA_EAST_SEED_SP16(
@@ -1068,10 +1069,10 @@ public enum Gmm {
 
   /** @see NgaEast_2018 */
   NGA_EAST_SEED_YA15(
-      NgaEast_2018.Seed_YA15.class,
-      NgaEast_2018.Seed_YA15.NAME,
-      NgaEast_2018.COEFFS_SIGMA_PANEL,
-      NgaEast_2018.CONSTRAINTS),
+      NgaEast.Seed_YA15.class,
+      NgaEast.Seed_YA15.NAME,
+      NgaEast.COEFFS_SIGMA_PANEL,
+      NgaEast.CONSTRAINTS),
 
   /* Combined: must be declared after any dependent models above. */
 
@@ -1523,7 +1524,6 @@ public enum Gmm {
             NGA_EAST_SEED_1CVSP,
             NGA_EAST_SEED_2CCSP,
             NGA_EAST_SEED_2CVSP,
-            // NGA_EAST_SEED_ANC15,
             NGA_EAST_SEED_B_A04,
             NGA_EAST_SEED_B_AB14,
             NGA_EAST_SEED_B_AB95,
diff --git a/src/main/java/gov/usgs/earthquake/nshmp/gmm/GroundMotionTables.java b/src/main/java/gov/usgs/earthquake/nshmp/gmm/GroundMotionTables.java
index a9941f47cab4d65abb2265890f3869a3f5be693f..8ab7f3f4e8a5a76bf28921056c49b91fc027945f 100644
--- a/src/main/java/gov/usgs/earthquake/nshmp/gmm/GroundMotionTables.java
+++ b/src/main/java/gov/usgs/earthquake/nshmp/gmm/GroundMotionTables.java
@@ -216,7 +216,6 @@ final class GroundMotionTables {
     NGA_EAST = initNgaEast();
     NGA_EAST_WEIGHTS = initNgaEastWeights();
     NGA_EAST_SEEDS = initNgaEastSeeds();
-
     KBCG20_EPISTEMIC = initKbcg20();
   }
 
diff --git a/src/main/java/gov/usgs/earthquake/nshmp/gmm/NgaEast_2018.java b/src/main/java/gov/usgs/earthquake/nshmp/gmm/NgaEast.java
similarity index 79%
rename from src/main/java/gov/usgs/earthquake/nshmp/gmm/NgaEast_2018.java
rename to src/main/java/gov/usgs/earthquake/nshmp/gmm/NgaEast.java
index 0c057d2cd686ed8be4bd68c6978c44204905155a..7ea883f2178115e0793446f5246168ca8614bdbb 100644
--- a/src/main/java/gov/usgs/earthquake/nshmp/gmm/NgaEast_2018.java
+++ b/src/main/java/gov/usgs/earthquake/nshmp/gmm/NgaEast.java
@@ -14,6 +14,7 @@ import static java.lang.Math.sqrt;
 import static java.util.stream.Collectors.toMap;
 
 import java.io.IOException;
+import java.net.URL;
 import java.nio.charset.StandardCharsets;
 import java.util.ArrayList;
 import java.util.EnumSet;
@@ -97,35 +98,19 @@ import gov.usgs.earthquake.nshmp.tree.LogicTree;
  * href="https://escholarship.org/uc/item/2sc5g220">
  * https://escholarship.org/uc/item/2sc5g220</a> (accessed 18 November 2019).
  *
+ * <p><b>Reference:</b> Chapman, M.C. and Guo, Z., 2021, A response spectral
+ * ratio model to account for amplification and attenuation effects in the
+ * Atlantic and Gulf coastal plain: Bulletin of the Seismological Society of
+ * America, v. 111, n. 4, p. 1849-1867, doi: <a
+ * href="https://doi.org/10.1785/0120200322"> 10.1785/0120200322</a>.
+ *
  * <p><b>Component:</b> average horizontal (RotD50)
  *
  * @author U.S. Geological Survey
  * @see Gmm#NGA_EAST_2018
  * @see Gmm#NGA_EAST_SEEDS_2018
- * @see Gmm#NGA_EAST_SEED_1CCSP
- * @see Gmm#NGA_EAST_SEED_1CVSP
- * @see Gmm#NGA_EAST_SEED_2CCSP
- * @see Gmm#NGA_EAST_SEED_2CVSP
- * @see Gmm#NGA_EAST_SEED_B_A04
- * @see Gmm#NGA_EAST_SEED_B_AB14
- * @see Gmm#NGA_EAST_SEED_B_AB95
- * @see Gmm#NGA_EAST_SEED_B_BCA10D
- * @see Gmm#NGA_EAST_SEED_B_BS11
- * @see Gmm#NGA_EAST_SEED_B_SGD02
- * @see Gmm#NGA_EAST_SEED_FRANKEL
- * @see Gmm#NGA_EAST_SEED_GRAIZER
- * @see Gmm#NGA_EAST_SEED_GRAIZER16
- * @see Gmm#NGA_EAST_SEED_GRAIZER17
- * @see Gmm#NGA_EAST_SEED_HA15
- * @see Gmm#NGA_EAST_SEED_PEER_EX
- * @see Gmm#NGA_EAST_SEED_PEER_GP
- * @see Gmm#NGA_EAST_SEED_PZCT15_M1SS
- * @see Gmm#NGA_EAST_SEED_PZCT15_M2ES
- * @see Gmm#NGA_EAST_SEED_SP15
- * @see Gmm#NGA_EAST_SEED_SP16
- * @see Gmm#NGA_EAST_SEED_YA15
  */
-public abstract class NgaEast_2018 implements GroundMotionModel {
+public abstract class NgaEast implements GroundMotionModel {
 
   /*
    * Developer notes:
@@ -159,7 +144,7 @@ public abstract class NgaEast_2018 implements GroundMotionModel {
    * the aleatory variability logic tree.
    */
 
-  static final String NAME = "NGA-East (2018)";
+  static final String NAME = "NGA-East";
 
   static final Constraints CONSTRAINTS = Constraints.builder()
       .set(MW, Range.closed(4.0, 8.2))
@@ -185,16 +170,14 @@ public abstract class NgaEast_2018 implements GroundMotionModel {
 
   private static Map<String, Double> initSeedWeights() {
     try {
-      Map<String, Double> wtMap = readLines(
-          getResource(TABLE_DIR + "nga-east-seed-weights.dat"),
-          StandardCharsets.UTF_8)
-              .stream()
-              .skip(1)
-              .map(line -> Text.splitToList(line, Delimiter.COMMA))
-              .collect(toMap(
-                  entry -> entry.get(0),
-                  entry -> Double.valueOf(entry.get(1))));
-
+      URL wtsUrl = getResource(TABLE_DIR + "nga-east-seed-weights.dat");
+      Map<String, Double> wtMap = readLines(wtsUrl, StandardCharsets.UTF_8)
+          .stream()
+          .skip(1)
+          .map(line -> Text.splitToList(line, Delimiter.COMMA))
+          .collect(toMap(
+              entry -> entry.get(0),
+              entry -> Double.valueOf(entry.get(1))));
       checkWeights(wtMap.values());
       return Map.copyOf(wtMap);
 
@@ -257,7 +240,7 @@ public abstract class NgaEast_2018 implements GroundMotionModel {
   private final CoefficientsSigmaEpri σCoeffsEpri;
   final Imt imt;
 
-  NgaEast_2018(Imt imt) {
+  NgaEast(Imt imt) {
     σCoeffsPanel = new CoefficientsSigmaPanel(imt, COEFFS_SIGMA_PANEL);
     σCoeffsEpri = new CoefficientsSigmaEpri(imt, COEFFS_SIGMA_EPRI);
     this.imt = imt;
@@ -357,11 +340,10 @@ public abstract class NgaEast_2018 implements GroundMotionModel {
     return φs2s2;
   }
 
-  /*
-   * Base model used for sammons and seed model groups that share common site
-   * class and sigma models.
-   */
-  static class NgaEastBase extends NgaEast_2018 {
+  /* Implementation of sammons map models. */
+  static class NgaEast_2018 extends NgaEast {
+
+    static final String NAME = NgaEast.NAME + " (2018)";
 
     static final int MODEL_COUNT = 17;
     static final String[] MEAN_IDS = IntStream.range(1, MODEL_COUNT + 1)
@@ -374,12 +356,15 @@ public abstract class NgaEast_2018 implements GroundMotionModel {
     final SiteAmp siteAmp;
     final double[] μWts;
 
-    /* Specifiy an array of models ids. */
-    NgaEastBase(Imt imt) {
+    NgaEast_2018(Imt imt) {
+      this(imt, new SiteAmp(imt));
+    }
+
+    NgaEast_2018(Imt imt, SiteAmp siteAmp) {
       super(imt);
       this.tables = GroundMotionTables.getNgaEast(imt);
       this.pgaTables = GroundMotionTables.getNgaEast(Imt.PGA);
-      this.siteAmp = new SiteAmp(imt);
+      this.siteAmp = siteAmp;
       this.μWts = GroundMotionTables.getNgaEastWeights(imt);
     }
 
@@ -402,26 +387,44 @@ public abstract class NgaEast_2018 implements GroundMotionModel {
     }
   }
 
-  /* Guo and Chapman Gulf Coastal Plain Amplification (CPA) model. */
-  static class Usgs17Cpa extends NgaEastBase {
+  /*
+   * Updated NGA-East for use in the 2023 nshm-conus update. This model includes
+   * (1) the final published nonlinear site amplification model of Hshash et al.
+   * (2020) and (2) the Gulf and Atlantic coastal plain effects model of Chapman
+   * & Guo (2021).
+   */
+  static class NgaEast_2023 extends NgaEast_2018 {
 
-    // static final String NAME = "NGA-East (2023)";
-    static final String NAME = NgaEast_2018.NAME + " (Gulf Coast)";
+    static final String NAME = "NGA-East (2023)";
 
-    Usgs17Cpa(Imt imt) {
-      super(imt);
+    NgaEast_2023(Imt imt) {
+      super(imt, new SiteAmp_2023(imt));
     }
 
+    /*
+     * Developer notes: The current implementation assumes a reference site
+     * condition of Vs30 = 590 m/s. This means that we apply the full Chapman &
+     * Guo PSA ratio if Vs30 = 590 and scale it by the ratio of the site term at
+     * the target Vs30 to the reference Vs30.
+     */
     @Override
     public LogicTree<GroundMotion> calc(GmmInput in) {
-      double cpa = Double.isNaN(in.zSed)
-          ? 0.0
-          : log(ChapmanGuo_2021.cpaPsaRatio(imt, in.zSed, in.Mw, in.rJB));
+      boolean cpa = !Double.isNaN(in.zSed);
+      double fCpa = cpa
+          ? log(ChapmanGuo_2021.cpaPsaRatio(imt, in.zSed, in.Mw, in.rJB))
+          : 0.0;
       Position p = tables[0].position(in.rRup, in.Mw);
       double[] μs = new double[MODEL_COUNT];
       for (int i = 0; i < MODEL_COUNT; i++) {
         double μ = tables[i].get(p);
-        μs[i] = μ + cpa;
+        double μPga = exp(pgaTables[i].get(p));
+        SiteAmp.Value fSite = siteAmp.calc(μPga, in.vs30);
+        if (cpa) {
+          SiteAmp.Value fCpaRef = siteAmp.calc(μPga, ChapmanGuo_2021.VS_REF);
+          double cpaScale = fSite.siteAmp / fCpaRef.siteAmp;
+          fCpa *= cpaScale;
+        }
+        μs[i] = fSite.apply(μ) + fCpa;
       }
       double[] σs = new double[] {
           sigmaEpri(in.Mw),
@@ -444,8 +447,8 @@ public abstract class NgaEast_2018 implements GroundMotionModel {
    * individual seed models which results in repeated position lookups. Both
    * sigma models considered include coefficients for PGV.
    */
-  static class UsgsSeeds extends NgaEast_2018 {
-    static final String NAME = "NGA-East Seed Tree (2018)";
+  static class UsgsSeeds_2018 extends NgaEast {
+    static final String NAME = NgaEast.NAME + " Seed Tree (2018)";
     static final String SEED_PREFIX = "NGA_EAST_SEED_";
     static final String SP16_ID = "SP16";
     static final Set<Gmm> noPgvSeeds = EnumSet.of(
@@ -468,6 +471,7 @@ public abstract class NgaEast_2018 implements GroundMotionModel {
     final Map<Gmm, GroundMotionTable> tables;
     final Map<Gmm, GroundMotionTable> pgaTables;
     final ShahjoueiPezeshk_2016 sp16;
+    final ShahjoueiPezeshk_2016 sp16pga;
     final SiteAmp siteAmp;
 
     static {
@@ -492,12 +496,17 @@ public abstract class NgaEast_2018 implements GroundMotionModel {
           .toArray();
     }
 
-    UsgsSeeds(Imt imt) {
+    UsgsSeeds_2018(Imt imt) {
+      this(imt, new SiteAmp(imt));
+    }
+
+    UsgsSeeds_2018(Imt imt, SiteAmp siteAmp) {
       super(imt);
       this.tables = getImtTables(imt);
       this.pgaTables = getImtTables(Imt.PGA);
       this.sp16 = (ShahjoueiPezeshk_2016) Gmm.NGA_EAST_SEED_SP16.instance(imt);
-      this.siteAmp = new SiteAmp(imt);
+      this.sp16pga = (ShahjoueiPezeshk_2016) Gmm.NGA_EAST_SEED_SP16.instance(Imt.PGA);
+      this.siteAmp = siteAmp;
     }
 
     private static Map<Gmm, GroundMotionTable> getImtTables(Imt imt) {
@@ -515,15 +524,18 @@ public abstract class NgaEast_2018 implements GroundMotionModel {
       for (int i = 0; i < GMMS.size(); i++) {
         Gmm seed = GMMS.get(i);
         if (seed == Gmm.NGA_EAST_SEED_SP16) {
-          μs[i] = GroundMotions.combine(sp16.calc(in)).mean();
+          double μ = sp16.calcMeanRock(in.Mw, in.rRup);
+          double μPga = exp(sp16pga.calcMeanRock(in.Mw, in.rRup));
+          SiteAmp.Value fSite = siteAmp.calc(μPga, in.vs30);
+          μs[i] = fSite.apply(μ);
         } else if (imt == Imt.PGV && noPgvSeeds.contains(seed)) {
           // site is included when calling individual seed
           μs[i] = UsgsPgvSupport.calcAB20Pgv(seed, in).mean();
         } else {
-          double μRock = tables.get(seed).get(p);
+          double μ = tables.get(seed).get(p);
           double μPga = exp(pgaTables.get(seed).get(p));
           SiteAmp.Value fSite = siteAmp.calc(μPga, in.vs30);
-          μs[i] = fSite.apply(μRock);
+          μs[i] = fSite.apply(μ);
         }
       }
       double[] σs = new double[] {
@@ -535,34 +547,65 @@ public abstract class NgaEast_2018 implements GroundMotionModel {
     }
   }
 
-  /* Guo and Chapman Gulf Coastal Plain Amplification (CPA) model. */
-  static class UsgsSeedsCpa extends UsgsSeeds {
+  public static void main(String[] args) {
+    // TODO clean
+    // Gmm gmm = Gmm.NGA_EAST_SEED_SP16;
+    Gmm gmm = Gmm.NGA_EAST_SEEDS_2018;
+    // Gmm gmm = Gmm.NGA_EAST_SEED_SP16;
+    GmmInput in = GmmInput.builder().withDefaults().build();
+    LogicTree<GroundMotion> gms = gmm.instance(Imt.PGA).calc(in);
+    System.out.println(gms);
+    gms.forEach(gm -> System.out.println(gm.id() + ": " + gm.value()));
+    GroundMotion gm = GroundMotions.combine(gms);
+    System.out.println(gm);
 
-    // static final String NAME = "NGA-East Seed Tree (2023)";
-    static final String NAME = UsgsSeeds.NAME + " (Gulf Coast)";
+  }
 
-    UsgsSeedsCpa(Imt imt) {
-      super(imt);
+  /*
+   * Updated NGA-East for use in the 2023 nshm-conus update. This model includes
+   * (1) the final published nonlinear site amplification model of Hshash et al.
+   * (2020) and (2) the Gulf and Atlantic coastal plain effects model of Chapman
+   * & Guo (2021).
+   */
+  static class UsgsSeeds_2023 extends UsgsSeeds_2018 {
+
+    static final String NAME = NgaEast.NAME + " Seed Tree (2023)";
+
+    UsgsSeeds_2023(Imt imt) {
+      super(imt, new SiteAmp_2023(imt));
     }
 
     @Override
     public LogicTree<GroundMotion> calc(GmmInput in) {
       GmmInput inRock = GmmInput.builder().fromCopy(in).vs30(3000).build();
-      double cpa = Double.isNaN(in.zSed)
-          ? 0.0
-          : log(ChapmanGuo_2021.cpaPsaRatio(imt, in.zSed, in.Mw, in.rJB));
+      boolean cpa = !Double.isNaN(in.zSed);
+      double fCpa = cpa
+          ? log(ChapmanGuo_2021.cpaPsaRatio(imt, in.zSed, in.Mw, in.rJB))
+          : 0.0;
       Position p = tables.values().iterator().next().position(in.rRup, in.Mw);
       double[] μs = new double[GMMS.size()];
       for (int i = 0; i < GMMS.size(); i++) {
         Gmm seed = GMMS.get(i);
+
+        double μ;
+        double μPga;
+
         if (seed == Gmm.NGA_EAST_SEED_SP16) {
-          μs[i] = GroundMotions.combine(sp16.calc(inRock)).mean() + cpa;
+          μ = sp16.calcMeanRock(in.Mw, in.rRup);
+          μPga = sp16pga.calcMeanRock(in.Mw, in.rRup);
         } else if (imt == Imt.PGV && noPgvSeeds.contains(seed)) {
-          // use custom input to ensure hard rock from seeds
-          μs[i] = UsgsPgvSupport.calcAB20Pgv(seed, inRock).mean() + cpa;
+          // note rock input; TODO this doesn't really work as the PGV
+          // is conditioned on vs30 so site should already be applied
+          μ = UsgsPgvSupport.calcAB20Pgv(seed, inRock).mean();
+          μPga = exp(pgaTables.get(seed).get(p));
         } else {
-          μs[i] = tables.get(seed).get(p) + cpa;
+          μ = tables.get(seed).get(p);
+          μPga = exp(pgaTables.get(seed).get(p));
         }
+        SiteAmp.Value fSite = siteAmp.calc(μPga, in.vs30);
+        double cpaScale = cpa ? cpaScale(μPga, fSite) : 0.0;
+        μs[i] = fSite.apply(μ) + fCpa * cpaScale;
+
       }
       double[] σs = new double[] {
           sigmaEpri(in.Mw),
@@ -571,10 +614,15 @@ public abstract class NgaEast_2018 implements GroundMotionModel {
           MEAN_IDS, μs, MEAN_WTS,
           SIGMA_IDS, σs, SIGMA_WTS);
     }
+
+    private double cpaScale(double μPga, SiteAmp.Value fSite) {
+      SiteAmp.Value fCpaRef = siteAmp.calc(μPga, ChapmanGuo_2021.VS_REF);
+      return fSite.siteAmp / fCpaRef.siteAmp;
+    }
   }
 
-  static abstract class Seed extends NgaEast_2018 {
-    static final String NAME = NgaEast_2018.NAME + " : Seed : ";
+  static abstract class Seed extends NgaEast {
+    static final String NAME = NgaEast.NAME + " : Seed : ";
 
     final String id;
     final GroundMotionTable table;
@@ -623,8 +671,8 @@ public abstract class NgaEast_2018 implements GroundMotionModel {
   }
 
   static final class Seed_2CCSP extends Seed {
-    static final String ID = "2CCSPáµ€";
-    static final String NAME = Seed.NAME + ID;
+    static final String ID = "2CCSP";
+    static final String NAME = Seed.NAME + ID + "áµ€";
 
     Seed_2CCSP(Imt imt) {
       super(ID, imt);
@@ -632,23 +680,14 @@ public abstract class NgaEast_2018 implements GroundMotionModel {
   }
 
   static final class Seed_2CVSP extends Seed {
-    static final String ID = "2CVSPáµ€";
-    static final String NAME = Seed.NAME + ID;
+    static final String ID = "2CVSP";
+    static final String NAME = Seed.NAME + ID + "áµ€";
 
     Seed_2CVSP(Imt imt) {
       super(ID, imt);
     }
   }
 
-  static final class Seed_ANC15 extends Seed {
-    static final String ID = "ANC15";
-    static final String NAME = Seed.NAME + ID;
-
-    Seed_ANC15(Imt imt) {
-      super(ID, imt);
-    }
-  }
-
   static final class Seed_B_a04 extends Seed {
     static final String ID = "B_a04";
     static final String NAME = Seed.NAME + ID;
@@ -668,8 +707,8 @@ public abstract class NgaEast_2018 implements GroundMotionModel {
   }
 
   static final class Seed_B_ab95 extends Seed {
-    static final String ID = "B_ab95áµ€";
-    static final String NAME = Seed.NAME + ID;
+    static final String ID = "B_ab95";
+    static final String NAME = Seed.NAME + ID + "áµ€";
 
     Seed_B_ab95(Imt imt) {
       super(ID, imt);
@@ -677,8 +716,8 @@ public abstract class NgaEast_2018 implements GroundMotionModel {
   }
 
   static final class Seed_B_bca10d extends Seed {
-    static final String ID = "B_bca10dáµ€";
-    static final String NAME = Seed.NAME + ID;
+    static final String ID = "B_bca10d";
+    static final String NAME = Seed.NAME + ID + "áµ€";
 
     Seed_B_bca10d(Imt imt) {
       super(ID, imt);
@@ -686,8 +725,8 @@ public abstract class NgaEast_2018 implements GroundMotionModel {
   }
 
   static final class Seed_B_bs11 extends Seed {
-    static final String ID = "B_bs11áµ€";
-    static final String NAME = Seed.NAME + ID;
+    static final String ID = "B_bs11";
+    static final String NAME = Seed.NAME + ID + "áµ€";
 
     Seed_B_bs11(Imt imt) {
       super(ID, imt);
@@ -704,8 +743,8 @@ public abstract class NgaEast_2018 implements GroundMotionModel {
   }
 
   static final class Seed_B20_ab14mod1 extends Seed {
-    static final String ID = "B20_ab14mod1*";
-    static final String NAME = Seed.NAME + ID;
+    static final String ID = "B20_ab14mod1";
+    static final String NAME = Seed.NAME + ID + "*";
 
     Seed_B20_ab14mod1(Imt imt) {
       super(ID, imt);
@@ -713,8 +752,8 @@ public abstract class NgaEast_2018 implements GroundMotionModel {
   }
 
   static final class Seed_B20_ab14mod2 extends Seed {
-    static final String ID = "B20_ab14mod2*";
-    static final String NAME = Seed.NAME + ID;
+    static final String ID = "B20_ab14mod2";
+    static final String NAME = Seed.NAME + ID + "*";
 
     Seed_B20_ab14mod2(Imt imt) {
       super(ID, imt);
@@ -722,8 +761,8 @@ public abstract class NgaEast_2018 implements GroundMotionModel {
   }
 
   static final class Seed_B20_bca10d extends Seed {
-    static final String ID = "B20_bca10d*";
-    static final String NAME = Seed.NAME + ID;
+    static final String ID = "B20_bca10d";
+    static final String NAME = Seed.NAME + ID + "*";
 
     Seed_B20_bca10d(Imt imt) {
       super(ID, imt);
@@ -731,8 +770,8 @@ public abstract class NgaEast_2018 implements GroundMotionModel {
   }
 
   static final class Seed_Frankel extends Seed {
-    static final String ID = "Frankeláµ€";
-    static final String NAME = Seed.NAME + ID;
+    static final String ID = "Frankel";
+    static final String NAME = Seed.NAME + ID + "áµ€";
 
     Seed_Frankel(Imt imt) {
       super(ID, imt);
@@ -749,8 +788,8 @@ public abstract class NgaEast_2018 implements GroundMotionModel {
   }
 
   static final class Seed_Graizer16 extends Seed {
-    static final String ID = "Graizer16áµ€*";
-    static final String NAME = Seed.NAME + ID;
+    static final String ID = "Graizer16";
+    static final String NAME = Seed.NAME + ID + "áµ€*";
 
     Seed_Graizer16(Imt imt) {
       super(ID, imt);
@@ -758,8 +797,8 @@ public abstract class NgaEast_2018 implements GroundMotionModel {
   }
 
   static final class Seed_Graizer17 extends Seed {
-    static final String ID = "Graizer17áµ€*";
-    static final String NAME = Seed.NAME + ID;
+    static final String ID = "Graizer17";
+    static final String NAME = Seed.NAME + ID + "áµ€*";
 
     Seed_Graizer17(Imt imt) {
       super(ID, imt);
@@ -767,8 +806,8 @@ public abstract class NgaEast_2018 implements GroundMotionModel {
   }
 
   static final class Seed_HA15 extends Seed {
-    static final String ID = "HA15áµ€";
-    static final String NAME = Seed.NAME + ID;
+    static final String ID = "HA15";
+    static final String NAME = Seed.NAME + ID + "áµ€";
 
     Seed_HA15(Imt imt) {
       super(ID, imt);
@@ -785,8 +824,8 @@ public abstract class NgaEast_2018 implements GroundMotionModel {
   }
 
   static final class Seed_PEER_GP extends Seed {
-    static final String ID = "PEER_GPáµ€";
-    static final String NAME = Seed.NAME + ID;
+    static final String ID = "PEER_GP";
+    static final String NAME = Seed.NAME + ID + "áµ€";
 
     Seed_PEER_GP(Imt imt) {
       super(ID, imt);
@@ -794,8 +833,8 @@ public abstract class NgaEast_2018 implements GroundMotionModel {
   }
 
   static final class Seed_PZCT15_M1SS extends Seed {
-    static final String ID = "PZCT15_M1SSáµ€";
-    static final String NAME = Seed.NAME + ID;
+    static final String ID = "PZCT15_M1SS";
+    static final String NAME = Seed.NAME + ID + "áµ€";
 
     Seed_PZCT15_M1SS(Imt imt) {
       super(ID, imt);
@@ -803,8 +842,8 @@ public abstract class NgaEast_2018 implements GroundMotionModel {
   }
 
   static final class Seed_PZCT15_M2ES extends Seed {
-    static final String ID = "PZCT15_M2ESáµ€";
-    static final String NAME = Seed.NAME + ID;
+    static final String ID = "PZCT15_M2ES";
+    static final String NAME = Seed.NAME + ID + "áµ€";
 
     Seed_PZCT15_M2ES(Imt imt) {
       super(ID, imt);
@@ -821,24 +860,21 @@ public abstract class NgaEast_2018 implements GroundMotionModel {
   }
 
   static final class Seed_YA15 extends Seed {
-    static final String ID = "YA15áµ€";
-    static final String NAME = Seed.NAME + ID;
+    static final String ID = "YA15";
+    static final String NAME = Seed.NAME + ID + "áµ€";
 
     Seed_YA15(Imt imt) {
       super(ID, imt);
     }
   }
 
-  /**
+  /*
    * Stewart et al. site amplification model.
    *
-   * The model is applicable to 200 ≤ vs30 ≤ 2000 m/s. In the current
-   * implementation, for vs30 < 200, vs30 = 200 m/s; for vs30 > 2000, vs30 =
-   * 3000 m/s.
+   * The model is applicable to 200 ≤ vs30 ≤ 2000 m/s and smoothly scales from
+   * 200 m/s up to 3000 m;s and reasonably extrapolates down to 150 m/s.
    */
-  static final class SiteAmp {
-
-    static final String NAME = NgaEast_2018.NAME + " : Site Amplification";
+  static class SiteAmp {
 
     private static final CoefficientContainer COEFFS = new CoefficientContainer(
         "nga-east-usgs-siteamp.csv");
@@ -855,14 +891,14 @@ public abstract class NgaEast_2018 implements GroundMotionModel {
     private static final double WT2 = 0.1; // impedance model @ VW2
     private static final double WT_SCALE = (WT1 - WT2) / (log(VW1) - log(VW2)); // ≈1.65
 
-    private final Coefficients c;
+    final Coefficients c;
 
     private static final class Coefficients {
 
       final Imt imt;
       final double c, v1, v2, vf, σvc, σl, σu;
       final double f760i, f760g, f760iσ, f760gσ;
-      final double f3, f4, f5, vc, σc;
+      final double f3, f4, f4mod, f5, vc, σc;
 
       Coefficients(Imt imt, CoefficientContainer cc) {
         this.imt = imt;
@@ -880,6 +916,7 @@ public abstract class NgaEast_2018 implements GroundMotionModel {
         f760gσ = coeffs.get("f760gs");
         f3 = coeffs.get("f3");
         f4 = coeffs.get("f4");
+        f4mod = coeffs.get("f4mod");
         f5 = coeffs.get("f5");
         vc = coeffs.get("Vc");
         σc = coeffs.get("sig_c");
@@ -1010,6 +1047,10 @@ public abstract class NgaEast_2018 implements GroundMotionModel {
       return new Value(fT, σT);
     }
 
+    double calcF4() {
+      return c.f4;
+    }
+
     /**
      * Wrapper class for site amplification and associated epistemic
      * uncertainty.
@@ -1036,4 +1077,20 @@ public abstract class NgaEast_2018 implements GroundMotionModel {
     }
   }
 
+  /*
+   * Stewart et al. site amplification model, updated with alternate non-linear
+   * coefficient f4 per final Hashash et al. (2020) model.
+   */
+  static class SiteAmp_2023 extends SiteAmp {
+
+    SiteAmp_2023(Imt imt) {
+      super(imt);
+    }
+
+    @Override
+    double calcF4() {
+      return c.f4 * 0.5 + c.f4mod * 0.5;
+    }
+  }
+
 }
diff --git a/src/main/java/gov/usgs/earthquake/nshmp/gmm/PezeshkEtAl_2018.java b/src/main/java/gov/usgs/earthquake/nshmp/gmm/PezeshkEtAl_2018.java
index 4e67c71a9211ae4032871d292bb561e734c9afdb..416c4b5c38f25e8f2d7014610a639bb3922ca876 100644
--- a/src/main/java/gov/usgs/earthquake/nshmp/gmm/PezeshkEtAl_2018.java
+++ b/src/main/java/gov/usgs/earthquake/nshmp/gmm/PezeshkEtAl_2018.java
@@ -19,7 +19,7 @@ import com.google.common.annotations.Beta;
 import com.google.common.collect.Range;
 
 import gov.usgs.earthquake.nshmp.gmm.GmmInput.Constraints;
-import gov.usgs.earthquake.nshmp.gmm.NgaEast_2018.SiteAmp;
+import gov.usgs.earthquake.nshmp.gmm.NgaEast.SiteAmp;
 import gov.usgs.earthquake.nshmp.tree.LogicTree;
 
 /**
@@ -157,7 +157,7 @@ public abstract class PezeshkEtAl_2018 implements GroundMotionModel {
     CoefficientContainer cc = (model == Model.M1SS) ? COEFFS_M1SS : COEFFS_M2ES;
     coeffs = new Coefficients(imt, cc, COEFFS_SIGMAS, model);
     coeffsPga = new Coefficients(Imt.PGA, cc, COEFFS_SIGMAS, model);
-    this.siteAmp = new NgaEast_2018.SiteAmp(imt);
+    this.siteAmp = new NgaEast.SiteAmp(imt);
   }
 
   @Override
@@ -209,7 +209,7 @@ public abstract class PezeshkEtAl_2018 implements GroundMotionModel {
 
   static final class Seed_PZCT18_M1SS extends PezeshkEtAl_2018 {
     static final String MODEL = Model.M1SS;
-    static final String NAME = NgaEast_2018.Seed.NAME + MODEL + "*";
+    static final String NAME = NgaEast.Seed.NAME + MODEL + "*";
 
     Seed_PZCT18_M1SS(Imt imt) {
       super(imt, MODEL);
@@ -218,7 +218,7 @@ public abstract class PezeshkEtAl_2018 implements GroundMotionModel {
 
   static final class Seed_PZCT18_M2ES extends PezeshkEtAl_2018 {
     static final String MODEL = Model.M2ES;
-    static final String NAME = NgaEast_2018.Seed.NAME + MODEL + "*";
+    static final String NAME = NgaEast.Seed.NAME + MODEL + "*";
 
     Seed_PZCT18_M2ES(Imt imt) {
       super(imt, MODEL);
diff --git a/src/main/java/gov/usgs/earthquake/nshmp/gmm/ShahjoueiPezeshk_2016.java b/src/main/java/gov/usgs/earthquake/nshmp/gmm/ShahjoueiPezeshk_2016.java
index 1232ce60a7dcd336bb87ebaab6e65068108f730e..dba741f995861d155ce35b47bbdede5359267917 100644
--- a/src/main/java/gov/usgs/earthquake/nshmp/gmm/ShahjoueiPezeshk_2016.java
+++ b/src/main/java/gov/usgs/earthquake/nshmp/gmm/ShahjoueiPezeshk_2016.java
@@ -15,7 +15,7 @@ import java.util.Map;
 import com.google.common.collect.Range;
 
 import gov.usgs.earthquake.nshmp.gmm.GmmInput.Constraints;
-import gov.usgs.earthquake.nshmp.gmm.NgaEast_2018.SiteAmp;
+import gov.usgs.earthquake.nshmp.gmm.NgaEast.SiteAmp;
 import gov.usgs.earthquake.nshmp.tree.LogicTree;
 
 /**
@@ -53,7 +53,7 @@ public final class ShahjoueiPezeshk_2016 implements GroundMotionModel {
    * the sigma provided by this model is ignored in favor of the NGA-East sigma
    * logic tree when used with the seed model logic tree.
    */
-  static final String NAME = NgaEast_2018.Seed.NAME + "SP16áµ€*";
+  static final String NAME = NgaEast.Seed.NAME + "SP16áµ€*";
 
   static final Constraints CONSTRAINTS = Constraints.builder()
       .set(MW, Range.closed(4.0, 8.0))
@@ -99,19 +99,24 @@ public final class ShahjoueiPezeshk_2016 implements GroundMotionModel {
   ShahjoueiPezeshk_2016(Imt imt) {
     this.coeffs = new Coefficients(imt, COEFFS);
     this.coeffsPga = new Coefficients(Imt.PGA, COEFFS);
-    this.siteAmp = new NgaEast_2018.SiteAmp(imt);
+    this.siteAmp = new NgaEast.SiteAmp(imt);
   }
 
   @Override
   public final LogicTree<GroundMotion> calc(GmmInput in) {
     double μPga = exp(calcMean(coeffsPga, in.Mw, in.rJB));
-    double μ = calcMean(coeffs, in.Mw, in.rJB);
+    double μ = calcMeanRock(in.Mw, in.rJB);
     double σ = calcStdDev(coeffs, in.Mw);
     SiteAmp.Value fSite = siteAmp.calc(μPga, in.vs30);
     μ = fSite.apply(μ);
     return GroundMotions.createTree(μ, σ);
   }
 
+  /* Convenince method to get mean for Vs30 = 3000 m/s; for NgaEast */
+  final double calcMeanRock(double Mw, double rJB) {
+    return calcMean(coeffs, Mw, rJB);
+  }
+
   private static double calcMean(Coefficients c, double Mw, double rJB) {
     double r = sqrt(rJB * rJB + c.c11 * c.c11);
     double μ = c.c1 +
diff --git a/src/main/resources/gmm/coeffs/nga-east-usgs-siteamp.csv b/src/main/resources/gmm/coeffs/nga-east-usgs-siteamp.csv
index 47c0d18fcf6c81e40038284dbe00bfc15634e12a..53dc320a6c7d366f0da39d9bf21e1d28c97e09ef 100644
--- a/src/main/resources/gmm/coeffs/nga-east-usgs-siteamp.csv
+++ b/src/main/resources/gmm/coeffs/nga-east-usgs-siteamp.csv
@@ -1,27 +1,27 @@
-  T,     f760i, f760g, f760is, f760gs,      c,  V1,   V2,  Vf, sig_vc, sig_l, sig_u,      f3,       f4,       f5,   Vc, sig_c
-  PGV,   0.375, 0.297,  0.313,  0.117, -0.449, 331,  760, 314,  0.251, 0.306, 0.334, 0.06089, -0.08344, -0.00667, 2257, 0.120
-  PGA,   0.185, 0.121,  0.434,  0.248, -0.290, 319,  760, 345,  0.300, 0.345, 0.480, 0.07520, -0.43755, -0.00131, 2990, 0.120
-  0.01,  0.185, 0.121,  0.434,  0.248, -0.290, 319,  760, 345,  0.300, 0.345, 0.480, 0.07520, -0.43755, -0.00131, 2990, 0.120
-  0.02,  0.185, 0.031,  0.434,  0.270, -0.303, 319,  760, 343,  0.290, 0.336, 0.479, 0.05660, -0.41511, -0.00098, 2990, 0.120
-  0.03,  0.224, 0.000,  0.404,  0.229, -0.315, 319,  810, 342,  0.282, 0.327, 0.478, 0.10360, -0.49871, -0.00127, 2990, 0.120
-# 0.04,  0.283, 0.012,  0.390,  0.139, -0.331, 319,  900, 340,  0.275, 0.317, 0.477, 0.11836, -0.48734, -0.00169, 2990, 0.120
-  0.05,  0.337, 0.062,  0.363,  0.093, -0.344, 319, 1010, 338,  0.271, 0.308, 0.476, 0.16781, -0.58073, -0.00187, 2990, 0.120
-  0.075, 0.475, 0.211,  0.322,  0.102, -0.348, 319, 1380, 334,  0.269, 0.285, 0.473, 0.17386, -0.53646, -0.00259, 2990, 0.120
-# 0.1,   0.674, 0.338,  0.366,  0.088, -0.372, 317, 1900, 319,  0.270, 0.263, 0.470, 0.15083, -0.44661, -0.00335, 2990, 0.120
-  0.1,   0.521, 0.338,  0.293,  0.088, -0.372, 317, 1900, 319,  0.270, 0.263, 0.470, 0.15083, -0.44661, -0.00335, 2990, 0.120
-  0.15,  0.586, 0.470,  0.253,  0.066, -0.385, 302, 1500, 317,  0.261, 0.284, 0.402, 0.14272, -0.38264, -0.00410, 2335, 0.120
-  0.2,   0.419, 0.509,  0.214,  0.053, -0.403, 279, 1073, 314,  0.251, 0.306, 0.334, 0.12815, -0.30481, -0.00488, 1533, 0.120
-  0.25,  0.332, 0.509,  0.177,  0.052, -0.417, 250,  945, 282,  0.238, 0.291, 0.357, 0.13286, -0.27506, -0.00564, 1318, 0.135
-  0.3,   0.270, 0.498,  0.131,  0.055, -0.426, 225,  867, 250,  0.225, 0.276, 0.381, 0.13070, -0.22825, -0.00655, 1152, 0.150
-  0.4,   0.209, 0.473,  0.112,  0.060, -0.452, 217,  843, 250,  0.225, 0.275, 0.381, 0.09414, -0.11591, -0.00872, 1018, 0.150
-  0.5,   0.175, 0.447,  0.105,  0.067, -0.480, 217,  822, 280,  0.225, 0.311, 0.323, 0.09888, -0.07793, -0.01028,  939, 0.150
-  0.75,  0.127, 0.386,  0.138,  0.077, -0.510, 227,  814, 280,  0.225, 0.330, 0.310, 0.06101, -0.01780, -0.01456,  835, 0.125
-  1.0,   0.095, 0.344,  0.124,  0.078, -0.557, 255,  790, 300,  0.225, 0.377, 0.361, 0.04367, -0.00478, -0.01823,  951, 0.060
-  1.5,   0.083, 0.289,  0.112,  0.081, -0.574, 276,  805, 300,  0.242, 0.405, 0.375, 0.00480, -0.00086, -0.02000,  882, 0.050
-  2.0,   0.079, 0.258,  0.118,  0.088, -0.584, 296,  810, 300,  0.259, 0.413, 0.388, 0.00164, -0.00236, -0.01296,  879, 0.040
-  3.0,   0.073, 0.233,  0.111,  0.100, -0.588, 312,  820, 313,  0.306, 0.410, 0.551, 0.00746, -0.00626, -0.01043,  894, 0.040
-  4.0,   0.066, 0.224,  0.120,  0.109, -0.579, 321,  821, 322,  0.340, 0.405, 0.585, 0.00269, -0.00331, -0.01215,  875, 0.030
-  5.0,   0.064, 0.220,  0.108,  0.115, -0.558, 324,  825, 325,  0.340, 0.409, 0.587, 0.00242, -0.00256, -0.01325,  856, 0.020
-  7.5,   0.056, 0.216,  0.082,  0.130, -0.544, 325,  820, 328,  0.345, 0.420, 0.594, 0.04219, -0.00536, -0.01418,  832, 0.020
-  10.0,  0.053, 0.218,  0.069,  0.137, -0.507, 325,  820, 330,  0.350, 0.440, 0.600, 0.05329, -0.00631, -0.01403,  837, 0.020
+  T,     f760i, f760g, f760is, f760gs,      c,  V1,   V2,  Vf, sig_vc, sig_l, sig_u,      f3,       f4,    f4mod,       f5,   Vc, sig_c
+  PGV,   0.375, 0.297,  0.313,  0.117, -0.449, 331,  760, 314,  0.251, 0.306, 0.334, 0.06089, -0.08344, -0.08344, -0.00667, 2257, 0.120
+  PGA,   0.185, 0.121,  0.434,  0.248, -0.290, 319,  760, 345,  0.300, 0.345, 0.480, 0.07520, -0.43755, -0.43755, -0.00131, 2990, 0.120
+  0.01,  0.185, 0.121,  0.434,  0.248, -0.290, 319,  760, 345,  0.300, 0.345, 0.480, 0.07520, -0.43755, -0.43755, -0.00131, 2990, 0.120
+  0.02,  0.185, 0.031,  0.434,  0.270, -0.303, 319,  760, 343,  0.290, 0.336, 0.479, 0.05660, -0.41511, -0.41511, -0.00098, 2990, 0.120
+  0.03,  0.224, 0.000,  0.404,  0.229, -0.315, 319,  810, 342,  0.282, 0.327, 0.478, 0.10360, -0.49871, -0.49871, -0.00127, 2990, 0.120
+# 0.04,  0.283, 0.012,  0.390,  0.139, -0.331, 319,  900, 340,  0.275, 0.317, 0.477, 0.11836, -0.48734, -0.48734, -0.00169, 2990, 0.120
+  0.05,  0.337, 0.062,  0.363,  0.093, -0.344, 319, 1010, 338,  0.271, 0.308, 0.476, 0.16781, -0.58073, -0.58073, -0.00187, 2990, 0.120
+  0.075, 0.475, 0.211,  0.322,  0.102, -0.348, 319, 1380, 334,  0.269, 0.285, 0.473, 0.17386, -0.53646, -0.53646, -0.00259, 2990, 0.120
+# 0.1,   0.674, 0.338,  0.366,  0.088, -0.372, 317, 1900, 319,  0.270, 0.263, 0.470, 0.15083, -0.44661, -0.44661, -0.00335, 2990, 0.120
+  0.1,   0.521, 0.338,  0.293,  0.088, -0.372, 317, 1900, 319,  0.270, 0.263, 0.470, 0.15083, -0.44661, -0.44661, -0.00335, 2990, 0.120
+  0.15,  0.586, 0.470,  0.253,  0.066, -0.385, 302, 1500, 317,  0.261, 0.284, 0.402, 0.14272, -0.38264, -0.38264, -0.00410, 2335, 0.120
+  0.2,   0.419, 0.509,  0.214,  0.053, -0.403, 279, 1073, 314,  0.251, 0.306, 0.334, 0.12815, -0.30481, -0.30481, -0.00488, 1533, 0.120
+  0.25,  0.332, 0.509,  0.177,  0.052, -0.417, 250,  945, 282,  0.238, 0.291, 0.357, 0.13286, -0.27506, -0.27506, -0.00564, 1318, 0.135
+  0.3,   0.270, 0.498,  0.131,  0.055, -0.426, 225,  867, 250,  0.225, 0.276, 0.381, 0.13070, -0.22825, -0.22825, -0.00655, 1152, 0.150
+  0.4,   0.209, 0.473,  0.112,  0.060, -0.452, 217,  843, 250,  0.225, 0.275, 0.381, 0.09414, -0.11591, -0.13060, -0.00872, 1018, 0.150
+  0.5,   0.175, 0.447,  0.105,  0.067, -0.480, 217,  822, 280,  0.225, 0.311, 0.323, 0.09888, -0.07793, -0.09571, -0.01028,  939, 0.150
+  0.75,  0.127, 0.386,  0.138,  0.077, -0.510, 227,  814, 280,  0.225, 0.330, 0.310, 0.06101, -0.01780, -0.02909, -0.01456,  835, 0.125
+  1.0,   0.095, 0.344,  0.124,  0.078, -0.557, 255,  790, 300,  0.225, 0.377, 0.361, 0.04367, -0.00478, -0.01057, -0.01823,  951, 0.060
+  1.5,   0.083, 0.289,  0.112,  0.081, -0.574, 276,  805, 300,  0.242, 0.405, 0.375, 0.00480, -0.00086, -0.00253, -0.02000,  882, 0.050
+  2.0,   0.079, 0.258,  0.118,  0.088, -0.584, 296,  810, 300,  0.259, 0.413, 0.388, 0.00164, -0.00236, -0.00236, -0.01296,  879, 0.040
+  3.0,   0.073, 0.233,  0.111,  0.100, -0.588, 312,  820, 313,  0.306, 0.410, 0.551, 0.00746, -0.00626, -0.00626, -0.01043,  894, 0.040
+  4.0,   0.066, 0.224,  0.120,  0.109, -0.579, 321,  821, 322,  0.340, 0.405, 0.585, 0.00269, -0.00331, -0.00331, -0.01215,  875, 0.030
+  5.0,   0.064, 0.220,  0.108,  0.115, -0.558, 324,  825, 325,  0.340, 0.409, 0.587, 0.00242, -0.00256, -0.00256, -0.01325,  856, 0.020
+  7.5,   0.056, 0.216,  0.082,  0.130, -0.544, 325,  820, 328,  0.345, 0.420, 0.594, 0.04219, -0.00536, -0.00536, -0.01418,  832, 0.020
+  10.0,  0.053, 0.218,  0.069,  0.137, -0.507, 325,  820, 330,  0.350, 0.440, 0.600, 0.05329, -0.00631, -0.00631, -0.01403,  837, 0.020
 # commented 0.1s line containes original (unsmoothed) 0.1s F760 mean and sigma
diff --git a/src/test/java/gov/usgs/earthquake/nshmp/gmm/NgaEast.java b/src/test/java/gov/usgs/earthquake/nshmp/gmm/NgaEastTests.java
similarity index 95%
rename from src/test/java/gov/usgs/earthquake/nshmp/gmm/NgaEast.java
rename to src/test/java/gov/usgs/earthquake/nshmp/gmm/NgaEastTests.java
index d60eb6f7d570f7a63140462b1f4768587e84a3d2..1c41fb4f242b7fdb9f29357baddb499f3437da40 100644
--- a/src/test/java/gov/usgs/earthquake/nshmp/gmm/NgaEast.java
+++ b/src/test/java/gov/usgs/earthquake/nshmp/gmm/NgaEastTests.java
@@ -22,13 +22,13 @@ import org.junit.jupiter.params.provider.Arguments;
 import org.junit.jupiter.params.provider.ArgumentsProvider;
 import org.junit.jupiter.params.provider.ArgumentsSource;
 
-class NgaEast implements ArgumentsProvider {
+class NgaEastTests implements ArgumentsProvider {
 
   private static String GMM_INPUTS = "/gmm/nga-east-inputs.csv";
   private static String GMM_RESULTS = "/gmm/nga-east-results.csv";
 
   @ParameterizedTest(name = "({index}) {0} {2} {1}")
-  @ArgumentsSource(NgaEast.class)
+  @ArgumentsSource(NgaEastTests.class)
   void test(int index, Gmm gmm, Imt imt, double exMedian, double exSigma, String inputs) {
     GmmTest.test(index, gmm, imt, exMedian, exSigma, inputs);
   }