/*
* XMLGenerator.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.bss;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;
import dr.evolution.tree.TreeUtils;
import dr.evomodelxml.substmodel.MG94CodonModelParser;
import dr.evomodel.substmodel.aminoacid.AminoAcidModelType;
import dr.evomodel.substmodel.nucleotide.NucModelType;
import dr.app.beagle.tools.parsers.BeagleSequenceSimulatorParser;
import dr.app.beagle.tools.parsers.PartitionParser;
import dr.app.beauti.util.XMLWriter;
import dr.evolution.datatype.AminoAcids;
import dr.evolution.datatype.DataType;
import dr.evolution.util.Taxa;
import dr.evolution.util.Taxon;
import dr.oldevomodel.sitemodel.SiteModel;
import dr.evomodel.tree.TreeModel;
import dr.evomodelxml.branchratemodel.DiscretizedBranchRatesParser;
import dr.evomodelxml.branchratemodel.StrictClockBranchRatesParser;
import dr.evomodelxml.coalescent.CoalescentSimulatorParser;
import dr.evomodelxml.coalescent.ConstantPopulationModelParser;
import dr.evomodelxml.coalescent.ExponentialGrowthModelParser;
import dr.oldevomodelxml.sitemodel.GammaSiteModelParser;
import dr.oldevomodelxml.substmodel.EmpiricalAminoAcidModelParser;
import dr.oldevomodelxml.substmodel.FrequencyModelParser;
import dr.oldevomodelxml.substmodel.GTRParser;
import dr.oldevomodelxml.substmodel.HKYParser;
import dr.oldevomodelxml.substmodel.TN93Parser;
import dr.oldevomodelxml.substmodel.YangCodonModelParser;
import dr.evomodelxml.tree.TreeModelParser;
import dr.evoxml.NewickParser;
import dr.evoxml.SequenceParser;
import dr.evoxml.TaxaParser;
import dr.evoxml.TaxonParser;
import dr.evoxml.util.XMLUnits;
import dr.inference.distribution.ExponentialDistributionModel;
import dr.inference.model.ParameterParser;
import dr.inferencexml.distribution.DistributionModelParser;
import dr.inferencexml.distribution.InverseGaussianDistributionModelParser;
import dr.inferencexml.distribution.LogNormalDistributionModelParser;
import dr.util.Attribute;
import dr.xml.Report;
import dr.xml.XMLParser;
/**
* @author Filip Bielejec
* @version $Id$
*/
public class XMLGenerator {
private PartitionDataList dataList;
public XMLGenerator(PartitionDataList dataList) {
this.dataList = dataList;
}// END: Constructor
public void generateXML(File file) throws IOException {
XMLWriter writer = new XMLWriter(new BufferedWriter(
new FileWriter(file)));
// //////////////
// ---header---//
// //////////////
writer.writeText("<?xml version=\"1.0\" standalone=\"yes\"?>");
writer.writeComment("Generated by "
+ BeagleSequenceSimulatorApp.LONG_NAME + " "
+ BeagleSequenceSimulatorApp.VERSION);
writer.writeOpenTag("beast");
writer.writeBlankLine();
// ////////////////////
// ---taxa element---//
// ////////////////////
try {
int suffix = 1;
ArrayList<Taxa> taxaList = new ArrayList<Taxa>();
for (PartitionData data : dataList) {
if (data.record == null) {
throw new RuntimeException("Set Tree Model in Partitions tab for " + suffix + " partition.");
} else {
Taxa taxa = null;
if (data.demographicModelIndex == 0 && data.record.isTreeSet()) {
taxa = new Taxa(data.record.getTree().asList());
} else if (data.demographicModelIndex == 0 && data.record.isTaxaSet()) {
throw new RuntimeException("Data and demographic model incompatible for partition " + suffix);
} else if( (data.demographicModelIndex > 0 && data.demographicModelIndex <= PartitionData.lastImplementedIndex) && data.record.isTreeSet()) {
taxa = new Taxa(data.record.getTree().asList());
} else if((data.demographicModelIndex > 0 && data.demographicModelIndex <= PartitionData.lastImplementedIndex) && data.record.isTaxaSet()) {
taxa = data.record.getTaxa();
} else {
//
}// END: demo model check
if (taxaList.size() == 0
| !Utils.isTaxaInList(taxa, taxaList)
) {
data.taxaIdref += suffix;
writeTaxa(taxa, writer, String.valueOf(suffix));
writer.writeBlankLine();
taxaList.add(taxa);
// System.out.println("NOT IN LIST");
} else {
int index = Utils.taxaIsIdenticalWith(taxa, taxaList) + 1;
data.taxaIdref += index;
// System.out.println("IDENTICAL WITH " + index);
}
}// END: treeModel set check
suffix++;
}// END: partition loop
} catch (Exception e) {
throw new RuntimeException("Taxa generation has failed:\n"
+ e.getMessage());
}// END: try-catch block
// ////////////////////////
// ---topology element---//
// ////////////////////////
try {
int suffix = 1;
ArrayList<TreeModel> treeModelList = new ArrayList<TreeModel>();
for (PartitionData data : dataList) {
if (data.demographicModelIndex == 0) {
TreeModel treeModel = data.createTreeModel();
if (treeModelList.size() == 0 | !Utils.isTreeModelInList(treeModel, treeModelList)) {
data.treeModelIdref += suffix;
writeNewick(treeModel, writer, String.valueOf(suffix));
writer.writeBlankLine();
treeModelList.add(treeModel);
} else {
int index = Utils.treeModelIsIdenticalWith(treeModel, treeModelList) + 1;
data.treeModelIdref += index;
}// END: list check
} else if(data.demographicModelIndex > 0 && data.demographicModelIndex <= PartitionData.lastImplementedIndex){
data.demographicModelIdref += suffix;
data.treeModelIdref += suffix;
writeDemographicModel(data, writer, String.valueOf(suffix));
writer.writeBlankLine();
} else {
// throw exception
}// END: demo model check
suffix++;
}// END: partition loop
} catch (Exception e) {
throw new RuntimeException("Topology generation has failed:\n"
+ e.getMessage());
}// END: try-catch block
// //////////////////////////
// ---tree model element---//
// //////////////////////////
try {
int suffix = 1;
ArrayList<TreesTableRecord> recordsList = new ArrayList<TreesTableRecord>();
for (PartitionData data : dataList) {
TreesTableRecord record = data.record;
if (recordsList.size() == 0 | !Utils.isRecordInList(record, recordsList)) {
writeTreeModel(writer, String.valueOf(suffix));
writer.writeBlankLine();
recordsList.add(record);
}
suffix++;
}// END: partition loop
} catch (Exception e) {
throw new RuntimeException("Tree model generation has failed:\n"
+ e.getMessage());
}// END: try-catch block
// //////////////////////////////////
// ---branch rates model element---//
// //////////////////////////////////
try {
int suffix = 1;
ArrayList<PartitionData> partitionList = new ArrayList<PartitionData>();
for (PartitionData data : dataList) {
if (partitionList.size() == 0
| !Utils.isElementInList(data, partitionList,
Utils.BRANCH_RATE_MODEL_ELEMENT)) {
data.clockModelIdref += suffix;
writeBranchRatesModel(data, writer, String.valueOf(suffix));
writer.writeBlankLine();
partitionList.add(data);
// System.out.println("NOT IN LIST");
} else {
int index = Utils.isIdenticalWith(data, partitionList,
Utils.BRANCH_RATE_MODEL_ELEMENT) + 1;
data.clockModelIdref += index;
// System.out.println("IDENTICAL WITH " + index);
}
suffix++;
}// END: partition loop
} catch (Exception e) {
throw new RuntimeException("Clock model generation has failed:\n"
+ e.getMessage());
}// END: try-catch block
// ///////////////////////////////
// ---frequency model element---//
// ///////////////////////////////
try {
int suffix = 1;
ArrayList<PartitionData> partitionList = new ArrayList<PartitionData>();
for (PartitionData data : dataList) {
if (partitionList.size() == 0
| !Utils.isElementInList(data, partitionList,
Utils.FREQUENCY_MODEL_ELEMENT)) {
data.frequencyModelIdref += suffix;
writeFrequencyModel(data, writer);
writer.writeBlankLine();
partitionList.add(data);
// System.out.println("NOT IN LIST");
} else {
int index = Utils.isIdenticalWith(data, partitionList,
Utils.FREQUENCY_MODEL_ELEMENT) + 1;
data.frequencyModelIdref += index;
// System.out.println("IDENTICAL WITH " + index);
}
suffix++;
}// END: partition loop
} catch (Exception e) {
throw new RuntimeException(
"Frequency model generation has failed:\n" + e.getMessage());
}// END: try-catch block
// ////////////////////////////
// ---branch model element---//
// ////////////////////////////
try {
int suffix = 1;
ArrayList<PartitionData> partitionList = new ArrayList<PartitionData>();
for (PartitionData data : dataList) {
if (partitionList.size() == 0
| !Utils.isElementInList(data, partitionList,
Utils.BRANCH_MODEL_ELEMENT)) {
data.substitutionModelIdref += suffix;
writeBranchModel(data, writer, String.valueOf(suffix));
writer.writeBlankLine();
partitionList.add(data);
} else {
int index = Utils.isIdenticalWith(data, partitionList,
Utils.BRANCH_MODEL_ELEMENT) + 1;
data.substitutionModelIdref += index;
}
suffix++;
}// END: partition loop
} catch (Exception e) {
throw new RuntimeException("Branch model generation has failed:\n"
+ e.getMessage());
}// END: try-catch block
// ///////////////////////////////
// ---site rate model element---//
// ///////////////////////////////
try {
int suffix = 1;
ArrayList<PartitionData> partitionList = new ArrayList<PartitionData>();
for (PartitionData data : dataList) {
if (partitionList.size() == 0
| !Utils.isElementInList(data, partitionList,
Utils.SITE_RATE_MODEL_ELEMENT)) {
data.siteRateModelIdref += suffix;
writeSiteRateModel(data, writer, suffix);
writer.writeBlankLine();
partitionList.add(data);
} else {
int index = Utils.isIdenticalWith(data, partitionList,
Utils.SITE_RATE_MODEL_ELEMENT) + 1;
data.siteRateModelIdref += index;
}
suffix++;
}// END: partition loop
} catch (Exception e) {
System.err.println(e);
throw new RuntimeException(
"Site rate model generation has failed:\n" + e.getMessage());
}// END: try-catch block
// /////////////////////////////////////////
// ---beagle sequence simulator element---//
// /////////////////////////////////////////
try {
writeBeagleSequenceSimulator(writer);
writer.writeBlankLine();
} catch (Exception e) {
throw new RuntimeException(
"Beagle Sequence Simulator element generation has failed:\n"
+ e.getMessage());
}// END: try-catch block
// //////////////////////
// ---report element---//
// //////////////////////
try {
writeReport(writer);
writer.writeBlankLine();
} catch (Exception e) {
System.err.println(e);
throw new RuntimeException(
"Report element generation has failed:\n" + e.getMessage());
}// END: try-catch block
writer.writeCloseTag("beast");
writer.flush();
writer.close();
// reset all idrefs
for (PartitionData data : dataList) {
data.resetIdrefs();
}
}// END: generateXML
private void writeBeagleSequenceSimulator(XMLWriter writer) {
writer.writeOpenTag(
BeagleSequenceSimulatorParser.BEAGLE_SEQUENCE_SIMULATOR,
new Attribute[] {
new Attribute.Default<String>(XMLParser.ID, "simulator"), //
new Attribute.Default<String>(
BeagleSequenceSimulatorParser.PARALLEL, String
.valueOf(dataList.useParallel)), //
new Attribute.Default<String>(
BeagleSequenceSimulatorParser.OUTPUT, String
.valueOf(dataList.outputFormat))
});
int suffix = 1;
for (PartitionData data : dataList) {
writer.writeOpenTag(
PartitionParser.PARTITION,
new Attribute[] {
new Attribute.Default<String>(PartitionParser.FROM,
String.valueOf(data.from)),
new Attribute.Default<String>(PartitionParser.TO,
String.valueOf(data.to)),
new Attribute.Default<String>(
PartitionParser.EVERY, String
.valueOf(data.every)) });
writer.writeIDref(TreeModel.TREE_MODEL, data.treeModelIdref);
int substitutionModelIndex = data.substitutionModelIndex;
switch (substitutionModelIndex) {
case 0: // HKY
writer.writeIDref(NucModelType.HKY.getXMLName(),
data.substitutionModelIdref);
break;
case 1: // GTR
writer.writeIDref(GTRParser.GTR_MODEL,
data.substitutionModelIdref);
break;
case 2: // TN93
writer.writeIDref(NucModelType.TN93.getXMLName(),
data.substitutionModelIdref);
break;
case 3: // Yang Codon Model
writer.writeIDref(YangCodonModelParser.YANG_CODON_MODEL,
data.substitutionModelIdref);
break;
case 4: // Blosum62
writer.writeIDref(EmpiricalAminoAcidModelParser.EMPIRICAL_AMINO_ACID_MODEL,
data.substitutionModelIdref);
break;
case 5: // CPREV
writer.writeIDref(EmpiricalAminoAcidModelParser.EMPIRICAL_AMINO_ACID_MODEL,
data.substitutionModelIdref);
break;
case 6: // Dayhoff
writer.writeIDref(EmpiricalAminoAcidModelParser.EMPIRICAL_AMINO_ACID_MODEL,
data.substitutionModelIdref);
break;
case 7: // FLU
writer.writeIDref(EmpiricalAminoAcidModelParser.EMPIRICAL_AMINO_ACID_MODEL,
data.substitutionModelIdref);
break;
case 8: // JTT
writer.writeIDref(EmpiricalAminoAcidModelParser.EMPIRICAL_AMINO_ACID_MODEL,
data.substitutionModelIdref);
break;
case 9: // LG
writer.writeIDref(EmpiricalAminoAcidModelParser.EMPIRICAL_AMINO_ACID_MODEL,
data.substitutionModelIdref);
break;
case 10: // MTREV
writer.writeIDref(EmpiricalAminoAcidModelParser.EMPIRICAL_AMINO_ACID_MODEL,
data.substitutionModelIdref);
break;
case 11: // WAG
writer.writeIDref(EmpiricalAminoAcidModelParser.EMPIRICAL_AMINO_ACID_MODEL,
data.substitutionModelIdref);
break;
}// END: switch
writer.writeIDref(SiteModel.SITE_MODEL, data.siteRateModelIdref);
int clockModel = data.clockModelIndex;
switch (clockModel) {
case 0: // StrictClock
writer.writeIDref(
StrictClockBranchRatesParser.STRICT_CLOCK_BRANCH_RATES,
data.clockModelIdref);
break;
case 1: // LognormalRelaxedClock
writer.writeIDref(
DiscretizedBranchRatesParser.DISCRETIZED_BRANCH_RATES,
data.clockModelIdref);
break;
case 2: // ExponentialRelaxedClock
writer.writeIDref(
DiscretizedBranchRatesParser.DISCRETIZED_BRANCH_RATES,
data.clockModelIdref);
break;
}// END: switch
writer.writeIDref(FrequencyModelParser.FREQUENCY_MODEL,
data.frequencyModelIdref);
if (data.ancestralSequenceString != null) {
writeAncestralSequence(data, writer, suffix);
}
writer.writeCloseTag(PartitionParser.PARTITION);
suffix++;
}// END: partitions loop
writer.writeCloseTag(BeagleSequenceSimulatorParser.BEAGLE_SEQUENCE_SIMULATOR);
}// END: writeBeagleSequenceSimulator
private void writeAncestralSequence(PartitionData data, XMLWriter writer, int suffix) {
writer.writeOpenTag(SequenceParser.SEQUENCE);
writer.writeTag(
TaxonParser.TAXON, // tagname
new Attribute[] { // attributes[]
new Attribute.Default<String>(XMLParser.ID, Utils.ANCESTRAL_SEQUENCE + suffix) },
true // close
);
writer.write (data.ancestralSequenceString + "\n");
writer.writeCloseTag(SequenceParser.SEQUENCE);
}//END: writeAncestralSequence
private void writeNewick(TreeModel tree, XMLWriter writer,
String suffix) {
writer.writeOpenTag(NewickParser.NEWICK,
new Attribute[] { new Attribute.Default<String>(XMLParser.ID,
Utils.TOPOLOGY + suffix), //
new Attribute.Default<String>(NewickParser.USING_DATES,
"false"), //
new Attribute.Default<String>(NewickParser.USING_HEIGHTS,
"true") //
});
writer.writeText(TreeUtils.newick(tree));
writer.writeCloseTag(NewickParser.NEWICK);
}// END: writeNewick
private void writeDemographicModel(PartitionData data, XMLWriter writer,
String suffix) {
int demographicModel = data.demographicModelIndex;
switch (demographicModel) {
case 0: // NoModel
// do nothing
break;
case 1: // Constant Population
writer.writeOpenTag(
ConstantPopulationModelParser.CONSTANT_POPULATION_MODEL,
new Attribute[] {
new Attribute.Default<String>(XMLParser.ID,
Utils.DEMOGRAPHIC_MODEL + suffix
// data.demographicModelIdref
),
new Attribute.Default<String>(XMLUnits.UNITS,
XMLUnits.YEARS) });
writeParameter(ConstantPopulationModelParser.POPULATION_SIZE,
"constant.popSize" + suffix, 1,
String.valueOf(data.demographicParameterValues[0]), writer);
writer.writeCloseTag(ConstantPopulationModelParser.CONSTANT_POPULATION_MODEL);
writer.writeBlankLine();
writer.writeOpenTag(
CoalescentSimulatorParser.COALESCENT_SIMULATOR,
new Attribute[] {
new Attribute.Default<String>(XMLParser.ID,
Utils.TOPOLOGY + suffix) });
writer.writeIDref(TaxaParser.TAXA, data.taxaIdref);
writer.writeIDref(ConstantPopulationModelParser.CONSTANT_POPULATION_MODEL, data.demographicModelIdref);
writer.writeCloseTag(CoalescentSimulatorParser.COALESCENT_SIMULATOR);
break;
case 2: // Exponential Growth (Growth Rate)
writer.writeOpenTag(
ExponentialGrowthModelParser.EXPONENTIAL_GROWTH_MODEL,
new Attribute[] {
new Attribute.Default<String>(XMLParser.ID,
data.demographicModelIdref),
new Attribute.Default<String>(XMLUnits.UNITS,
XMLUnits.YEARS) });
writeParameter(ExponentialGrowthModelParser.POPULATION_SIZE,
"exponential.popSize" + suffix, 1,
String.valueOf(data.demographicParameterValues[1]), writer);
writeParameter(ExponentialGrowthModelParser.GROWTH_RATE,
"exponential.growthRate" + suffix, 1,
String.valueOf(data.demographicParameterValues[2]), writer);
writer.writeCloseTag(ExponentialGrowthModelParser.EXPONENTIAL_GROWTH_MODEL);
writer.writeBlankLine();
writer.writeOpenTag(
CoalescentSimulatorParser.COALESCENT_SIMULATOR,
new Attribute[] {
new Attribute.Default<String>(XMLParser.ID,
Utils.TOPOLOGY + suffix) });
writer.writeIDref(TaxaParser.TAXA, TaxaParser.TAXA);
writer.writeIDref(ExponentialGrowthModelParser.EXPONENTIAL_GROWTH_MODEL, data.demographicModelIdref);
writer.writeCloseTag(CoalescentSimulatorParser.COALESCENT_SIMULATOR);
break;
case 3: // Exponential Growth (Doubling Time)
writer.writeOpenTag(
ExponentialGrowthModelParser.EXPONENTIAL_GROWTH_MODEL,
new Attribute[] {
new Attribute.Default<String>(XMLParser.ID,
data.demographicModelIdref),
new Attribute.Default<String>(XMLUnits.UNITS,
XMLUnits.YEARS) });
writeParameter(ExponentialGrowthModelParser.POPULATION_SIZE,
"exponential.popSize" + suffix, 1,
String.valueOf(data.demographicParameterValues[3]), writer);
writeParameter(ExponentialGrowthModelParser.DOUBLING_TIME,
"exponential.doublingTime" + suffix, 1,
String.valueOf(data.demographicParameterValues[4]), writer);
writer.writeCloseTag(ExponentialGrowthModelParser.EXPONENTIAL_GROWTH_MODEL);
writer.writeBlankLine();
writer.writeOpenTag(
CoalescentSimulatorParser.COALESCENT_SIMULATOR,
new Attribute[] {
new Attribute.Default<String>(XMLParser.ID,
Utils.TOPOLOGY + suffix) });
writer.writeIDref(TaxaParser.TAXA, TaxaParser.TAXA);
writer.writeIDref(ExponentialGrowthModelParser.EXPONENTIAL_GROWTH_MODEL, data.demographicModelIdref);
writer.writeCloseTag(CoalescentSimulatorParser.COALESCENT_SIMULATOR);
break;
// case 4: // Logistic Growth (Growth Rate)
}// END: switch
}// END: writeDemographicModel
private void writeBranchRatesModel(PartitionData data, XMLWriter writer,
String suffix) {
double numberOfBranches = 0;
int clockModel = data.clockModelIndex;
switch (clockModel) {
case 0: // StrictClock
writer.writeOpenTag(
StrictClockBranchRatesParser.STRICT_CLOCK_BRANCH_RATES,
new Attribute[] { new Attribute.Default<String>(
XMLParser.ID, data.clockModelIdref) });
writeParameter(StrictClockBranchRatesParser.RATE,
PartitionData.clockParameterNames[0] + suffix, 1,
String.valueOf(data.clockParameterValues[0]), writer);
writer.writeCloseTag(StrictClockBranchRatesParser.STRICT_CLOCK_BRANCH_RATES);
break;
case 1: // Lognormal relaxed clock
writer.writeOpenTag(
DiscretizedBranchRatesParser.DISCRETIZED_BRANCH_RATES,
new Attribute[] {
new Attribute.Default<String>(XMLParser.ID,
data.clockModelIdref),
new Attribute.Default<String>(
DiscretizedBranchRatesParser.RANDOMIZE_RATES,
"true") }
);
writer.writeIDref(TreeModel.TREE_MODEL, data.treeModelIdref);
writer.writeOpenTag(DiscretizedBranchRatesParser.DISTRIBUTION);
writer.writeOpenTag(
LogNormalDistributionModelParser.LOGNORMAL_DISTRIBUTION_MODEL,
new Attribute[] {
new Attribute.Default<String>(
LogNormalDistributionModelParser.OFFSET,
String.valueOf(data.clockParameterValues[3]) ),
new Attribute.Default<String>(
LogNormalDistributionModelParser.MEAN_IN_REAL_SPACE,
"false"),
new Attribute.Default<String>(
LogNormalDistributionModelParser.STDEV_IN_REAL_SPACE,
"false") });
writeParameter(LogNormalDistributionModelParser.MEAN,
PartitionData.clockParameterNames[1] + suffix, 1,
String.valueOf(data.clockParameterValues[1]), writer);
writeParameter(LogNormalDistributionModelParser.STDEV,
PartitionData.clockParameterNames[2] + suffix, 1,
String.valueOf(data.clockParameterValues[2]), writer);
writer.writeCloseTag(LogNormalDistributionModelParser.LOGNORMAL_DISTRIBUTION_MODEL);
writer.writeCloseTag(DiscretizedBranchRatesParser.DISTRIBUTION);
numberOfBranches = 2 * (data.createTreeModel().getTaxonCount() - 1);
writeParameter(DiscretizedBranchRatesParser.RATE_CATEGORIES,
"branchRates.categories" + suffix, (int) numberOfBranches, null, writer);
writer.writeCloseTag(DiscretizedBranchRatesParser.DISCRETIZED_BRANCH_RATES);
break;
case 2: // Exponential relaxed clock
writer.writeOpenTag(
DiscretizedBranchRatesParser.DISCRETIZED_BRANCH_RATES,
new Attribute[] {
new Attribute.Default<String>(XMLParser.ID,
data.clockModelIdref),
new Attribute.Default<String>(
DiscretizedBranchRatesParser.RANDOMIZE_RATES,
"true") }
);
writer.writeIDref(TreeModel.TREE_MODEL, data.treeModelIdref);
writer.writeOpenTag(DiscretizedBranchRatesParser.DISTRIBUTION);
writer.writeOpenTag(
ExponentialDistributionModel.EXPONENTIAL_DISTRIBUTION_MODEL,
new Attribute[] {
new Attribute.Default<String>(
LogNormalDistributionModelParser.OFFSET,
String.valueOf(data.clockParameterValues[5]) ),
new Attribute.Default<String>(
LogNormalDistributionModelParser.MEAN_IN_REAL_SPACE,
"true") });
writeParameter(DistributionModelParser.MEAN,
PartitionData.clockParameterNames[4] + suffix, 1,
String.valueOf(data.clockParameterValues[4]), writer);
writer.writeCloseTag(ExponentialDistributionModel.EXPONENTIAL_DISTRIBUTION_MODEL);
writer.writeCloseTag(DiscretizedBranchRatesParser.DISTRIBUTION);
numberOfBranches = 2 * (data.createTreeModel().getTaxonCount() - 1);
writeParameter(DiscretizedBranchRatesParser.RATE_CATEGORIES,
"branchRates.categories" + suffix, (int) numberOfBranches, null, writer);
writer.writeCloseTag(DiscretizedBranchRatesParser.DISCRETIZED_BRANCH_RATES);
break;
case 3: // Inverse Gaussian
writer.writeOpenTag(
DiscretizedBranchRatesParser.DISCRETIZED_BRANCH_RATES,
new Attribute[] {
new Attribute.Default<String>(XMLParser.ID,
data.clockModelIdref),
new Attribute.Default<String>(
DiscretizedBranchRatesParser.RANDOMIZE_RATES,
"true") }
);
writer.writeIDref(TreeModel.TREE_MODEL, data.treeModelIdref);
writer.writeOpenTag(DiscretizedBranchRatesParser.DISTRIBUTION);
writer.writeOpenTag(
InverseGaussianDistributionModelParser.INVERSEGAUSSIAN_DISTRIBUTION_MODEL,
new Attribute[] { new Attribute.Default<String>(
InverseGaussianDistributionModelParser.OFFSET,
String.valueOf(data.clockParameterValues[8])) });
writeParameter(InverseGaussianDistributionModelParser.MEAN,
PartitionData.clockParameterNames[7] + suffix, 1,
String.valueOf(data.clockParameterValues[7]), writer);
writeParameter(InverseGaussianDistributionModelParser.STDEV,
PartitionData.clockParameterNames[6] + suffix, 1,
String.valueOf(data.clockParameterValues[6]), writer);
writer.writeCloseTag(InverseGaussianDistributionModelParser.INVERSEGAUSSIAN_DISTRIBUTION_MODEL);
writer.writeCloseTag(DiscretizedBranchRatesParser.DISTRIBUTION);
numberOfBranches = 2 * (data.createTreeModel().getTaxonCount() - 1);
writeParameter(DiscretizedBranchRatesParser.RATE_CATEGORIES,
"branchRates.categories" + suffix, (int) numberOfBranches, null, writer);
writer.writeCloseTag(DiscretizedBranchRatesParser.DISCRETIZED_BRANCH_RATES);
}// END: switch
}// END: writeBranchRatesModel
private void writeTaxa(Taxa taxa, XMLWriter writer, String suffix) {
writer.writeOpenTag(TaxaParser.TAXA, // tagname
new Attribute[] { // attributes[]
new Attribute.Default<String>(XMLParser.ID, TaxaParser.TAXA + suffix) });
for (int i = 0; i < taxa.getTaxonCount(); i++) {
Taxon taxon = taxa.getTaxon(i);
writer.writeTag(
TaxonParser.TAXON, // tagname
new Attribute[] { // attributes[]
new Attribute.Default<String>(XMLParser.ID, taxon.getId()) },
true // close
);
}// END: i loop
writer.writeCloseTag(TaxaParser.TAXA);
}// END: writeTaxa
private void writeTreeModel(
// TreeModel tree,
XMLWriter writer, String suffix) {
final String treeModelName = TreeModel.TREE_MODEL + suffix;
writer.writeTag(TreeModel.TREE_MODEL, new Attribute.Default<String>(
XMLParser.ID, treeModelName), false);
writer.writeIDref("tree", Utils.TOPOLOGY + suffix);
writeParameter(TreeModelParser.ROOT_HEIGHT, treeModelName + "."
+ TreeModelParser.ROOT_HEIGHT, 1, null, writer);
writer.writeOpenTag(TreeModelParser.NODE_HEIGHTS,
new Attribute.Default<String>(TreeModelParser.INTERNAL_NODES,
"true"));
writeParameter(null, treeModelName + "." + "internalNodeHeights", 1,
null, writer);
writer.writeCloseTag(TreeModelParser.NODE_HEIGHTS);
writer.writeOpenTag(TreeModelParser.NODE_HEIGHTS,
new Attribute[] {
new Attribute.Default<String>(
TreeModelParser.INTERNAL_NODES, "true"),
new Attribute.Default<String>(
TreeModelParser.ROOT_NODE, "true") });
writeParameter(null, treeModelName + "." + "allInternalNodeHeights", 1,
null, writer);
writer.writeCloseTag(TreeModelParser.NODE_HEIGHTS);
writer.writeCloseTag(TreeModel.TREE_MODEL);
}// END: writeTreeModel
private void writeReport(XMLWriter writer) {
writer.writeOpenTag(
Report.REPORT,
new Attribute[] { new Attribute.Default<String>(
Report.FILENAME, "sequences."
+ String.valueOf(dataList.outputFormat)
.toLowerCase()) });
writer.writeIDref(
BeagleSequenceSimulatorParser.BEAGLE_SEQUENCE_SIMULATOR,
"simulator");
writer.writeCloseTag(Report.REPORT);
}// END: writeReport
private void writeSiteRateModel(PartitionData data, XMLWriter writer, int suffix) {
writer.writeOpenTag(SiteModel.SITE_MODEL,
new Attribute[] { new Attribute.Default<String>(XMLParser.ID,
data.siteRateModelIdref) });
writer.writeOpenTag(GammaSiteModelParser.SUBSTITUTION_MODEL);
int substitutionModelIndex = data.substitutionModelIndex;
switch (substitutionModelIndex) {
case 0: // HKY
writer.writeIDref(NucModelType.HKY.getXMLName(),
data.substitutionModelIdref);
break;
case 1: // GTR
writer.writeIDref(GTRParser.GTR_MODEL, data.substitutionModelIdref);
break;
case 2: // TN93
writer.writeIDref(NucModelType.TN93.getXMLName(),
data.substitutionModelIdref);
break;
case 3: // GY94CodonModel
writer.writeIDref(YangCodonModelParser.YANG_CODON_MODEL,
data.substitutionModelIdref);
break;
case 4: // MG94CodonModel
writer.writeIDref(MG94CodonModelParser.MUSE_CODON_MODEL,
data.substitutionModelIdref);
break;
case 5: // Blosum62
writer.writeIDref(EmpiricalAminoAcidModelParser.EMPIRICAL_AMINO_ACID_MODEL,
data.substitutionModelIdref);
break;
case 6: // CPREV
writer.writeIDref(EmpiricalAminoAcidModelParser.EMPIRICAL_AMINO_ACID_MODEL,
data.substitutionModelIdref);
break;
case 7: // Dayhoff
writer.writeIDref(EmpiricalAminoAcidModelParser.EMPIRICAL_AMINO_ACID_MODEL,
data.substitutionModelIdref);
break;
case 8: // FLU
writer.writeIDref(EmpiricalAminoAcidModelParser.EMPIRICAL_AMINO_ACID_MODEL,
data.substitutionModelIdref);
break;
case 9: // JTT
writer.writeIDref(EmpiricalAminoAcidModelParser.EMPIRICAL_AMINO_ACID_MODEL,
data.substitutionModelIdref);
break;
case 10: // LG
writer.writeIDref(EmpiricalAminoAcidModelParser.EMPIRICAL_AMINO_ACID_MODEL,
data.substitutionModelIdref);
break;
case 11: // MTREV
writer.writeIDref(EmpiricalAminoAcidModelParser.EMPIRICAL_AMINO_ACID_MODEL,
data.substitutionModelIdref);
break;
case 12: // WAG
writer.writeIDref(EmpiricalAminoAcidModelParser.EMPIRICAL_AMINO_ACID_MODEL,
data.substitutionModelIdref);
break;
}// END: switch
writer.writeCloseTag(GammaSiteModelParser.SUBSTITUTION_MODEL);
int siteRateModelIndex = data.siteRateModelIndex;
switch (siteRateModelIndex) {
case 0: // no model
// do nothing
break;
case 1: // GammaSiteRateModel
writer.writeOpenTag(
GammaSiteModelParser.GAMMA_SHAPE,
new Attribute.Default<String>(
GammaSiteModelParser.GAMMA_CATEGORIES,
String.valueOf((int) data.siteRateModelParameterValues[0])));
//TODO
writeParameter(null, "alpha" + suffix, 1,
String.valueOf(data.siteRateModelParameterValues[1]),
writer);
writer.writeCloseTag(GammaSiteModelParser.GAMMA_SHAPE);
if (data.siteRateModelParameterValues[2] > 0.0) {
writeParameter(GammaSiteModelParser.PROPORTION_INVARIANT, "pInv", 1,
String.valueOf(data.siteRateModelParameterValues[2]),
writer);
}
break;
}// END: switch
writer.writeCloseTag(SiteModel.SITE_MODEL);
}// END: writeSiteModel
private void writeBranchModel(PartitionData data, XMLWriter writer,
String suffix) {
int substitutionModelIndex = data.substitutionModelIndex;
switch (substitutionModelIndex) {
case 0: // HKY
writer.writeOpenTag(NucModelType.HKY.getXMLName(),
new Attribute[] { new Attribute.Default<String>(
XMLParser.ID, data.substitutionModelIdref) });
writer.writeOpenTag(FrequencyModelParser.FREQUENCIES);
writer.writeIDref(FrequencyModelParser.FREQUENCY_MODEL,
data.frequencyModelIdref);
writer.writeCloseTag(FrequencyModelParser.FREQUENCIES);
writeParameter(HKYParser.KAPPA, HKYParser.KAPPA + suffix, 1,
String.valueOf(data.substitutionParameterValues[0]), writer);
writer.writeCloseTag(NucModelType.HKY.getXMLName());
break;
case 1: // GTR
writer.writeOpenTag(GTRParser.GTR_MODEL,
new Attribute[] { new Attribute.Default<String>(
XMLParser.ID, data.substitutionModelIdref) });
writer.writeOpenTag(FrequencyModelParser.FREQUENCIES);
writer.writeIDref(FrequencyModelParser.FREQUENCY_MODEL,
data.frequencyModelIdref);
writer.writeCloseTag(FrequencyModelParser.FREQUENCIES);
writeParameter(GTRParser.A_TO_C, "ac" + suffix, 1,
String.valueOf(data.substitutionParameterValues[1]), writer);
writeParameter(GTRParser.A_TO_G, "ag" + suffix, 1,
String.valueOf(data.substitutionParameterValues[2]), writer);
writeParameter(GTRParser.A_TO_T, "at" + suffix, 1,
String.valueOf(data.substitutionParameterValues[3]), writer);
writeParameter(GTRParser.C_TO_G, "cg" + suffix, 1,
String.valueOf(data.substitutionParameterValues[4]), writer);
writeParameter(GTRParser.C_TO_T, "ct" + suffix, 1,
String.valueOf(data.substitutionParameterValues[5]), writer);
// writeParameter(GTRParser.G_TO_T, "gt" + suffix, 1,
// String.valueOf(data.substitutionParameterValues[6]), writer);
writer.writeCloseTag(GTRParser.GTR_MODEL);
break;
case 2: // TN93
writer.writeOpenTag(NucModelType.TN93.getXMLName(),
new Attribute[] { new Attribute.Default<String>(
XMLParser.ID, data.substitutionModelIdref) });
writer.writeOpenTag(FrequencyModelParser.FREQUENCIES);
writer.writeIDref(FrequencyModelParser.FREQUENCY_MODEL,
data.frequencyModelIdref);
writer.writeCloseTag(FrequencyModelParser.FREQUENCIES);
writeParameter(TN93Parser.KAPPA1, TN93Parser.KAPPA1 + suffix, 1,
String.valueOf(data.substitutionParameterValues[7]), writer);
writeParameter(TN93Parser.KAPPA2, TN93Parser.KAPPA2 + suffix, 1,
String.valueOf(data.substitutionParameterValues[8]), writer);
writer.writeCloseTag(NucModelType.TN93.getXMLName());
break;
case 3: // Yang Codon Model
writer.writeOpenTag(YangCodonModelParser.YANG_CODON_MODEL,
new Attribute[] { new Attribute.Default<String>(
XMLParser.ID, data.substitutionModelIdref) });
writer.writeIDref(FrequencyModelParser.FREQUENCY_MODEL,
data.frequencyModelIdref);
writeParameter(YangCodonModelParser.OMEGA,
YangCodonModelParser.OMEGA + suffix, 1,
String.valueOf(data.substitutionParameterValues[9]), writer);
writeParameter(YangCodonModelParser.KAPPA,
YangCodonModelParser.KAPPA + suffix, 1,
String.valueOf(data.substitutionParameterValues[10]),
writer);
writer.writeCloseTag(YangCodonModelParser.YANG_CODON_MODEL);
break;
case 4: //
writer.writeOpenTag(MG94CodonModelParser.MUSE_CODON_MODEL,
new Attribute[] { new Attribute.Default<String>(
XMLParser.ID, data.substitutionModelIdref) });
writer.writeIDref(FrequencyModelParser.FREQUENCY_MODEL,
data.frequencyModelIdref);
writeParameter(MG94CodonModelParser.ALPHA,
MG94CodonModelParser.ALPHA + suffix, 1,
String.valueOf(data.substitutionParameterValues[11]), writer);
writeParameter(MG94CodonModelParser.BETA,
MG94CodonModelParser.BETA + suffix, 1,
String.valueOf(data.substitutionParameterValues[12]), writer);
writeParameter(MG94CodonModelParser.KAPPA,
MG94CodonModelParser.KAPPA + suffix, 1,
String.valueOf(data.substitutionParameterValues[13]), writer);
writer.writeCloseTag(MG94CodonModelParser.MUSE_CODON_MODEL);
break;
case 5: // Blosum62
writer.writeOpenTag(
EmpiricalAminoAcidModelParser.EMPIRICAL_AMINO_ACID_MODEL,
new Attribute[] {
new Attribute.Default<String>(XMLParser.ID,
data.substitutionModelIdref), //
new Attribute.Default<String>(
EmpiricalAminoAcidModelParser.TYPE,
AminoAcidModelType.BLOSUM_62.getXMLName())
});
writer.writeOpenTag(FrequencyModelParser.FREQUENCIES);
writer.writeIDref(FrequencyModelParser.FREQUENCY_MODEL,
data.frequencyModelIdref);
writer.writeCloseTag(FrequencyModelParser.FREQUENCIES);
writer.writeCloseTag(EmpiricalAminoAcidModelParser.EMPIRICAL_AMINO_ACID_MODEL);
break;
case 6: // CPREV
writer.writeOpenTag(
EmpiricalAminoAcidModelParser.EMPIRICAL_AMINO_ACID_MODEL,
new Attribute[] {
new Attribute.Default<String>(XMLParser.ID,
data.substitutionModelIdref), //
new Attribute.Default<String>(
EmpiricalAminoAcidModelParser.TYPE,
AminoAcidModelType.CP_REV_45.getXMLName())
});
writer.writeOpenTag(FrequencyModelParser.FREQUENCIES);
writer.writeIDref(FrequencyModelParser.FREQUENCY_MODEL,
data.frequencyModelIdref);
writer.writeCloseTag(FrequencyModelParser.FREQUENCIES);
writer.writeCloseTag(EmpiricalAminoAcidModelParser.EMPIRICAL_AMINO_ACID_MODEL);
break;
case 7: // Dayhoff
writer.writeOpenTag(
EmpiricalAminoAcidModelParser.EMPIRICAL_AMINO_ACID_MODEL,
new Attribute[] {
new Attribute.Default<String>(XMLParser.ID,
data.substitutionModelIdref), //
new Attribute.Default<String>(
EmpiricalAminoAcidModelParser.TYPE,
AminoAcidModelType.DAYHOFF.getXMLName())
});
writer.writeOpenTag(FrequencyModelParser.FREQUENCIES);
writer.writeIDref(FrequencyModelParser.FREQUENCY_MODEL,
data.frequencyModelIdref);
writer.writeCloseTag(FrequencyModelParser.FREQUENCIES);
writer.writeCloseTag(EmpiricalAminoAcidModelParser.EMPIRICAL_AMINO_ACID_MODEL);
break;
case 8: // FLU
writer.writeOpenTag(
EmpiricalAminoAcidModelParser.EMPIRICAL_AMINO_ACID_MODEL,
new Attribute[] {
new Attribute.Default<String>(XMLParser.ID,
data.substitutionModelIdref), //
new Attribute.Default<String>(
EmpiricalAminoAcidModelParser.TYPE,
AminoAcidModelType.FLU.getXMLName())
});
writer.writeOpenTag(FrequencyModelParser.FREQUENCIES);
writer.writeIDref(FrequencyModelParser.FREQUENCY_MODEL,
data.frequencyModelIdref);
writer.writeCloseTag(FrequencyModelParser.FREQUENCIES);
writer.writeCloseTag(EmpiricalAminoAcidModelParser.EMPIRICAL_AMINO_ACID_MODEL);
break;
case 9: // JTT
writer.writeOpenTag(
EmpiricalAminoAcidModelParser.EMPIRICAL_AMINO_ACID_MODEL,
new Attribute[] {
new Attribute.Default<String>(XMLParser.ID,
data.substitutionModelIdref), //
new Attribute.Default<String>(
EmpiricalAminoAcidModelParser.TYPE,
AminoAcidModelType.JTT.getXMLName())
});
writer.writeOpenTag(FrequencyModelParser.FREQUENCIES);
writer.writeIDref(FrequencyModelParser.FREQUENCY_MODEL,
data.frequencyModelIdref);
writer.writeCloseTag(FrequencyModelParser.FREQUENCIES);
writer.writeCloseTag(EmpiricalAminoAcidModelParser.EMPIRICAL_AMINO_ACID_MODEL);
break;
case 10: // LG
writer.writeOpenTag(
EmpiricalAminoAcidModelParser.EMPIRICAL_AMINO_ACID_MODEL,
new Attribute[] {
new Attribute.Default<String>(XMLParser.ID,
data.substitutionModelIdref), //
new Attribute.Default<String>(
EmpiricalAminoAcidModelParser.TYPE,
AminoAcidModelType.LG.getXMLName())
});
writer.writeOpenTag(FrequencyModelParser.FREQUENCIES);
writer.writeIDref(FrequencyModelParser.FREQUENCY_MODEL,
data.frequencyModelIdref);
writer.writeCloseTag(FrequencyModelParser.FREQUENCIES);
writer.writeCloseTag(EmpiricalAminoAcidModelParser.EMPIRICAL_AMINO_ACID_MODEL);
break;
case 11: // MTREV
writer.writeOpenTag(
EmpiricalAminoAcidModelParser.EMPIRICAL_AMINO_ACID_MODEL,
new Attribute[] {
new Attribute.Default<String>(XMLParser.ID,
data.substitutionModelIdref), //
new Attribute.Default<String>(
EmpiricalAminoAcidModelParser.TYPE,
AminoAcidModelType.MT_REV_24.getXMLName())
});
writer.writeOpenTag(FrequencyModelParser.FREQUENCIES);
writer.writeIDref(FrequencyModelParser.FREQUENCY_MODEL,
data.frequencyModelIdref);
writer.writeCloseTag(FrequencyModelParser.FREQUENCIES);
writer.writeCloseTag(EmpiricalAminoAcidModelParser.EMPIRICAL_AMINO_ACID_MODEL);
break;
case 12: // WAG
writer.writeOpenTag(
EmpiricalAminoAcidModelParser.EMPIRICAL_AMINO_ACID_MODEL,
new Attribute[] {
new Attribute.Default<String>(XMLParser.ID,
data.substitutionModelIdref), //
new Attribute.Default<String>(
EmpiricalAminoAcidModelParser.TYPE,
AminoAcidModelType.WAG.getXMLName())
});
writer.writeOpenTag(FrequencyModelParser.FREQUENCIES);
writer.writeIDref(FrequencyModelParser.FREQUENCY_MODEL,
data.frequencyModelIdref);
writer.writeCloseTag(FrequencyModelParser.FREQUENCIES);
writer.writeCloseTag(EmpiricalAminoAcidModelParser.EMPIRICAL_AMINO_ACID_MODEL);
break;
}// END: switch
}// END: writeBranchModel
private void writeFrequencyModel(PartitionData data, XMLWriter writer) {
DataType dataType = null;
String frequencies = null;
// int dataTypeIndex = data.dataTypeIndex;
int frequencyModelIndex = data.frequencyModelIndex;
switch (frequencyModelIndex) {
case 0: // Nucleotide
dataType = data.createDataType();
// dataType = Nucleotides.INSTANCE;
frequencies = data.frequencyParameterValues[0] + "";
for (int i = 1; i < 4; i++) {
frequencies += " " + data.frequencyParameterValues[i];
}
writer.writeOpenTag(FrequencyModelParser.FREQUENCY_MODEL, // tagname
new Attribute[] { // attributes[]
new Attribute.Default<String>(XMLParser.ID,
data.frequencyModelIdref), // id
new Attribute.Default<String>(DataType.DATA_TYPE,
dataType.getDescription()) // dataType
});
writeParameter(FrequencyModelParser.FREQUENCIES, null,
dataType.getStateCount(), frequencies, writer);
writer.writeCloseTag(FrequencyModelParser.FREQUENCY_MODEL);
break;
case 1: // Codon
dataType = data.createDataType();
// dataType = Codons.UNIVERSAL;
frequencies = data.frequencyParameterValues[4] + "";
for (int i = 5; i < 65; i++) {
frequencies += " " + data.frequencyParameterValues[i];
}
writer.writeOpenTag(FrequencyModelParser.FREQUENCY_MODEL, // tagname
new Attribute[] { // attributes[]
new Attribute.Default<String>(XMLParser.ID,
data.frequencyModelIdref), // id
new Attribute.Default<String>(DataType.DATA_TYPE,
// dataType.getDescription()
Utils.CODON_UNIVERSAL
) // dataType
});
writeParameter(FrequencyModelParser.FREQUENCIES, null,
dataType.getStateCount(), frequencies, writer);
writer.writeCloseTag(FrequencyModelParser.FREQUENCY_MODEL);
break;
case 2: // Amino acid
dataType = data.createDataType();
// dataType = AminoAcids.INSTANCE;
frequencies = data.frequencyParameterValues[65] + "";
for (int i = 66; i < 85; i++) {
frequencies += " " + data.frequencyParameterValues[i];
}
writer.writeOpenTag(FrequencyModelParser.FREQUENCY_MODEL, // tagname
new Attribute[] { // attributes[]
new Attribute.Default<String>(XMLParser.ID,
data.frequencyModelIdref), // id
new Attribute.Default<String>(DataType.DATA_TYPE,
// dataType.getDescription()
AminoAcids.DESCRIPTION
) // dataType
});
writeParameter(FrequencyModelParser.FREQUENCIES, null,
dataType.getStateCount(), frequencies, writer);
writer.writeCloseTag(FrequencyModelParser.FREQUENCY_MODEL);
break;
}// END: switch
}// END: writeFrequencyModel
@SuppressWarnings("rawtypes")
private void writeParameter(String wrapper, String id, int dimension,
String value, XMLWriter writer) {
if (wrapper != null) {
writer.writeOpenTag(wrapper);
}
ArrayList<Attribute.Default> attributes = new ArrayList<Attribute.Default>();
if (id != null) {
attributes.add(new Attribute.Default<String>(XMLParser.ID, id));
}
if (dimension > 1) {
attributes.add(new Attribute.Default<String>(
ParameterParser.DIMENSION, String.valueOf(dimension)));
}
if (value != null) {
attributes.add(new Attribute.Default<String>(ParameterParser.VALUE,
value));
}
Attribute[] attrArray = new Attribute[attributes.size()];
for (int i = 0; i < attrArray.length; i++) {
attrArray[i] = attributes.get(i);
}
writer.writeTag(ParameterParser.PARAMETER, attrArray, true);
if (wrapper != null) {
writer.writeCloseTag(wrapper);
}
}// END: writeParameter
}// END: class