CMS 3D CMS Logo

/data/refman/pasoursint/CMSSW_5_3_3/src/HLTrigger/HLTanalyzers/src/HLTOfflineReproducibility.cc

Go to the documentation of this file.
00001 // -*- C++ -*-
00002 //
00003 // Package:    HLTOfflineReproducibility
00004 // Class:      HLTOfflineReproducibility
00005 // 
00013 //
00014 // Original Author:  Juliette Marie Alimena,40 3-A02,+41227671577,
00015 //         Created:  Fri Apr 22 15:46:58 CEST 2011
00016 // $Id: HLTOfflineReproducibility.cc,v 1.6 2011/11/15 11:27:03 fwyzard Exp $
00017 //
00018 //
00019 
00020 using namespace std;
00021 
00022 // system include files
00023 #include <memory>
00024 
00025 // user include files
00026 #include "FWCore/Framework/interface/Frameworkfwd.h"
00027 #include "FWCore/Framework/interface/EDAnalyzer.h"
00028 #include "FWCore/Framework/interface/Event.h"
00029 #include "FWCore/Framework/interface/MakerMacros.h"
00030 #include "FWCore/Framework/interface/TriggerNamesService.h"
00031 #include "FWCore/Common/interface/TriggerNames.h"
00032 #include "FWCore/Common/interface/TriggerResultsByName.h"
00033 #include "FWCore/Utilities/interface/InputTag.h"
00034 #include "FWCore/ServiceRegistry/interface/Service.h"
00035 #include "FWCore/ParameterSet/interface/ParameterSet.h"
00036 
00037 #include "DataFormats/Common/interface/TriggerResults.h"
00038 #include "DataFormats/Common/interface/HLTGlobalStatus.h"
00039 #include "DataFormats/HLTReco/interface/HLTPrescaleTable.h"
00040 #include "DataFormats/HLTReco/interface/TriggerObject.h"
00041 #include "DataFormats/HLTReco/interface/TriggerEvent.h"
00042 
00043 #include "CommonTools/UtilAlgos/interface/TFileService.h"
00044 
00045 #include "HLTrigger/HLTcore/interface/HLTConfigProvider.h"
00046 #include "HLTrigger/HLTcore/interface/HLTConfigData.h"
00047 
00048 #include <TMath.h>
00049 #include <TFile.h>
00050 #include <TTree.h>
00051 #include <TH1.h>
00052 #include <TH2.h>
00053 #include <vector>
00054 #include <iostream>
00055 #include <ostream>
00056 //
00057 // class declaration
00058 //
00059 
00060 class HLTOfflineReproducibility : public edm::EDAnalyzer {
00061 public:
00062   explicit HLTOfflineReproducibility(const edm::ParameterSet&);
00063   ~HLTOfflineReproducibility();
00064   
00065   static void fillDescriptions(edm::ConfigurationDescriptions& descriptions);
00066   
00067   
00068 private:
00069   virtual void beginJob() ;
00070   virtual void analyze(const edm::Event&, const edm::EventSetup&);
00071   virtual void endJob() ;
00072   
00073   virtual void beginRun(edm::Run const&, edm::EventSetup const&);
00074   virtual void endRun(edm::Run const&, edm::EventSetup const&);
00075   virtual void beginLuminosityBlock(edm::LuminosityBlock const&, edm::EventSetup const&);
00076   virtual void endLuminosityBlock(edm::LuminosityBlock const&, edm::EventSetup const&);
00077   
00078   bool check(std::string process, std::string pCheck);
00079 
00080   // ----------member data ---------------------------  
00081   edm::InputTag triggerLabelON_;
00082   edm::InputTag triggerLabelOFF_;
00083   
00084   //Trigger Stuff
00085   unsigned int nPaths_, nPathsON_, nPathsOFF_, nDatasets_;
00086   vector<string> triggerNames_;
00087   vector< vector<string> > moduleLabel_, moduleLabelON_, moduleLabelOFF_;
00088   vector<unsigned int> nModules_, nPaths_PD_;
00089   vector<string> datasetNames_;
00090   vector<vector<string> > datasetContent_;
00091   vector< vector< vector<bool> > > triggerNames_matched_;
00092 
00093   string processNameON_;
00094   string processNameOFF_;
00095   HLTConfigProvider hltConfig_;
00096 
00097   int Nfiles_;
00098   double Normalization_;
00099   bool isRealData_;
00100   int LumiSecNumber_; 
00101   vector<int> trigger_online_;
00102   vector<int> trigger_offline_;
00103 
00104   TH1D* path_ON_hist;
00105   TH1D* path_ONnotOFF_hist;
00106   TH1D* path_OFFnotON_hist;
00107   TH2D* pathmodule_ONnotOFF_hist;
00108   TH2D* pathmodule_OFFnotON_hist;
00109 
00110   vector<TH1D*> path_ON_hist_PD;
00111   vector<TH1D*> path_ONnotOFF_hist_PD;
00112   vector<TH1D*> path_OFFnotON_hist_PD;
00113   vector<TH2D*> pathmodule_ONnotOFF_hist_PD;
00114   vector<TH2D*> pathmodule_OFFnotON_hist_PD;
00115 
00116 };
00117 
00118 //
00119 // constants, enums and typedefs
00120 //
00121 
00122 //
00123 // static data member definitions
00124 //
00125 
00126 //
00127 // constructors and destructor
00128 //
00129 HLTOfflineReproducibility::HLTOfflineReproducibility(const edm::ParameterSet& iConfig):  
00130   triggerLabelON_       (iConfig.getUntrackedParameter<edm::InputTag>("triggerTagON")),
00131   triggerLabelOFF_      (iConfig.getUntrackedParameter<edm::InputTag>("triggerTagOFF")), 
00132   nPaths_               (0),
00133   nDatasets_            (0),
00134   triggerNames_         (),
00135   moduleLabel_          (),
00136   nModules_             (), 
00137   nPaths_PD_            (),
00138   datasetNames_         (),
00139   datasetContent_       (),
00140   triggerNames_matched_ (),
00141   processNameON_(iConfig.getParameter<std::string>("processNameON")),
00142   processNameOFF_       (iConfig.getParameter<std::string>("processNameOFF")),
00143   Nfiles_               (iConfig.getUntrackedParameter<int>("Nfiles",0)),
00144   Normalization_        (iConfig.getUntrackedParameter<double>("Norm",40.)),
00145   isRealData_           (iConfig.getUntrackedParameter<bool>("isRealData",true)),
00146   LumiSecNumber_        (iConfig.getUntrackedParameter<int>("LumiSecNumber",1)),
00147   path_ON_hist          (0),
00148   path_ONnotOFF_hist    (0),
00149   path_OFFnotON_hist    (0),
00150   pathmodule_ONnotOFF_hist(0),
00151   pathmodule_OFFnotON_hist(0),
00152   path_ON_hist_PD       (),
00153   path_ONnotOFF_hist_PD (),
00154   path_OFFnotON_hist_PD (),
00155   pathmodule_ONnotOFF_hist_PD(),
00156   pathmodule_OFFnotON_hist_PD()
00157 {
00158 }
00159 
00160 
00161 HLTOfflineReproducibility::~HLTOfflineReproducibility()
00162 {
00163  
00164    // do anything here that needs to be done at desctruction time
00165    // (e.g. close files, deallocate resources etc.)
00166 
00167 }
00168 
00169 
00170 //
00171 // member functions
00172 //
00173 
00174 // ------------ method called for each event  ------------
00175 void
00176 HLTOfflineReproducibility::analyze(const edm::Event& iEvent, const edm::EventSetup& iSetup)
00177 {
00178   using namespace edm;
00179   
00180   //cout <<"Run/Event/Lumi block "<< iEvent.id().run()<<" "<<iEvent.id().event()<<" "<<iEvent.luminosityBlock() <<endl;
00181   
00182   //Initialize Trigger
00183   TriggerResults trON_;
00184   Handle<TriggerResults> h_trigResON_;
00185   iEvent.getByLabel(triggerLabelON_, h_trigResON_);
00186   trON_ = *h_trigResON_;  
00187   
00188   TriggerResults trOFF_;
00189   Handle<TriggerResults> h_trigResOFF_;
00190   iEvent.getByLabel(triggerLabelOFF_, h_trigResOFF_);  
00191   trOFF_ = *h_trigResOFF_;
00192 
00193   vector<string> triggerListON_;
00194   Service<service::TriggerNamesService> tnsON_;
00195   bool foundNamesON_ = tnsON_->getTrigPaths(trON_,triggerListON_);
00196   if (!foundNamesON_) cout << "Could not get trigger names!\n";
00197   if (trON_.size()!=triggerListON_.size()) cout << "ERROR: length of names and paths not the same: " << triggerListON_.size() << "," << trON_.size() << endl;  
00198   
00199   vector<string> triggerListOFF_;
00200   Service<service::TriggerNamesService> tnsOFF_;
00201   bool foundNamesOFF_ = tnsOFF_->getTrigPaths(trOFF_,triggerListOFF_);
00202   if (!foundNamesOFF_) cout << "Could not get trigger names!\n";
00203   if (trOFF_.size()!=triggerListOFF_.size()) cout << "ERROR: length of names and paths not the same: " << triggerListOFF_.size() << "," << trOFF_.size() << endl;  
00204   
00205 
00206   vector<bool> online_accept_, offline_accept_, fails_prescaler_; 
00207   vector<int> module_indexON_, module_indexOFF_;
00208   vector<string> module_index_labelON_, module_index_labelOFF_;
00209   
00210   for (unsigned int x=0; x<nPaths_; x++) {
00211     online_accept_.push_back(false);
00212     offline_accept_.push_back(false);
00213     module_indexON_.push_back(-1);
00214     module_indexOFF_.push_back(-1);
00215     module_index_labelON_.push_back(" ");
00216     module_index_labelOFF_.push_back(" ");
00217     fails_prescaler_.push_back(false);
00218   }
00219   
00220   //loop over online trigger paths
00221   for (unsigned int i=0; i<nPathsON_; i++) {
00222     for (unsigned int x=0; x<nPaths_; x++) {
00223       if (triggerListON_[i]==triggerNames_[x]) {
00224 
00225         //if online accepted
00226         if (trON_[i].wasrun()==1 && trON_[i].accept()==1 && trON_[i].error()==0) {
00227           online_accept_.at(x) = true;
00228           trigger_online_[x]++;
00229           path_ON_hist->Fill(x);
00230           for (unsigned int a=0; a<nDatasets_; a++) {
00231             for (unsigned int b=0; b<nPaths_PD_[a]; b++) {
00232               if (triggerNames_matched_[i][a][b]) path_ON_hist_PD[a]->Fill(b);
00233             }
00234           }
00235         }
00236         
00237         //if online failed
00238         if (trON_[i].accept() == 0){
00239           module_index_labelON_.at(x) = moduleLabelON_[i][trON_[i].index()];
00240           module_indexON_.at(x) = hltConfig_.moduleIndex(triggerNames_[x],module_index_labelON_[x]);
00241         }
00242         
00243         //for each path, loop over modules and find if a path fails on a prescaler
00244         for (unsigned int j=0; j<nModules_[x]; ++j) {
00245           //const string& moduleLabel_(moduleLabel[j]);
00246           const string& moduleType = hltConfig_.moduleType(moduleLabel_[x][j]);
00247           if ( (trON_[i].accept()==0 && j==trON_[i].index()) && (moduleType=="HLTPrescaler" || moduleType=="TriggerResultsFilter") ) fails_prescaler_[x] = true;
00248         }
00249 
00250       }
00251     }
00252   }
00253 
00254 
00255   //loop over offline trigger paths
00256   for (unsigned int i=0; i<nPathsOFF_; i++) {
00257     for (unsigned int x=0; x<nPaths_; x++) {
00258       if (triggerListOFF_[i]==triggerNames_[x]) {
00259 
00260         //if offline accepted
00261         if (trOFF_[i].wasrun()==1 && trOFF_[i].accept()==1 && trOFF_[i].error()==0) {
00262           offline_accept_[x] = true;
00263           trigger_offline_[x]++;
00264         }
00265 
00266         //if offline failed
00267         if (trOFF_[i].accept() == 0) {
00268           module_index_labelOFF_.at(x) = moduleLabelOFF_[i][trOFF_[i].index()];
00269           module_indexOFF_.at(x) = hltConfig_.moduleIndex(triggerNames_[x],module_index_labelOFF_[x]);
00270         }
00271         
00272         //for each path, loop over modules and find if a path fails on a prescaler
00273         for (unsigned int j=0; j<nModules_[x]; ++j) {
00274           //const string& moduleLabel_(moduleLabel[j]);
00275           const string& moduleType = hltConfig_.moduleType(moduleLabel_[x][j]);
00276           if ( (trOFF_[i].accept()==0 && j==trOFF_[i].index()) && (moduleType=="HLTPrescaler" || moduleType=="TriggerResultsFilter") ) fails_prescaler_[x] = true;
00277         }
00278 
00279       }
00280     }
00281   }
00282 
00283 
00284 
00285   //check agreement between online and offline
00286   //loop over trigger paths (online and offline)
00287   for (unsigned int x=0; x<nPaths_; x++) {
00288     if (!fails_prescaler_[x]){ //ignore paths that fail on a prescale
00289       if(online_accept_[x] && !offline_accept_[x]){ //online fires but offline doesn't
00290         path_ONnotOFF_hist->Fill(x);
00291         pathmodule_ONnotOFF_hist->Fill(x,module_indexOFF_[x]); //module and path for where it fails offline
00292         cout<<"  Event "<<iEvent.id().event()<<" in run "<<iEvent.id().run()<<" and luminosity block "<<iEvent.luminosityBlock()<<endl;
00293         cout<<"  fires online but not offline!!"<<endl;
00294         cout<<"  Path is: "<<triggerNames_[x]<<", last run module is: "<<module_index_labelOFF_[x]<<endl;
00295         for (unsigned int a=0; a<nDatasets_; a++) {
00296           for (unsigned int b=0; b<nPaths_PD_[a]; b++) {
00297             if (triggerNames_matched_[x][a][b]){
00298               path_ONnotOFF_hist_PD[a]->Fill(b);
00299               pathmodule_ONnotOFF_hist_PD[a]->Fill(b,module_indexOFF_[x]); //module and path for where it fails offline
00300             }
00301           }
00302         }
00303       }
00304       if(!online_accept_[x] && offline_accept_[x]){//offline fires but online doesn't
00305         path_OFFnotON_hist->Fill(x);
00306         pathmodule_OFFnotON_hist->Fill(x,module_indexON_[x]); //module and path for where it fails online
00307         cout<<"  Event "<<iEvent.id().event()<<" in run "<<iEvent.id().run()<<" and luminosity block "<<iEvent.luminosityBlock()<<endl;
00308         cout<<"  fires offline but not online!!"<<endl;
00309         cout<<"  Path is: "<<triggerNames_[x]<<", last run module is: "<<module_index_labelON_[x]<<endl;
00310         for (unsigned int a=0; a<nDatasets_; a++) {
00311           for (unsigned int b=0; b<nPaths_PD_[a]; b++) {
00312             if (triggerNames_matched_[x][a][b]){
00313               path_OFFnotON_hist_PD[a]->Fill(b);
00314               pathmodule_OFFnotON_hist_PD[a]->Fill(b,module_indexON_[x]); //module and path for where it fails online
00315             }
00316           }
00317         }
00318       }
00319     }
00320 
00321   }//end of loop over trigger paths
00322 
00323 
00324 
00325   //const vector<string> & moduleLabels(hltConfig_.moduleLabels(i));
00326   //cout<<"triggerListON_["<<i<<"] is: "<<triggerListON_[i]<<endl;
00327   
00328 
00329 }
00330 
00331 
00332 // ------------ method called once each job just before starting event loop  ------------
00333 void 
00334 HLTOfflineReproducibility::beginJob()
00335 {
00336 }
00337 
00338 // ------------ method called once each job just after ending the event loop  ------------
00339 void 
00340 HLTOfflineReproducibility::endJob() 
00341 {
00342 }
00343 
00344 // ------------ method called when starting to processes a run  ------------
00345 void 
00346 HLTOfflineReproducibility::beginRun(edm::Run const& iRun, edm::EventSetup const& iSetup)
00347 {
00348   edm::Service<TFileService> fs;  
00349   void init(const edm::TriggerResults &, const edm::TriggerNames & HLTNames);
00350 
00351   bool changed(true);
00352   nPathsON_=0, nPathsOFF_=0;
00353   vector<string> triggerNamesON_, triggerNamesOFF_;
00354   vector<string> temp_;
00355   unsigned int max_nModules_=0;
00356   vector<unsigned int> max_nModules_PD_, nModules_diff_;
00357   bool TriggerModuleNamesOK_ = true;
00358 
00359   //---------------------------------------hltConfig for online-------------------------------
00360   if (hltConfig_.init(iRun,iSetup,processNameON_,changed)) {
00361     // if init returns TRUE, initialisation has succeeded!
00362     if (changed) {
00363       cout<<"hlt_Config_.init returns true for online"<<endl;
00364       // The HLT config has actually changed wrt the previous Run, hence rebook your
00365       // histograms or do anything else dependent on the revised HLT config
00366       // check if trigger name in (new) config
00367       triggerNamesON_ = hltConfig_.triggerNames();
00368 
00369       //loop over trigger paths
00370       nPathsON_ = hltConfig_.size();
00371       for (unsigned int i=0; i<nPathsON_; i++) {
00372         temp_.clear();
00373         //const vector<string> & moduleLabelsON(hltConfig_.moduleLabels(i));
00374         for (unsigned int j=0; j<hltConfig_.moduleLabels(i).size(); j++) {
00375           temp_.push_back(hltConfig_.moduleLabel(i,j));
00376         }
00377         moduleLabelON_.push_back(temp_);
00378       }
00379 
00380     }
00381   } 
00382   else {
00383     // if init returns FALSE, initialisation has NOT succeeded, which indicates a problem
00384     // with the file and/or code and needs to be investigated!
00385     cout<<" HLT config extraction failure with process name " << processNameON_;
00386     // In this case, all access methods will return empty values!
00387   }
00388 
00389   //-------------------hltConfig for offline----------------------------------------
00390   if (hltConfig_.init(iRun,iSetup,processNameOFF_,changed)) {
00391     // if init returns TRUE, initialisation has succeeded!
00392     if (changed) {
00393       cout<<"hlt_Config_.init returns true for offline"<<endl;
00394       // The HLT config has actually changed wrt the previous Run, hence rebook your
00395       // histograms or do anything else dependent on the revised HLT config
00396       // check if trigger name in (new) config
00397       triggerNamesOFF_ = hltConfig_.triggerNames();
00398 
00399       //loop over trigger paths
00400       nPathsOFF_ = hltConfig_.size();
00401       for (unsigned int i=0; i<nPathsOFF_; i++) {
00402         temp_.clear();
00403         for (unsigned int j=0; j<hltConfig_.moduleLabels(i).size(); j++){
00404           temp_.push_back(hltConfig_.moduleLabel(i,j));
00405         }
00406         moduleLabelOFF_.push_back(temp_);
00407       }
00408 
00409     }
00410   } 
00411   else {
00412     // if init returns FALSE, initialisation has NOT succeeded, which indicates a problem
00413     // with the file and/or code and needs to be investigated!
00414     cout<<" HLT config extraction failure with process name " << processNameOFF_;
00415     // In this case, all access methods will return empty values!
00416   }
00417 
00418   //------------------compare online and offline hltConfig------------------------
00419   if (nPathsON_==0 || nPathsOFF_==0){
00420     cout<<"There are 0 paths online or offline!! There are "<<nPathsON_<<" paths online and "<<nPathsOFF_<<" paths offline!!!"<<endl;
00421     TriggerModuleNamesOK_ = false;
00422   }
00423   else{
00424     //define nPaths_ as number of paths shared between online and offline
00425     if (nPathsON_<=nPathsOFF_) nPaths_=nPathsON_;
00426     else nPaths_=nPathsOFF_;
00427 
00428     for (unsigned int i=0; i<nPathsON_; i++) {
00429       for (unsigned int j=0; j<nPathsOFF_; j++) {
00430         if (triggerNamesON_[i]==triggerNamesOFF_[j]){
00431           triggerNames_.push_back(triggerNamesON_[i]);
00432           if (i!=j) cout<<"Path "<<triggerNamesON_[i]<<" corresponds to path number "<<i<<" for online and path number "<<j<<" for offline"<<endl;
00433 
00434           //define nModules_ as number of modules shared between online and offline
00435           if (moduleLabelON_[i].size()<=moduleLabelOFF_[j].size()) nModules_.push_back(moduleLabelON_[i].size());
00436           else nModules_.push_back(moduleLabelOFF_[j].size());
00437 
00438           if (nModules_[i]>max_nModules_) max_nModules_=nModules_[i];
00439           
00440           if (moduleLabelON_[i].size()>moduleLabelOFF_[j].size()) nModules_diff_.push_back(moduleLabelON_[i].size()-moduleLabelOFF_[j].size());
00441           else nModules_diff_.push_back(moduleLabelOFF_[j].size()-moduleLabelON_[i].size());
00442 
00443           temp_.clear();
00444           for (unsigned int a=0; a<moduleLabelON_[i].size(); a++) {
00445             for (unsigned int b=0; b<moduleLabelOFF_[j].size(); b++) {
00446               //match online and offline module labels
00447               //since a module can be run twice per path, but not usually right after one another,
00448               //require that a and b be fairly close to each other, +/- the difference in the number of modules run offline vs online,
00449               //to avoid double-counting modules that are repeated later in the path
00450               //also, since we need to work with unsigned ints, a or b could also be 0, ignoring the requirement described above
00451               if ( (moduleLabelON_[i][a]==moduleLabelOFF_[j][b]) && ( (b<=a+nModules_diff_[i] && b>=a-nModules_diff_[i]) || (a==0 || b==0) ) ){
00452                 temp_.push_back(moduleLabelON_[i][a]);
00453                 if (a!=b){
00454                   cout<<"For path "<<triggerNamesON_[i]<<" online and "<<triggerNamesOFF_[j]<<" offline:"<<endl;
00455                   cout<<"  module "<<moduleLabelON_[i][a]<<" corresponds to module number "<<a<<" for online and module number "<<b<<" for offline"<<endl;
00456                 }
00457               }
00458             }
00459           }
00460           moduleLabel_.push_back(temp_);
00461         }
00462       }
00463     }
00464   }
00465 
00466 
00467   //----------------------------------------------------------------------------------------------------------
00468 
00469   //if everything is good:
00470   //save path and module names to be used in event loop, print out the module names and types for each path
00471   //get paths in each dataset
00472   if (TriggerModuleNamesOK_){
00473 
00474     //------------all paths--------------
00475     cout<<endl<<"There are "<<nPaths_<<" paths in total"<<endl;
00476     cout<<"Maximum number of modules over all paths is: "<<max_nModules_<<endl;  
00477 
00478     for (unsigned int x=0; x<nPaths_; x++) {
00479       trigger_online_.push_back(0);
00480       trigger_offline_.push_back(0);
00481       cout<<endl<<"For "<<triggerNames_[x]<<" (trigger number "<<x<<"), there are "<<nModules_[x]<<" modules:"<<endl;
00482       for (unsigned int j=0; j<nModules_[x]; j++) {
00483         const string& moduleType_ = hltConfig_.moduleType(moduleLabel_[x][j]);
00484         cout<<"  module "<<j<<" is "<<moduleLabel_[x][j]<<" and is of type "<<moduleType_<<endl;
00485       }
00486     }
00487 
00488 
00489     //---------paths per dataset-------------------------------------------
00490     //get datasets, initialize max_nModules_PD_
00491     datasetNames_ = hltConfig_.datasetNames();
00492     nDatasets_ = datasetNames_.size();    
00493     for (unsigned int a=0; a<nDatasets_; a++) {
00494       max_nModules_PD_.push_back(0);
00495     }
00496 
00497     //loop over datasets, paths in each dataset
00498     for (unsigned int a=0; a<nDatasets_; a++) {
00499       temp_.clear();
00500       vector<string> datasetcontent_ = hltConfig_.datasetContent(a);
00501       nPaths_PD_.push_back(datasetcontent_.size());
00502       cout<<endl<<"For dataset "<<datasetNames_[a]<<" (dataset number "<<a<<"), there are "<<nPaths_PD_[a]<<" paths:"<<endl;
00503       for (unsigned int b=0; b<nPaths_PD_[a]; b++) {
00504         cout<<"  path "<<b<<" is "<<datasetcontent_[b]<<endl;
00505         temp_.push_back(datasetcontent_[b]);
00506       }
00507       datasetContent_.push_back(temp_);
00508     }
00509 
00510     //match trigger names in full list to trigger names per dataset; find max number of modules over all triggers in each dataset
00511     //find matches
00512     vector <vector<bool> > temp1_;
00513     vector<bool> temp2_;
00514     for (unsigned int x=0; x<nPaths_; x++) {
00515       temp1_.clear();
00516       for (unsigned int a=0; a<nDatasets_; a++) {
00517         temp2_.clear();
00518         for (unsigned int b=0; b<nPaths_PD_[a]; b++) {
00519           if (triggerNames_[x]==datasetContent_[a][b]){
00520             temp2_.push_back(true);         
00521             //cout<<"Matched trigger name is: "<<datasetContent_[a][b]<<" for dataset "<<a<<" and dataset path "<<b<<endl;
00522           }
00523           else temp2_.push_back(false);
00524         }
00525         temp1_.push_back(temp2_);
00526       }
00527       triggerNames_matched_.push_back(temp1_);
00528     }
00529 
00530     //if matched and # of modules is bigger than all previous ones, take that number as new maximum
00531     for (unsigned int x=0; x<nPaths_; x++) {
00532       for (unsigned int a=0; a<nDatasets_; a++) {
00533         for (unsigned int b=0; b<nPaths_PD_[a]; b++) {
00534           if (triggerNames_matched_[x][a][b] && nModules_[x]>max_nModules_PD_[a]) max_nModules_PD_[a]=nModules_[x];
00535         }
00536       }
00537     }
00538 
00539     //for (unsigned int a=0; a<nDatasets_; a++) {
00540     //cout<<"For dataset "<<datasetNames_[a]<<", the max number of modules is: "<<max_nModules_PD_[a]<<endl;
00541     //}
00542 
00543   }//end if all triggers and modules match from online to offline
00544   
00545 
00546   //----------------------------------------------------------------------------------------------------------
00547 
00548 
00549   //define histograms
00550 
00551   //all paths
00552   path_ON_hist = fs->make<TH1D>("path_ON_hist", "Total Times Online Path Fires", nPaths_, 0, nPaths_);
00553   path_ONnotOFF_hist = fs->make<TH1D>("path_ONnotOFF_hist", "Online Path fires but Offline does not", nPaths_, 0, nPaths_);
00554   path_OFFnotON_hist = fs->make<TH1D>("path_OFFnotON_hist", "Offline Path fires but Online does not", nPaths_, 0, nPaths_);
00555   pathmodule_ONnotOFF_hist = fs->make<TH2D>("pathmodule_ONnotOFF_hist", "Last run module index vs Path for Offline, when Online fired but Offline didn't", nPaths_, 0, nPaths_, max_nModules_, 0, max_nModules_);
00556   pathmodule_OFFnotON_hist = fs->make<TH2D>("pathmodule_OFFnotON_hist", "Last run module index vs Path for Online, when Offline fired but Online didn't", nPaths_, 0, nPaths_, max_nModules_, 0, max_nModules_);
00557   
00558   //paths per dataset
00559   char path_ON_name[100], path_ONnotOFF_name[100], path_OFFnotON_name[100], pathmodule_ONnotOFF_name[100], pathmodule_OFFnotON_name[100];
00560   for (unsigned int a = 0; a < nDatasets_; ++a) {
00561     snprintf(path_ON_name,             100, "path_ON_hist_PD[%i]",              a);
00562     snprintf(path_ONnotOFF_name,       100, "path_ONnotOFF_hist_PD[%i]",        a);
00563     snprintf(path_OFFnotON_name,       100, "path_OFFnotON_hist_PD[%i]",        a);
00564     snprintf(pathmodule_ONnotOFF_name, 100, "pathmodule_ONnotOFF_hist_PD[%i]",  a);
00565     snprintf(pathmodule_OFFnotON_name, 100, "pathmodule_OFFnotON_hist_PD[%i]",  a);
00566 
00567     TString path_ON_title             = "Total Times Online Path Fires (" + datasetNames_[a] + " dataset)";
00568     TString path_ONnotOFF_title       = "Online Path fires but Offline does not (" + datasetNames_[a] + " dataset)";
00569     TString path_OFFnotON_title       = "Offline Path fires but Online does not (" + datasetNames_[a] + " dataset)";
00570     TString pathmodule_ONnotOFF_title = "Last run module index vs Path for Offline, when Online fired but Offline didn't (" + datasetNames_[a] + " dataset)";
00571     TString pathmodule_OFFnotON_title = "Last run module index vs Path for Online, when Offline fired but Online didn't (" + datasetNames_[a] + " dataset)";
00572 
00573     path_ON_hist_PD.push_back(fs->make<TH1D>(path_ON_name, path_ON_title, nPaths_PD_[a], 0, nPaths_PD_[a]));
00574     path_ONnotOFF_hist_PD.push_back(fs->make<TH1D>(path_ONnotOFF_name, path_ONnotOFF_title, nPaths_PD_[a], 0, nPaths_PD_[a]));
00575     path_OFFnotON_hist_PD.push_back(fs->make<TH1D>(path_OFFnotON_name, path_OFFnotON_title, nPaths_PD_[a], 0, nPaths_PD_[a]));
00576     pathmodule_ONnotOFF_hist_PD.push_back(fs->make<TH2D>(pathmodule_ONnotOFF_name, pathmodule_ONnotOFF_title, nPaths_PD_[a], 0, nPaths_PD_[a], max_nModules_PD_[a], 0, max_nModules_PD_[a]));
00577     pathmodule_OFFnotON_hist_PD.push_back(fs->make<TH2D>(pathmodule_OFFnotON_name, pathmodule_OFFnotON_title, nPaths_PD_[a], 0, nPaths_PD_[a], max_nModules_PD_[a], 0, max_nModules_PD_[a]));
00578   }
00579   
00580 }
00581 
00582 // ------------ method called when ending the processing of a run  ------------
00583 void 
00584 HLTOfflineReproducibility::endRun(edm::Run const&, edm::EventSetup const&)
00585 {
00586   //all paths
00587   cout<<endl;
00588   for (unsigned int x=0; x<nPaths_; x++) {
00589     cout<<triggerNames_[x]<<" online accepts: "<<trigger_online_[x]<<", offline accepts: "<<trigger_offline_[x]<<endl;
00590     path_ON_hist->GetXaxis()->SetBinLabel(x+1,triggerNames_[x].c_str());
00591     path_ONnotOFF_hist->GetXaxis()->SetBinLabel(x+1,triggerNames_[x].c_str());
00592     path_OFFnotON_hist->GetXaxis()->SetBinLabel(x+1,triggerNames_[x].c_str());
00593     pathmodule_ONnotOFF_hist->GetXaxis()->SetBinLabel(x+1,triggerNames_[x].c_str());
00594     pathmodule_OFFnotON_hist->GetXaxis()->SetBinLabel(x+1,triggerNames_[x].c_str());
00595   }
00596 
00597   //paths per dataset
00598   for (unsigned int a=0; a<nDatasets_; a++) {
00599     for (unsigned int b=0; b<nPaths_PD_[a]; b++) {
00600       path_ON_hist_PD[a]->GetXaxis()->SetBinLabel(b+1,datasetContent_[a][b].c_str());
00601       path_ONnotOFF_hist_PD[a]->GetXaxis()->SetBinLabel(b+1,datasetContent_[a][b].c_str());
00602       path_OFFnotON_hist_PD[a]->GetXaxis()->SetBinLabel(b+1,datasetContent_[a][b].c_str());
00603       pathmodule_ONnotOFF_hist_PD[a]->GetXaxis()->SetBinLabel(b+1,datasetContent_[a][b].c_str());
00604       pathmodule_OFFnotON_hist_PD[a]->GetXaxis()->SetBinLabel(b+1,datasetContent_[a][b].c_str());
00605     }
00606   }
00607 
00608 }
00609 
00610 // ------------ method called when starting to processes a luminosity block  ------------
00611 void 
00612 HLTOfflineReproducibility::beginLuminosityBlock(edm::LuminosityBlock const&, edm::EventSetup const&)
00613 {
00614 }
00615 
00616 // ------------ method called when ending the processing of a luminosity block  ------------
00617 void 
00618 HLTOfflineReproducibility::endLuminosityBlock(edm::LuminosityBlock const&, edm::EventSetup const&)
00619 {
00620 }
00621 
00622 // ------------ method fills 'descriptions' with the allowed parameters for the module  ------------
00623 void
00624 HLTOfflineReproducibility::fillDescriptions(edm::ConfigurationDescriptions& descriptions) {
00625   //The following says we do not know what parameters are allowed so do no validation
00626   // Please change this to state exactly what you do use, even if it is no parameters
00627   edm::ParameterSetDescription desc;
00628   desc.setUnknown();
00629   descriptions.addDefault(desc);
00630 }
00631 
00632 //define this as a plug-in
00633 DEFINE_FWK_MODULE(HLTOfflineReproducibility);