/* * MulSpeciesBindingsParser.java * * Copyright (c) 2002-2017 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.alloppnet.parsers; import dr.evomodel.alloppnet.speciation.AlloppSpeciesBindings; import dr.evomodel.alloppnet.speciation.MulSpeciesBindings; import dr.evomodel.tree.TreeModel; import dr.xml.*; import java.util.ArrayList; import java.util.List; /** * Parser for list of possibly-allopolyploid species containing individuals * in turn containing taxons (which are diploid genomes). This is similar * to AlloppSpeciesBindingsParser but makes a MulSpeciesBindings not a * AlloppSpeciesBindings. XML only different in using "mulSpecies" not * "alloppspecies", and no "minGeneNodeHeight".. * * @author Graham Jones * Date: 20/12/2011 */ /* * * Parses something like this: <mulSpecies id="mulSpecies"> <sp id="Alpha" ploidylevel = 2> <individual id = "1"> <taxon idref="1_Alpha" /> </individual> <individual id = "2"> <taxon idref="2_Alpha" /> </individual> <individual id = "3"> <taxon idref="3_Alpha" /> </individual> </sp> <sp id="Beta" ploidylevel = 4> <individual id = "4"> <taxon idref="4_Beta_A" /> <taxon idref="4_Beta_B" /> </individual> <individual id = "5"> <taxon idref="5_Beta_A" /> <taxon idref="5_Beta_B" /> </individual> </sp> ... (more species, then genetrees) </mulSpecies> */ // I have adapted code from SpeciesBindingsParser. // I changed 'ploidy' to 'popfactor' to reduce confusion with the ploidy level // of a species which is independent of which gene is considered. // Use of popfactors is untested. Maybe chloroplast data would use it. public class MulSpeciesBindingsParser extends AbstractXMLObjectParser { public static final String MUL_SPECIES = "mulSpecies"; public static final String GENE_TREES = "geneTrees"; public static final String GTREE = "gtree"; public static final String POPFACTOR = "popfactor"; public String getParserName() { return MUL_SPECIES; } public Object parseXMLObject(XMLObject xo) throws XMLParseException { List<AlloppSpeciesBindings.ApSpInfo> apsp = new ArrayList<AlloppSpeciesBindings.ApSpInfo>(); for (int k = 0; k < xo.getChildCount(); ++k) { final Object child = xo.getChild(k); if (child instanceof AlloppSpeciesBindings.ApSpInfo) { apsp.add((AlloppSpeciesBindings.ApSpInfo) child); } } final XMLObject xogt = xo.getChild(GENE_TREES); final int nTrees = xogt.getChildCount(); final TreeModel[] trees = new TreeModel[nTrees]; double[] popFactors = new double[nTrees]; for (int nt = 0; nt < trees.length; ++nt) { Object child = xogt.getChild(nt); if (!(child instanceof TreeModel)) { assert child instanceof XMLObject; popFactors[nt] = ((XMLObject) child).getDoubleAttribute(POPFACTOR); child = ((XMLObject) child).getChild(TreeModel.class); } else { popFactors[nt] = -1; } trees[nt] = (TreeModel) child; } try { return new MulSpeciesBindings(apsp.toArray(new AlloppSpeciesBindings.ApSpInfo[apsp.size()]), trees, popFactors); } catch (Error e) { throw new XMLParseException(e.getMessage()); } } // I have adapted code from SpeciesBindingsParser // I changed 'Ploidy' to 'PopFactors' to reduce confusion - // the only use I can think of for popfactors in an AlloppNetwork is chloroplast data ElementRule treeWithPopFactors = new ElementRule(GTREE, new XMLSyntaxRule[]{AttributeRule.newDoubleRule(POPFACTOR), new ElementRule(TreeModel.class)}, 0, Integer.MAX_VALUE); @Override public XMLSyntaxRule[] getSyntaxRules() { return new XMLSyntaxRule[]{ new ElementRule(AlloppSpeciesBindings.ApSpInfo.class, 2, Integer.MAX_VALUE), new ElementRule(GENE_TREES, new XMLSyntaxRule[]{ new ElementRule(TreeModel.class, 0, Integer.MAX_VALUE), treeWithPopFactors }), }; } @Override public String getParserDescription() { return "Binds taxa to gene trees with information about possibly allopolyploid species."; } @Override public Class getReturnType() { return MulSpeciesBindings.class; } }