CMS 3D CMS Logo

InitRootHandlers.cc

Go to the documentation of this file.
00001 #include "FWCore/Services/src/InitRootHandlers.h"
00002 #include "FWCore/ParameterSet/interface/ParameterSet.h"
00003 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00004 #include "FWCore/MessageLogger/interface/ELseverityLevel.h"
00005 #include "FWCore/Utilities/interface/EDMException.h"
00006 #include "FWCore/RootAutoLibraryLoader/interface/RootAutoLibraryLoader.h"
00007 #include "DataFormats/Provenance/interface/TransientStreamer.h"
00008 #include "DataFormats/Common/interface/CacheStreamers.h"
00009 #include "DataFormats/Common/interface/RefCoreStreamer.h"
00010 
00011 #include <string.h>
00012 #include <sstream>
00013 
00014 #include "TSystem.h"
00015 #include "TError.h"
00016 #include "TTree.h"
00017 #include "Cintex/Cintex.h"
00018 #include "TH1.h"
00019 #include "G__ci.h"
00020 
00021 namespace {
00022 
00023 void RootErrorHandler(int level, bool die, char const* location, char const* message)
00024 {
00025  
00026 // Translate ROOT severity level to MessageLogger severity level
00027 
00028   edm::ELseverityLevel el_severity = edm::ELseverityLevel::ELsev_info;
00029 
00030   if (level >= kFatal) {
00031     el_severity = edm::ELseverityLevel::ELsev_fatal;
00032   }
00033   else if (level >= kSysError) {
00034     el_severity = edm::ELseverityLevel::ELsev_severe;
00035   }
00036   else if (level >= kError) {
00037     el_severity = edm::ELseverityLevel::ELsev_error;
00038   }
00039   else if (level >= kWarning) {
00040     el_severity = edm::ELseverityLevel::ELsev_warning;
00041   }
00042 
00043 // Adapt C-strings to std::strings
00044 // Arrange to report the error location as furnished by Root
00045 
00046   std::string el_location = "@SUB=?";
00047   if (location != 0) el_location = std::string("@SUB=")+std::string(location);
00048 
00049   std::string el_message  = "?";
00050   if (message != 0)  el_message  = message;
00051 
00052 // Try to create a meaningful id string using knowledge of ROOT error messages
00053 //
00054 // id ==     "ROOT-ClassName" where ClassName is the affected class
00055 //      else "ROOT/ClassName" where ClassName is the error-declaring class
00056 //      else "ROOT"
00057 
00058   std::string el_identifier = "ROOT";
00059 
00060   std::string precursor("class ");
00061   size_t index1 = el_message.find(precursor);
00062   if (index1 != std::string::npos) {
00063     size_t index2 = index1 + precursor.length();
00064     size_t index3 = el_message.find_first_of(" :", index2);
00065     if (index3 != std::string::npos) {
00066       size_t substrlen = index3-index2;
00067       el_identifier += "-";
00068       el_identifier += el_message.substr(index2,substrlen);
00069     }
00070   } else {
00071     index1 = el_location.find("::");
00072     if (index1 != std::string::npos) {
00073       el_identifier += "/";
00074       el_identifier += el_location.substr(0, index1);
00075     }
00076   }
00077 
00078 // Intercept some messages and upgrade the severity
00079 
00080     if ((el_location.find("TBranchElement::Fill") != std::string::npos)
00081      && (el_message.find("fill branch") != std::string::npos)
00082      && (el_message.find("address") != std::string::npos)
00083      && (el_message.find("not set") != std::string::npos)) {
00084       el_severity = edm::ELseverityLevel::ELsev_fatal;
00085     }
00086 
00087     if ((el_message.find("Tree branches") != std::string::npos)
00088      && (el_message.find("different numbers of entries") != std::string::npos)) {
00089       el_severity = edm::ELseverityLevel::ELsev_fatal;
00090     }
00091 
00092 
00093 // Intercept some messages and downgrade the severity
00094 
00095     if ((el_message.find("dictionary") != std::string::npos) ||
00096         (el_message.find("already in TClassTable") != std::string::npos) ||
00097         (el_message.find("matrix not positive definite") != std::string::npos) ||
00098         (el_location.find("Fit") != std::string::npos) ||
00099         (el_location.find("TDecompChol::Solve") != std::string::npos) ||
00100         (el_location.find("THistPainter::PaintInit") != std::string::npos)) {
00101       el_severity = edm::ELseverityLevel::ELsev_info;
00102     }
00103 
00104     
00105   if (el_severity == edm::ELseverityLevel::ELsev_info) {
00106     // Don't throw if the message is just informational.
00107     die = false;
00108   } else {
00109     die = true;
00110   }
00111 
00112 // Feed the message to the MessageLogger and let it choose to suppress or not.
00113 
00114 // Root has declared a fatal error.  Throw an EDMException unless the
00115 // message corresponds to a pending signal. In that case, do not throw
00116 // but let the OS deal with the signal in the usual way.
00117   if (die && (location != std::string("TUnixSystem::DispatchSignals"))) {
00118      std::ostringstream sstr;
00119      sstr << "Fatal Root Error: " << el_location << "\n" << el_message << '\n';
00120      edm::Exception except(edm::errors::FatalRootError, sstr.str());
00121      throw except;
00122   }
00123  
00124   // Currently we get here only for informational messages,
00125   // but we leave the other code in just in case we change
00126   // the criteria for throwing.
00127   if (el_severity == edm::ELseverityLevel::ELsev_fatal) {
00128     edm::LogError("Root_Fatal") << el_location << el_message;
00129   }
00130   else if (el_severity == edm::ELseverityLevel::ELsev_severe) {
00131     edm::LogError("Root_Severe") << el_location << el_message;
00132   }
00133   else if (el_severity == edm::ELseverityLevel::ELsev_error) {
00134     edm::LogError("Root_Error") << el_location << el_message;
00135   }
00136   else if (el_severity == edm::ELseverityLevel::ELsev_warning) {
00137     edm::LogWarning("Root_Warning") << el_location << el_message ;
00138   }
00139   else if (el_severity == edm::ELseverityLevel::ELsev_info) {
00140     edm::LogInfo("Root_Information") << el_location << el_message ;
00141   }
00142 
00143 }
00144 }  // end of unnamed namespace
00145 
00146 namespace edm {
00147 namespace service {
00148 InitRootHandlers::InitRootHandlers (edm::ParameterSet const& pset, edm::ActivityRegistry & activity)
00149   : RootHandlers(),
00150     unloadSigHandler_(pset.getUntrackedParameter<bool> ("UnloadRootSigHandler", false)),
00151     resetErrHandler_(pset.getUntrackedParameter<bool> ("ResetRootErrHandler", true)),
00152     autoLibraryLoader_(pset.getUntrackedParameter<bool> ("AutoLibraryLoader", true))
00153 {
00154 
00155   if(unloadSigHandler_) {
00156   // Deactivate all the Root signal handlers and restore the system defaults
00157     gSystem->ResetSignal(kSigChild);
00158     gSystem->ResetSignal(kSigBus);
00159     gSystem->ResetSignal(kSigSegmentationViolation);
00160     gSystem->ResetSignal(kSigIllegalInstruction);
00161     gSystem->ResetSignal(kSigSystem);
00162     gSystem->ResetSignal(kSigPipe);
00163     gSystem->ResetSignal(kSigAlarm);
00164     gSystem->ResetSignal(kSigUrgent);
00165     gSystem->ResetSignal(kSigFloatingException);
00166     gSystem->ResetSignal(kSigWindowChanged);
00167   }
00168 
00169   if(resetErrHandler_) {
00170 
00171   // Replace the Root error handler with one that uses the MessageLogger
00172     SetErrorHandler(RootErrorHandler);
00173   }
00174 
00175   // Enable automatic Root library loading.
00176   if(autoLibraryLoader_) {
00177     RootAutoLibraryLoader::enable();
00178   }
00179 
00180   // Enable Cintex.
00181   ROOT::Cintex::Cintex::Enable();
00182 
00183   // Set ROOT parameters.
00184   TTree::SetMaxTreeSize(kMaxLong64);
00185   TH1::AddDirectory(kFALSE);
00186   G__SetCatchException(0);
00187 
00188   // Set custom streamers
00189   setCacheStreamers();
00190   setTransientStreamers();
00191   setRefCoreStreamer();
00192 }
00193 
00194 
00195 InitRootHandlers::~InitRootHandlers () {}
00196 
00197 void
00198 InitRootHandlers::disableErrorHandler_() {
00199     SetErrorHandler(DefaultErrorHandler);
00200 }
00201 
00202 void
00203 InitRootHandlers::enableErrorHandler_() {
00204     SetErrorHandler(RootErrorHandler);
00205 }
00206 }  // end of namespace service
00207 }  // end of namespace edm

Generated on Tue Jun 9 17:36:39 2009 for CMSSW by  doxygen 1.5.4