All Downloads are FREE. Search and download functionalities are using the official Maven repository.

net.maizegenetics.taxa.tree.RootedTreeUtils Maven / Gradle / Ivy

// RootedTreeUtils.java
//
// (c) 1999-2001 PAL Development Core Team
//
// This package may be distributed under the
// terms of the Lesser GNU General Public License (LGPL)
package net.maizegenetics.taxa.tree;

import java.util.HashMap;
import java.util.Map;
import java.util.Vector;

/**
 * This class contains utility methods. These include: 
* 1. gathering information about subtrees from a set of trees
* 2. comparing subtrees and clades.
* All these methods assume rooted trees! * * @author Alexei Drummond * @version $Id: RootedTreeUtils.java,v 1.1 2007/01/12 03:26:17 tcasstevens Exp $ */ public class RootedTreeUtils { /** * @return true if the first node contains a subtree identical to the second node * or is identical to the second node. * @param root the root of the tree in which search for a subtree * @param node the subtree to search for. */ public static boolean containsSubtree(Node root, Node node) { return (getSubtree(root, node) != null); } /** * @return true if the given tree contains a clade holding all the * taxa in the given subtree. * * @param root the root of the tree in which search for a subtree * @param clade the hashtable of taxa. */ public static boolean containsClade(Node root, Node clade) { return (getClade(root, clade) != null); } /** * @return a subtree within the first node with the same * labelled topology as the second node or null if it doesn't exist. */ public static Node getSubtree(Node root, Node node) { if (equal(root, node)) return root; for (int i =0; i < root.getChildCount(); i++) { Node match = getSubtree(root.getChild(i), node); if (match != null) return match; } return null; } /** * @return a subtree within the first node with the same * labels as the second node or null if it doesn't exist. */ public static Node getClade(Node root, Node clade) { if (sameTaxa(root, clade)) return root; for (int i =0; i < root.getChildCount(); i++) { Node match = getClade(root.getChild(i), clade); if (match != null) return match; } return null; } /** * @return true if the trees have the same tip-labelled * structure. Child order is not important. */ public static boolean equal(Node node1, Node node2) { int nodeCount1 = node1.getChildCount(); int nodeCount2 = node2.getChildCount(); // if different childCount not the same if (nodeCount1 != nodeCount2) return false; if (nodeCount1 == 0) { return (node1.getIdentifier().getName().equals(node2.getIdentifier().getName())); } else { // ASSUMES BIFURCATING TREES // CHILD ORDER DIFFERENCES ARE ALLOWED! if (equal(node1.getChild(0), node2.getChild(0))) { return (equal(node1.getChild(1), node2.getChild(1))); } else if (equal(node1.getChild(0), node2.getChild(1))) { return (equal(node1.getChild(1), node2.getChild(0))); } else return false; } } /** * @return true if the trees have the same tip labels. topology unimportant. */ public static boolean sameTaxa(Node node1, Node node2) { int leafCount1 = NodeUtils.getLeafCount(node1); int leafCount2 = NodeUtils.getLeafCount(node2); if (leafCount1 != leafCount2) return false; HashMap table = new HashMap<>(leafCount1+1); collectTaxa(node1, table); return !containsNovelTaxa(node2, table); } /** * Collects all of the names of the taxa in the tree into a hashtable. * @return the number of new taxa added to the hashtable from this tree. * @param root the root node of the tree. * @param table a hashtable to hold the taxa names, may already hold some taxa names. */ public static int collectTaxa(Node root, Map table) { int nc = root.getChildCount(); if (nc == 0) { String name = root.getIdentifier().getName(); if (table.containsKey(name)) { return 0; } else { table.put(name, name); return 1; } } else { int newTaxaCount = 0; for (int i = 0; i < nc; i++) { newTaxaCount += collectTaxa(root.getChild(i), table); } return newTaxaCount; } } /** * @return true if the given tree contains taxa not already in the given hashtable. * @param root the root node of the tree. * @param taxa a hashtable holding taxa names. */ public static boolean containsNovelTaxa(Node root, Map taxa) { int nc = root.getChildCount(); if (nc == 0) { return !taxa.containsKey(root.getIdentifier().getName()); } else { for (int i = 0; i < nc; i++) { if (containsNovelTaxa(root.getChild(i), taxa)) return true; } return false; } } /** * @return the number of taxa in the given tree that are NOT in the given hashtable. * @param root the root node of the tree. * @param table a hashtable holding taxa names. */ private static int newTaxaCount(Node root, Map table) { int nc = root.getChildCount(); if (nc == 0) { return (table.containsKey(root.getIdentifier().getName()) ? 0 : 1); } else { int newTaxaCount = 0; for (int i = 0; i < nc; i++) { newTaxaCount += newTaxaCount(root.getChild(i), table); } return newTaxaCount; } } /** * @return the number of times the subtree was found in the * given list of trees. If a subtree occurs more than once in a tree * (for some bizarre reason) it is counted only once. * @param subtree the subtree being searched for. * @param trees a vector of trees to search for the subtree in. */ public static int subtreeCount(Node subtree, Vector trees) { int count = 0; Node root; for (int i = 0; i < trees.size(); i++) { root = (trees.elementAt(i)).getRoot(); if (containsSubtree(root, subtree)) { count += 1; } } return count; } /** * @return the mean height of the given subtree in the * given list of trees. If a subtree occurs more than once in a tree * (for some bizarre reason) results are undefined. * @param subtree the subtree being searched for. * @param trees a vector of trees to search for the subtree in. */ public static double getMeanSubtreeHeight(Node subtree, Vector trees) { int count = 0; double totalHeight = 0.0; Node root; for (int i = 0; i < trees.size(); i++) { root = ((Tree)trees.elementAt(i)).getRoot(); Node match = getSubtree(root, subtree); if (match != null) { count += 1; totalHeight += match.getNodeHeight(); } } return totalHeight / (double)count; } /** * @return the mean height of the given clade in the * given list of trees. If a clade occurs more than once in a tree * (for some bizarre reason) results are undefined. * @param clade a node containing the clade being searched for. * @param trees a vector of trees to search for the clade in. */ public static double getMeanCladeHeight(Node clade, Vector trees) { int count = 0; double totalHeight = 0.0; Node root; for (int i = 0; i < trees.size(); i++) { root = (trees.elementAt(i)).getRoot(); Node match = getClade(root, clade); if (match != null) { count += 1; totalHeight += match.getNodeHeight(); } } return totalHeight / (double)count; } /** * @return the number of times the clade was found in the * given list of trees. If a clade occurs more than once in a tree * (for some bizarre reason) it is counted only once. * @param subtree a subtree containing the taxaset being searched for. * @param trees a vector of trees to search for the clade in. */ public static int cladeCount(Node subtree, Vector trees) { int count = 0; Node root; for (int i = 0; i < trees.size(); i++) { root = (trees.elementAt(i)).getRoot(); if (containsClade(root, subtree)) { count += 1; } } return count; } public static void collectProportions(Tree tree, Vector trees) { for (int i =0; i < tree.getInternalNodeCount(); i++) { Node node = tree.getInternalNode(i); if (!node.isRoot()) { int cladeCount = cladeCount(node, trees); StringBuffer buffer = new StringBuffer(); collectLeafNames(node, buffer); double pr = (double)cladeCount / (double)trees.size(); tree.setAttribute(node, AttributeNode.CLADE_PROBABILITY, new Double(pr)); double meanCladeHeight = getMeanCladeHeight(node, trees); tree.setAttribute(node, AttributeNode.MEAN_CLADE_HEIGHT, new Double(meanCladeHeight)); } int subtreeCount = subtreeCount(node, trees); double pr = (double)subtreeCount / (double)trees.size(); tree.setAttribute(node, AttributeNode.SUBTREE_PROBABILITY, new Double(pr)); } } /** * Fills given string buffer with preorder traversal space-delimited leaf names. */ private static void collectLeafNames(Node node, StringBuffer buffer) { if (node.isLeaf()) { buffer.append(node.getIdentifier().getName()); buffer.append(' '); } else { for (int i = 0; i < node.getChildCount(); i++) { collectLeafNames(node.getChild(i), buffer); } } } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy