15.1 The OutputManager Class

(Mac version)

< 15.0 | 15.1 | 15.2 >

The OutputManager will handle opening and closing tree and parameter files, saving sampled trees to the tree file, saving sampled parameter values to the parameter file, and displaying output to the console.

Some changes/additions will need to be made to the Data and Model classes, but that will be postponed until after we’ve created the OutputManager class.

Create a new file output_manager.hpp and replace the default contents with the following class declaration.

#pragma once    

#include "data.hpp"
#include "tree_manip.hpp"
#include "model.hpp"
#include "xstrom.hpp"
#include &lt;fstream&gt;

namespace strom {

    class OutputManager {
        public:
            typedef std::shared_ptr&lt; OutputManager &gt; SharedPtr;

                                       OutputManager();
                                       ~OutputManager();
            
            void                       setModel(Model::SharedPtr model) {_model = model;}
            void                       setTreeManip(TreeManip::SharedPtr tm) {_tree_manip = tm;}
            
            void                       openTreeFile(std::string filename, Data::SharedPtr data);
            void                       openParameterFile(std::string filename, Model::SharedPtr model);
            
            void                       closeTreeFile();
            void                       closeParameterFile();

            void                       outputConsole(std::string s);
            void                       outputTree(unsigned iter, TreeManip::SharedPtr tm);
            void                       outputParameters(unsigned iter, double lnL, double lnP, double TL, Model::SharedPtr model);
            

        private:

            TreeManip::SharedPtr       _tree_manip;
            Model::SharedPtr           _model;
            std::ofstream              _treefile;
            std::ofstream              _parameterfile;
            std::string                _tree_file_name;
            std::string                _param_file_name;
    };

    // member function bodies go here
    
}   

Constructor and destructor

The constructor stores default names for the tree and parameter files, and the destructor is empty. (The output lines are provided but can remain commented out unless you need them at a later time.)

    inline OutputManager::OutputManager() { 
        //std::cout &lt;&lt; "Constructing an OutputManager" &lt;&lt; std::endl;
        _tree_file_name = "trees.t";
        _param_file_name = "params.p";
    }

    inline OutputManager::~OutputManager() {
        //std::cout &lt;&lt; "Destroying an OutputManager" &lt;&lt; std::endl;
    } 

The openTreeFile and closeTreeFile member functions

These functions are responsible for opening and closing the file used to store trees sampled during the MCMC simulation. Note that some of the work in the openTreeFile function is done by the Data class: because the Data object knows the taxon names, it can easily write out the taxa block for us, as well as the translate command in the trees block.

    inline void OutputManager::openTreeFile(std::string filename, Data::SharedPtr data) {   
        assert(!_treefile.is_open());
        _tree_file_name = filename;
        _treefile.open(_tree_file_name.c_str());
        if (!_treefile.is_open())
            throw XStrom(boost::str(boost::format("Could not open tree file \"%s\"") % _tree_file_name));

        _treefile &lt;&lt; "#nexus\n\n";
        _treefile &lt;&lt; data-&gt;createTaxaBlock() &lt;&lt; std::endl;
       
        _treefile &lt;&lt; "begin trees;\n";
        _treefile &lt;&lt; data-&gt;createTranslateStatement() &lt;&lt; std::endl;
    }

    inline void OutputManager::closeTreeFile() {
        assert(_treefile.is_open());
        _treefile &lt;&lt; "end;\n";
        _treefile.close();
    }   

The openParameterFile and closeParameterFile member functions

These functions are responsible for opening and closing the file used to store model parameters sampled during the MCMC simulation. The openParameterFile function asks the supplied Model object to provide a list of parameter names that it then uses for column headers when creating a new parameter file.

    inline void OutputManager::openParameterFile(std::string filename, Model::SharedPtr model) {    
        assert(model);
        assert(!_parameterfile.is_open());
        _param_file_name = filename;
        _parameterfile.open(_param_file_name.c_str());
        if (!_parameterfile.is_open())
            throw XStrom(boost::str(boost::format("Could not open parameter file \"%s\"") % _param_file_name));
        _parameterfile &lt;&lt; boost::str(boost::format("%s\t%s\t%s\t%s\t%s") % "iter" % "lnL" % "lnPr" % "TL" % model-&gt;paramNamesAsString("\t")) &lt;&lt; std::endl;
    }

    inline void OutputManager::closeParameterFile() {
        assert(_parameterfile.is_open());
        _parameterfile.close();
    }   

The outputConsole, outputTree, and outputParameters member functions

These three functions are called to output messages to the user on the console, output sampled trees to the tree file, and output sampled parameters to the parameter file, respectively. The outputConsole function currently just outputs the supplied message to the terminal (console), but could easily be modified to output the same message to both the console and to a file (we are not going to write that code in this tutorial, however). The outputTree function asks the supplied TreeManip object to provide the tree description that it then stores in the tree file. The outputParameters function asks the supplied Model object to provide the current values of all model parameters that it then stores in the parameters file.

    inline void OutputManager::outputConsole(std::string s) {   
        std::cout &lt;&lt; s &lt;&lt; std::endl;
    }
    
    inline void OutputManager::outputTree(unsigned iter, TreeManip::SharedPtr tm) {
        assert(_treefile.is_open());
        assert(tm);
        _treefile &lt;&lt; boost::str(boost::format("  tree iter_%d = %s;") % iter % tm-&gt;makeNewick(5)) &lt;&lt; std::endl;
    }
    
    inline void OutputManager::outputParameters(unsigned iter, double lnL, double lnP, double TL, Model::SharedPtr model) {
        assert(model);
        assert(_parameterfile.is_open());
        _parameterfile &lt;&lt; boost::str(boost::format("%d\t%.5f\t%.5f\t%.5f\t%s") % iter % lnL % lnP % TL % model-&gt;paramValuesAsString("\t")) &lt;&lt; std::endl;
    }

< 15.0 | 15.1 | 15.2 >