Пример #1
0
  /**
   * Create a tree from the given newick format
   *
   * @param taxaNames a list of taxa names to use, or null. If null then IsLabelledNewick will be
   *     set to true
   * @param newick the newick of the tree
   * @param offset the offset to map node numbers in newick format to indices in taxaNames. so,
   *     name(node with nodeNumber) = taxaNames[nodeNumber-offset]
   * @param adjustTipHeightsWhenMissingDateTraits true if tip heights should be adjusted to zero
   * @throws Exception
   */
  public TreeParser(
      final List<String> taxaNames,
      final String newick,
      final int offset,
      final boolean adjustTipHeightsWhenMissingDateTraits)
      throws Exception {

    if (taxaNames == null) {
      isLabelledNewickInput.setValue(true, this);
    } else {
      m_taxonset.setValue(new TaxonSet(Taxon.createTaxonList(taxaNames)), this);
    }
    newickInput.setValue(newick, this);
    offsetInput.setValue(offset, this);
    adjustTipHeightsInput.setValue(adjustTipHeightsWhenMissingDateTraits, this);
    labels = taxaNames;
    initAndValidate();
  }
Пример #2
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