CMS 3D CMS Logo

/data/refman/pasoursint/CMSSW_5_3_0/src/HLTriggerOffline/Common/src/HltComparator.cc

Go to the documentation of this file.
00001 // Originally written by James Jackson
00002 // modified by Peter Wittich
00003 // $Id: HltComparator.cc,v 1.8 2010/02/25 19:14:36 wdd Exp $
00004 
00005 // user include files
00006 #include "HLTriggerOffline/Common/interface/HltComparator.h"
00007 #include "FWCore/Common/interface/TriggerNames.h"
00008 //#include "FWCore/Utilities/interface/Exception.h"
00009 
00010 //#include "FWCore/MessageLogger/interface/MessageLogger.h"
00011 #include "FWCore/ServiceRegistry/interface/Service.h"
00012 #include "CommonTools/UtilAlgos/interface/TFileService.h"
00013 
00014 #include <TH1.h>
00015 #include <vector>
00016 #include <string>
00017 
00018 
00019 typedef std::vector<std::string> StringCollection;
00020 
00021 
00022 // types of outcomes possible.
00023 // only some are errors
00024 enum {
00025     kOnOffPass = 0, kOnOffFail, kOnPassOffFail, kOnFailOffPass, 
00026     kOnOffError, kOnRunOffError, kOnErrorOffRun, kOnRunOffNot, kOnNotOffRun,
00027     kOnOffNot
00028 };
00029 
00030 
00031 // Analyser constructor
00032 HltComparator::HltComparator(const edm::ParameterSet & iConfig):
00033   hltOnlineResults_(iConfig.getParameter<edm::InputTag>("OnlineResults")),
00034   hltOfflineResults_(iConfig.getParameter<edm::InputTag>("OfflineResults")),
00035   init_(false),
00036   verbose_(iConfig.getUntrackedParameter<bool>("verbose")),
00037   skipPathList_(iConfig.getUntrackedParameter<std::vector<std::string> >("skipPaths")),
00038   usePathList_(iConfig.getUntrackedParameter<std::vector<std::string> >("usePaths"))
00039 {
00040   //std::cout << " HERE I AM " << std::endl;
00041   produces<StringCollection >("failedTriggerDescription");
00042   //std::cout << " HERE I GO " << std::endl;
00043 }
00044 
00045 
00046 HltComparator::~HltComparator()
00047 {
00048 }
00049 
00050 // Initialises online --> offline trigger bit mappings and histograms
00051 void
00052 HltComparator::initialise(const edm::TriggerResults & onlineResults,
00053                           const edm::TriggerResults & offlineResults,
00054                           edm::Event& e)
00055 {
00056   init_ = true;
00057 
00058   // Get trigger names 
00059   const edm::TriggerNames & onlineTriggerNames = e.triggerNames(onlineResults);
00060   const edm::TriggerNames & offlineTriggerNames = e.triggerNames(offlineResults);
00061   onlineActualNames_ = onlineTriggerNames.triggerNames();
00062   offlineActualNames_ = offlineTriggerNames.triggerNames();
00063   numTriggers_ = onlineActualNames_.size();
00064   
00065   // do we need to throw? I guess the whole job is crap if this happens.
00066   // sort of assumes we're the only game in town.
00067   if (numTriggers_ != offlineActualNames_.size()) {
00068     throw cms::Exception("IncorrectTriggers") << "Online had "
00069                                               << numTriggers_ << "triggers, "
00070                                               << "Offline had " 
00071                                               << offlineActualNames_.size()
00072                                               << "triggers";
00073   }
00074 
00075   // Create bit mappings
00076   std::map<std::string, unsigned int >offlineNameBitMap;
00077   for (unsigned int i = 0; i < numTriggers_; ++i) {
00078     offlineNameBitMap[offlineActualNames_[i]] = i;
00079   }
00080   for (unsigned int i = 0; i < numTriggers_; ++i) {
00081     // Find offline position for fixed online bit
00082     std::map<std::string, unsigned int >::iterator it =
00083       offlineNameBitMap.find(onlineActualNames_[i]);
00084     if (it != offlineNameBitMap.end()) {
00085       onlineToOfflineBitMappings_.push_back(it->second);
00086     }
00087     else {
00088       throw cms:: Exception("IncorrectTriggers") << "Online trigger path " 
00089                                                  << onlineActualNames_[i] 
00090                                                  << " not found in Offline "
00091         "processing";
00092     }
00093   }
00094   
00095   // Create histograms
00096   edm::Service<TFileService> fs;
00097   for (std::vector<std::string>::iterator it = onlineActualNames_.begin();
00098        it != onlineActualNames_.end(); ++it) {
00099     // Bin descriptions: OnOfPass, OnOffFail, OnPassOffFail, OnFailOffPass, 
00100     // OnOffError, OnRunOffError, OnErrorOffRun, OnRunOffNot OnNotOffRun 
00101     // OnNotOffNot
00102     TH1F *h = fs->make<TH1F>(it->c_str(), it->c_str(), 10, 0, 10);
00103     TAxis *a = h->GetXaxis();
00104     a->SetBinLabel(1, "OnPass_OffPass");
00105     a->SetBinLabel(2, "OnFail_OffFail");
00106     a->SetBinLabel(3, "OnPass_OffFail");
00107     a->SetBinLabel(4, "OnFail_OffPass");
00108     a->SetBinLabel(5, "OnError_OffError");
00109     a->SetBinLabel(6, "OnRun_OffError");
00110     a->SetBinLabel(7, "OnError_OffRun");
00111     a->SetBinLabel(8, "OnRun_OffNotRun");
00112     a->SetBinLabel(9, "OnNotRun_OffRun");
00113     a->SetBinLabel(10, "OnNotRun_OffNotRun");
00114     comparisonHists_.push_back(h);
00115   }
00116 }
00117 
00118 // Format a comparison result
00119 std::string HltComparator::formatResult(const unsigned int i)
00120 {
00121   switch (i) {
00122   case 0:
00123     return std::string("OnPass_OffPass");
00124     break;
00125   case 1:
00126     return std::string("OnFail_OffFail");
00127     break;
00128   case 2:
00129     return std::string("OnPass_OffFail");
00130     break;
00131   case 3:
00132     return std::string("OnFail_OffPass");
00133     break;
00134   case 4:
00135     return std::string("OnError_OffError");
00136     break;
00137   case 5:
00138     return std::string("OnRun_OffError");
00139     break;
00140   case 6:
00141     return std::string("OnError_OffRun");
00142     break;
00143   case 7:
00144     return std::string("OnRun_OffNotRun");
00145     break;
00146   case 8:
00147     return std::string("OnNotRun_OffRun");
00148     break;
00149   case 9:
00150     return std::string("OnNotRun_OffNotRun");
00151     break;
00152   }
00153   return std::string("CODE NOT KNOWN");
00154 }
00155 
00156 bool
00157 HltComparator::filter(edm::Event & event,
00158                       const edm::EventSetup & iSetup)
00159 {
00160   //std::cout << "top of the filter " << std::endl;
00161   // Get trigger results
00162   edm::Handle<edm::TriggerResults> onlineResults;
00163   edm::Handle<edm::TriggerResults> offlineResults;
00164   event.getByLabel(hltOnlineResults_, onlineResults);
00165   event.getByLabel(hltOfflineResults_, offlineResults);
00166 
00167   std::auto_ptr<StringCollection> resultDescription(new StringCollection);
00168   
00169   // Initialise comparator if required
00170   if (!init_) {
00171     initialise(*onlineResults, *offlineResults, event);
00172   }
00173   
00174   // Perform trigger checks
00175   bool hasDisagreement = false;
00176   for (unsigned int i = 0; i < numTriggers_; ++i) {
00177     unsigned int offlineTriggerBit = onlineToOfflineBitMappings_[i];
00178     
00179     bool onRun = onlineResults->wasrun(i);
00180     bool offRun = offlineResults->wasrun(offlineTriggerBit);
00181     bool onAccept = onlineResults->accept(i);
00182     bool offAccept = offlineResults->accept(offlineTriggerBit);
00183     bool onError = onlineResults->error(i);
00184     bool offError = offlineResults->error(offlineTriggerBit);
00185     
00186     int result = -1;
00187     if (onError || offError) {
00188       if (onError && offError) {
00189         result = 4;
00190       }
00191       else if (onError) {
00192         result = 6;
00193       }
00194       else {
00195         result = 5;
00196       }
00197     }
00198     else if ((!onRun) || (!offRun)) {
00199       if ((!onRun) && (!offRun)) {
00200         result = 9;
00201       }
00202       else if (!onRun) {
00203         result = 8;
00204       }
00205       else {
00206         result = 7;
00207       }
00208     }
00209     else {
00210       if (onAccept && offAccept) {
00211         result = 0;
00212       }
00213       else if ((!onAccept) && (!offAccept)) {
00214         result = 1;
00215       }
00216       else if (onAccept) {
00217         result = 2;
00218       }
00219       else {
00220         result = 3;
00221       }
00222     }
00223     
00224     // Fill the results histogram
00225     comparisonHists_[i]->Fill(result);
00226 
00227   // if the online-offline comparison results in a failure, we
00228   // want to send the result to a special stream. Hence we _pass_ the filter.
00229   // If it all worked as expected the filter fails and the event doesn't go
00230   // to the output stream.
00231     if ( (result == kOnPassOffFail) || ( result == kOnFailOffPass ) ||
00232          (result == kOnRunOffError) || ( result == kOnErrorOffRun ) ||
00233          (result == kOnRunOffNot)   || ( result == kOnNotOffRun ) ) {
00234       // is this one we should ignore? check the skip list
00235       if ( verbose() ) {
00236         std::cout << "Found disagreemenet " << result << ", name is " 
00237                   << onlineActualNames_[i]
00238                   << std::endl;
00239       }
00240       std::ostringstream desc;
00241       desc << onlineActualNames_[i] << ":" << formatResult(result);
00242       resultDescription->push_back(desc.str());
00243       if ( std::find(skipPathList_.begin(), skipPathList_.end(), 
00244                      onlineActualNames_[i]) == skipPathList_.end() ) {
00245 
00246         if (usePathList_.size()!=0){
00247           //only use specified paths to debug
00248           if (std::find(usePathList_.begin(), usePathList_.end(),
00249                         onlineActualNames_[i]) != usePathList_.end() )
00250             hasDisagreement = true;
00251         }
00252         else
00253           hasDisagreement = true;
00254       }
00255     }
00256       
00257     // Record the trigger error code
00258     // I think this should be result > 2? (pw)
00259     if (verbose() && (result > 1)) {
00260       std::cout << "HLT-Compare: Event " << event.id().event() 
00261                 << " Path " << onlineActualNames_[i] << " " 
00262                 << formatResult(result) << std::endl;
00263 #ifdef NOTDEF      
00264       triggerComparisonErrors_[event.id().event()][onlineActualNames_[i]] = result;
00265 #endif // NOTDEF
00266     }
00267   }
00268 
00269   //std::cout << " HERE I STAY " << std::endl;
00270   event.put(resultDescription,"failedTriggerDescription");
00271   //std::cout << " HERE I WENT " << std::endl;
00272 
00273   if ( hasDisagreement ) 
00274     return true;
00275   else
00276     return false;
00277 }
00278 
00279 
00280 void
00281 HltComparator::beginJob()
00282 {
00283 }
00284 
00285 // Print the trigger results
00286 void
00287 HltComparator::endJob()
00288 {
00289 #ifdef NOTDEF
00290   std::cout << "HLT-Compare ---------- Trigger Comparison Summary ----------" << std::endl;
00291   std::cout << "HLT-Compare  The following events had trigger mismatches:" << std::endl;
00292   std::map<unsigned int, std::map<std::string, unsigned int> >::iterator it;
00293   for(it = triggerComparisonErrors_.begin(); it != triggerComparisonErrors_.end(); ++it) {
00294     std::cout << "HLT-Compare  Event: " << it->first << std::endl;
00295     std::map<std::string, unsigned int>::iterator jt;
00296     for(jt = it->second.begin(); jt != it->second.end(); ++jt) {
00297       std::cout << "HLT-Compare    Path: " << jt->first << " : " << formatResult(jt->second) << std::endl;
00298     }
00299   }
00300   std::cout << "HLT-Compare ------------ End Trigger Comparison ------------" << std::endl;
00301 #endif //NOTDEF
00302 }
00303