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/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";