/* * Copyright (C) 2014 Tim Vaughan <tgvaughan@gmail.com>. * * This library 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.1 of the License, or (at your option) any later version. * * This library 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 this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, * MA 02110-1301 USA */ package test.beast.evolution.tree; import java.util.ArrayList; import java.util.List; import org.junit.Test; import beast.core.parameter.RealParameter; import beast.evolution.alignment.Alignment; import beast.evolution.alignment.Sequence; import beast.evolution.alignment.TaxonSet; import beast.evolution.tree.RandomTree; import beast.evolution.tree.TraitSet; import beast.evolution.tree.coalescent.ConstantPopulation; import beast.evolution.tree.coalescent.TreeIntervals; import beast.util.Randomizer; /** * @author Tim Vaughan <tgvaughan@gmail.com> */ public class RandomTreeTest { public RandomTreeTest() { } @Test public void testCoalescentTimes() throws Exception { Randomizer.setSeed(53); int Nleaves = 10; int Niter = 5000; // (Serially sampled) coalescent time means and variances // estimated from 50000 trees simulated using MASTER double[] coalTimeMeansTruth = { 1.754662, 2.833337, 3.843532, 4.850805, 5.849542, 6.847016, 7.8482, 8.855137, 10.15442}; double[] coalTimeVarsTruth = { 0.2751625, 0.2727121, 0.2685172, 0.2705117, 0.2678611, 0.2671793, 0.2686952, 0.2828477, 1.076874}; // Assemble BEASTObjects needed by RandomTree StringBuilder traitSB = new StringBuilder(); List<Sequence> seqList = new ArrayList<Sequence>(); for (int i=0; i<Nleaves; i++) { String taxonID = "t " + i; seqList.add(new Sequence(taxonID, "?")); if (i>0) traitSB.append(","); traitSB.append(taxonID).append("=").append(i); } Alignment alignment = new Alignment(seqList, "nucleotide"); TaxonSet taxonSet = new TaxonSet(alignment); TraitSet timeTrait = new TraitSet(); timeTrait.initByName( "traitname", "date-backward", "taxa", taxonSet, "value", traitSB.toString()); ConstantPopulation popFunc = new ConstantPopulation(); popFunc.initByName("popSize", new RealParameter("1.0")); // Create RandomTree and TreeInterval instances RandomTree tree = new RandomTree(); TreeIntervals intervals = new TreeIntervals(); // Estimate coalescence time moments double[] coalTimeMeans = new double[Nleaves-1]; double[] coalTimeVars = new double[Nleaves-1]; double[] coalTimes = new double[Nleaves-1]; for (int i=0; i<Niter; i++) { tree.initByName( "taxa", alignment, "populationModel", popFunc, "trait", timeTrait); intervals.initByName("tree", tree); intervals.getCoalescentTimes(coalTimes); for (int j=0; j<Nleaves-1; j++) { coalTimeMeans[j] += coalTimes[j]; coalTimeVars[j] += coalTimes[j]*coalTimes[j]; } } // Normalise means and variances for (int j=0; j<Nleaves-1; j++) { coalTimeMeans[j] /= Niter; coalTimeVars[j] /= Niter; coalTimeVars[j] -= coalTimeMeans[j]*coalTimeMeans[j]; } // Test means and variances against independently estimated values for (int j=0; j<Nleaves-1; j++) { // System.out.format("%d %g %g\n", j, // relError(coalTimeMeans[j],coalTimeMeansTruth[j]), // relError(coalTimeVars[j],coalTimeVarsTruth[j])); assert(relError(coalTimeMeans[j],coalTimeMeansTruth[j]) < 5e-3); assert(relError(coalTimeVars[j],coalTimeVarsTruth[j]) < 5e-2); } } /** * Return the relative difference between val and truth. * * @param val * @param truth * @return relative error */ private double relError(double val, double truth) { return 2.0*Math.abs(val-truth)/(val+truth); } }