CMS 3D CMS Logo

PostProcessor.cc

Go to the documentation of this file.
00001 /*
00002  *  Class:PostProcessor 
00003  *
00004  *
00005  *  $Date: 2009/01/16 13:21:49 $
00006  *  $Revision: 1.3 $
00007  * 
00008  *  \author Junghwan Goh - SungKyunKwan University
00009  */
00010 
00011 #include "Validation/Tools/interface/PostProcessor.h"
00012 
00013 #include "Validation/Tools/interface/FitSlicesYTool.h"
00014 #include "DQMServices/Core/interface/DQMStore.h"
00015 #include "DQMServices/Core/interface/MonitorElement.h"
00016 #include "FWCore/ServiceRegistry/interface/Service.h"
00017 
00018 #include <TH1F.h>
00019 #include <cmath>
00020 
00021 using namespace std;
00022 using namespace edm;
00023 
00024 typedef MonitorElement ME;
00025 typedef vector<string> vstring;
00026 
00027 PostProcessor::PostProcessor(const ParameterSet& pset)
00028 {
00029   verbose_ = pset.getUntrackedParameter<unsigned int>("verbose", 0);
00030 
00031   effCmds_ = pset.getParameter<vstring>("efficiency");
00032   resCmds_ = pset.getParameter<vstring>("resolution");
00033 
00034   resLimitedFit_ = pset.getUntrackedParameter<bool>("resolutionLimitedFit",false);
00035 
00036   outputFileName_ = pset.getUntrackedParameter<string>("outputFileName", "");
00037   subDirs_ = pset.getUntrackedParameter<vstring>("subDirs");
00038 
00039   isWildcardUsed_ = false;
00040 }
00041 
00042 void PostProcessor::endJob()
00043 {
00044   theDQM = 0;
00045   theDQM = Service<DQMStore>().operator->();
00046 
00047   if ( ! theDQM ) {
00048     LogError("PostProcessor") << "Cannot create DQMStore instance\n";
00049     return;
00050   }
00051 
00052   // Process wildcard in the sub-directory
00053   set<string> subDirSet;
00054 
00055   for(vstring::const_iterator iSubDir = subDirs_.begin();
00056       iSubDir != subDirs_.end(); ++iSubDir) {
00057     string subDir = *iSubDir;
00058 
00059     if ( subDir[subDir.size()-1] == '/' ) subDir.erase(subDir.size()-1);
00060 
00061     if ( subDir[subDir.size()-1] == '*' ) {
00062       isWildcardUsed_ = true;
00063       const string::size_type shiftPos = subDir.rfind('/');
00064 
00065       const string searchPath = subDir.substr(0, shiftPos);
00066       theDQM->cd(searchPath);
00067 
00068       vector<string> foundDirs = theDQM->getSubdirs();
00069       const string matchStr = subDir.substr(0, subDir.size()-2);
00070 
00071       for(vector<string>::const_iterator iDir = foundDirs.begin();
00072           iDir != foundDirs.end(); ++iDir) {
00073         const string dirPrefix = iDir->substr(0, matchStr.size());
00074 
00075         if ( dirPrefix == matchStr ) {
00076           subDirSet.insert(*iDir);
00077         }
00078       }
00079     }
00080     else {
00081       subDirSet.insert(subDir);
00082     }
00083   }
00084 
00085   for(set<string>::const_iterator iSubDir = subDirSet.begin();
00086       iSubDir != subDirSet.end(); ++iSubDir) {
00087     typedef boost::escaped_list_separator<char> elsc;
00088 
00089     const string& dirName = *iSubDir;
00090 
00091     for(vstring::const_iterator iCmd = effCmds_.begin();
00092         iCmd != effCmds_.end(); ++iCmd) {
00093       if ( iCmd->empty() ) continue;
00094       boost::tokenizer<elsc> tokens(*iCmd, elsc("\\", " \t", "\'"));
00095 
00096       vector<string> args;
00097       for(boost::tokenizer<elsc>::const_iterator iToken = tokens.begin();
00098           iToken != tokens.end(); ++iToken) {
00099         if ( iToken->empty() ) continue;
00100         args.push_back(*iToken);
00101       }
00102 
00103       if ( args.size() < 4 ) {
00104         LogError("PostProcessor") << "Wrong input to effCmds\n";
00105         continue;
00106       }
00107 
00108       if ( args.size() == 4 ) args.push_back("eff");
00109 
00110       computeEfficiency(dirName, args[0], args[1], args[2], args[3], args[4]);
00111     }
00112 
00113     for(vstring::const_iterator iCmd = resCmds_.begin();
00114         iCmd != resCmds_.end(); ++ iCmd) {
00115       if ( iCmd->empty() ) continue;
00116       boost::tokenizer<elsc> tokens(*iCmd, elsc("\\", " \t", "\'"));
00117 
00118       vector<string> args;
00119       for(boost::tokenizer<elsc>::const_iterator iToken = tokens.begin();
00120           iToken != tokens.end(); ++iToken) {
00121         if ( iToken->empty() ) continue;
00122         args.push_back(*iToken);
00123       }
00124 
00125       if ( args.size() != 3 ) {
00126         LogError("PostProcessor") << "Wrong input to resCmds\n";
00127         continue;
00128       }
00129 
00130       computeResolution(dirName, args[0], args[1], args[2]);
00131     }
00132   }
00133 
00134   if ( verbose_ > 0 ) theDQM->showDirStructure();
00135 
00136   if ( ! outputFileName_.empty() ) theDQM->save(outputFileName_);
00137 }
00138 
00139 void PostProcessor::computeEfficiency(const string& startDir, const string& efficMEName, const string& efficMETitle,
00140                                       const string& recoMEName, const string& simMEName, const std::string & type)
00141 {
00142   if ( ! theDQM->dirExists(startDir) ) {
00143     if ( verbose_ >= 2 || (verbose_ == 1 && !isWildcardUsed_) ) {
00144       LogWarning("PostProcessor") << "computeEfficiency() : "
00145                                   << "Cannot find sub-directory " << startDir << endl; 
00146     }
00147     return;
00148   }
00149 
00150   theDQM->cd();
00151 
00152   ME* simME  = theDQM->get(startDir+"/"+simMEName);
00153   ME* recoME = theDQM->get(startDir+"/"+recoMEName);
00154 
00155   if ( !simME ) {
00156     if ( verbose_ >= 2 || (verbose_ == 1 && !isWildcardUsed_) ) {
00157       LogWarning("PostProcessor") << "computeEfficiency() : "
00158                                   << "No sim-ME '" << simMEName << "' found\n";
00159     }
00160     return;
00161   }
00162 
00163   if ( !recoME ) {
00164     if ( verbose_ >= 2 || (verbose_ == 1 && !isWildcardUsed_) ) {
00165       LogWarning("PostProcessor") << "computeEfficiency() : " 
00166                                   << "No reco-ME '" << recoMEName << "' found\n";
00167     }
00168     return;
00169   }
00170 
00171   TH1F* hSim  = simME ->getTH1F();
00172   TH1F* hReco = recoME->getTH1F();
00173   if ( !hSim || !hReco ) {
00174     if ( verbose_ >= 2 || (verbose_ == 1 && !isWildcardUsed_) ) {
00175       LogWarning("PostProcessor") << "computeEfficiency() : "
00176                                   << "Cannot create TH1F from ME\n";
00177     }
00178     return;
00179   }
00180 
00181   string efficDir = startDir;
00182   string newEfficMEName = efficMEName;
00183   string::size_type shiftPos;
00184   if ( string::npos != (shiftPos = efficMEName.rfind('/')) ) {
00185     efficDir += "/"+efficMEName.substr(0, shiftPos);
00186     newEfficMEName.erase(0, shiftPos+1);
00187   }
00188   theDQM->setCurrentFolder(efficDir);
00189   ME* efficME = theDQM->book1D(newEfficMEName, efficMETitle, hSim->GetNbinsX(), hSim->GetXaxis()->GetXmin(), hSim->GetXaxis()->GetXmax()); 
00190 
00191   if ( !efficME ) {
00192     LogWarning("PostProcessor") << "computeEfficiency() : "
00193                                 << "Cannot book effic-ME from the DQM\n";
00194     return;
00195   }
00196 
00197   const int nBin = efficME->getNbinsX();
00198   for(int bin = 0; bin <= nBin; ++bin) {
00199     const float nSim  = simME ->getBinContent(bin);
00200     const float nReco = recoME->getBinContent(bin);
00201     float eff =0;
00202     if (type=="fake")eff = nSim ? 1-nReco/nSim : 0.;
00203     else eff= nSim ? nReco/nSim : 0.;
00204     const float err = nSim && eff <= 1 ? sqrt(eff*(1-eff)/nSim) : 0.;
00205     efficME->setBinContent(bin, eff);
00206     efficME->setBinError(bin, err);
00207   }
00208   efficME->setEntries(simME->getEntries());
00209 
00210   // Global efficiency
00211   ME* globalEfficME = theDQM->get(efficDir+"/globalEfficiencies");
00212   if ( !globalEfficME ) globalEfficME = theDQM->book1D("globalEfficiencies", "Global efficiencies", 1, 0, 1);
00213   if ( !globalEfficME ) {
00214     LogError("PostProcessor") << "computeEfficiency() : "
00215                               << "Cannot book globalEffic-ME from the DQM\n";
00216     return;
00217   }
00218   TH1F* hGlobalEffic = globalEfficME->getTH1F();
00219   if ( !hGlobalEffic ) {
00220     LogError("PostProcessor") << "computeEfficiency() : "
00221                               << "Cannot create TH1F from ME, globalEfficME\n";
00222     return;
00223   }
00224 
00225   const float nSimAll = hSim->GetEntries();
00226   const float nRecoAll = hReco->GetEntries();
00227   float efficAll=0; 
00228   if (type=="fake")   efficAll = nSimAll ? 1-nRecoAll/nSimAll : 0;
00229   else   efficAll = nSimAll ? nRecoAll/nSimAll : 0;
00230   const float errorAll = nSimAll && efficAll < 1 ? sqrt(efficAll*(1-efficAll)/nSimAll) : 0;
00231 
00232   const int iBin = hGlobalEffic->Fill(newEfficMEName.c_str(), 0);
00233   hGlobalEffic->SetBinContent(iBin, efficAll);
00234   hGlobalEffic->SetBinError(iBin, errorAll);
00235 }
00236 
00237 void PostProcessor::computeResolution(const string& startDir, const string& namePrefix, const string& titlePrefix,
00238                                       const std::string& srcName)
00239 {
00240   if ( ! theDQM->dirExists(startDir) ) {
00241     if ( verbose_ >= 2 || (verbose_ == 1 && !isWildcardUsed_) ) {
00242       LogWarning("PostProcessor") << "computeResolution() : "
00243                                   << "Cannot find sub-directory " << startDir << endl;
00244     }
00245     return;
00246   }
00247 
00248   theDQM->cd();
00249 
00250   ME* srcME = theDQM->get(startDir+"/"+srcName);
00251   if ( !srcME ) {
00252     if ( verbose_ >= 2 || (verbose_ == 1 && !isWildcardUsed_) ) {
00253       LogWarning("PostProcessor") << "computeResolution() : "
00254                                   << "No source ME '" << srcName << "' found\n";
00255     }
00256     return;
00257   }
00258 
00259   TH2F* hSrc = srcME->getTH2F();
00260   if ( !hSrc ) {
00261     if ( verbose_ >= 2 || (verbose_ == 1 && !isWildcardUsed_) ) {
00262       LogWarning("PostProcessor") << "computeResolution() : "
00263                                   << "Cannot create TH2F from source-ME\n";
00264     }
00265     return;
00266   }
00267 
00268   const int nBin = hSrc->GetNbinsX();
00269   const double xMin = hSrc->GetXaxis()->GetXmin();
00270   const double xMax = hSrc->GetXaxis()->GetXmax();
00271 
00272   string newDir = startDir;
00273   string newPrefix = namePrefix;
00274   string::size_type shiftPos;
00275   if ( string::npos != (shiftPos = namePrefix.rfind('/')) ) {
00276     newDir += "/"+namePrefix.substr(0, shiftPos);
00277     newPrefix.erase(0, shiftPos+1);
00278   }
00279 
00280   theDQM->setCurrentFolder(newDir);
00281 
00282   ME* meanME = theDQM->book1D(newPrefix+"_Mean", titlePrefix+" Mean", nBin, xMin, xMax);
00283   ME* sigmaME = theDQM->book1D(newPrefix+"_Sigma", titlePrefix+" Sigma", nBin, xMin, xMax);
00284 //  ME* chi2ME  = theDQM->book1D(namePrefix+"_Chi2" , titlePrefix+" #Chi^{2}", nBin, xMin, xMax); // N/A
00285 
00286   if (! resLimitedFit_ ) {
00287     FitSlicesYTool fitTool(srcME);
00288     fitTool.getFittedMeanWithError(meanME);
00289     fitTool.getFittedSigmaWithError(sigmaME);
00291   } else {
00292     limitedFit(srcME,meanME,sigmaME);
00293   }
00294 }
00295 
00296 void PostProcessor::limitedFit(MonitorElement * srcME, MonitorElement * meanME, MonitorElement * sigmaME)
00297 {
00298   TH2F * histo = srcME->getTH2F();
00299 
00300   static int i = 0;
00301   i++;
00302 
00303   // Fit slices projected along Y from bins in X 
00304   double cont_min = 100;    //Minimum number of entries
00305   Int_t binx =  histo->GetXaxis()->GetNbins();
00306 
00307   for (int i = 1; i <= binx ; i++) {
00308     TString iString(i);
00309     TH1 *histoY =  histo->ProjectionY(" ", i, i);
00310     double cont = histoY->GetEntries();
00311 
00312     if (cont >= cont_min) {
00313       float minfit = histoY->GetMean() - histoY->GetRMS();
00314       float maxfit = histoY->GetMean() + histoY->GetRMS();
00315       
00316       TF1 *fitFcn = new TF1(TString("g")+histo->GetName()+iString,"gaus",minfit,maxfit);
00317       double x1,x2;
00318       fitFcn->GetRange(x1,x2);
00319 
00320       histoY->Fit(fitFcn,"QR0","",x1,x2);
00321 
00322 //      histoY->Fit(fitFcn->GetName(),"RME");
00323       double *par = fitFcn->GetParameters();
00324       double *err = fitFcn->GetParErrors();
00325 
00326       meanME->setBinContent(i,par[1]);
00327       meanME->setBinError(i,err[1]);
00328 
00329       sigmaME->setBinContent(i,par[2]);
00330       sigmaME->setBinError(i,err[2]);
00331       if(fitFcn) delete fitFcn;
00332       if(histoY) delete histoY;
00333     }
00334     else {
00335       if(histoY) delete histoY;
00336       continue;
00337     }
00338   }
00339 }
00340 
00341 /* vim:set ts=2 sts=2 sw=2 expandtab: */

Generated on Tue Jun 9 17:49:42 2009 for CMSSW by  doxygen 1.5.4