/* * AlloppNode.java * * Copyright (c) 2002-2017 Alexei Drummond, Andrew Rambaut and Marc Suchard * * This file is part of BEAST. * See the NOTICE file distributed with this work for additional * information regarding copyright ownership and licensing. * * BEAST is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * BEAST is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with BEAST; if not, write to the * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, * Boston, MA 02110-1301 USA */ package dr.evomodel.alloppnet.speciation; import java.util.Stack; import dr.evolution.tree.SimpleNode; import dr.evolution.util.Taxon; import jebl.util.FixedBitSet; /** * An AlloppNode is an interface implemented by DipHistNode in AlloppDiploidHistory, * and MulLabNode in AlloppMulLabTree. * The ABC AlloppNode.Abstract contains some common functionality. * * @author Graham Jones * Date: 20/03/2012 */ public interface AlloppNode { int nofChildren(); AlloppNode getChild(int ch); AlloppNode getAnc(); Taxon getTaxon(); double getHeight(); FixedBitSet getUnion(); void setChild(int ch, AlloppNode newchild); void setAnc(AlloppNode anc); void setTaxon(String name); void setHeight(double height); void setUnion(FixedBitSet union); void addChildren(AlloppNode c0, AlloppNode c1); String asText(int indentlen); void fillinUnionsInSubtree(int unionsize); AlloppNode nodeOfUnionInSubtree(FixedBitSet x); public abstract class Abstract implements AlloppNode { public void fillinUnionsInSubtree(int unionsize) { if (nofChildren() > 0) { getChild(0).fillinUnionsInSubtree(unionsize); getChild(1).fillinUnionsInSubtree(unionsize); FixedBitSet union = new FixedBitSet(unionsize); union.union(getChild(0).getUnion()); union.union(getChild(1).getUnion()); setUnion(union); } } /* * For constructor of AlloppDiploidHistory, AlloppMulLabTree. * Searches subtree rooted at node for most tipward node * whose union contains x. If x is known to be a union of one of the nodes, * it finds that node, so acts as a map union -> node */ public AlloppNode nodeOfUnionInSubtree(FixedBitSet x) { if (nofChildren() == 0) { return this; } if (x.setInclusion(getChild(0).getUnion())) { return getChild(0).nodeOfUnionInSubtree(x); } else if (x.setInclusion(getChild(1).getUnion())) { return getChild(1).nodeOfUnionInSubtree(x); } else { return this; } } public static String subtreeAsText(AlloppNode node, String s, Stack<Integer> x, int depth, String b) { Integer[] y = x.toArray(new Integer[x.size()]); StringBuffer indent = new StringBuffer(); for (int i = 0; i < depth; i++) { indent.append(" "); } for (int i = 0; i < y.length; i++) { indent.replace(2*y[i], 2*y[i]+1, "|"); } if (b.length() > 0) { indent.replace(indent.length()-b.length(), indent.length(), b); } s += indent; s += node.asText(indent.length()); s += System.getProperty("line.separator"); String subs = ""; if (node.nofChildren() > 0) { x.push(depth); subs += subtreeAsText(node.getChild(0), "", x, depth+1, "-"); x.pop(); subs += subtreeAsText(node.getChild(1), "", x, depth+1, "`-"); } return s + subs; } } }