diff --git a/src/main/java/gov/usgs/earthquake/nshmp/calc/CalcConfig.java b/src/main/java/gov/usgs/earthquake/nshmp/calc/CalcConfig.java
index 9d1ca70acdbe619d773a7a9da11172927ac568ea..ecbd29e712c1af6f275ee7238c95140291ca5280 100644
--- a/src/main/java/gov/usgs/earthquake/nshmp/calc/CalcConfig.java
+++ b/src/main/java/gov/usgs/earthquake/nshmp/calc/CalcConfig.java
@@ -24,7 +24,6 @@ import java.nio.file.Path;
 import java.nio.file.Paths;
 import java.util.Arrays;
 import java.util.Collections;
-import java.util.EnumSet;
 import java.util.List;
 import java.util.Map;
 import java.util.NavigableMap;
@@ -341,7 +340,7 @@ public final class CalcConfig {
         if (that.truncationLevel != null) {
           this.truncationLevel = that.truncationLevel;
         }
-        if (that.imts != null) {
+        if (that.imts != null && !that.imts.isEmpty()) {
           this.imts = that.imts;
         }
         if (that.tectonicSettings != null) {
@@ -797,10 +796,7 @@ public final class CalcConfig {
 
     private Output(Builder b) {
       this.directory = b.directory;
-      Set<DataType> dataTypes = EnumSet.copyOf(b.dataTypes);
-      dataTypes.add(DataType.TOTAL);
-      dataTypes.add(DataType.MAP);
-      this.dataTypes = Collections.unmodifiableSet(dataTypes);
+      this.dataTypes = Collections.unmodifiableSet(b.dataTypes);
       this.returnPeriods = List.copyOf(b.returnPeriods);
     }
 
@@ -819,7 +815,7 @@ public final class CalcConfig {
 
       void copy(Output that) {
         this.directory = that.directory;
-        this.dataTypes = EnumSet.copyOf(that.dataTypes);
+        this.dataTypes = that.dataTypes;
         this.returnPeriods = that.returnPeriods;
       }
 
@@ -827,8 +823,8 @@ public final class CalcConfig {
         if (that.directory != null) {
           this.directory = that.directory;
         }
-        if (that.dataTypes != null) {
-          this.dataTypes = EnumSet.copyOf(that.dataTypes);
+        if (that.dataTypes != null && !that.dataTypes.isEmpty()) {
+          this.dataTypes.addAll(that.dataTypes);
         }
         if (that.returnPeriods != null) {
           this.returnPeriods = that.returnPeriods;
@@ -984,7 +980,8 @@ public final class CalcConfig {
 
     /**
      * Extend {@code this} builder to match {@code that} builder. Fields in
-     * {@code that} builder take precedence unless they are not set.
+     * {@code that} builder take precedence unless they are not set. Array based
+     * settings are replaced.
      */
     public Builder extend(Builder that) {
       checkNotNull(that);
diff --git a/src/main/java/gov/usgs/earthquake/nshmp/gmm/UsgsDampingScaling.java b/src/main/java/gov/usgs/earthquake/nshmp/gmm/UsgsDampingScaling.java
index 66e8b5d87e555ff521b8845f10e466489a3231a0..46b1c79bc7fcf95c3b6466b84e65626872cbe528 100644
--- a/src/main/java/gov/usgs/earthquake/nshmp/gmm/UsgsDampingScaling.java
+++ b/src/main/java/gov/usgs/earthquake/nshmp/gmm/UsgsDampingScaling.java
@@ -79,13 +79,17 @@ public class UsgsDampingScaling {
    * TODO Disable subduction below 0.1s
    */
 
-  /** The range of supported damping ratios: {@code [0.5..30]}. */
+  /** The range of supported damping scaling factors: {@code [0.5..30]}. */
   public static final Range<Double> DAMPING_RATIO_RANGE = Range.closed(0.05, 30.0);
 
   private static final String[] DSF_KEYS =
       { "0.5", "1", "2", "3", "5", "7", "10", "15", "20", "25", "30" };
 
-  private static final List<Double> DSF_VALUES = Arrays.stream(DSF_KEYS)
+  /**
+   * The list of supported damping scaling factors (percentage values):
+   * {@code [0.5, 1, 2, 3, 5, 7, 10, 15, 20, 25, 30]}.
+   */
+  public static final List<Double> DSF_VALUES = Arrays.stream(DSF_KEYS)
       .map(Double::valueOf)
       .collect(toList());
 
@@ -148,7 +152,7 @@ public class UsgsDampingScaling {
     return XySequence.create(DSF_VALUES, corrCoeffs);
   }
 
-  /** The set of IMTs supported by this class. */
+  /** The set of IMTs supported by the damping models in this class. */
   public static final Set<Imt> supportedImts() {
     return INSTANCE_MAP.get(ACTIVE_CRUST).coeffs.keySet();
   }
diff --git a/src/main/java/gov/usgs/earthquake/nshmp/model/ModelTrees.java b/src/main/java/gov/usgs/earthquake/nshmp/model/ModelTrees.java
index 62f177253825a4478dcbfef6b83470f63266534a..072b6c1a1c57027cfac7c5e0081cecd949cbb2eb 100644
--- a/src/main/java/gov/usgs/earthquake/nshmp/model/ModelTrees.java
+++ b/src/main/java/gov/usgs/earthquake/nshmp/model/ModelTrees.java
@@ -249,7 +249,7 @@ class ModelTrees {
 
   /*
    * Convert a SourceTree to a logic tree of the total MFDs for each branch
-   * (RuptureSet). A LogicGroup is accomodates null (do-nothing) branches in the
+   * (RuptureSet). A LogicGroup accomodates null (do-nothing) branches in the
    * source tree.
    */
   static LogicGroup<Mfd> toMfdTree(SourceTree sourceTree) {
diff --git a/src/test/java/gov/usgs/earthquake/nshmp/calc/CalcConfigTests.java b/src/test/java/gov/usgs/earthquake/nshmp/calc/CalcConfigTests.java
index a8933b7993324ea4ec8144a3dbf2f0b707fde71d..5324603329921e1ae26f07d50756d12631cf0a5b 100644
--- a/src/test/java/gov/usgs/earthquake/nshmp/calc/CalcConfigTests.java
+++ b/src/test/java/gov/usgs/earthquake/nshmp/calc/CalcConfigTests.java
@@ -63,6 +63,8 @@ class CalcConfigTests {
   static final CalcConfig DEFAULTS;
   static final CalcConfig EXTENDS;
   static final CalcConfig EXTENDS_EMPTY; // same as DEFAULTS
+  // used to test that arrays are both non-null and not empty
+  static final CalcConfig EXTENDS_EMPTY_ARRAYS; // imts, types
 
   static {
     try {
@@ -73,6 +75,9 @@ class CalcConfigTests {
       EXTENDS_EMPTY = CalcConfig.defaults()
           .extend(CalcConfig.from(RESOURCES.resolve("calc-config-extends-empty.json")))
           .build();
+      EXTENDS_EMPTY_ARRAYS = CalcConfig.defaults()
+          .extend(CalcConfig.from(RESOURCES.resolve("calc-config-extends-empty-arrays.json")))
+          .build();
 
     } catch (IOException ioe) {
       throw new RuntimeException();
@@ -278,6 +283,9 @@ class CalcConfigTests {
     assertEquals(ValueFormat.ANNUAL_RATE, def.valueFormat);
     assertEquals(true, def.distanceFilterUpdate);
     assertEquals(true, def.gridFocalMechUpdate);
+
+    def = EXTENDS_EMPTY_ARRAYS.hazard;
+    assertEquals(IMTS, def.imts);
   }
 
   @Test
@@ -379,6 +387,9 @@ class CalcConfigTests {
     assertEquals(Path.of("hazout"), def.directory);
     assertEquals(Set.of(DataType.TOTAL, DataType.MAP), def.dataTypes);
     assertEquals(defaultReturnPeroiods, def.returnPeriods);
+
+    def = EXTENDS_EMPTY_ARRAYS.output;
+    assertEquals(Set.of(DataType.TOTAL, DataType.MAP), def.dataTypes);
   }
 
   @Test
diff --git a/src/test/resources/calc/calc-config-extends-empty-arrays.json b/src/test/resources/calc/calc-config-extends-empty-arrays.json
new file mode 100644
index 0000000000000000000000000000000000000000..1f82401fce1e452dc9f3886ff0867ab7db582171
--- /dev/null
+++ b/src/test/resources/calc/calc-config-extends-empty-arrays.json
@@ -0,0 +1,8 @@
+{
+  "hazard": {
+    "imts": []
+  },
+  "output": {
+  	"dataTypes": []
+  }
+}