/* * TransformedTreeModel.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.tree.*; import dr.evolution.util.MutableTaxonListListener; import dr.evolution.util.Taxon; import dr.inference.model.AbstractModel; import dr.inference.model.Model; import dr.inference.model.Variable; import dr.util.Citable; import dr.util.Citation; import dr.util.CommonCitations; import java.util.*; import java.util.logging.Logger; /** * A transformation of a tree model * * @author Marc Suchard */ public class TransformedTreeModel extends AbstractModel implements MultivariateTraitTree, Citable { public TransformedTreeModel(String id, TreeModel tree, TreeTransform treeTransform) { super(id); this.treeModel = tree; this.treeTransform = treeTransform; addModel(tree); addModel(treeTransform); Logger log = Logger.getLogger("dr.evomodel.tree"); log.info("Creating a transform tree."); } public String toString() { return TreeUtils.newick(this); } public double getNodeHeight(NodeRef node) { return treeTransform.transform(treeModel, node, treeModel.getNodeHeight(node)); } public double getBranchLength(NodeRef node) { NodeRef parent = treeModel.getParent(node); if (parent == null) { return 0.0; } // System.err.println("p: " + this.getNodeHeight(parent)); // System.err.println("c: " + this.getNodeHeight(node)); return this.getNodeHeight(parent) - this.getNodeHeight(node); } // public double getOriginalNodeHeight(NodeRef node) { // return treeModel.getNodeHeight(node); // } // TODO 1. Reparameterize via parentNodeHeight // TODO 2. Deal with branchRateModel issues and no values from external nodes protected void handleModelChangedEvent(Model model, Object object, int index) { if (model == treeTransform) { treeModel.pushTreeChangedEvent(); // All internal node heights have changed! } else if (model == treeModel) { fireModelChanged(object, index); } else { throw new IllegalArgumentException("Illegal model"); } } protected void handleVariableChangedEvent(Variable variable, int index, Variable.ChangeType type) { // Do nothing; no variables } // Delegate the rest to treeModel public NodeRef getRoot() { return treeModel.getRoot(); } public int getNodeCount() { return treeModel.getNodeCount(); } public NodeRef getNode(int i) { return treeModel.getNode(i); } public NodeRef getInternalNode(int i) { return treeModel.getInternalNode(i); } public NodeRef getExternalNode(int i) { return treeModel.getExternalNode(i); } public int getExternalNodeCount() { return treeModel.getExternalNodeCount(); } public int getInternalNodeCount() { return treeModel.getInternalNodeCount(); } public Taxon getNodeTaxon(NodeRef node) { return treeModel.getNodeTaxon(node); } public boolean hasNodeHeights() { return treeModel.hasNodeHeights(); } public boolean hasBranchLengths() { return treeModel.hasBranchLengths(); } public double getNodeRate(NodeRef node) { return treeModel.getNodeRate(node); } public Object getNodeAttribute(NodeRef node, String name) { return treeModel.getNodeAttribute(node, name); } public Iterator getNodeAttributeNames(NodeRef node) { return treeModel.getNodeAttributeNames(node); } public boolean isExternal(NodeRef node) { return treeModel.isExternal(node); } public boolean isRoot(NodeRef node) { return treeModel.isRoot(node); } public int getChildCount(NodeRef node) { return treeModel.getChildCount(node); } public NodeRef getChild(NodeRef node, int j) { return treeModel.getChild(node, j); } public NodeRef getParent(NodeRef node) { return treeModel.getParent(node); } public Tree getCopy() { return treeModel.getCopy(); } protected void storeState() { // Do nothing } protected void restoreState() { // Do nothing } protected void acceptState() { // Do nothing } private final TreeTransform treeTransform; private final TreeModel treeModel; public double[] getMultivariateNodeTrait(NodeRef node, String name) { return treeModel.getMultivariateNodeTrait(node, name); } public void setMultivariateTrait(NodeRef n, String name, double[] value) { treeModel.setMultivariateTrait(n, name, value); } // public Parameter getRootHeightParameter() { // return treeModel.getRootHeightParameter(); // } public boolean beginTreeEdit() { return treeModel.beginTreeEdit(); } public void endTreeEdit() { treeModel.endTreeEdit(); } public void addChild(NodeRef parent, NodeRef child) { treeModel.addChild(parent, child); } public void removeChild(NodeRef parent, NodeRef child) { treeModel.removeChild(parent, child); } public void replaceChild(NodeRef node, NodeRef child, NodeRef newChild) { treeModel.replaceChild(node, child, newChild); } public void setRoot(NodeRef root) { treeModel.setRoot(root); } public void setNodeHeight(NodeRef node, double height) { treeModel.setNodeHeight(node, height); } public void setNodeRate(NodeRef node, double height) { treeModel.setNodeRate(node, height); } public void setBranchLength(NodeRef node, double length) { treeModel.setBranchLength(node, length); } public void setNodeAttribute(NodeRef node, String name, Object value) { treeModel.setNodeAttribute(node, name, value); } public void addMutableTreeListener(MutableTreeListener listener) { treeModel.addMutableTreeListener(listener); } public void setAttribute(String name, Object value) { treeModel.setAttribute(name, value); } public Object getAttribute(String name) { return treeModel.getAttribute(name); } public Iterator<String> getAttributeNames() { return treeModel.getAttributeNames(); } public int addTaxon(Taxon taxon) { return treeModel.addTaxon(taxon); } public boolean removeTaxon(Taxon taxon) { return treeModel.removeTaxon(taxon); } public void setTaxonId(int taxonIndex, String id) { treeModel.setTaxonId(taxonIndex, id); } public void setTaxonAttribute(int taxonIndex, String name, Object value) { treeModel.setTaxonAttribute(taxonIndex, name, value); } public void addMutableTaxonListListener(MutableTaxonListListener listener) { treeModel.addMutableTaxonListListener(listener); } public int getTaxonCount() { return treeModel.getTaxonCount(); } public Taxon getTaxon(int taxonIndex) { return treeModel.getTaxon(taxonIndex); } public String getTaxonId(int taxonIndex) { return treeModel.getTaxonId(taxonIndex); } public int getTaxonIndex(String id) { return treeModel.getTaxonIndex(id); } public int getTaxonIndex(Taxon taxon) { return treeModel.getTaxonIndex(taxon); } public List<Taxon> asList() { return treeModel.asList(); } public Object getTaxonAttribute(int taxonIndex, String name) { return treeModel.getTaxonAttribute(taxonIndex, name); } public Iterator<Taxon> iterator() { return treeModel.iterator(); } public Type getUnits() { return treeModel.getUnits(); } public void setUnits(Type units) { treeModel.setUnits(units); } @Override public Citation.Category getCategory() { return Citation.Category.TRAIT_MODELS; } @Override public String getDescription() { return "Bayesian estimation of Pagel's lambda"; } @Override public List<Citation> getCitations() { return Collections.singletonList(CommonCitations.VRANCKEN_2015_SIMULTANEOUSLY); } }