/* * ARGTreeLogger.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.arg; import dr.evolution.tree.Tree; import dr.evomodel.branchratemodel.BranchRateModel; import dr.evomodel.coalescent.structure.ColourSamplerModel; import dr.inference.loggers.LogFormatter; import dr.inference.loggers.MLLogger; import dr.inference.loggers.TabDelimitedFormatter; import dr.inference.model.Likelihood; import dr.xml.*; import java.io.File; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.PrintWriter; /** * A logger that logs tree and clade frequencies from a given partition in an ARG * * @author Marc Suchard * @version $Id: ARGTreeLogger.java,v 1.25 2006/09/05 13:29:34 rambaut Exp $ */ public class ARGTreeLogger extends OldTreeLogger { public static final String LOG_ARG = "logArgTree"; public static final String PARTITION = "partition"; private int partition; /** * Constructor */ public ARGTreeLogger(Tree tree, int partition, BranchRateModel branchRateModel, String rateLabel, ColourSamplerModel colourSamplerModel, String colouringLabel, Likelihood likelihood, String likelihoodLabel, LogFormatter formatter, int logEvery, boolean nexusFormat, boolean substitutions) { super(tree, branchRateModel, rateLabel, colourSamplerModel, colouringLabel, likelihood, likelihoodLabel, formatter, logEvery, nexusFormat, substitutions); this.partition = partition; } @Override protected String additionalInfo() { return " [&PARTITION=" + partition + "]" + " [&YULE=" + getLogYuleProbabilityString() + "]" + " [&NUM_REC=" + getNumberOfReassortments() + "]" ; } private int getNumberOfReassortments() { ARGModel arg = (ARGModel) getTree(); return arg.getReassortmentNodeCount(); } private String getLogYuleProbabilityString() { ARGTree tree = new ARGTree((ARGModel) getTree(), partition); // BetaSplittingModel betaModel = new BetaSplittingModel( // new Parameter.Default(1.0), tree); // betaModel.setBeta(0.0); // double otherLP = 0; double logProbability = 0; for (int i = 0, n = tree.getNodeCount(); i < n; i++) { // System.err.println(n); ARGModel.Node node = (ARGModel.Node) tree.getNode(i); int count = node.getDescendentTipCount(); // System.err.println(count); if (count > 2) logProbability -= 2 * Math.log(count - 1); // otherLP += betaModel.logNodeProbability(tree,node); } // System.err.println("me : "+logProbability); // System.err.println("old: "+otherLP); return String.format("%5.4f", logProbability); } @Override protected Tree getPrintTree() { return new ARGTree((ARGModel) getTree(), partition); } @Override protected boolean useTaxonLabels() { return true; } public static XMLObjectParser PARSER = new AbstractXMLObjectParser() { public String getParserName() { return LOG_ARG; } /** * @return an object based on the XML element it was passed. */ public Object parseXMLObject(XMLObject xo) throws XMLParseException { ARGModel tree = (ARGModel) xo.getChild(ARGModel.class); String fileName = null; String title = null; boolean nexusFormat = false; String colouringLabel = "demes"; String rateLabel = "rate"; String likelihoodLabel = "lnP"; if (xo.hasAttribute(TITLE)) { title = xo.getStringAttribute(TITLE); } if (xo.hasAttribute(FILE_NAME)) { fileName = xo.getStringAttribute(FILE_NAME); } if (xo.hasAttribute(NEXUS_FORMAT)) { nexusFormat = xo.getBooleanAttribute(NEXUS_FORMAT); } boolean substitutions = false; if (xo.hasAttribute(BRANCH_LENGTHS)) { substitutions = xo.getStringAttribute(BRANCH_LENGTHS).equals(SUBSTITUTIONS); } BranchRateModel branchRateModel = (BranchRateModel) xo.getChild(BranchRateModel.class); ColourSamplerModel colourSamplerModel = (ColourSamplerModel) xo.getChild(ColourSamplerModel.class); Likelihood likelihood = (Likelihood) xo.getChild(Likelihood.class); // logEvery of zero only displays at the end int logEvery = 1; if (xo.hasAttribute(LOG_EVERY)) { logEvery = xo.getIntegerAttribute(LOG_EVERY); } int partition = 0; if (xo.hasAttribute(PARTITION)) { partition = xo.getIntegerAttribute(PARTITION); } if (partition > tree.getMaxPartitionNumber()) throw new XMLParseException("ARGModel does not contain a partition #" + partition); PrintWriter pw = null; if (fileName != null) { try { File file = new File(fileName); String name = file.getName(); String parent = file.getParent(); if (!file.isAbsolute()) { parent = System.getProperty("user.dir"); } // System.out.println("Writing log file to "+parent+System.getProperty("path.separator")+name); pw = new PrintWriter(new FileOutputStream(new File(parent, name))); } catch (FileNotFoundException fnfe) { throw new XMLParseException("File '" + fileName + "' can not be opened for " + getParserName() + " element."); } } else { pw = new PrintWriter(System.out); } LogFormatter formatter = new TabDelimitedFormatter(pw); ARGTreeLogger logger = new ARGTreeLogger(tree, partition, branchRateModel, rateLabel, colourSamplerModel, colouringLabel, likelihood, likelihoodLabel, formatter, logEvery, nexusFormat, substitutions); if (title != null) { logger.setTitle(title); } return logger; } //************************************************************************ // AbstractXMLObjectParser implementation //************************************************************************ public XMLSyntaxRule[] getSyntaxRules() { return rules; } private XMLSyntaxRule[] rules = new XMLSyntaxRule[]{ AttributeRule.newIntegerRule(LOG_EVERY), AttributeRule.newIntegerRule(PARTITION), new StringAttributeRule(FILE_NAME, "The name of the file to send log output to. " + "If no file name is specified then log is sent to standard output", true), new StringAttributeRule(TITLE, "The title of the log", true), AttributeRule.newBooleanRule(NEXUS_FORMAT, true, "Whether to use the NEXUS format for the tree log"), new StringAttributeRule(BRANCH_LENGTHS, "What units should the branch lengths be in", new String[]{TIME, SUBSTITUTIONS}, true), new ElementRule(ARGModel.class, "The ARG which is to be logged"), new ElementRule(BranchRateModel.class, true), new ElementRule(ColourSamplerModel.class, true), new ElementRule(Likelihood.class, true) }; public String getParserDescription() { return "Logs a tree to a file"; } public String getExample() { return "<!-- The " + getParserName() + " element takes an argTreeModel to be logged -->\n" + "<" + getParserName() + " " + LOG_EVERY + "=\"100\" " + FILE_NAME + "=\"log.trees\" " + NEXUS_FORMAT + "=\"true\">\n" + " <treeModel idref=\"treeModel1\"/>\n" + "</" + getParserName() + ">\n"; } public Class getReturnType() { return MLLogger.class; } }; }