@@ -1330,6 +1330,10 @@ void printOutfilesInfo(Params ¶ms, IQTree &tree) {
13301330 if (params.optimize_linked_gtr ) {
13311331 cout << " GTRPMIX nex file: " << params.out_prefix << " .GTRPMIX.nex" << endl;
13321332 }
1333+
1334+ if (params.mr_bayes_output ) {
1335+ cout << " MrBayes block written to: " << params.out_prefix << " .mr_bayes.nex" << endl;
1336+ }
13331337 cout << endl;
13341338
13351339}
@@ -3307,6 +3311,91 @@ SuperNeighbor* findRootedNeighbour(SuperNeighbor* super_root, int part_id) {
33073311 return nullptr ;
33083312}
33093313
3314+ void printMrBayesBlockFile (Params ¶ms, IQTree* &iqtree) {
3315+ ofstream out;
3316+ string filename = string (params.out_prefix ) + " .mr_bayes.nex" ;
3317+ try {
3318+ out.exceptions (ios::failbit | ios::badbit);
3319+ out.open (filename);
3320+
3321+ // Write Warning
3322+ out << " #nexus" << endl << endl
3323+ <<" [This MrBayes Block Declaration provides the basic "
3324+ << (iqtree->isSuperTree () ? " partition structure and models" : " models" )
3325+ << " from the IQTree Run.]" << endl
3326+ << " [Note that MrBayes does not support a large collection of models, so defaults of 'nst=6' for DNA and 'gtr' for Protein will be used if a model that does not exist in MrBayes is used.]" << endl
3327+ << " [Furthermore, the Model Parameter '+R' will be replaced by '+G+I'.]" << endl
3328+ << " [This should be used as a Template Only.]" << endl << endl;
3329+
3330+ // Begin File, Print Charsets
3331+ out << " begin mrbayes;" << endl;
3332+ } catch (ios::failure &) {
3333+ outError (ERR_WRITE_OUTPUT, filename);
3334+ }
3335+
3336+ if (!iqtree->isSuperTree ()) {
3337+ out << " [IQTree inferred model " << iqtree->getModelName () << " , " ;
3338+ iqtree->getModel ()->printMrBayesModelText (out, " all" , " " );
3339+
3340+ out << endl << " end;" << endl;
3341+ out.close ();
3342+ return ;
3343+ }
3344+
3345+ auto stree = (PhyloSuperTree*) iqtree;
3346+ auto saln = (SuperAlignment*) stree->aln ;
3347+ auto size = stree->size ();
3348+
3349+ for (int part = 0 ; part < size; part++) {
3350+ string name = saln->partitions [part]->name ;
3351+ replace (name.begin (), name.end (), ' +' , ' _' );
3352+ out << " charset " << name << " = " ;
3353+
3354+ string pos = saln->partitions [part]->position_spec ;
3355+ replace (pos.begin (), pos.end (), ' ,' , ' ' );
3356+ out << pos << " ;" << endl;
3357+ }
3358+
3359+ // Create Partition
3360+ out << endl << " partition iqtree = " << size << " : " ;
3361+ for (int part = 0 ; part < size; part++) {
3362+ if (part != 0 ) out << " , " ;
3363+
3364+ string name = saln->partitions [part]->name ;
3365+ replace (name.begin (), name.end (), ' +' , ' _' );
3366+ out << name;
3367+ }
3368+ out << " ;" << endl;
3369+
3370+ // Set Partition for Use
3371+ out << " set partition = iqtree;" << endl << endl;
3372+
3373+ // Partition-Specific Model Information
3374+ for (int part = 0 ; part < size; part++) {
3375+ PhyloTree* curr_tree = stree->at (part);
3376+
3377+ out << " [Subset #" << part + 1 << " : IQTree inferred model " << curr_tree->getModelName () << " , " ;
3378+ curr_tree->getModel ()->printMrBayesModelText (out,
3379+ convertIntToString (part + 1 ),
3380+ saln->partitions [part]->name );
3381+ out << endl;
3382+ }
3383+
3384+ // Partition Type Settings
3385+ if (params.partition_type != TOPO_UNLINKED) {
3386+ out << " unlink statefreq=(all) revmat=(all) shape=(all) pinvar=(all) tratio=(all);" << endl;
3387+ if (params.partition_type != BRLEN_FIX) {
3388+ out << " prset applyto=(all) ratepr=variable;" << endl;
3389+ if (params.partition_type != BRLEN_SCALE) {
3390+ out << " unlink brlens=(all);" << endl;
3391+ }
3392+ }
3393+ }
3394+
3395+ out << " end;" << endl;
3396+ out.close ();
3397+ }
3398+
33103399/* ***********************************************************
33113400 * MAIN TREE RECONSTRUCTION
33123401 ***********************************************************/
@@ -3810,8 +3899,14 @@ void runTreeReconstruction(Params ¶ms, IQTree* &iqtree) {
38103899
38113900 }
38123901 if (iqtree->isSuperTree ()) {
3813- ((PhyloSuperTree*) iqtree)->computeBranchLengths ();
3814- ((PhyloSuperTree*) iqtree)->printBestPartitionParams ((string (params.out_prefix ) + " .best_model.nex" ).c_str ());
3902+ auto stree = (PhyloSuperTree*) iqtree;
3903+ stree->computeBranchLengths ();
3904+ stree->printBestPartitionParams ((string (params.out_prefix ) + " .best_model.nex" ).c_str ());
3905+ }
3906+ if (params.mr_bayes_output ) {
3907+ cout << endl << " Writing MrBayes Block Files..." << endl;
3908+ printMrBayesBlockFile (params, iqtree);
3909+ cout << endl;
38153910 }
38163911
38173912 cout << " BEST SCORE FOUND : " << iqtree->getCurScore () << endl;
0 commit comments