/**
  * create new instance of src object, connecting all inputs from src object Note if input is a
  * SubstModel, it is duplicated as well.
  *
  * @param src object to be copied
  * @param i index used to extend ID with.
  * @return copy of src object
  */
 private Object duplicate(BEASTInterface src, int i) {
   if (src == null) {
     return null;
   }
   BEASTInterface copy;
   try {
     copy = src.getClass().newInstance();
     copy.setID(src.getID() + "_" + i);
   } catch (InstantiationException | IllegalAccessException e) {
     e.printStackTrace();
     throw new RuntimeException(
         "Programmer error: every object in the model should have a default constructor that is publicly accessible: "
             + src.getClass().getName());
   }
   for (Input<?> input : src.listInputs()) {
     if (input.get() != null) {
       if (input.get() instanceof List) {
         // handle lists
         // ((List)copy.getInput(input.getName())).clear();
         for (Object o : (List<?>) input.get()) {
           if (o instanceof BEASTInterface) {
             // make sure it is not already in the list
             copy.setInputValue(input.getName(), o);
           }
         }
       } else if (input.get() instanceof SubstitutionModel) {
         // duplicate subst models
         BEASTInterface substModel = (BEASTInterface) duplicate((BEASTInterface) input.get(), i);
         copy.setInputValue(input.getName(), substModel);
       } else {
         // it is some other value
         copy.setInputValue(input.getName(), input.get());
       }
     }
   }
   copy.initAndValidate();
   return copy;
 }
Example #2
0
 /**
  * produce XML for an input of a beast object, both as attribute/value pairs for primitive inputs
  * (if isShort=true) and as individual elements (if isShort=false)
  *
  * @param input: name of the input
  * @param beastObject: beast object to produce this input XML for
  * @param buf: gets XML results are appended
  * @param isShort: flag to indicate attribute/value format (true) or element format (false)
  * @throws Exception
  */
 void inputToXML(
     Input<?> input, Object value, BEASTInterface beastObject, StringBuffer buf, boolean isShort)
     throws Exception {
   // if (input.getName().equals("*")) {
   // this can happen with beast.core.parameter.Map
   // and * is not a valid XML attribute name
   // return;
   // }
   if (value != null) {
     if (value instanceof Map) {
       // distinguish between List, Map, BEASTInterface and primitive input types
       if (isShort) {
         @SuppressWarnings("unchecked")
         Map<String, ?> map = (Map<String, ?>) value;
         // determine label width
         int whiteSpaceWidth = 0;
         List<String> keys = new ArrayList<>();
         keys.addAll(map.keySet());
         Collections.sort(keys);
         for (String key : keys) {
           whiteSpaceWidth = Math.max(whiteSpaceWidth, key.length());
         }
         for (String key : map.keySet()) {
           // buf.append("        <input name='" + key + "'>");
           buf.append("\n        " + key);
           for (int k = key.length(); k < whiteSpaceWidth; k++) {
             buf.append(' ');
           }
           buf.append("=\"" + normalise(map.get(key).toString()) + "\"");
         }
       }
       return;
     } else if (value instanceof List) {
       if (!isShort) {
         int k = 0;
         List<?> list = (List<?>) value;
         for (Object o2 : list) {
           if (o2 instanceof BEASTInterface) {
             beastObjectToXML((BEASTInterface) o2, buf, input.getName(), false);
           } else {
             k++;
             buf.append(o2.toString());
             if (k < list.size()) {
               buf.append(' ');
             }
           }
         }
       }
       return;
     } else if (value instanceof BEASTInterface) {
       if (!value.equals(input.defaultValue)) {
         if (isShort && isDone.contains(value)) {
           buf.append(
               " " + input.getName() + "='@" + normalise(((BEASTInterface) value).getID()) + "'");
           if (!isInputsDone.containsKey(beastObject)) {
             isInputsDone.put(beastObject, new HashSet<>());
           }
           isInputsDone.get(beastObject).add(input.getName());
         }
         if (!isShort
             && (!isInputsDone.containsKey(beastObject)
                 || !isInputsDone.get(beastObject).contains(input.getName()))) {
           beastObjectToXML((BEASTInterface) value, buf, input.getName(), false);
         }
       }
       return;
     } else {
       if (!value.equals(input.defaultValue)) {
         // primitive type
         String valueString = value.toString();
         if (isShort) {
           if (valueString.indexOf('\n') < 0) {
             buf.append(" " + input.getName() + "='" + normalise(value.toString()) + "'");
           }
         } else {
           if (valueString.indexOf('\n') >= 0) {
             for (int j = 0; j < indent; j++) {
               buf.append("    ");
             }
             if (input.getName().equals("value")) {
               buf.append(normalise(value.toString()));
             } else {
               buf.append(
                   "<input name='"
                       + input.getName()
                       + "'>"
                       + normalise(value.toString())
                       + "</input>\n");
             }
           }
         }
       }
       return;
     }
   } else {
     // value=null, no XML to produce
     return;
   }
 } // inputToXML
Example #3
0
  /** Ensure the class behaves properly, even when inputs are not specified. */
  @Override
  public void initAndValidate() throws Exception {
    boolean sortNodesAlphabetically = false;

    if (dataInput.get() != null) {
      labels = dataInput.get().getTaxaNames();
    } else if (m_taxonset.get() != null) {
      if (labels == null) {
        labels = m_taxonset.get().asStringList();
      } else { // else labels were set by TreeParser c'tor
        sortNodesAlphabetically = true;
      }
    } else {
      if (isLabelledNewickInput.get()) {
        if (m_initial.get() != null) {
          labels = m_initial.get().getTaxonset().asStringList();
        } else {
          labels = new ArrayList<>();
          createUnrecognizedTaxa = true;
          sortNodesAlphabetically = true;
        }
      } else {
        if (m_initial.get() != null) {
          // try to pick up taxa from initial tree
          final Tree tree = m_initial.get();
          if (tree.m_taxonset.get() != null) {
            labels = tree.m_taxonset.get().asStringList();
          } else {
            // m_sLabels = null;
          }
        } else {
          // m_sLabels = null;
        }
      }
      //            m_bIsLabelledNewick = false;
    }
    final String newick = newickInput.get();
    if (newick == null || newick.equals("")) {
      // can happen while initalising Beauti
      final Node dummy = new Node();
      setRoot(dummy);
    } else {
      try {
        setRoot(parseNewick(newickInput.get()));
      } catch (ParseCancellationException e) {
        throw new RuntimeException(
            "TreeParser cannot make sense of the Newick string "
                + "provided.  It gives the following clue:\n"
                + e.getMessage());
      }
    }

    super.initAndValidate();

    if (sortNodesAlphabetically) {
      // correct for node ordering: ensure order is alphabetical
      for (int i = 0; i < getNodeCount() && i < labels.size(); i++) {
        m_nodes[i].setID(labels.get(i));
      }

      Node[] nodes = new Node[labels.size()];
      System.arraycopy(m_nodes, 0, nodes, 0, labels.size());

      Arrays.sort(nodes, (o1, o2) -> o1.getID().compareTo(o2.getID()));
      for (int i = 0; i < labels.size(); i++) {
        m_nodes[i] = nodes[i];
        nodes[i].setNr(i);
      }
    }

    if (m_initial.get() != null) processTraits(m_initial.get().m_traitList.get());
    else processTraits(m_traitList.get());

    if (timeTraitSet != null) {
      adjustTreeNodeHeights(root);
    } else if (adjustTipHeightsInput.get()) {

      double treeLength = TreeUtils.getTreeLength(this, getRoot());

      double extraTreeLength = 0.0;
      double maxTipHeight = 0.0;

      // all nodes should be at zero height if no date-trait is available
      for (int i = 0; i < getLeafNodeCount(); i++) {
        double height = getNode(i).getHeight();
        if (maxTipHeight < height) {
          maxTipHeight = height;
        }
        extraTreeLength += height;
        getNode(i).setHeight(0);
      }

      double scaleFactor = (treeLength + extraTreeLength) / treeLength;

      final double SCALE_FACTOR_THRESHOLD = 0.001;

      // if the change in total tree length is more than 0.1% then give the user a warning!
      if (scaleFactor > 1.0 + SCALE_FACTOR_THRESHOLD) {

        DecimalFormat format = new DecimalFormat("#.##");

        Log.info.println(
            "WARNING: Adjust tip heights attribute set to 'true' in " + getClass().getSimpleName());
        Log.info.println(
            "         has resulted in significant (>"
                + format.format(SCALE_FACTOR_THRESHOLD * 100.0)
                + "%) change in tree length.");
        Log.info.println(
            "         Use "
                + adjustTipHeightsInput.getName()
                + "='false' to override this default.");
        Log.info.printf("  original max tip age = %8.3f\n", maxTipHeight);
        Log.info.printf("       new max tip age = %8.3f\n", 0.0);
        Log.info.printf("  original tree length = %8.3f\n", treeLength);
        Log.info.printf("       new tree length = %8.3f\n", treeLength + extraTreeLength);
        Log.info.printf("       TL scale factor = %8.3f\n", scaleFactor);
      }
    }

    if (m_taxonset.get() == null && labels != null && isLabelledNewickInput.get()) {
      m_taxonset.setValue(new TaxonSet(Taxon.createTaxonList(labels)), this);
    }

    initStateNodes();
  } // init
Example #4
0
  /**
   * produce JSON for an input of a beastObject, both as attribute/value pairs for primitive inputs
   * (if isShort=true) and as individual elements (if isShort=false)
   *
   * @param input0: name of the input
   * @param beastObject: beastObject to produce this input JSON for
   * @param buf: gets JSON results are appended
   * @param isShort: flag to indicate attribute/value format (true) or element format (false)
   * @throws Exception
   */
  @SuppressWarnings({"rawtypes", "unchecked"})
  private void inputToJSON(
      Input input,
      Object value,
      BEASTInterface beastObject,
      StringBuffer buf,
      boolean isShort,
      String indent)
      throws Exception {
    if (value != null) {

      // distinguish between Map, List, BEASTObject and primitive input types
      if (value instanceof Map) {
        if (!isShort) {
          Map<String, ?> map = (Map<String, ?>) value;
          StringBuffer buf2 = new StringBuffer();

          // determine label width
          int whiteSpaceWidth = 0;
          for (String key : map.keySet()) {
            whiteSpaceWidth = Math.max(whiteSpaceWidth, key.length());
          }
          boolean needsComma = false;
          List<String> keys = new ArrayList<>();
          keys.addAll(map.keySet());
          Collections.sort(keys);
          for (String key : keys) {
            if (needsComma) {
              buf2.append(",\n");
            }
            buf2.append(indent + " " + key);
            for (int k = key.length(); k < whiteSpaceWidth; k++) {
              buf2.append(' ');
            }
            buf2.append(" :\"" + map.get(key) + "\"");
            needsComma = true;
          }
          buf.append(buf2);
        }
        return;
      } else if (value instanceof List) {
        if (!isShort) {
          StringBuffer buf2 = new StringBuffer();
          // buf2.append(indent + " \"" + input0 + "\": [\n");
          buf2.append(indent + " " + input.getName() + ": [\n");
          boolean needsComma = false;
          int oldLen = buf2.length();
          for (Object o2 : (List) value) {
            if (needsComma) {
              buf2.append(",\n");
            }
            StringBuffer buf3 = new StringBuffer();
            if (o2 instanceof BEASTInterface) {
              beastObjectToJSON((BEASTInterface) o2, input.getType(), buf3, null, false);
            } else {
              buf2.append(o2.toString());
            }
            buf2.append(buf3);
            needsComma = oldLen < buf2.length();
          }
          if (buf2.length() != oldLen) {
            buf.append(buf2);
            buf.append("\n" + indent + "  ]");
          }
        }
        return;
      } else if (value instanceof BEASTInterface) {
        if (!value.equals(input.defaultValue)) {

          // Parameters can use short hand notation if they are not in the state
          // Note this means lower and upper bounds are lost -- no problem for BEAST, but maybe for
          // BEAUti
          if (value instanceof Parameter.Base) {
            Parameter.Base parameter = (Parameter.Base) value;
            boolean isInState = false;
            for (Object o : parameter.getOutputs()) {
              if (o instanceof State) {
                isInState = true;
                break;
              }
            }
            if (!isInState) {
              if (isShort) {
                buf.append(" " + input.getName() + ": \"" + parameter.getValue() + "\"");
              } else {
                return;
              }
            }
          }

          if (isShort && isDone.contains(value)) {
            buf.append(" " + input.getName() + ": \"@" + ((BEASTInterface) value).getID() + "\"");
            if (!isInputsDone.containsKey(beastObject)) {
              isInputsDone.put(beastObject, new HashSet<>());
            }
            isInputsDone.get(beastObject).add(input.getName());
          }
          if (!isShort
              && (!isInputsDone.containsKey(beastObject)
                  || !isInputsDone.get(beastObject).contains(input.getName()))) {
            beastObjectToJSON((BEASTInterface) value, input.getType(), buf, input.getName(), false);
          }
        }
        return;
      } else {
        // primitive type

        if (!value.equals(input.defaultValue)) {

          String valueString = value.toString();
          if (isShort) {
            if (valueString.indexOf('\n') < 0) {
              buf.append(" " + input.getName() + ": " + normalise(input, value.toString()) + "");
            }
          } else {
            if (valueString.indexOf('\n') >= 0) {
              buf.append(
                  indent + "" + input.getName() + ": " + normalise(input, value.toString()) + "");
            }
          }
        }
        return;
      }
    } else {
      // value=null, no JSON to produce
      return;
    }
  } // inputToJSON