/* * CodonPartitionedRobustCountingParser.java * * Copyright (c) 2002-2016 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.evomodelxml.substmodel; import dr.evomodel.substmodel.CodonLabeling; import dr.evomodel.substmodel.CodonPartitionedRobustCounting; import dr.evomodel.substmodel.StratifiedTraitOutputFormat; import dr.evomodel.treelikelihood.AncestralStateBeagleTreeLikelihood; import dr.evolution.datatype.Codons; import dr.evolution.datatype.GeneticCode; import dr.evomodel.branchratemodel.BranchRateModel; import dr.evomodel.tree.TreeModel; import dr.xml.*; /** * @author Marc A. Suchard */ public class CodonPartitionedRobustCountingParser extends AbstractXMLObjectParser { public static final String PARSER_NAME = "codonPartitionedRobustCounting"; public static final String FIRST = "firstPosition"; public static final String SECOND = "secondPosition"; public static final String THIRD = "thirdPosition"; public static final String LABELING = "labeling"; public static final String BRANCH_FORMAT = "branchFormat"; public static final String LOG_FORMAT = "logFormat"; public static final String USE_UNIFORMIZATION = "useUniformization"; public static final String INCLUDE_EXTERNAL = "includeExternalBranches"; public static final String INCLUDE_INTERNAL = "includeInternalBranches"; public static final String DO_UNCONDITIONED_PER_BRANCH = "unconditionedPerBranch"; public static final String SAVE_HISTORY = "saveCompleteHistory"; public static final String AVERAGE_RATES = "averageRates"; public static final String USE_NEW_NEUTRAL_MODEL = "useNewNeutralModel"; public static final String PREFIX = "prefix"; public Object parseXMLObject(XMLObject xo) throws XMLParseException { AncestralStateBeagleTreeLikelihood[] partition = new AncestralStateBeagleTreeLikelihood[3]; String[] labels = new String[]{FIRST, SECOND, THIRD}; int patternCount = -1; BranchRateModel testBranchRateModel = null; for (int i = 0; i < 3; i++) { partition[i] = (AncestralStateBeagleTreeLikelihood) xo.getChild(labels[i]).getChild(AncestralStateBeagleTreeLikelihood.class); if (i == 0) { patternCount = partition[i].getPatternCount(); } else { if (partition[i].getPatternCount() != patternCount) { throw new XMLParseException("Codon-partitioned robust counting requires all partitions to have the same length." + " Make sure that partitions include all unique sites and do not strip gaps."); } } // Ensure that siteRateModel has one category if (partition[i].getSiteRateModel().getCategoryCount() > 1) { throw new XMLParseException("Robust counting currently only implemented for single category models"); } // Ensure that branchRateModel is the same across all partitions if (testBranchRateModel == null) { testBranchRateModel = partition[i].getBranchRateModel(); } else if (testBranchRateModel != partition[i].getBranchRateModel()) { throw new XMLParseException( "Robust counting currently requires the same branch rate model for all partitions"); } } TreeModel tree = (TreeModel) xo.getChild(TreeModel.class); Codons codons = Codons.UNIVERSAL; if (xo.hasAttribute(GeneticCode.GENETIC_CODE)) { String codeStr = xo.getStringAttribute(GeneticCode.GENETIC_CODE); codons = Codons.findByName(codeStr); } String labelingString = (String) xo.getAttribute(LABELING); CodonLabeling codonLabeling = CodonLabeling.parseFromString(labelingString); if (codonLabeling == null) { throw new XMLParseException("Unrecognized codon labeling '" + labelingString + "'"); } String branchFormatString = xo.getAttribute(BRANCH_FORMAT, StratifiedTraitOutputFormat.SUM_OVER_SITES.getText()); StratifiedTraitOutputFormat branchFormat = StratifiedTraitOutputFormat.parseFromString(branchFormatString); if (branchFormat == null) { throw new XMLParseException("Unrecognized branch output format '" + branchFormat + "'"); } String logFormatString = xo.getAttribute(LOG_FORMAT, StratifiedTraitOutputFormat.SUM_OVER_SITES.getText()); StratifiedTraitOutputFormat logFormat = StratifiedTraitOutputFormat.parseFromString(logFormatString); if (logFormat == null) { throw new XMLParseException("Unrecognized log output format '" + branchFormat + "'"); } boolean useUniformization = xo.getAttribute(USE_UNIFORMIZATION, false); boolean includeExternalBranches = xo.getAttribute(INCLUDE_EXTERNAL, true); boolean includeInternalBranches = xo.getAttribute(INCLUDE_INTERNAL, true); boolean doUnconditionedPerBranch = xo.getAttribute(DO_UNCONDITIONED_PER_BRANCH, false); boolean averageRates = xo.getAttribute(AVERAGE_RATES, true); boolean saveCompleteHistory = xo.getAttribute(SAVE_HISTORY, false); boolean useNewNeutralModel = xo.getAttribute(USE_NEW_NEUTRAL_MODEL, false); String prefix = xo.hasAttribute(PREFIX) ? xo.getStringAttribute(PREFIX) : null; return new CodonPartitionedRobustCounting( xo.getId(), tree, partition, codons, codonLabeling, useUniformization, includeExternalBranches, includeInternalBranches, doUnconditionedPerBranch, saveCompleteHistory, averageRates, useNewNeutralModel, branchFormat, logFormat, prefix); } private static final XMLSyntaxRule[] rules = new XMLSyntaxRule[]{ new ElementRule(FIRST, new XMLSyntaxRule[]{ new ElementRule(AncestralStateBeagleTreeLikelihood.class), }), new ElementRule(SECOND, new XMLSyntaxRule[]{ new ElementRule(AncestralStateBeagleTreeLikelihood.class), }), new ElementRule(THIRD, new XMLSyntaxRule[]{ new ElementRule(AncestralStateBeagleTreeLikelihood.class), }), new ElementRule(TreeModel.class), new StringAttributeRule(GeneticCode.GENETIC_CODE, "The genetic code to use", GeneticCode.GENETIC_CODE_NAMES, true), AttributeRule.newBooleanRule(USE_UNIFORMIZATION, true), AttributeRule.newBooleanRule(INCLUDE_EXTERNAL, true), AttributeRule.newBooleanRule(INCLUDE_INTERNAL, true), AttributeRule.newBooleanRule(DO_UNCONDITIONED_PER_BRANCH, true), AttributeRule.newBooleanRule(AVERAGE_RATES, true), AttributeRule.newStringRule(LABELING), AttributeRule.newBooleanRule(SAVE_HISTORY, true), AttributeRule.newBooleanRule(USE_NEW_NEUTRAL_MODEL, true), }; public XMLSyntaxRule[] getSyntaxRules() { return rules; } public String getParserDescription() { return "A parser to specify robust counting procedures on codon partitioned models"; } public Class getReturnType() { return CodonPartitionedRobustCounting.class; } public String getParserName() { return PARSER_NAME; } }