Skip to content

Commit e1b7d35

Browse files
committed
Support Exporting DNA/RNA Analysis to MrBayes Block Files (iqtree#260)
* Support Exporting DNA/RNA Analysis to MrBayes Block Files * Fix Formatting Issues * Move Functions to Supplementary, Fix +R Remapping
1 parent 74da454 commit e1b7d35

File tree

12 files changed

+368
-27
lines changed

12 files changed

+368
-27
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ tags
1414
test_scripts/iqtree_test_cmds.txt
1515
pllrepo/
1616
build/
17+
cmake-build-debug/
1718
/Default-clang
1819
.idea/
1920
.idea/codeStyleSettings.xml

main/phyloanalysis.cpp

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1156,6 +1156,12 @@ void printOutfilesInfo(Params &params, IQTree &tree) {
11561156
if (params.optimize_linked_gtr) {
11571157
cout << " GTRPMIX nex file: " << params.out_prefix << ".GTRPMIX.nex" << endl;
11581158
}
1159+
1160+
if (params.mr_bayes_output) {
1161+
cout << endl << "MrBayes block written to:" << endl;
1162+
cout << " Base template file: " << params.out_prefix << ".mr_bayes_scheme.nex" << endl;
1163+
cout << " Template file with parameters: " << params.out_prefix << ".mr_bayes_model.nex" << endl;
1164+
}
11591165
cout << endl;
11601166

11611167
}
@@ -3100,8 +3106,13 @@ void runTreeReconstruction(Params &params, IQTree* &iqtree) {
31003106

31013107
}
31023108
if (iqtree->isSuperTree()) {
3103-
((PhyloSuperTree*) iqtree)->computeBranchLengths();
3104-
((PhyloSuperTree*) iqtree)->printBestPartitionParams((string(params.out_prefix) + ".best_model.nex").c_str());
3109+
auto superTree = (PhyloSuperTree*) iqtree;
3110+
superTree->computeBranchLengths();
3111+
superTree->printBestPartitionParams((string(params.out_prefix) + ".best_model.nex").c_str());
3112+
}
3113+
if (params.mr_bayes_output) {
3114+
iqtree->printMrBayesBlock((string(params.out_prefix) + ".mr_bayes_scheme.nex").c_str(), false);
3115+
iqtree->printMrBayesBlock((string(params.out_prefix) + ".mr_bayes_model.nex").c_str(), true);
31053116
}
31063117

31073118
cout << "BEST SCORE FOUND : " << iqtree->getCurScore() << endl;

main/phylotesting.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -390,5 +390,12 @@ string convertSeqTypeToSeqTypeName(SeqType seq_type);
390390

391391
string detectSeqTypeName(string model_name);
392392

393+
/**
394+
* get string name from a SeqType object
395+
* @param seq_type input sequence type
396+
* @return name
397+
*/
398+
string getSeqTypeName(SeqType seq_type);
399+
393400

394401
#endif /* PHYLOTESTING_H_ */

model/modeldna.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -564,3 +564,7 @@ void ModelDNA::setVariables(double *variables) {
564564
// j++;
565565
// }
566566
}
567+
568+
string ModelDNA::getModelDNACode() {
569+
return param_spec;
570+
}

model/modeldna.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,12 @@ class ModelDNA : public ModelMarkov
114114
*/
115115
virtual void computeTipLikelihood(PML::StateType state, double *state_lk);
116116

117+
/**
118+
* Get the Model DNA 'code', in form 'abcdef', used with ModelDNA model
119+
* Returns empty string by default (this is not a dna specific model)
120+
*/
121+
virtual string getModelDNACode();
122+
117123
protected:
118124

119125
/**

model/modelsubst.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -392,6 +392,12 @@ class ModelSubst: public Optimization, public CheckpointFactory
392392
*/
393393
virtual ModelSubst *getMutationModel() { return this; }
394394

395+
/**
396+
* Get the Model DNA 'code', in form 'abcdef', used with ModelDNA model
397+
* Returns empty string by default (this is not a dna specific model)
398+
*/
399+
virtual string getModelDNACode() { return ""; }
400+
395401
/*****************************************************
396402
Checkpointing facility
397403
*****************************************************/

tree/phylosupertree.cpp

Lines changed: 67 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
#include "main/phylotesting.h"
2424
#include "model/partitionmodel.h"
2525
#include "utils/MPIHelper.h"
26+
#include "utils/tools.h"
2627

2728
PhyloSuperTree::PhyloSuperTree()
2829
: IQTree()
@@ -1519,29 +1520,37 @@ void PhyloSuperTree::writeBranches(ostream &out) {
15191520
}
15201521
}
15211522

1522-
void PhyloSuperTree::printBestPartitionParams(const char *filename) {
1523+
void printCharsets(SuperAlignment* saln, size_t size, ofstream &out)
1524+
{
1525+
for (int part = 0; part < size; part++) {
1526+
string name = saln->partitions[part]->name;
1527+
replace(name.begin(), name.end(), '+', '_');
1528+
out << " charset " << name << " = ";
1529+
if (!saln->partitions[part]->aln_file.empty()) out << saln->partitions[part]->aln_file << ": ";
1530+
/*if (saln->partitions[part]->seq_type == SEQ_CODON)
1531+
out << "CODON, ";*/
1532+
if (!saln->partitions[part]->sequence_type.empty())
1533+
out << saln->partitions[part]->sequence_type << ", ";
1534+
string pos = saln->partitions[part]->position_spec;
1535+
replace(pos.begin(), pos.end(), ',' , ' ');
1536+
out << pos << ";" << endl;
1537+
}
1538+
}
1539+
1540+
void PhyloSuperTree::printBestPartitionParams(const char *filename)
1541+
{
15231542
try {
15241543
ofstream out;
15251544
out.exceptions(ios::failbit | ios::badbit);
15261545
out.open(filename);
15271546
out << "#nexus" << endl
15281547
<< "begin sets;" << endl;
1529-
int part;
1530-
SuperAlignment *saln = (SuperAlignment*)aln;
1531-
for (part = 0; part < size(); part++) {
1532-
string name = saln->partitions[part]->name;
1533-
replace(name.begin(), name.end(), '+', '_');
1534-
out << " charset " << name << " = ";
1535-
if (!saln->partitions[part]->aln_file.empty()) out << saln->partitions[part]->aln_file << ": ";
1536-
/*if (saln->partitions[part]->seq_type == SEQ_CODON)
1537-
out << "CODON, ";*/
1538-
out << saln->partitions[part]->sequence_type << ", ";
1539-
string pos = saln->partitions[part]->position_spec;
1540-
replace(pos.begin(), pos.end(), ',' , ' ');
1541-
out << pos << ";" << endl;
1542-
}
1548+
auto *saln = (SuperAlignment*)aln;
1549+
1550+
printCharsets(saln, size(), out);
1551+
15431552
out << " charpartition mymodels =" << endl;
1544-
for (part = 0; part < size(); part++) {
1553+
for (int part = 0; part < size(); part++) {
15451554
string name = saln->partitions[part]->name;
15461555
replace(name.begin(), name.end(), '+', '_');
15471556
if (part > 0) out << "," << endl;
@@ -1555,3 +1564,45 @@ void PhyloSuperTree::printBestPartitionParams(const char *filename) {
15551564
outError(ERR_WRITE_OUTPUT, filename);
15561565
}
15571566
}
1567+
1568+
void PhyloSuperTree::printMrBayesFreeRateReplacement(RateHeterogeneity *rate, string &charset, ofstream &out) {
1569+
// Call PhyloTree's function inside the correct checkpoint struct
1570+
checkpoint->startStruct("PartitionModelPlen");
1571+
checkpoint->startStruct(charset);
1572+
PhyloTree::printMrBayesFreeRateReplacement(rate, charset, out);
1573+
checkpoint->endStruct();
1574+
checkpoint->endStruct();
1575+
}
1576+
1577+
void PhyloSuperTree::printMrBayesBlock(const char *filename, bool inclParams)
1578+
{
1579+
ofstream out = startMrBayesBlock(filename);
1580+
auto *saln = (SuperAlignment*)aln;
1581+
printCharsets(saln, size(), out);
1582+
out << endl;
1583+
1584+
// Create Partition
1585+
size_type listSize = size();
1586+
out << " partition iqtree = " << listSize << ": ";
1587+
for (int part = 0; part < listSize; part++) {
1588+
string name = saln->partitions[part]->name;
1589+
replace(name.begin(), name.end(), '+', '_');
1590+
out << name;
1591+
if (part != listSize - 1) out << ", ";
1592+
else out << ";" << endl;
1593+
}
1594+
1595+
// Set Partition for Use
1596+
out << " set partition = iqtree;" << endl;
1597+
1598+
// Set Outgroup (if available)
1599+
if (!rooted) out << " outgroup " << root->name << ";" << endl << endl;
1600+
1601+
// Partition-Specific Model Information
1602+
for (int part = 0; part < listSize; part++) {
1603+
// MrBayes Partitions are 1-indexed
1604+
printMrBayesModelText(this, at(part), out, convertIntToString(part + 1), saln->partitions[part]->name, inclParams);
1605+
}
1606+
out << "end;" << endl;
1607+
out.close();
1608+
}

tree/phylosupertree.h

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -475,12 +475,25 @@ class PhyloSuperTree : public IQTree, public vector<PhyloTree* >
475475
*/
476476
void printBestPartitionParams(const char *filename);
477477

478-
478+
/**
479+
print mr bayes block with partition information and best model parameters
480+
@param filename output file name
481+
@param inclParams whether to include iqtree params
482+
*/
483+
virtual void printMrBayesBlock(const char *filename, bool inclParams);
484+
485+
/**
486+
* Prints the replacement prior settings for +R or +R+I.
487+
* @param rate the heterogeneity rate
488+
* @param charset the (original) charset of the current partition. An empty string if not a partitioned tree
489+
* @param out the ofstream to print to
490+
*/
491+
virtual void printMrBayesFreeRateReplacement(RateHeterogeneity* rate, string &charset, ofstream &out);
492+
479493
/** True when mixed codon with other data type */
480494
bool rescale_codon_brlen;
481-
482-
int totalNNIs, evalNNIs;
483495

496+
int totalNNIs, evalNNIs;
484497
};
485498

486499
#endif

0 commit comments

Comments
 (0)