/* * EmpiricalTreeDistributionModel.java * * Copyright (c) 2002-2015 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.tree; import dr.evolution.io.Importer; import dr.evolution.io.NexusImporter; import dr.evolution.io.TreeImporter; import dr.evolution.tree.NodeRef; import dr.evolution.tree.Tree; import dr.evolution.util.Taxon; import dr.math.MathUtils; import dr.inference.model.Statistic; import java.io.IOException; import java.util.Iterator; import java.util.List; /** * @author Andrew Rambaut * @version $Id$ */ public class EmpiricalTreeDistributionModel extends TreeModel { /** * This constructor takes an array of trees and jumps randomly amongst them. * @param trees * @param startingTree */ public EmpiricalTreeDistributionModel(final Tree[] trees, int startingTree) { this(trees, null, startingTree); } /** * This constructor takes a TreeImporter and reads the trees one by one to the end (and * then starts throwing exceptions). * @param importer * @param startingTree */ public EmpiricalTreeDistributionModel(final TreeImporter importer, int startingTree) { this(null, importer, startingTree); } private EmpiricalTreeDistributionModel(final Tree[] trees, final TreeImporter importer, int startingTree) { super(EMPIRICAL_TREE_DISTRIBUTION_MODEL); this.trees = trees; this.importer = importer; drawTreeIndex(startingTree); addStatistic(new Statistic.Abstract("Current Tree") { public int getDimension() { return 1; } public double getStatisticValue(int dim) { return currentTreeIndex; } }); } protected void storeState() { storedCurrentTree = currentTree; } protected void restoreState() { currentTree = storedCurrentTree; } protected void acceptState() { } public void drawTreeIndex() { drawTreeIndex(-1); } private void drawTreeIndex(int treeNumber) { // System.err.print("Drawing new tree, (old tree = " + currentTreeIndex); if (importer != null) { try { if (importer.hasTree() == false) { throw new RuntimeException("EmpiricalTreeDistributionModel has run out of trees"); } currentTree = importer.importNextTree(); } catch (IOException e) { throw new RuntimeException("EmpiricalTreeDistributionModel unable to load next tree"); } catch (Importer.ImportException e) { throw new RuntimeException("EmpiricalTreeDistributionModel unable to load next tree"); } currentTreeIndex += 1; } else { if (treeNumber == -1) { currentTreeIndex = MathUtils.nextInt(trees.length); currentTree = trees[currentTreeIndex]; } else { currentTreeIndex = treeNumber; currentTree = trees[currentTreeIndex]; } } // Force computation of node heights now rather than later in the evaluation // where multithreading may get conflicts. currentTree.getNodeHeight(currentTree.getRoot()); // System.err.println(") new tree = " + currentTreeIndex); fireModelChanged(new TreeModel.TreeChangedEvent()); } public NodeRef getRoot() { return currentTree.getRoot(); } public int getNodeCount() { return currentTree.getNodeCount(); } public NodeRef getNode(final int i) { return currentTree.getNode(i); } public NodeRef getInternalNode(final int i) { return currentTree.getInternalNode(i); } public NodeRef getExternalNode(final int i) { return currentTree.getExternalNode(i); } public int getExternalNodeCount() { return currentTree.getExternalNodeCount(); } public int getInternalNodeCount() { return currentTree.getInternalNodeCount(); } public Taxon getNodeTaxon(final NodeRef node) { return trees[currentTreeIndex].getNodeTaxon(node); } public boolean hasNodeHeights() { return currentTree.hasNodeHeights(); } public double getNodeHeight(final NodeRef node) { return currentTree.getNodeHeight(node); } public boolean hasBranchLengths() { return currentTree.hasBranchLengths(); } public double getBranchLength(final NodeRef node) { return currentTree.getBranchLength(node); } public double getNodeRate(final NodeRef node) { return currentTree.getNodeRate(node); } public Object getNodeAttribute(final NodeRef node, final String name) { return currentTree.getNodeAttribute(node, name); } public Iterator getNodeAttributeNames(final NodeRef node) { return currentTree.getNodeAttributeNames(node); } public boolean isExternal(final NodeRef node) { return currentTree.isExternal(node); } public boolean isRoot(final NodeRef node) { return currentTree.isRoot(node); } public int getChildCount(final NodeRef node) { return currentTree.getChildCount(node); } public NodeRef getChild(final NodeRef node, final int j) { return currentTree.getChild(node, j); } public NodeRef getParent(final NodeRef node) { return currentTree.getParent(node); } public Tree getCopy() { return currentTree.getCopy(); } public int getTaxonCount() { return currentTree.getTaxonCount(); } public Taxon getTaxon(final int taxonIndex) { return currentTree.getTaxon(taxonIndex); } public String getTaxonId(final int taxonIndex) { return currentTree.getTaxonId(taxonIndex); } public int getTaxonIndex(final String id) { return currentTree.getTaxonIndex(id); } public int getTaxonIndex(final Taxon taxon) { return currentTree.getTaxonIndex(taxon); } public List<Taxon> asList() { return currentTree.asList(); } public Object getTaxonAttribute(final int taxonIndex, final String name) { return currentTree.getTaxonAttribute(taxonIndex, name); } public Iterator<Taxon> iterator() { return currentTree.iterator(); } public Type getUnits() { return currentTree.getUnits(); } public void setUnits(final Type units) { currentTree.setUnits(units); } public void setAttribute(final String name, final Object value) { currentTree.setAttribute(name, value); } public Object getAttribute(final String name) { return currentTree.getAttribute(name); } public Iterator<String> getAttributeNames() { return currentTree.getAttributeNames(); } public static final String EMPIRICAL_TREE_DISTRIBUTION_MODEL = "empiricalTreeDistributionModel"; private final Tree[] trees; private final TreeImporter importer; private Tree currentTree; private Tree storedCurrentTree; private int currentTreeIndex; }