/* * AlignmentGenerator.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.app.beauti.generator; import dr.app.beauti.components.ComponentFactory; import dr.app.beauti.components.dollo.DolloComponentOptions; import dr.app.beauti.options.BeautiOptions; import dr.app.beauti.types.BinaryModelType; import dr.app.beauti.util.XMLWriter; import dr.evolution.alignment.Alignment; import dr.evolution.datatype.DataType; import dr.evolution.datatype.TwoStateCovarion; import dr.evolution.util.Taxon; import dr.evoxml.AlignmentParser; import dr.evoxml.SequenceParser; import dr.evoxml.TaxonParser; import dr.util.Attribute; import dr.xml.XMLParser; import java.util.List; /** * @author Alexei Drummond * @author Andrew Rambaut * @author Walter Xie */ public class AlignmentGenerator extends Generator { // used as a null sequence if sampling from the prior only. It is // three characters long in case it is codon partitioned. private static final String NULL_SEQUENCE = "???"; public AlignmentGenerator(BeautiOptions options, ComponentFactory[] components) { super(options, components); } /** * Write all Alignments * @param writer XMLWriter */ public void writeAlignments(List<Alignment> alignments, XMLWriter writer) { int index = 1; for (Alignment alignment : alignments) { if (alignments.size() > 1) { //if (!options.allowDifferentTaxa) { alignment.setId(AlignmentParser.ALIGNMENT + index); //} else { // e.g. alignment_gene1 // alignment.setId("alignment_" + mulitTaxaTagName + index); //} } else { alignment.setId(AlignmentParser.ALIGNMENT); } writeAlignment(alignment, writer); index += 1; writer.writeText(""); } } /** * Generate an alignment block from these beast options * * @param alignment the alignment to write * @param writer the writer */ private void writeAlignment(Alignment alignment, XMLWriter writer) { writer.writeText(""); writer.writeComment("The sequence alignment (each sequence refers to a taxon above).", "ntax=" + alignment.getTaxonCount() + " nchar=" + alignment.getSiteCount()); if (options.samplePriorOnly) { writer.writeComment("Null sequences generated in order to sample from the prior only."); } if (getAlignmentDataTypeDescription(alignment) != null) { writer.writeOpenTag( AlignmentParser.ALIGNMENT, new Attribute[]{ new Attribute.Default<String>(XMLParser.ID, alignment.getId()), new Attribute.Default<String>(DataType.DATA_TYPE, getAlignmentDataTypeDescription(alignment)) } ); } else { writer.writeOpenTag( AlignmentParser.ALIGNMENT, new Attribute.Default<String>(XMLParser.ID, alignment.getId())); writer.writeIDref(DataType.DATA_TYPE, getAlignmentDataTypeIdref(alignment)); } for (int i = 0; i < alignment.getTaxonCount(); i++) { Taxon taxon = alignment.getTaxon(i); writer.writeOpenTag(SequenceParser.SEQUENCE); writer.writeIDref(TaxonParser.TAXON, taxon.getId()); if (!options.samplePriorOnly) { // writer.checkText(alignment.getAlignedSequenceString(i)); writer.writeText(alignment.getAlignedSequenceString(i)); // System.out.println(taxon.getId() + ": \n" + alignment.getAlignedSequenceString(i)); // System.out.println("len = " + alignment.getAlignedSequenceString(i).length() + "\n"); } else { // generate a codon in case there is codon partitioning writer.writeText(NULL_SEQUENCE); } writer.writeCloseTag(SequenceParser.SEQUENCE); } writer.writeCloseTag(AlignmentParser.ALIGNMENT); } /** * Determine and return the datatype description for these beast options * note that the datatype in XML may differ from the actual datatype * * @param alignment the alignment to get data type description of * @return description */ private String getAlignmentDataTypeDescription(Alignment alignment) { String description = alignment.getDataType().getDescription(); switch (alignment.getDataType().getType()) { case DataType.TWO_STATES: // when dataType="binary" // case DataType.COVARION: // description = alignment.getDataType().getDescription(); // if choose Covarion model then should change into dataType="twoStateCovarion" if (options.getPartitionData(alignment).getPartitionSubstitutionModel().getBinarySubstitutionModel() == BinaryModelType.BIN_COVARION) { description = TwoStateCovarion.INSTANCE.getDescription(); // dataType="twoStateCovarion" } else if (options.getPartitionData(alignment).getPartitionSubstitutionModel().getBinarySubstitutionModel() == BinaryModelType.BIN_DOLLO) { description = null; } break; } return description; } private String getAlignmentDataTypeIdref(Alignment alignment) { String description = alignment.getDataType().getDescription(); switch (alignment.getDataType().getType()) { case DataType.TWO_STATES: if (options.getPartitionData(alignment).getPartitionSubstitutionModel().getBinarySubstitutionModel() == BinaryModelType.BIN_DOLLO) { description = DolloComponentOptions.DATA_NAME; } } return description; } }