MsgLogger.cxx

Go to the documentation of this file.
00001 // @(#)root/tmva $Id: MsgLogger.cxx 36966 2010-11-26 09:50:13Z evt $
00002 // Author: Attila Krasznahorkay
00003 
00004 /**********************************************************************************
00005  * Project: TMVA - a Root-integrated toolkit for multivariate data analysis       *
00006  * Package: TMVA                                                                  *
00007  * Class  : MsgLogger                                                             *
00008  * Web    : http://tmva.sourceforge.net                                           *
00009  *                                                                                *
00010  * Description:                                                                   *
00011  *      Implementation (see header for description)                               *
00012  *                                                                                *
00013  * Author:                                                                        *
00014  *      Attila Krasznahorkay <Attila.Krasznahorkay@cern.ch> - CERN, Switzerland   *
00015  *                                                                                *
00016  * Copyright (c) 2005:                                                            *
00017  *      CERN, Switzerland                                                         *
00018  *      MPI-K Heidelberg, Germany                                                 *
00019  *                                                                                *
00020  * Redistribution and use in source and binary forms, with or without             *
00021  * modification, are permitted according to the terms listed in LICENSE           *
00022  * (http://tmva.sourceforge.net/LICENSE)                                          *
00023  **********************************************************************************/
00024 
00025 // Local include(s):
00026 #include "TMVA/MsgLogger.h"
00027 #include "TMVA/Config.h"
00028 
00029 #include "Riostream.h"
00030 
00031 // STL include(s):
00032 #include <iomanip>
00033 
00034 #include <cstdlib>
00035 
00036 #include <assert.h>
00037 
00038 // ROOT include(s):
00039 
00040 ClassImp(TMVA::MsgLogger)
00041 
00042 // declaration of global variables
00043 // this is the hard-coded maximum length of the source names
00044 UInt_t                                 TMVA::MsgLogger::fgMaxSourceSize = 25;
00045 Bool_t                                 TMVA::MsgLogger::fgInhibitOutput = kFALSE;
00046 
00047 const std::string                      TMVA::MsgLogger::fgPrefix = "--- ";
00048 const std::string                      TMVA::MsgLogger::fgSuffix = ": ";
00049 std::map<TMVA::EMsgType, std::string>* TMVA::MsgLogger::fgTypeMap  = 0;
00050 std::map<TMVA::EMsgType, std::string>* TMVA::MsgLogger::fgColorMap = 0;
00051 Int_t                                  TMVA::MsgLogger::fgInstanceCounter = 0;
00052 
00053 void   TMVA::MsgLogger::InhibitOutput() { fgInhibitOutput = kTRUE;  }
00054 void   TMVA::MsgLogger::EnableOutput()  { fgInhibitOutput = kFALSE; }
00055 //_______________________________________________________________________
00056 TMVA::MsgLogger::MsgLogger( const TObject* source, EMsgType minType )
00057    : fObjSource ( source ),
00058      fStrSource ( "" ),
00059      fActiveType( kINFO ),
00060      fMinType   ( minType )
00061 {
00062    // constructor
00063    fgInstanceCounter++;
00064    InitMaps();   
00065 }
00066 
00067 //_______________________________________________________________________
00068 TMVA::MsgLogger::MsgLogger( const std::string& source, EMsgType minType )
00069    : fObjSource ( 0 ),
00070      fStrSource ( source ),
00071      fActiveType( kINFO ),
00072      fMinType   ( minType )
00073 {
00074    // constructor
00075    fgInstanceCounter++;
00076    InitMaps();
00077 }
00078 
00079 //_______________________________________________________________________
00080 TMVA::MsgLogger::MsgLogger( EMsgType minType )
00081    : fObjSource ( 0 ),
00082      fStrSource ( "Unknown" ),
00083      fActiveType( kINFO ),
00084      fMinType   ( minType )
00085 {
00086    // constructor
00087    fgInstanceCounter++;
00088    InitMaps();
00089 }
00090 
00091 //_______________________________________________________________________
00092 TMVA::MsgLogger::MsgLogger( const MsgLogger& parent )
00093    : std::basic_ios<MsgLogger::char_type, MsgLogger::traits_type>(),
00094      std::ostringstream(),
00095      TObject()
00096 {
00097    // copy constructor
00098    fgInstanceCounter++;
00099    InitMaps();
00100    *this = parent;
00101 }
00102 
00103 //_______________________________________________________________________
00104 TMVA::MsgLogger::~MsgLogger()
00105 {
00106    // destructor
00107    fgInstanceCounter--;
00108    if (fgInstanceCounter == 0) {
00109       // last MsgLogger instance has been deleted, can also delete the maps
00110       delete fgTypeMap;  fgTypeMap  = 0;
00111       delete fgColorMap; fgColorMap = 0;
00112    }
00113 }
00114 
00115 //_______________________________________________________________________
00116 TMVA::MsgLogger& TMVA::MsgLogger::operator= ( const MsgLogger& parent )
00117 {
00118    // assingment operator
00119    if (&parent != this) {
00120       fObjSource  = parent.fObjSource;
00121       fStrSource  = parent.fStrSource;
00122       fActiveType = parent.fActiveType;
00123       fMinType    = parent.fMinType;
00124    }
00125 
00126    return *this;
00127 }
00128 
00129 //_______________________________________________________________________
00130 std::string TMVA::MsgLogger::GetFormattedSource() const
00131 {
00132    // make sure the source name is no longer than fgMaxSourceSize:
00133    std::string source_name;
00134    if (fObjSource) source_name = fObjSource->GetName();
00135    else            source_name = fStrSource;
00136 
00137    if (source_name.size() > fgMaxSourceSize) {
00138       source_name = source_name.substr( 0, fgMaxSourceSize - 3 );
00139       source_name += "...";
00140    }
00141 
00142    return source_name;
00143 }
00144 
00145 //_______________________________________________________________________
00146 std::string TMVA::MsgLogger::GetPrintedSource() const
00147 {
00148    // the full logger prefix
00149    std::string source_name = GetFormattedSource();
00150    if (source_name.size() < fgMaxSourceSize)
00151       for (std::string::size_type i=source_name.size(); i<fgMaxSourceSize; i++) source_name.push_back( ' ' );
00152 
00153    return fgPrefix + source_name + fgSuffix;
00154 }
00155 
00156 //_______________________________________________________________________
00157 void TMVA::MsgLogger::Send()
00158 {
00159    // activates the logger writer
00160 
00161    // make sure the source name is no longer than fgMaxSourceSize:
00162    std::string source_name = GetFormattedSource();
00163 
00164    std::string message = this->str();
00165    std::string::size_type previous_pos = 0, current_pos = 0;
00166 
00167    // slice the message into lines:
00168    while (kTRUE) {
00169       current_pos = message.find( '\n', previous_pos );
00170       std::string line = message.substr( previous_pos, current_pos - previous_pos );
00171 
00172       std::ostringstream message_to_send;
00173       // must call the modifiers like this, otherwise g++ get's confused with the operators...
00174       message_to_send.setf( std::ios::adjustfield, std::ios::left );
00175       message_to_send.width( fgMaxSourceSize );
00176       message_to_send << source_name << fgSuffix << line;
00177       this->WriteMsg( fActiveType, message_to_send.str() );
00178 
00179       if (current_pos == message.npos) break;
00180       previous_pos = current_pos + 1;
00181    }
00182 
00183    // reset the stream buffer:
00184    this->str( "" );
00185    fActiveType = kINFO; // To always print messages that have no level specified...
00186    return;
00187 }
00188 
00189 //_______________________________________________________________________
00190 void TMVA::MsgLogger::WriteMsg( EMsgType type, const std::string& line ) const
00191 {
00192    // putting the output string, the message type, and the color
00193    // switcher together into a single string
00194 
00195    if ( (type < fMinType || fgInhibitOutput) && type!=kFATAL ) return; // no output
00196 
00197    std::map<EMsgType, std::string>::const_iterator stype;
00198 
00199    if ((stype = fgTypeMap->find( type )) != fgTypeMap->end()) {
00200       if (!gConfig().IsSilent() || type==kFATAL) {
00201          if (gConfig().UseColor()) {
00202             // no text for INFO or VERBOSE
00203             if (type == kINFO || type == kVERBOSE)
00204                std::cout << fgPrefix << line << std::endl; // no color for info
00205             else
00206                std::cout << fgColorMap->find( type )->second << fgPrefix << "<"
00207                          << stype->second << "> " << line  << "\033[0m" << std::endl;
00208          }
00209          else {
00210             if (type == kINFO) std::cout << fgPrefix << line << std::endl;
00211             else               std::cout << fgPrefix << "<" << stype->second << "> " << line << std::endl;
00212          }
00213       }
00214    }
00215 
00216    // take decision to stop if fatal error
00217    if (type == kFATAL) {
00218       std::cout << "***> abort program execution" << std::endl;
00219       std::exit(1);
00220       assert(false);
00221    }
00222 }
00223 
00224 //_______________________________________________________________________
00225 TMVA::MsgLogger& TMVA::MsgLogger::Endmsg( MsgLogger& logger )
00226 {
00227    // end line
00228    logger.Send();
00229    return logger;
00230 }
00231 
00232 //_______________________________________________________________________
00233 void TMVA::MsgLogger::InitMaps()
00234 {
00235    // Create the message type and color maps
00236    if (fgTypeMap != 0 && fgColorMap != 0) return;
00237 
00238    fgTypeMap  = new std::map<TMVA::EMsgType, std::string>();
00239    fgColorMap = new std::map<TMVA::EMsgType, std::string>();
00240    
00241    (*fgTypeMap)[kVERBOSE]  = std::string("VERBOSE");
00242    (*fgTypeMap)[kDEBUG]    = std::string("DEBUG");
00243    (*fgTypeMap)[kINFO]     = std::string("INFO");
00244    (*fgTypeMap)[kWARNING]  = std::string("WARNING");
00245    (*fgTypeMap)[kERROR]    = std::string("ERROR");
00246    (*fgTypeMap)[kFATAL]    = std::string("FATAL");
00247    (*fgTypeMap)[kSILENT]   = std::string("SILENT");
00248 
00249    (*fgColorMap)[kVERBOSE] = std::string("");
00250    (*fgColorMap)[kDEBUG]   = std::string("\033[34m");
00251    (*fgColorMap)[kINFO]    = std::string("");
00252    (*fgColorMap)[kWARNING] = std::string("\033[1;31m");
00253    (*fgColorMap)[kERROR]   = std::string("\033[31m");
00254    (*fgColorMap)[kFATAL]   = std::string("\033[37;41;1m");
00255    (*fgColorMap)[kSILENT]  = std::string("\033[30m");
00256 }

Generated on Tue Jul 5 15:25:11 2011 for ROOT_528-00b_version by  doxygen 1.5.1