CMS 3D CMS Logo

/data/refman/pasoursint/CMSSW_5_2_9/src/DQMServices/ClientConfig/plugins/DQMGenericClient.cc

Go to the documentation of this file.
00001 /*
00002  *  Class:DQMGenericClient 
00003  *
00004  *
00005  *  $Date: 2012/02/12 16:19:29 $
00006  *  $Revision: 1.32 $
00007  * 
00008  *  \author Junghwan Goh - SungKyunKwan University
00009  */
00010 
00011 #include "DQMServices/ClientConfig/interface/DQMGenericClient.h"
00012 
00013 #include "DQMServices/ClientConfig/interface/FitSlicesYTool.h"
00014 #include "DQMServices/Core/interface/DQMStore.h"
00015 #include "DQMServices/Core/interface/MonitorElement.h"
00016 #include "FWCore/ParameterSet/interface/ParameterSet.h"
00017 #include "FWCore/ServiceRegistry/interface/Service.h"
00018 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00019 
00020 #include <TH1F.h>
00021 #include <TClass.h>
00022 #include <TString.h>
00023 #include <TPRegexp.h>
00024 
00025 #include <cmath>
00026 #include <boost/tokenizer.hpp>
00027 
00028 using namespace std;
00029 using namespace edm;
00030 
00031 typedef MonitorElement ME;
00032 
00033 TPRegexp metacharacters("[\\^\\$\\.\\*\\+\\?\\|\\(\\)\\{\\}\\[\\]]");
00034 TPRegexp nonPerlWildcard("\\w\\*|^\\*");
00035 
00036 DQMGenericClient::DQMGenericClient(const ParameterSet& pset)
00037 {
00038   typedef std::vector<edm::ParameterSet> VPSet;
00039   typedef std::vector<std::string> vstring;
00040   typedef boost::escaped_list_separator<char> elsc;
00041 
00042   elsc commonEscapes("\\", " \t", "\'");
00043 
00044   verbose_ = pset.getUntrackedParameter<unsigned int>("verbose", 0);
00045 
00046   // Parse efficiency commands
00047   vstring effCmds = pset.getParameter<vstring>("efficiency");
00048   for ( vstring::const_iterator effCmd = effCmds.begin();
00049         effCmd != effCmds.end(); ++effCmd )
00050   {
00051     if ( effCmd->empty() ) continue;
00052 
00053     boost::tokenizer<elsc> tokens(*effCmd, commonEscapes);
00054 
00055     vector<string> args;
00056     for(boost::tokenizer<elsc>::const_iterator iToken = tokens.begin();
00057         iToken != tokens.end(); ++iToken) {
00058       if ( iToken->empty() ) continue;
00059       args.push_back(*iToken);
00060     }
00061 
00062     if ( args.size() < 4 ) {
00063       LogInfo("DQMGenericClient") << "Wrong input to effCmds\n";
00064       continue;
00065     }
00066 
00067     EfficOption opt;
00068     opt.name = args[0];
00069     opt.title = args[1];
00070     opt.numerator = args[2];
00071     opt.denominator = args[3];
00072     opt.isProfile = false;
00073 
00074     const string typeName = args.size() == 4 ? "eff" : args[4];
00075     if ( typeName == "eff" ) opt.type = 1;
00076     else if ( typeName == "fake" ) opt.type = 2;
00077     else opt.type = 0;
00078  
00079     efficOptions_.push_back(opt);
00080   }
00081   
00082   VPSet efficSets = pset.getUntrackedParameter<VPSet>("efficiencySets", VPSet());
00083   for ( VPSet::const_iterator efficSet = efficSets.begin();
00084         efficSet != efficSets.end(); ++efficSet )
00085   {
00086     EfficOption opt;
00087     opt.name = efficSet->getUntrackedParameter<string>("name");
00088     opt.title = efficSet->getUntrackedParameter<string>("title");
00089     opt.numerator = efficSet->getUntrackedParameter<string>("numerator");
00090     opt.denominator = efficSet->getUntrackedParameter<string>("denominator");
00091     opt.isProfile = false;
00092 
00093     const string typeName = efficSet->getUntrackedParameter<string>("typeName", "eff");
00094     if ( typeName == "eff" ) opt.type = 1;
00095     else if ( typeName == "fake" ) opt.type = 2;
00096     else opt.type = 0;
00097 
00098     efficOptions_.push_back(opt);
00099   }
00100 
00101   // Parse profiles
00102   vstring profileCmds = pset.getUntrackedParameter<vstring>("efficiencyProfile", vstring());
00103   for ( vstring::const_iterator profileCmd = profileCmds.begin();
00104         profileCmd != profileCmds.end(); ++profileCmd )
00105   {
00106     if ( profileCmd->empty() ) continue;
00107 
00108     boost::tokenizer<elsc> tokens(*profileCmd, commonEscapes);
00109 
00110     vector<string> args;
00111     for(boost::tokenizer<elsc>::const_iterator iToken = tokens.begin();
00112         iToken != tokens.end(); ++iToken) {
00113       if ( iToken->empty() ) continue;
00114       args.push_back(*iToken);
00115     }
00116 
00117     if ( args.size() < 4 ) {
00118       LogInfo("DQMGenericClient") << "Wrong input to profileCmds\n";
00119       continue;
00120     }
00121 
00122     EfficOption opt;
00123     opt.name = args[0];
00124     opt.title = args[1];
00125     opt.numerator = args[2];
00126     opt.denominator = args[3];
00127     opt.isProfile = true;
00128 
00129     const string typeName = args.size() == 4 ? "eff" : args[4];
00130     if ( typeName == "eff" ) opt.type = 1;
00131     else if ( typeName == "fake" ) opt.type = 2;
00132     else opt.type = 0;
00133  
00134     efficOptions_.push_back(opt);
00135   }
00136 
00137   VPSet profileSets = pset.getUntrackedParameter<VPSet>("efficiencyProfileSets", VPSet());
00138   for ( VPSet::const_iterator profileSet = profileSets.begin();
00139         profileSet != profileSets.end(); ++profileSet )
00140   {
00141     EfficOption opt;
00142     opt.name = profileSet->getUntrackedParameter<string>("name");
00143     opt.title = profileSet->getUntrackedParameter<string>("title");
00144     opt.numerator = profileSet->getUntrackedParameter<string>("numerator");
00145     opt.denominator = profileSet->getUntrackedParameter<string>("denominator");
00146     opt.isProfile = true;
00147 
00148     const string typeName = profileSet->getUntrackedParameter<string>("typeName", "eff");
00149     if ( typeName == "eff" ) opt.type = 1;
00150     else if ( typeName == "fake" ) opt.type = 2;
00151     else opt.type = 0;
00152 
00153     efficOptions_.push_back(opt);
00154   }
00155 
00156   // Parse resolution commands
00157   vstring resCmds = pset.getParameter<vstring>("resolution");
00158   for ( vstring::const_iterator resCmd = resCmds.begin();
00159         resCmd != resCmds.end(); ++resCmd )
00160   {
00161     if ( resCmd->empty() ) continue;
00162     boost::tokenizer<elsc> tokens(*resCmd, commonEscapes);
00163 
00164     vector<string> args;
00165     for(boost::tokenizer<elsc>::const_iterator iToken = tokens.begin();
00166         iToken != tokens.end(); ++iToken) {
00167       if ( iToken->empty() ) continue;
00168       args.push_back(*iToken);
00169     }
00170 
00171     if ( args.size() != 3 ) {
00172       LogInfo("DQMGenericClient") << "Wrong input to resCmds\n";
00173       continue;
00174     }
00175 
00176     ResolOption opt;
00177     opt.namePrefix = args[0];
00178     opt.titlePrefix = args[1];
00179     opt.srcName = args[2];
00180 
00181     resolOptions_.push_back(opt);
00182   }
00183 
00184   VPSet resolSets = pset.getUntrackedParameter<VPSet>("resolutionSets", VPSet());
00185   for ( VPSet::const_iterator resolSet = resolSets.begin();
00186         resolSet != resolSets.end(); ++resolSet )
00187   {
00188     ResolOption opt;
00189     opt.namePrefix = resolSet->getUntrackedParameter<string>("namePrefix");
00190     opt.titlePrefix = resolSet->getUntrackedParameter<string>("titlePrefix");
00191     opt.srcName = resolSet->getUntrackedParameter<string>("srcName");
00192 
00193     resolOptions_.push_back(opt);
00194   }
00195 
00196   // Parse Normalization commands
00197   vstring normCmds = pset.getUntrackedParameter<vstring>("normalization", vstring());
00198   for ( vstring::const_iterator normCmd = normCmds.begin();
00199         normCmd != normCmds.end(); ++normCmd )
00200   {
00201     if ( normCmd->empty() ) continue;
00202     boost::tokenizer<elsc> tokens(*normCmd, commonEscapes);
00203 
00204     vector<string> args;
00205     for(boost::tokenizer<elsc>::const_iterator iToken = tokens.begin();
00206         iToken != tokens.end(); ++iToken) {
00207       if ( iToken->empty() ) continue;
00208       args.push_back(*iToken);
00209     }
00210 
00211     if ( args.empty() or args.size() > 2 ) {
00212       LogInfo("DQMGenericClient") << "Wrong input to normCmds\n";
00213       continue;
00214     }
00215 
00216     NormOption opt;
00217     opt.name = args[0];
00218     opt.normHistName = args.size() == 2 ? args[1] : args[0];
00219 
00220     normOptions_.push_back(opt);
00221   }
00222 
00223   VPSet normSets = pset.getUntrackedParameter<VPSet>("normalizationSets", VPSet());
00224   for ( VPSet::const_iterator normSet = normSets.begin();
00225         normSet != normSets.end(); ++normSet )
00226   {
00227     NormOption opt;
00228     opt.name = normSet->getUntrackedParameter<string>("name");
00229     opt.normHistName = normSet->getUntrackedParameter<string>("normalizedTo", opt.name);
00230 
00231     normOptions_.push_back(opt);
00232   }
00233 
00234   // Cumulative distributions
00235   vstring cdCmds = pset.getUntrackedParameter<vstring>("cumulativeDists", vstring());
00236   for ( vstring::const_iterator cdCmd = cdCmds.begin();
00237         cdCmd != cdCmds.end(); ++cdCmd )
00238   {
00239     if ( cdCmd->empty() ) continue;
00240     boost::tokenizer<elsc> tokens(*cdCmd, commonEscapes);
00241 
00242     vector<string> args;
00243     for(boost::tokenizer<elsc>::const_iterator iToken = tokens.begin();
00244         iToken != tokens.end(); ++iToken) {
00245       if ( iToken->empty() ) continue;
00246       args.push_back(*iToken);
00247     }
00248 
00249     if ( args.size() != 1 ) {
00250       LogInfo("DQMGenericClient") << "Wrong input to cdCmds\n";
00251       continue;
00252     }
00253 
00254     CDOption opt;
00255     opt.name = args[0];
00256 
00257     cdOptions_.push_back(opt);
00258   }
00259 
00260   VPSet cdSets = pset.getUntrackedParameter<VPSet>("cumulativeDistSets", VPSet());
00261   for ( VPSet::const_iterator cdSet = cdSets.begin();
00262         cdSet != cdSets.end(); ++cdSet )
00263   {
00264     CDOption opt;
00265     opt.name = cdSet->getUntrackedParameter<string>("name");
00266 
00267     cdOptions_.push_back(opt);
00268   }
00269 
00270   outputFileName_ = pset.getUntrackedParameter<string>("outputFileName", "");
00271   subDirs_ = pset.getUntrackedParameter<vstring>("subDirs");
00272 
00273   resLimitedFit_ = pset.getUntrackedParameter<bool>("resolutionLimitedFit",false);
00274   isWildcardUsed_ = false;
00275 }
00276 
00277 void DQMGenericClient::endRun(const edm::Run& r, const edm::EventSetup& c) {
00278 
00279   typedef vector<string> vstring;
00280 
00281   // Update 2009-09-23
00282   // Migrated all code from endJob to this function
00283   // endJob is not necessarily called in the proper sequence
00284   // and does not necessarily book histograms produced in
00285   // that step.
00286   // It more robust to do the histogram manipulation in
00287   // this endRun function
00288 
00289 
00290   
00291   theDQM = 0;
00292   theDQM = Service<DQMStore>().operator->();
00293 
00294   if ( ! theDQM ) {
00295     LogInfo("DQMGenericClient") << "Cannot create DQMStore instance\n";
00296     return;
00297   }
00298 
00299   // Process wildcard in the sub-directory
00300   set<string> subDirSet;
00301 
00302   for(vstring::const_iterator iSubDir = subDirs_.begin();
00303       iSubDir != subDirs_.end(); ++iSubDir) {
00304     string subDir = *iSubDir;
00305 
00306     if ( subDir[subDir.size()-1] == '/' ) subDir.erase(subDir.size()-1);
00307 
00308     if ( TString(subDir).Contains(metacharacters) ) {
00309       isWildcardUsed_ = true;
00310 
00311       const string::size_type shiftPos = subDir.rfind('/');
00312       const string searchPath = subDir.substr(0, shiftPos);
00313       const string pattern    = subDir.substr(shiftPos + 1, subDir.length());
00314       //std::cout << "\n\n\n\nLooking for all subdirs of " << subDir << std::endl;
00315       
00316       findAllSubdirectories (searchPath, &subDirSet, pattern);
00317 
00318     }
00319     else {
00320       subDirSet.insert(subDir);
00321     }
00322   }
00323 
00324   for(set<string>::const_iterator iSubDir = subDirSet.begin();
00325       iSubDir != subDirSet.end(); ++iSubDir) {
00326     const string& dirName = *iSubDir;
00327 
00328     for ( vector<EfficOption>::const_iterator efficOption = efficOptions_.begin();
00329           efficOption != efficOptions_.end(); ++efficOption )
00330     {
00331       computeEfficiency(dirName, efficOption->name, efficOption->title, 
00332                         efficOption->numerator, efficOption->denominator,
00333                         efficOption->type, efficOption->isProfile);
00334     }
00335 
00336     for ( vector<ResolOption>::const_iterator resolOption = resolOptions_.begin();
00337           resolOption != resolOptions_.end(); ++resolOption )
00338     {
00339       computeResolution(dirName, resolOption->namePrefix, resolOption->titlePrefix, resolOption->srcName);
00340     }
00341 
00342     for ( vector<NormOption>::const_iterator normOption = normOptions_.begin();
00343           normOption != normOptions_.end(); ++normOption )
00344     {
00345       normalizeToEntries(dirName, normOption->name, normOption->normHistName);
00346     }
00347 
00348     for ( vector<CDOption>::const_iterator cdOption = cdOptions_.begin();
00349           cdOption != cdOptions_.end(); ++cdOption )
00350     {
00351       makeCumulativeDist(dirName, cdOption->name);
00352     }
00353   }
00354 
00355   //if ( verbose_ > 0 ) theDQM->showDirStructure();
00356 
00357   if ( ! outputFileName_.empty() ) theDQM->save(outputFileName_);
00358   
00359 }
00360 
00361 void DQMGenericClient::endJob()
00362 {
00363 
00364   // Update 2009-09-23
00365   // Migrated all code from here to endRun
00366 
00367   LogTrace ("DQMGenericClient") << "inside of DQMGenericClient::endJob()"
00368                                 << endl;
00369 
00370 }
00371 
00372 void DQMGenericClient::computeEfficiency(const string& startDir, const string& efficMEName, const string& efficMETitle, 
00373                                          const string& recoMEName, const string& simMEName, const int type, const bool makeProfile)
00374 {
00375   if ( ! theDQM->dirExists(startDir) ) {
00376     if ( verbose_ >= 2 || (verbose_ == 1 && !isWildcardUsed_) ) {
00377       LogInfo("DQMGenericClient") << "computeEfficiency() : "
00378                                   << "Cannot find sub-directory " << startDir << endl; 
00379     }
00380     return;
00381   }
00382 
00383   theDQM->cd();
00384 
00385   ME* simME  = theDQM->get(startDir+"/"+simMEName);
00386   ME* recoME = theDQM->get(startDir+"/"+recoMEName);
00387 
00388   if ( !simME ) {
00389     if ( verbose_ >= 2 || (verbose_ == 1 && !isWildcardUsed_) ) {
00390       LogInfo("DQMGenericClient") << "computeEfficiency() : "
00391                                   << "No sim-ME '" << simMEName << "' found\n";
00392     }
00393     return;
00394   }
00395 
00396   if ( !recoME ) {
00397     if ( verbose_ >= 2 || (verbose_ == 1 && !isWildcardUsed_) ) {
00398       LogInfo("DQMGenericClient") << "computeEfficiency() : " 
00399                                   << "No reco-ME '" << recoMEName << "' found\n";
00400     }
00401     return;
00402   }
00403 
00404   // Treat everything as the base class, TH1
00405   
00406   TH1* hSim  = simME ->getTH1();
00407   TH1* hReco = recoME->getTH1();
00408   
00409   if ( !hSim || !hReco ) {
00410     if ( verbose_ >= 2 || (verbose_ == 1 && !isWildcardUsed_) ) {
00411       LogInfo("DQMGenericClient") << "computeEfficiency() : "
00412                                   << "Cannot create TH1 from ME\n";
00413     }
00414     return;
00415   }
00416 
00417   string efficDir = startDir;
00418   string newEfficMEName = efficMEName;
00419   string::size_type shiftPos;
00420   if ( string::npos != (shiftPos = efficMEName.rfind('/')) ) {
00421     efficDir += "/"+efficMEName.substr(0, shiftPos);
00422     newEfficMEName.erase(0, shiftPos+1);
00423   }
00424   theDQM->setCurrentFolder(efficDir);
00425 
00426   if (makeProfile) {
00427     TProfile * efficHist = (hReco->GetXaxis()->GetXbins()->GetSize()==0) ?
00428       new TProfile(newEfficMEName.c_str(), efficMETitle.c_str(),
00429                    hReco->GetXaxis()->GetNbins(),
00430                    hReco->GetXaxis()->GetXmin(),
00431                    hReco->GetXaxis()->GetXmax()) :
00432       new TProfile(newEfficMEName.c_str(), efficMETitle.c_str(),
00433                    hReco->GetXaxis()->GetNbins(),
00434                    hReco->GetXaxis()->GetXbins()->GetArray());
00435 #if ROOT_VERSION_CODE >= ROOT_VERSION(5,27,0)
00436     for (int i=1; i <= hReco->GetNbinsX(); i++) {
00437       const double nReco = hReco->GetBinContent(i);
00438       const double nSim = hSim->GetBinContent(i);
00439     
00440       if ( nSim == 0 || nReco > nSim ) continue;
00441       const double effVal = nReco/nSim;
00442 
00443       const double errLo = TEfficiency::ClopperPearson((int)hSim->GetBinContent(i), 
00444                                                        (int)hReco->GetBinContent(i),
00445                                                        0.683,false);
00446       const double errUp = TEfficiency::ClopperPearson((int)hSim->GetBinContent(i), 
00447                                                        (int)hReco->GetBinContent(i),
00448                                                        0.683,true);
00449       const double errVal = (effVal - errLo > errUp - effVal) ? effVal - errLo : errUp - effVal;
00450       efficHist->SetBinContent(i, effVal);
00451       efficHist->SetBinEntries(i, 1);
00452       efficHist->SetBinError(i, sqrt(effVal * effVal + errVal * errVal));
00453     }
00454 #else
00455     for (int i=1; i <= hReco->GetNbinsX(); i++) {
00456       TGraphAsymmErrorsWrapper asymm;
00457       std::pair<double, double> efficiencyWithError;
00458       efficiencyWithError = asymm.efficiency((int)hReco->GetBinContent(i), 
00459                                              (int)hSim->GetBinContent(i));
00460       double effVal = efficiencyWithError.first;
00461       double errVal = efficiencyWithError.second;
00462       if ((int)hSim->GetBinContent(i) > 0) {
00463         efficHist->SetBinContent(i, effVal);
00464         efficHist->SetBinEntries(i, 1);
00465         efficHist->SetBinError(i, sqrt(effVal * effVal + errVal * errVal));
00466       }
00467     }
00468 #endif
00469     theDQM->bookProfile(newEfficMEName.c_str(),efficHist);
00470     delete efficHist;  
00471   }
00472 
00473   else {
00474 
00475     TH1* efficHist = (TH1*)hSim->Clone(newEfficMEName.c_str());
00476     efficHist->SetTitle(efficMETitle.c_str());
00477 
00478     // Here is where you have trouble --- you need
00479     // to understand what type of hist you have.
00480 
00481     ME* efficME = 0;
00482 
00483     // Parse the class name
00484     // This works, but there might be a better way
00485     TClass * myHistClass = efficHist->IsA();
00486     TString histClassName = myHistClass->GetName();
00487   
00488     if (histClassName == "TH1F"){
00489       efficME = theDQM->book1D(newEfficMEName, (TH1F*)efficHist);
00490     } else if (histClassName == "TH2F"){
00491       efficME = theDQM->book2D(newEfficMEName, (TH2F*)efficHist);    
00492     } else if (histClassName == "TH3F"){
00493       efficME = theDQM->book3D(newEfficMEName, (TH3F*)efficHist);    
00494     } 
00495   
00496 
00497     if ( !efficME ) {
00498       LogInfo("DQMGenericClient") << "computeEfficiency() : "
00499                                   << "Cannot book effic-ME from the DQM\n";
00500       return;
00501     }
00502 
00503     // Update: 2009-9-16 slaunwhj
00504     // call the most generic efficiency function
00505     // works up to 3-d histograms
00506 
00507     generic_eff (hSim, hReco, efficME, type);
00508   
00509     //   const int nBin = efficME->getNbinsX();
00510     //   for(int bin = 0; bin <= nBin; ++bin) {
00511     //     const float nSim  = simME ->getBinContent(bin);
00512     //     const float nReco = recoME->getBinContent(bin);
00513     //     float eff =0;
00514     //     if (type=="fake")eff = nSim ? 1-nReco/nSim : 0.;
00515     //     else eff= nSim ? nReco/nSim : 0.;
00516     //     const float err = nSim && eff <= 1 ? sqrt(eff*(1-eff)/nSim) : 0.;
00517     //     efficME->setBinContent(bin, eff);
00518     //     efficME->setBinError(bin, err);
00519     //   }
00520     efficME->setEntries(simME->getEntries());
00521 
00522   }
00523 
00524   // Global efficiency
00525   ME* globalEfficME = theDQM->get(efficDir+"/globalEfficiencies");
00526   if ( !globalEfficME ) globalEfficME = theDQM->book1D("globalEfficiencies", "Global efficiencies", 1, 0, 1);
00527   if ( !globalEfficME ) {
00528     LogInfo("DQMGenericClient") << "computeEfficiency() : "
00529                               << "Cannot book globalEffic-ME from the DQM\n";
00530     return;
00531   }
00532   TH1F* hGlobalEffic = globalEfficME->getTH1F();
00533   if ( !hGlobalEffic ) {
00534     LogInfo("DQMGenericClient") << "computeEfficiency() : "
00535                               << "Cannot create TH1F from ME, globalEfficME\n";
00536     return;
00537   }
00538 
00539   const float nSimAll = hSim->GetEntries();
00540   const float nRecoAll = hReco->GetEntries();
00541   float efficAll=0; 
00542   if ( type == 1 ) efficAll = nSimAll ? nRecoAll/nSimAll : 0;
00543   else if ( type == 2 ) efficAll = nSimAll ? 1-nRecoAll/nSimAll : 0;
00544   const float errorAll = nSimAll && efficAll < 1 ? sqrt(efficAll*(1-efficAll)/nSimAll) : 0;
00545 
00546   const int iBin = hGlobalEffic->Fill(newEfficMEName.c_str(), 0);
00547   hGlobalEffic->SetBinContent(iBin, efficAll);
00548   hGlobalEffic->SetBinError(iBin, errorAll);
00549 }
00550 
00551 void DQMGenericClient::computeResolution(const string& startDir, const string& namePrefix, const string& titlePrefix,
00552                                          const std::string& srcName)
00553 {
00554   if ( ! theDQM->dirExists(startDir) ) {
00555     if ( verbose_ >= 2 || (verbose_ == 1 && !isWildcardUsed_) ) {
00556       LogInfo("DQMGenericClient") << "computeResolution() : "
00557                                   << "Cannot find sub-directory " << startDir << endl;
00558     }
00559     return;
00560   }
00561 
00562   theDQM->cd();
00563 
00564   ME* srcME = theDQM->get(startDir+"/"+srcName);
00565   if ( !srcME ) {
00566     if ( verbose_ >= 2 || (verbose_ == 1 && !isWildcardUsed_) ) {
00567       LogInfo("DQMGenericClient") << "computeResolution() : "
00568                                   << "No source ME '" << srcName << "' found\n";
00569     }
00570     return;
00571   }
00572 
00573   TH2F* hSrc = srcME->getTH2F();
00574   if ( !hSrc ) {
00575     if ( verbose_ >= 2 || (verbose_ == 1 && !isWildcardUsed_) ) {
00576       LogInfo("DQMGenericClient") << "computeResolution() : "
00577                                   << "Cannot create TH2F from source-ME\n";
00578     }
00579     return;
00580   }
00581 
00582   const int nBin = hSrc->GetNbinsX();
00583   const double xMin = hSrc->GetXaxis()->GetXmin();
00584   const double xMax = hSrc->GetXaxis()->GetXmax();
00585 //  const double yMin = hSrc->GetYaxis()->GetXmin();
00586 //  const double yMax = hSrc->GetYaxis()->GetXmax();
00587 
00588   string newDir = startDir;
00589   string newPrefix = namePrefix;
00590   string::size_type shiftPos;
00591   if ( string::npos != (shiftPos = namePrefix.rfind('/')) ) {
00592     newDir += "/"+namePrefix.substr(0, shiftPos);
00593     newPrefix.erase(0, shiftPos+1);
00594   }
00595 
00596   theDQM->setCurrentFolder(newDir);
00597 
00598 //   ME* meanME = theDQM->bookProfile(newPrefix+"_Mean", titlePrefix+" Mean", nBin, xMin, xMax, 10, yMin, yMax);
00599 //   ME* sigmaME = theDQM->bookProfile(newPrefix+"_Sigma", titlePrefix+" Sigma", nBin, xMin, xMax, 10, yMin, yMax);
00600   ME* meanME = theDQM->book1D(newPrefix+"_Mean", titlePrefix+" Mean", nBin, xMin, xMax);
00601   ME* sigmaME = theDQM->book1D(newPrefix+"_Sigma", titlePrefix+" Sigma", nBin, xMin, xMax);
00602   meanME->setEfficiencyFlag();
00603   sigmaME->setEfficiencyFlag();
00604   //  ME* chi2ME  = theDQM->book1D(namePrefix+"_Chi2" , titlePrefix+" #Chi^{2}", nBin, xMin, xMax); // N/A
00605 
00606   if (! resLimitedFit_ ) {
00607     FitSlicesYTool fitTool(srcME);
00608     fitTool.getFittedMeanWithError(meanME);
00609     fitTool.getFittedSigmaWithError(sigmaME);
00611   } else {
00612     limitedFit(srcME,meanME,sigmaME);
00613   }
00614 }
00615 
00616 void DQMGenericClient::normalizeToEntries(const std::string& startDir, const std::string& histName, const std::string& normHistName) 
00617 {
00618   if ( ! theDQM->dirExists(startDir) ) {
00619     if ( verbose_ >= 2 || (verbose_ == 1 && !isWildcardUsed_) ) {
00620       LogInfo("DQMGenericClient") << "normalizeToEntries() : "
00621                                      << "Cannot find sub-directory " << startDir << endl;
00622     }
00623     return;
00624   }
00625 
00626   theDQM->cd();
00627 
00628   ME* element = theDQM->get(startDir+"/"+histName);
00629   ME* normME = theDQM->get(startDir+"/"+normHistName);
00630 
00631   if ( !element ) {
00632     if ( verbose_ >= 2 || (verbose_ == 1 && !isWildcardUsed_) ) {
00633       LogInfo("DQMGenericClient") << "normalizeToEntries() : "
00634                                      << "No such element '" << histName << "' found\n";
00635     }
00636     return;
00637   }
00638 
00639   if ( !normME ) {
00640     if ( verbose_ >= 2 || (verbose_ == 1 && !isWildcardUsed_) ) {
00641       LogInfo("DQMGenericClient") << "normalizeToEntries() : "
00642                                      << "No such element '" << normHistName << "' found\n";
00643     }
00644     return;
00645   }
00646 
00647   TH1F* hist  = element->getTH1F();
00648   if ( !hist) {
00649     if ( verbose_ >= 2 || (verbose_ == 1 && !isWildcardUsed_) ) {
00650       LogInfo("DQMGenericClient") << "normalizeToEntries() : "
00651                                      << "Cannot create TH1F from ME\n";
00652     }
00653     return;
00654   }
00655 
00656   TH1F* normHist = normME->getTH1F();
00657   if ( !normHist ) {
00658     if ( verbose_ >= 2 || (verbose_ == 1 && !isWildcardUsed_) ) {
00659       LogInfo("DQMGenericClient") << "normalizeToEntries() : "
00660                                      << "Cannot create TH1F from ME\n";
00661     }
00662     return;
00663   }
00664 
00665   const double entries = normHist->GetEntries();
00666   if ( entries != 0 ) {
00667     hist->Scale(1./entries);
00668   }
00669   else {
00670     LogInfo("DQMGenericClient") << "normalizeToEntries() : " 
00671                                    << "Zero entries in histogram\n";
00672   }
00673 
00674   return;
00675 }
00676 
00677 void DQMGenericClient::makeCumulativeDist(const std::string& startDir, const std::string& cdName) 
00678 {
00679   if ( ! theDQM->dirExists(startDir) ) {
00680     if ( verbose_ >= 2 || (verbose_ == 1 && !isWildcardUsed_) ) {
00681       LogInfo("DQMGenericClient") << "makeCumulativeDist() : "
00682                                      << "Cannot find sub-directory " << startDir << endl;
00683     }
00684     return;
00685   }
00686 
00687   theDQM->cd();
00688 
00689   ME* element_cd = theDQM->get(startDir+"/"+cdName);
00690 
00691   if ( !element_cd ) {
00692     if ( verbose_ >= 2 || (verbose_ == 1 && !isWildcardUsed_) ) {
00693       LogInfo("DQMGenericClient") << "makeCumulativeDist() : "
00694                                      << "No such element '" << cdName << "' found\n";
00695     }
00696     return;
00697   }
00698 
00699   TH1F* cd  = element_cd->getTH1F();
00700 
00701   if ( !cd ) {
00702     if ( verbose_ >= 2 || (verbose_ == 1 && !isWildcardUsed_) ) {
00703       LogInfo("DQMGenericClient") << "makeCumulativeDist() : "
00704                                      << "Cannot create TH1F from ME\n";
00705     }
00706     return;
00707   }
00708 
00709   int n_bins = cd->GetNbinsX() + 1;
00710 
00711   for (int i = 1; i <= n_bins; i++) {
00712     cd->SetBinContent(i,cd->GetBinContent(i) + cd->GetBinContent(i-1));
00713   }
00714 
00715   return;
00716 }
00717 
00718 void DQMGenericClient::limitedFit(MonitorElement * srcME, MonitorElement * meanME, MonitorElement * sigmaME)
00719 {
00720   TH2F * histo = srcME->getTH2F();
00721 
00722   static int i = 0;
00723   i++;
00724 
00725   // Fit slices projected along Y from bins in X 
00726   double cont_min = 100;    //Minimum number of entries
00727   Int_t binx =  histo->GetXaxis()->GetNbins();
00728 
00729   for (int i = 1; i <= binx ; i++) {
00730     TString iString(i);
00731     TH1 *histoY =  histo->ProjectionY(" ", i, i);
00732     double cont = histoY->GetEntries();
00733 
00734     if (cont >= cont_min) {
00735       float minfit = histoY->GetMean() - histoY->GetRMS();
00736       float maxfit = histoY->GetMean() + histoY->GetRMS();
00737       
00738       TF1 *fitFcn = new TF1(TString("g")+histo->GetName()+iString,"gaus",minfit,maxfit);
00739       double x1,x2;
00740       fitFcn->GetRange(x1,x2);
00741 
00742       histoY->Fit(fitFcn,"QR0","",x1,x2);
00743 
00744 //      histoY->Fit(fitFcn->GetName(),"RME");
00745       double *par = fitFcn->GetParameters();
00746       double *err = fitFcn->GetParErrors();
00747 
00748       meanME->setBinContent(i, par[1]);
00749       meanME->setBinError(i, err[1]);
00750 //       meanME->setBinEntries(i, 1.);
00751 //       meanME->setBinError(i,sqrt(err[1]*err[1]+par[1]*par[1]));
00752 
00753       sigmaME->setBinContent(i, par[2]);
00754       sigmaME->setBinError(i, err[2]);
00755 //       sigmaME->setBinEntries(i, 1.);
00756 //       sigmaME->setBinError(i,sqrt(err[2]*err[2]+par[2]*par[2]));
00757 
00758       if(fitFcn) delete fitFcn;
00759       if(histoY) delete histoY;
00760     }
00761     else {
00762       if(histoY) delete histoY;
00763       continue;
00764     }
00765   }
00766 }
00767 
00768 //=================================
00769 
00770 void DQMGenericClient::findAllSubdirectories (std::string dir, std::set<std::string> * myList, TString pattern = "") {
00771   if (!theDQM->dirExists(dir)) {
00772     LogError("DQMGenericClient") << " DQMGenericClient::findAllSubdirectories ==> Missing folder " << dir << " !!!"; 
00773     return;
00774   }
00775   if (pattern != "") {
00776     if (pattern.Contains(nonPerlWildcard)) pattern.ReplaceAll("*",".*");
00777     TPRegexp regexp(pattern);
00778     theDQM->cd(dir);
00779     vector <string> foundDirs = theDQM->getSubdirs();
00780     for(vector<string>::const_iterator iDir = foundDirs.begin();
00781         iDir != foundDirs.end(); ++iDir) {
00782       TString dirName = iDir->substr(iDir->rfind('/') + 1, iDir->length());
00783       if (dirName.Contains(regexp))
00784         findAllSubdirectories ( *iDir, myList);
00785     }
00786   }
00787   //std::cout << "Looking for directory " << dir ;
00788   else if (theDQM->dirExists(dir)){
00789     //std::cout << "... it exists! Inserting it into the list ";
00790     myList->insert(dir);
00791     //std::cout << "... now list has size " << myList->size() << std::endl;
00792     theDQM->cd(dir);
00793     findAllSubdirectories (dir, myList, "*");
00794   } else {
00795     //std::cout << "... DOES NOT EXIST!!! Skip bogus dir" << std::endl;
00796     
00797     LogInfo ("DQMGenericClient") << "Trying to find sub-directories of " << dir
00798                                  << " failed because " << dir  << " does not exist";
00799                                  
00800   }
00801   return;
00802 }
00803 
00804 
00805 void DQMGenericClient::generic_eff (TH1* denom, TH1* numer, MonitorElement* efficiencyHist, const int type) {
00806   for (int iBinX = 1; iBinX < denom->GetNbinsX()+1; iBinX++){
00807     for (int iBinY = 1; iBinY < denom->GetNbinsY()+1; iBinY++){
00808       for (int iBinZ = 1; iBinZ < denom->GetNbinsZ()+1; iBinZ++){
00809 
00810         int globalBinNum = denom->GetBin(iBinX, iBinY, iBinZ);
00811         
00812         float numerVal = numer->GetBinContent(globalBinNum);
00813         float denomVal = denom->GetBinContent(globalBinNum);
00814 
00815         float effVal = 0;
00816 
00817         // fake eff is in use
00818         if (type == 2 ) {          
00819           effVal = denomVal ? (1 - numerVal / denomVal) : 0;
00820         } else {
00821           effVal = denomVal ? numerVal / denomVal : 0;
00822         }
00823 
00824         float errVal = (denomVal && (effVal <=1)) ? sqrt(effVal*(1-effVal)/denomVal) : 0;
00825 
00826         LogDebug ("DQMGenericClient") << "(iBinX, iBinY, iBinZ)  = "
00827              << iBinX << ", "
00828              << iBinY << ", "
00829              << iBinZ << "), global bin =  "  << globalBinNum
00830              << "eff = " << numerVal << "  /  " << denomVal
00831              << " =  " << effVal 
00832              << " ... setting the error for that bin ... " << endl
00833              << endl;
00834 
00835         
00836         efficiencyHist->setBinContent(globalBinNum, effVal);
00837         efficiencyHist->setBinError(globalBinNum, errVal);
00838       }
00839     }
00840   }
00841 
00842   //efficiencyHist->setMinimum(0.0);
00843   //efficiencyHist->setMaximum(1.0);
00844 }
00845 
00846 
00847 /* vim:set ts=2 sts=2 sw=2 expandtab: */