/* * SkylineLikelihood.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.coalescent; import dr.evolution.coalescent.ConstantPopulation; import dr.evolution.tree.Tree; import dr.evolution.util.Units; import dr.evomodel.tree.TreeModel; import dr.evomodelxml.coalescent.CoalescentLikelihoodParser; import dr.inference.model.Likelihood; import dr.inference.model.Parameter; import dr.util.Author; import dr.util.Citable; import dr.util.Citation; import dr.xml.*; import java.util.Collections; import java.util.List; /** * A likelihood function for the coalescent. Takes a tree and a exponential markov model. * * * @version $Id: SkylineLikelihood.java,v 1.3 2004/10/01 22:40:04 alexei Exp $ * * @author Alexei Drummond */ public class SkylineLikelihood extends OldAbstractCoalescentLikelihood implements Citable { // PUBLIC STUFF public static final String SKYLINE_LIKELIHOOD = "skyLineLikelihood"; public static final String POPULATION_SIZES = "populationSizes"; public SkylineLikelihood(Tree tree, Parameter popSizeParameter) { super(SKYLINE_LIKELIHOOD); this.popSizeParameter = popSizeParameter; int tips = tree.getExternalNodeCount(); int params = popSizeParameter.getDimension(); if (tips - params != 1) { throw new IllegalArgumentException("Number of tips (" + tips + ") must be one greater than number of pop sizes (" + params + ")"); } this.tree = tree; if (tree instanceof TreeModel) { addModel((TreeModel)tree); } addVariable(popSizeParameter); setupIntervals(); addStatistic(new DeltaStatistic()); } // ************************************************************** // Likelihood IMPLEMENTATION // ************************************************************** /** * Calculates the log likelihood of this set of coalescent intervals, * given a demographic model. */ public double calculateLogLikelihood() { if (!intervalsKnown) setupIntervals(); double logL = 0.0; double currentTime = 0.0; int popIndex=0; ConstantPopulation cp = new ConstantPopulation(Units.Type.YEARS); for (int j = 0; j < intervalCount; j++) { cp.setN0(popSizeParameter.getParameterValue(popIndex)); if (getIntervalType(j) == CoalescentEventType.COALESCENT) { popIndex += 1; } logL += calculateIntervalLikelihood(cp, intervals[j], currentTime, lineageCounts[j], getIntervalType(j)); // insert zero-length coalescent intervals int diff = getCoalescentEvents(j)-1; for (int k = 0; k < diff; k++) { cp.setN0(popSizeParameter.getParameterValue(popIndex)); logL += calculateIntervalLikelihood(cp, 0.0, currentTime, lineageCounts[j]-k-1, CoalescentEventType.COALESCENT); popIndex += 1; } currentTime += intervals[j]; } return logL; } // **************************************************************** // Private and protected stuff // **************************************************************** public static XMLObjectParser PARSER = new AbstractXMLObjectParser() { public String getParserName() { return SKYLINE_LIKELIHOOD; } public Object parseXMLObject(XMLObject xo) throws XMLParseException { XMLObject cxo = (XMLObject)xo.getChild(POPULATION_SIZES); Parameter param = (Parameter)cxo.getChild(Parameter.class); cxo = (XMLObject)xo.getChild(CoalescentLikelihoodParser.POPULATION_TREE); TreeModel treeModel = (TreeModel)cxo.getChild(TreeModel.class); return new SkylineLikelihood(treeModel, param); } //************************************************************************ // AbstractXMLObjectParser implementation //************************************************************************ public String getParserDescription() { return "This element represents the likelihood of the tree given the population size vector."; } public Class getReturnType() { return Likelihood.class; } public XMLSyntaxRule[] getSyntaxRules() { return rules; } private XMLSyntaxRule[] rules = new XMLSyntaxRule[] { new ElementRule(POPULATION_SIZES, new XMLSyntaxRule[] { new ElementRule(Parameter.class) }), new ElementRule(CoalescentLikelihoodParser.POPULATION_TREE, new XMLSyntaxRule[] { new ElementRule(TreeModel.class) }), }; }; /** The demographic model. */ Parameter popSizeParameter = null; @Override public Citation.Category getCategory() { return Citation.Category.TREE_PRIORS; } @Override public String getDescription() { return "Bayesian Skyline Coalescent"; } @Override public List<Citation> getCitations() { return Collections.singletonList(CITATION); } public static Citation CITATION = new Citation( new Author[]{ new Author("AJ", "Drummond"), new Author("A", "Rambaut"), new Author("B", "Shapiro"), new Author("OG", "Pybus") }, "Bayesian coalescent inference of past population dynamics from molecular sequences", 2005, "Mol Biol Evol", 22, 1185, 1192 ); }