CMS 3D CMS Logo

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

Go to the documentation of this file.
00001 /*
00002  *  Class:DQMGenericClient 
00003  *
00004  *
00005  *  $Date: 2012/04/02 11:41:17 $
00006  *  $Revision: 1.33 $
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 
00584   string newDir = startDir;
00585   string newPrefix = namePrefix;
00586   string::size_type shiftPos;
00587   if ( string::npos != (shiftPos = namePrefix.rfind('/')) ) {
00588     newDir += "/"+namePrefix.substr(0, shiftPos);
00589     newPrefix.erase(0, shiftPos+1);
00590   }
00591 
00592   theDQM->setCurrentFolder(newDir);
00593 
00594   float * lowedgesfloats = new float[nBin+1];
00595   ME* meanME;
00596   ME* sigmaME;
00597   if (hSrc->GetXaxis()->GetXbins()->GetSize())
00598   {
00599     for (int j=0; j<nBin+1; ++j)
00600       lowedgesfloats[j] = (float)hSrc->GetXaxis()->GetXbins()->GetAt(j);
00601     meanME = theDQM->book1D(newPrefix+"_Mean", titlePrefix+" Mean", nBin, lowedgesfloats);
00602     sigmaME = theDQM->book1D(newPrefix+"_Sigma", titlePrefix+" Sigma", nBin, lowedgesfloats);
00603   }
00604   else
00605   {
00606     meanME = theDQM->book1D(newPrefix+"_Mean", titlePrefix+" Mean", nBin,
00607                             hSrc->GetXaxis()->GetXmin(),
00608                             hSrc->GetXaxis()->GetXmax());
00609     sigmaME = theDQM->book1D(newPrefix+"_Sigma", titlePrefix+" Sigma", nBin,
00610                             hSrc->GetXaxis()->GetXmin(),
00611                             hSrc->GetXaxis()->GetXmax());                            
00612   }
00613   
00614   if (meanME && sigmaME)
00615   {
00616     meanME->setEfficiencyFlag();
00617     sigmaME->setEfficiencyFlag();
00618 
00619     if (! resLimitedFit_ ) {
00620       FitSlicesYTool fitTool(srcME);
00621       fitTool.getFittedMeanWithError(meanME);
00622       fitTool.getFittedSigmaWithError(sigmaME);
00624     } else {
00625       limitedFit(srcME,meanME,sigmaME);
00626     }
00627   }
00628   delete[] lowedgesfloats;
00629 }
00630 
00631 void DQMGenericClient::normalizeToEntries(const std::string& startDir, const std::string& histName, const std::string& normHistName) 
00632 {
00633   if ( ! theDQM->dirExists(startDir) ) {
00634     if ( verbose_ >= 2 || (verbose_ == 1 && !isWildcardUsed_) ) {
00635       LogInfo("DQMGenericClient") << "normalizeToEntries() : "
00636                                      << "Cannot find sub-directory " << startDir << endl;
00637     }
00638     return;
00639   }
00640 
00641   theDQM->cd();
00642 
00643   ME* element = theDQM->get(startDir+"/"+histName);
00644   ME* normME = theDQM->get(startDir+"/"+normHistName);
00645 
00646   if ( !element ) {
00647     if ( verbose_ >= 2 || (verbose_ == 1 && !isWildcardUsed_) ) {
00648       LogInfo("DQMGenericClient") << "normalizeToEntries() : "
00649                                      << "No such element '" << histName << "' found\n";
00650     }
00651     return;
00652   }
00653 
00654   if ( !normME ) {
00655     if ( verbose_ >= 2 || (verbose_ == 1 && !isWildcardUsed_) ) {
00656       LogInfo("DQMGenericClient") << "normalizeToEntries() : "
00657                                      << "No such element '" << normHistName << "' found\n";
00658     }
00659     return;
00660   }
00661 
00662   TH1F* hist  = element->getTH1F();
00663   if ( !hist) {
00664     if ( verbose_ >= 2 || (verbose_ == 1 && !isWildcardUsed_) ) {
00665       LogInfo("DQMGenericClient") << "normalizeToEntries() : "
00666                                      << "Cannot create TH1F from ME\n";
00667     }
00668     return;
00669   }
00670 
00671   TH1F* normHist = normME->getTH1F();
00672   if ( !normHist ) {
00673     if ( verbose_ >= 2 || (verbose_ == 1 && !isWildcardUsed_) ) {
00674       LogInfo("DQMGenericClient") << "normalizeToEntries() : "
00675                                      << "Cannot create TH1F from ME\n";
00676     }
00677     return;
00678   }
00679 
00680   const double entries = normHist->GetEntries();
00681   if ( entries != 0 ) {
00682     hist->Scale(1./entries);
00683   }
00684   else {
00685     LogInfo("DQMGenericClient") << "normalizeToEntries() : " 
00686                                    << "Zero entries in histogram\n";
00687   }
00688 
00689   return;
00690 }
00691 
00692 void DQMGenericClient::makeCumulativeDist(const std::string& startDir, const std::string& cdName) 
00693 {
00694   if ( ! theDQM->dirExists(startDir) ) {
00695     if ( verbose_ >= 2 || (verbose_ == 1 && !isWildcardUsed_) ) {
00696       LogInfo("DQMGenericClient") << "makeCumulativeDist() : "
00697                                      << "Cannot find sub-directory " << startDir << endl;
00698     }
00699     return;
00700   }
00701 
00702   theDQM->cd();
00703 
00704   ME* element_cd = theDQM->get(startDir+"/"+cdName);
00705 
00706   if ( !element_cd ) {
00707     if ( verbose_ >= 2 || (verbose_ == 1 && !isWildcardUsed_) ) {
00708       LogInfo("DQMGenericClient") << "makeCumulativeDist() : "
00709                                      << "No such element '" << cdName << "' found\n";
00710     }
00711     return;
00712   }
00713 
00714   TH1F* cd  = element_cd->getTH1F();
00715 
00716   if ( !cd ) {
00717     if ( verbose_ >= 2 || (verbose_ == 1 && !isWildcardUsed_) ) {
00718       LogInfo("DQMGenericClient") << "makeCumulativeDist() : "
00719                                      << "Cannot create TH1F from ME\n";
00720     }
00721     return;
00722   }
00723 
00724   int n_bins = cd->GetNbinsX() + 1;
00725 
00726   for (int i = 1; i <= n_bins; i++) {
00727     cd->SetBinContent(i,cd->GetBinContent(i) + cd->GetBinContent(i-1));
00728   }
00729 
00730   return;
00731 }
00732 
00733 void DQMGenericClient::limitedFit(MonitorElement * srcME, MonitorElement * meanME, MonitorElement * sigmaME)
00734 {
00735   TH2F * histo = srcME->getTH2F();
00736 
00737   static int i = 0;
00738   i++;
00739 
00740   // Fit slices projected along Y from bins in X 
00741   double cont_min = 100;    //Minimum number of entries
00742   Int_t binx =  histo->GetXaxis()->GetNbins();
00743 
00744   for (int i = 1; i <= binx ; i++) {
00745     TString iString(i);
00746     TH1 *histoY =  histo->ProjectionY(" ", i, i);
00747     double cont = histoY->GetEntries();
00748 
00749     if (cont >= cont_min) {
00750       float minfit = histoY->GetMean() - histoY->GetRMS();
00751       float maxfit = histoY->GetMean() + histoY->GetRMS();
00752       
00753       TF1 *fitFcn = new TF1(TString("g")+histo->GetName()+iString,"gaus",minfit,maxfit);
00754       double x1,x2;
00755       fitFcn->GetRange(x1,x2);
00756 
00757       histoY->Fit(fitFcn,"QR0","",x1,x2);
00758 
00759 //      histoY->Fit(fitFcn->GetName(),"RME");
00760       double *par = fitFcn->GetParameters();
00761       double *err = fitFcn->GetParErrors();
00762 
00763       meanME->setBinContent(i, par[1]);
00764       meanME->setBinError(i, err[1]);
00765 //       meanME->setBinEntries(i, 1.);
00766 //       meanME->setBinError(i,sqrt(err[1]*err[1]+par[1]*par[1]));
00767 
00768       sigmaME->setBinContent(i, par[2]);
00769       sigmaME->setBinError(i, err[2]);
00770 //       sigmaME->setBinEntries(i, 1.);
00771 //       sigmaME->setBinError(i,sqrt(err[2]*err[2]+par[2]*par[2]));
00772 
00773       if(fitFcn) delete fitFcn;
00774       if(histoY) delete histoY;
00775     }
00776     else {
00777       if(histoY) delete histoY;
00778       continue;
00779     }
00780   }
00781 }
00782 
00783 //=================================
00784 
00785 void DQMGenericClient::findAllSubdirectories (std::string dir, std::set<std::string> * myList, TString pattern = "") {
00786   if (!theDQM->dirExists(dir)) {
00787     LogError("DQMGenericClient") << " DQMGenericClient::findAllSubdirectories ==> Missing folder " << dir << " !!!"; 
00788     return;
00789   }
00790   if (pattern != "") {
00791     if (pattern.Contains(nonPerlWildcard)) pattern.ReplaceAll("*",".*");
00792     TPRegexp regexp(pattern);
00793     theDQM->cd(dir);
00794     vector <string> foundDirs = theDQM->getSubdirs();
00795     for(vector<string>::const_iterator iDir = foundDirs.begin();
00796         iDir != foundDirs.end(); ++iDir) {
00797       TString dirName = iDir->substr(iDir->rfind('/') + 1, iDir->length());
00798       if (dirName.Contains(regexp))
00799         findAllSubdirectories ( *iDir, myList);
00800     }
00801   }
00802   //std::cout << "Looking for directory " << dir ;
00803   else if (theDQM->dirExists(dir)){
00804     //std::cout << "... it exists! Inserting it into the list ";
00805     myList->insert(dir);
00806     //std::cout << "... now list has size " << myList->size() << std::endl;
00807     theDQM->cd(dir);
00808     findAllSubdirectories (dir, myList, "*");
00809   } else {
00810     //std::cout << "... DOES NOT EXIST!!! Skip bogus dir" << std::endl;
00811     
00812     LogInfo ("DQMGenericClient") << "Trying to find sub-directories of " << dir
00813                                  << " failed because " << dir  << " does not exist";
00814                                  
00815   }
00816   return;
00817 }
00818 
00819 
00820 void DQMGenericClient::generic_eff (TH1* denom, TH1* numer, MonitorElement* efficiencyHist, const int type) {
00821   for (int iBinX = 1; iBinX < denom->GetNbinsX()+1; iBinX++){
00822     for (int iBinY = 1; iBinY < denom->GetNbinsY()+1; iBinY++){
00823       for (int iBinZ = 1; iBinZ < denom->GetNbinsZ()+1; iBinZ++){
00824 
00825         int globalBinNum = denom->GetBin(iBinX, iBinY, iBinZ);
00826         
00827         float numerVal = numer->GetBinContent(globalBinNum);
00828         float denomVal = denom->GetBinContent(globalBinNum);
00829 
00830         float effVal = 0;
00831 
00832         // fake eff is in use
00833         if (type == 2 ) {          
00834           effVal = denomVal ? (1 - numerVal / denomVal) : 0;
00835         } else {
00836           effVal = denomVal ? numerVal / denomVal : 0;
00837         }
00838 
00839         float errVal = (denomVal && (effVal <=1)) ? sqrt(effVal*(1-effVal)/denomVal) : 0;
00840 
00841         LogDebug ("DQMGenericClient") << "(iBinX, iBinY, iBinZ)  = "
00842              << iBinX << ", "
00843              << iBinY << ", "
00844              << iBinZ << "), global bin =  "  << globalBinNum
00845              << "eff = " << numerVal << "  /  " << denomVal
00846              << " =  " << effVal 
00847              << " ... setting the error for that bin ... " << endl
00848              << endl;
00849 
00850         
00851         efficiencyHist->setBinContent(globalBinNum, effVal);
00852         efficiencyHist->setBinError(globalBinNum, errVal);
00853       }
00854     }
00855   }
00856 
00857   //efficiencyHist->setMinimum(0.0);
00858   //efficiencyHist->setMaximum(1.0);
00859 }
00860 
00861 
00862 /* vim:set ts=2 sts=2 sw=2 expandtab: */