CMS 3D CMS Logo

/data/doxygen/doxygen-1.7.3/gen/CMSSW_4_2_8/src/HLTriggerOffline/Egamma/src/EmDQMPostProcessor.cc

Go to the documentation of this file.
00001 #include "HLTriggerOffline/Egamma/interface/EmDQMPostProcessor.h"
00002 
00003 #include "DQMServices/Core/interface/DQMStore.h"
00004 #include "DQMServices/Core/interface/MonitorElement.h"
00005 #include "FWCore/ServiceRegistry/interface/Service.h"
00006 #include "FWCore/Framework/interface/MakerMacros.h"
00007 
00008 #include <iostream>
00009 #include <string.h>
00010 #include <iomanip>
00011 #include <fstream>
00012 #include <math.h>
00013 
00014 #include <TEfficiency.h>
00015 
00016 //----------------------------------------------------------------------
00017 
00018 EmDQMPostProcessor::EmDQMPostProcessor(const edm::ParameterSet& pset)
00019 {
00020   subDir_  = pset.getUntrackedParameter<std::string>("subDir");
00021 
00022   dataSet_ = pset.getUntrackedParameter<std::string>("dataSet","unknown");
00023 
00024   normalizeToReco = pset.getUntrackedParameter<bool>("normalizeToReco",false);
00025 }
00026 
00027 //----------------------------------------------------------------------
00028 
00029 void EmDQMPostProcessor::endRun(edm::Run const& run, edm::EventSetup const& es)
00030 {
00032   // setup DQM stor               //
00034   
00035   DQMStore * dqm = 0;
00036   dqm = edm::Service<DQMStore>().operator->();
00037 
00038   if ( ! dqm ) {
00039     edm::LogInfo("EmDQMPostProcessor") << "Cannot create DQMStore instance\n";
00040     return;
00041   }
00042 
00043 
00044   //go to the directory to be processed
00045   if(dqm->dirExists(subDir_)) dqm->cd(subDir_);
00046   else {
00047     edm::LogWarning("EmDQMPostProcessor") << "cannot find directory: " << subDir_ << " , skipping";
00048     return;
00049   }
00050 
00051   //--------------------
00052   // with respect to what are (some) efficiencies calculated ?
00053   std::string shortReferenceName;
00054   if (normalizeToReco)
00055     shortReferenceName = "RECO";
00056   else
00057     shortReferenceName = "gen";
00058 
00059 
00060 
00061   //--------------------
00062 
00063 
00065   //loop over all triggers/samples//
00067 
00068   // store dataset name (if defined) in output file
00069   // DQMStore:bookString seems to put a key in the file which is
00070   // of the form <dataSet>s=....</dataSet> which is not very convenient
00071   // (it points to a null pointer, one would have to loop over
00072   // all keys of the corresponding directory in the ROOT file
00073   // and check whether it is of the desired form and then parse
00074   // it from this string...).
00075   //
00076   // So we store the name of the dataset as the title of a histogram,
00077   // which is much easier to access...
00078   // TH1D *dataSetNameHisto = 
00079   dqm->book1D("DataSetNameHistogram",dataSet_,1,0,1);
00080 
00081   std::vector<std::string> subdirectories = dqm->getSubdirs();
00082   for(std::vector<std::string>::iterator dir = subdirectories.begin() ;dir!= subdirectories.end(); dir++ ){
00083     dqm->cd(*dir);
00084 
00085 
00087     // Do everything twice: once for mc-matched histos,   //
00088     // once for unmatched histos                          //
00090 
00091     std::vector<std::string> postfixes;
00092     postfixes.push_back("");   //unmatched histograms
00093     postfixes.push_back("_RECO_matched"); // for data
00094 
00095     // we put this on the list even when we're running on 
00096     // data (where there is no generator information).
00097     // The first test in the loop will then fail and
00098     // the iteration is skipped.
00099     postfixes.push_back("_MC_matched"); 
00100 
00101     for(std::vector<std::string>::iterator postfix=postfixes.begin(); postfix!=postfixes.end();postfix++){
00102       
00104       // computer per-event efficiencies //
00106       
00107       std::string histoName="efficiency_by_step"+ *postfix;
00108       std::string baseName = "total_eff"+ *postfix;
00109 
00110       TH1F* basehist = getHistogram(dqm, dqm->pwd() + "/" + baseName);
00111       if (basehist == NULL)
00112         {
00113           //edm::LogWarning("EmDQMPostProcessor") << "histogram " << (dqm->pwd() + "/" + baseName) << " does not exist, skipping postfix '" << *postfix << "'"; 
00114           continue;
00115         }
00116       TProfile* total = dqm->bookProfile(histoName,histoName,basehist->GetXaxis()->GetNbins(),basehist->GetXaxis()->GetXmin(),basehist->GetXaxis()->GetXmax(),0.,1.2)->getTProfile();
00117       total->GetXaxis()->SetBinLabel(1,basehist->GetXaxis()->GetBinLabel(1));
00118       
00119 //       std::vector<std::string> mes = dqm->getMEs();
00120 //       for(std::vector<std::string>::iterator me = mes.begin() ;me!= mes.end(); me++ )
00121 //      std::cout <<*me <<std::endl;
00122 //       std::cout <<std::endl;
00123       
00124       double value=0;
00125       double errorh=0,errorl=0,error=0;    
00126       //compute stepwise total efficiencies 
00127       for(int bin= total->GetNbinsX()-2 ; bin > 1  ; bin--){
00128         value=0;
00129         errorl=0;
00130         errorh=0;
00131         error=0;
00132         if(basehist->GetBinContent(bin-1) != 0){
00133           Efficiency( (int)basehist->GetBinContent(bin), (int)basehist->GetBinContent(bin-1), 0.683, value, errorl, errorh );
00134           error = value-errorl>errorh-value ? value-errorl : errorh-value;
00135         }
00136         total->SetBinContent( bin, value );
00137         total->SetBinEntries( bin, 1 );
00138         total->SetBinError( bin, sqrt(value*value+error*error) );
00139         total->GetXaxis()->SetBinLabel(bin,basehist->GetXaxis()->GetBinLabel(bin));
00140       }
00141 
00142       //set first bin to L1 efficiency
00143       if(basehist->GetBinContent(basehist->GetNbinsX()) !=0 ){
00144         Efficiency( (int)basehist->GetBinContent(1), (int)basehist->GetBinContent(basehist->GetNbinsX()), 0.683, value, errorl, errorh );
00145         error= value-errorl>errorh-value ? value-errorl : errorh-value;
00146       }else{
00147         value=0;error=0;
00148       }
00149       total->SetBinContent(1,value);
00150       total->SetBinEntries(1, 1 );
00151       total->SetBinError(1, sqrt(value*value+error*error) );
00152      
00153       // total efficiency relative to gen or reco
00154       if(basehist->GetBinContent(basehist->GetNbinsX()) !=0 ){
00155         Efficiency( (int)basehist->GetBinContent(basehist->GetNbinsX()-2), (int)basehist->GetBinContent(basehist->GetNbinsX()), 0.683, value, errorl, errorh );
00156         error= value-errorl>errorh-value ? value-errorl : errorh-value;
00157       }else{
00158         value=0;error=0;
00159       }
00160       total->SetBinContent(total->GetNbinsX(),value);
00161       total->SetBinEntries(total->GetNbinsX(),1);
00162       total->SetBinError(total->GetNbinsX(),sqrt(value*value+error*error));
00163       total->GetXaxis()->SetBinLabel(total->GetNbinsX(),("total efficiency rel. " + shortReferenceName).c_str());
00164       
00165       //total efficiency relative to L1
00166       if(basehist->GetBinContent(1) !=0 ){
00167         Efficiency( (int)basehist->GetBinContent(basehist->GetNbinsX()-2), (int)basehist->GetBinContent(1), 0.683, value, errorl, errorh );
00168         error= value-errorl > errorh-value ? value-errorl : errorh-value;
00169       }else{
00170         value=0;error=0;
00171       }
00172       total->SetBinContent(total->GetNbinsX()-1,value);
00173       total->SetBinError(total->GetNbinsX()-1,sqrt(value*value+error*error));
00174       total->SetBinEntries(total->GetNbinsX()-1,1);
00175       total->GetXaxis()->SetBinLabel(total->GetNbinsX()-1,"total efficiency rel. L1");
00176 
00177       //----------------------------------------
00178 
00180       // compute per-object efficiencies       //
00182       //MonitorElement *eff, *num, *denom, *genPlot, *effVsGen, *effL1VsGen;
00183       std::vector<std::string> varNames; 
00184       varNames.push_back("eta"); 
00185       varNames.push_back("phi"); 
00186       varNames.push_back("et");
00187 
00188       std::string filterName;
00189       std::string filterName2;
00190       std::string denomName;
00191       std::string numName;
00192 
00193       // Get the gen-level (or reco, for data) plots
00194       std::string genName;
00195 
00196       // Get the L1 over gen filter first
00197       filterName2= total->GetXaxis()->GetBinLabel(1);
00198         
00199       //loop over variables (eta/phi/et)
00200       for(std::vector<std::string>::iterator var = varNames.begin(); var != varNames.end() ; var++){
00201         
00202         numName   = dqm->pwd() + "/" + filterName2 + *var + *postfix;
00203 
00204         if (normalizeToReco)
00205           genName   = dqm->pwd() + "/reco_" + *var ;
00206         else
00207           genName   = dqm->pwd() + "/gen_" + *var ;
00208 
00209         // Create the efficiency plot
00210         if(!dividehistos(dqm,numName,genName,"efficiency_"+filterName2+"_vs_"+*var +*postfix,*var,"eff. of"+filterName2+" vs "+*var +*postfix))
00211           break;
00212       } // loop over variables
00213     
00214       // get the filter names from the bin-labels of the master-histogram
00215       for (int filter=1; filter < total->GetNbinsX()-2; filter++) {
00216         filterName = total->GetXaxis()->GetBinLabel(filter);
00217         filterName2= total->GetXaxis()->GetBinLabel(filter+1);
00218         
00219         //loop over variables (eta/et/phi)
00220         for(std::vector<std::string>::iterator var = varNames.begin(); var != varNames.end() ; var++){
00221           numName   = dqm->pwd() + "/" + filterName2 + *var + *postfix;
00222           denomName = dqm->pwd() + "/" + filterName  + *var + *postfix;
00223 
00224           // Is this the last filter? Book efficiency vs gen (or reco, for data) level
00225           std::string temp = *postfix;
00226           if (filter==total->GetNbinsX()-3 && temp.find("matched")!=std::string::npos) {
00227             if (normalizeToReco)
00228               genName = dqm->pwd() + "/reco_" + *var;
00229             else
00230               genName = dqm->pwd() + "/gen_" + *var;
00231 
00232             if(!dividehistos(dqm,numName,genName,"final_eff_vs_"+*var,*var,"Efficiency Compared to " + shortReferenceName + " vs "+*var))
00233               break;
00234           }
00235 
00236           if(!dividehistos(dqm,numName,denomName,"efficiency_"+filterName2+"_vs_"+*var +*postfix,*var,"efficiency_"+filterName2+"_vs_"+*var + *postfix))
00237             break;
00238 
00239         } // loop over variables
00240       } // loop over monitoring modules within path
00241     } // loop over postfixes 
00242     dqm->goUp();
00243   }
00244   
00245 }
00246 
00247 //----------------------------------------------------------------------
00248 
00249 TProfile* EmDQMPostProcessor::dividehistos(DQMStore * dqm, const std::string& numName, const std::string& denomName, const std::string& outName,const std::string& label,const std::string& titel){
00250   //std::cout << numName <<std::endl;
00251 
00252   TH1F* num = getHistogram(dqm,numName);
00253 
00254   //std::cout << denomName << std::endl;
00255   TH1F* denom = getHistogram(dqm, denomName);
00256 
00257   if (num == NULL)
00258     edm::LogWarning("EmDQMPostProcessor") << "numerator histogram " << numName << " does not exist";
00259 
00260   if (denom == NULL)
00261     edm::LogWarning("EmDQMPostProcessor") << "denominator histogram " << denomName << " does not exist";
00262 
00263   // Check if histograms actually exist
00264 
00265   if(!num || !denom) return 0;
00266 
00267   // Make sure we are able to book new element
00268   if (!dqm) return 0;
00269   
00270   TProfile* out = dqm->bookProfile(outName,titel,num->GetXaxis()->GetNbins(),num->GetXaxis()->GetXmin(),num->GetXaxis()->GetXmax(),0.,1.2)->getTProfile();
00271   out->GetXaxis()->SetTitle(label.c_str());
00272   out->SetYTitle("Efficiency");
00273   out->SetOption("PE");
00274   out->SetLineColor(2);
00275   out->SetLineWidth(2);
00276   out->SetMarkerStyle(20);
00277   out->SetMarkerSize(0.8);
00278   out->SetStats(kFALSE);
00279   for(int i=1;i<=num->GetNbinsX();i++){
00280     double e, low, high;
00281     Efficiency( (int)num->GetBinContent(i), (int)denom->GetBinContent(i), 0.683, e, low, high );
00282     double err = e-low>high-e ? e-low : high-e;
00283     //here is the trick to store info in TProfile:
00284     out->SetBinContent( i, e );
00285     out->SetBinEntries( i, 1 );
00286     out->SetBinError( i, sqrt(e*e+err*err) );
00287   }
00288 
00289   return out;
00290 }
00291 
00292 //----------------------------------------------------------------------
00293 
00294 TH1F *
00295 EmDQMPostProcessor::getHistogram(DQMStore *dqm, const std::string &histoPath)
00296 {
00297   MonitorElement *monElement = dqm->get(histoPath);
00298   if (monElement != NULL)
00299     return monElement->getTH1F();
00300   else
00301     return NULL;
00302 }
00303 
00304 //----------------------------------------------------------------------
00305 
00306 void 
00307 EmDQMPostProcessor::Efficiency(int passing, int total, double level, double &mode, double &lowerBound, double &upperBound)
00308 { 
00309   // protection (see also TGraphAsymmErrors::Efficiency(..), mimick the old behaviour )
00310   if (total == 0)
00311   {
00312     mode = 0.5;
00313     lowerBound = 0;
00314     upperBound = 1;
00315     return;
00316   }
00317 
00318   mode = passing / ((double) total);
00319 
00320   // note that the order of the two first arguments ('total' and 'passed') is the opposited
00321   // with respect to the earlier TGraphAsymmErrors::Efficiency(..) method
00322   //
00323   // see https://root.cern.ch/root/html/TEfficiency.html#compare for
00324   // an illustration of the coverage of the different methods provided by TEfficiency
00325   
00326   lowerBound = TEfficiency::Wilson(total, passing, level, false);
00327   upperBound = TEfficiency::Wilson(total, passing, level, true);
00328 }
00329 
00330 
00331 //----------------------------------------------------------------------
00332 
00333 DEFINE_FWK_MODULE(EmDQMPostProcessor);
00334 
00335 //----------------------------------------------------------------------