26 #include <boost/tokenizer.hpp>
33 TPRegexp
metacharacters(
"[\\^\\$\\.\\*\\+\\?\\|\\(\\)\\{\\}\\[\\]]");
38 typedef std::vector<edm::ParameterSet> VPSet;
39 typedef std::vector<std::string>
vstring;
40 typedef boost::escaped_list_separator<char> elsc;
42 elsc commonEscapes(
"\\",
" \t",
"\'");
47 vstring effCmds = pset.
getParameter<vstring>(
"efficiency");
48 for ( vstring::const_iterator effCmd = effCmds.begin();
49 effCmd != effCmds.end(); ++effCmd )
51 if ( effCmd->empty() )
continue;
53 boost::tokenizer<elsc>
tokens(*effCmd, commonEscapes);
56 for(boost::tokenizer<elsc>::const_iterator iToken = tokens.begin();
57 iToken != tokens.end(); ++iToken) {
58 if ( iToken->empty() )
continue;
59 args.push_back(*iToken);
62 if ( args.size() < 4 ) {
63 LogInfo(
"DQMGenericClient") <<
"Wrong input to effCmds\n";
74 const string typeName = args.size() == 4 ?
"eff" : args[4];
75 if ( typeName ==
"eff" ) opt.
type = 1;
76 else if ( typeName ==
"fake" ) opt.
type = 2;
79 efficOptions_.push_back(opt);
83 for ( VPSet::const_iterator
efficSet = efficSets.begin();
87 opt.
name =
efficSet->getUntrackedParameter<
string>(
"name");
93 const string typeName =
efficSet->getUntrackedParameter<
string>(
"typeName",
"eff");
94 if ( typeName ==
"eff" ) opt.
type = 1;
95 else if ( typeName ==
"fake" ) opt.
type = 2;
98 efficOptions_.push_back(opt);
103 for ( vstring::const_iterator profileCmd = profileCmds.begin();
104 profileCmd != profileCmds.end(); ++profileCmd )
106 if ( profileCmd->empty() )
continue;
108 boost::tokenizer<elsc>
tokens(*profileCmd, commonEscapes);
111 for(boost::tokenizer<elsc>::const_iterator iToken = tokens.begin();
112 iToken != tokens.end(); ++iToken) {
113 if ( iToken->empty() )
continue;
114 args.push_back(*iToken);
117 if ( args.size() < 4 ) {
118 LogInfo(
"DQMGenericClient") <<
"Wrong input to profileCmds\n";
129 const string typeName = args.size() == 4 ?
"eff" : args[4];
130 if ( typeName ==
"eff" ) opt.
type = 1;
131 else if ( typeName ==
"fake" ) opt.
type = 2;
134 efficOptions_.push_back(opt);
138 for ( VPSet::const_iterator profileSet = profileSets.begin();
139 profileSet != profileSets.end(); ++profileSet )
142 opt.
name = profileSet->getUntrackedParameter<
string>(
"name");
143 opt.
title = profileSet->getUntrackedParameter<
string>(
"title");
144 opt.
numerator = profileSet->getUntrackedParameter<
string>(
"numerator");
145 opt.
denominator = profileSet->getUntrackedParameter<
string>(
"denominator");
148 const string typeName = profileSet->getUntrackedParameter<
string>(
"typeName",
"eff");
149 if ( typeName ==
"eff" ) opt.
type = 1;
150 else if ( typeName ==
"fake" ) opt.
type = 2;
153 efficOptions_.push_back(opt);
157 vstring resCmds = pset.
getParameter<vstring>(
"resolution");
158 for ( vstring::const_iterator resCmd = resCmds.begin();
159 resCmd != resCmds.end(); ++resCmd )
161 if ( resCmd->empty() )
continue;
162 boost::tokenizer<elsc>
tokens(*resCmd, commonEscapes);
165 for(boost::tokenizer<elsc>::const_iterator iToken = tokens.begin();
166 iToken != tokens.end(); ++iToken) {
167 if ( iToken->empty() )
continue;
168 args.push_back(*iToken);
171 if ( args.size() != 3 ) {
172 LogInfo(
"DQMGenericClient") <<
"Wrong input to resCmds\n";
181 resolOptions_.push_back(opt);
185 for ( VPSet::const_iterator resolSet = resolSets.begin();
186 resolSet != resolSets.end(); ++resolSet )
189 opt.
namePrefix = resolSet->getUntrackedParameter<
string>(
"namePrefix");
190 opt.
titlePrefix = resolSet->getUntrackedParameter<
string>(
"titlePrefix");
191 opt.
srcName = resolSet->getUntrackedParameter<
string>(
"srcName");
193 resolOptions_.push_back(opt);
198 for ( vstring::const_iterator normCmd = normCmds.begin();
199 normCmd != normCmds.end(); ++normCmd )
201 if ( normCmd->empty() )
continue;
202 boost::tokenizer<elsc>
tokens(*normCmd, commonEscapes);
205 for(boost::tokenizer<elsc>::const_iterator iToken = tokens.begin();
206 iToken != tokens.end(); ++iToken) {
207 if ( iToken->empty() )
continue;
208 args.push_back(*iToken);
211 if ( args.empty()
or args.size() > 2 ) {
212 LogInfo(
"DQMGenericClient") <<
"Wrong input to normCmds\n";
218 opt.
normHistName = args.size() == 2 ? args[1] : args[0];
220 normOptions_.push_back(opt);
224 for ( VPSet::const_iterator normSet = normSets.begin();
225 normSet != normSets.end(); ++normSet )
228 opt.
name = normSet->getUntrackedParameter<
string>(
"name");
229 opt.
normHistName = normSet->getUntrackedParameter<
string>(
"normalizedTo", opt.
name);
231 normOptions_.push_back(opt);
236 for ( vstring::const_iterator cdCmd = cdCmds.begin();
237 cdCmd != cdCmds.end(); ++cdCmd )
239 if ( cdCmd->empty() )
continue;
240 boost::tokenizer<elsc>
tokens(*cdCmd, commonEscapes);
243 for(boost::tokenizer<elsc>::const_iterator iToken = tokens.begin();
244 iToken != tokens.end(); ++iToken) {
245 if ( iToken->empty() )
continue;
246 args.push_back(*iToken);
249 if ( args.size() != 1 ) {
250 LogInfo(
"DQMGenericClient") <<
"Wrong input to cdCmds\n";
257 cdOptions_.push_back(opt);
261 for ( VPSet::const_iterator cdSet = cdSets.begin();
262 cdSet != cdSets.end(); ++cdSet )
265 opt.
name = cdSet->getUntrackedParameter<
string>(
"name");
267 cdOptions_.push_back(opt);
274 isWildcardUsed_ =
false;
279 typedef vector<string>
vstring;
295 LogInfo(
"DQMGenericClient") <<
"Cannot create DQMStore instance\n";
300 set<string> subDirSet;
302 for(vstring::const_iterator iSubDir = subDirs_.begin();
303 iSubDir != subDirs_.end(); ++iSubDir) {
304 string subDir = *iSubDir;
306 if ( subDir[subDir.size()-1] ==
'/' ) subDir.erase(subDir.size()-1);
309 isWildcardUsed_ =
true;
312 const string searchPath = subDir.substr(0, shiftPos);
313 const string pattern = subDir.substr(shiftPos + 1, subDir.length());
316 findAllSubdirectories (searchPath, &subDirSet, pattern);
320 subDirSet.insert(subDir);
324 for(set<string>::const_iterator iSubDir = subDirSet.begin();
325 iSubDir != subDirSet.end(); ++iSubDir) {
326 const string&
dirName = *iSubDir;
328 for ( vector<EfficOption>::const_iterator efficOption = efficOptions_.begin();
329 efficOption != efficOptions_.end(); ++efficOption )
331 computeEfficiency(dirName, efficOption->name, efficOption->title,
332 efficOption->numerator, efficOption->denominator,
333 efficOption->type, efficOption->isProfile);
336 for ( vector<ResolOption>::const_iterator resolOption = resolOptions_.begin();
337 resolOption != resolOptions_.end(); ++resolOption )
339 computeResolution(dirName, resolOption->namePrefix, resolOption->titlePrefix, resolOption->srcName);
342 for ( vector<NormOption>::const_iterator normOption = normOptions_.begin();
343 normOption != normOptions_.end(); ++normOption )
345 normalizeToEntries(dirName, normOption->name, normOption->normHistName);
348 for ( vector<CDOption>::const_iterator cdOption = cdOptions_.begin();
349 cdOption != cdOptions_.end(); ++cdOption )
351 makeCumulativeDist(dirName, cdOption->name);
357 if ( ! outputFileName_.empty() ) theDQM->save(outputFileName_);
367 LogTrace (
"DQMGenericClient") <<
"inside of DQMGenericClient::endJob()"
373 const string& recoMEName,
const string& simMEName,
const int type,
const bool makeProfile)
375 if ( ! theDQM->dirExists(startDir) ) {
376 if ( verbose_ >= 2 || (verbose_ == 1 && !isWildcardUsed_) ) {
377 LogInfo(
"DQMGenericClient") <<
"computeEfficiency() : "
378 <<
"Cannot find sub-directory " << startDir << endl;
385 ME* simME = theDQM->get(startDir+
"/"+simMEName);
386 ME* recoME = theDQM->get(startDir+
"/"+recoMEName);
389 if ( verbose_ >= 2 || (verbose_ == 1 && !isWildcardUsed_) ) {
390 LogInfo(
"DQMGenericClient") <<
"computeEfficiency() : "
391 <<
"No sim-ME '" << simMEName <<
"' found\n";
397 if ( verbose_ >= 2 || (verbose_ == 1 && !isWildcardUsed_) ) {
398 LogInfo(
"DQMGenericClient") <<
"computeEfficiency() : "
399 <<
"No reco-ME '" << recoMEName <<
"' found\n";
406 TH1* hSim = simME ->getTH1();
407 TH1* hReco = recoME->getTH1();
409 if ( !hSim || !hReco ) {
410 if ( verbose_ >= 2 || (verbose_ == 1 && !isWildcardUsed_) ) {
411 LogInfo(
"DQMGenericClient") <<
"computeEfficiency() : "
412 <<
"Cannot create TH1 from ME\n";
417 string efficDir = startDir;
418 string newEfficMEName = efficMEName;
420 if ( string::npos != (shiftPos = efficMEName.rfind(
'/')) ) {
421 efficDir +=
"/"+efficMEName.substr(0, shiftPos);
422 newEfficMEName.erase(0, shiftPos+1);
424 theDQM->setCurrentFolder(efficDir);
427 TProfile * efficHist = (hReco->GetXaxis()->GetXbins()->GetSize()==0) ?
428 new TProfile(newEfficMEName.c_str(), efficMETitle.c_str(),
429 hReco->GetXaxis()->GetNbins(),
430 hReco->GetXaxis()->GetXmin(),
431 hReco->GetXaxis()->GetXmax()) :
432 new TProfile(newEfficMEName.c_str(), efficMETitle.c_str(),
433 hReco->GetXaxis()->GetNbins(),
434 hReco->GetXaxis()->GetXbins()->GetArray());
435 #if ROOT_VERSION_CODE >= ROOT_VERSION(5,27,0)
436 for (
int i=1;
i <= hReco->GetNbinsX();
i++) {
437 const double nReco = hReco->GetBinContent(
i);
438 const double nSim = hSim->GetBinContent(
i);
440 if ( nSim == 0 || nReco > nSim )
continue;
441 const double effVal = nReco/nSim;
443 const double errLo = TEfficiency::ClopperPearson((
int)hSim->GetBinContent(
i),
444 (int)hReco->GetBinContent(
i),
446 const double errUp = TEfficiency::ClopperPearson((
int)hSim->GetBinContent(
i),
447 (int)hReco->GetBinContent(
i),
449 const double errVal = (effVal - errLo > errUp - effVal) ? effVal - errLo : errUp - effVal;
450 efficHist->SetBinContent(
i, effVal);
451 efficHist->SetBinEntries(
i, 1);
452 efficHist->SetBinError(
i,
sqrt(effVal * effVal + errVal * errVal));
455 for (
int i=1;
i <= hReco->GetNbinsX();
i++) {
456 TGraphAsymmErrorsWrapper asymm;
457 std::pair<double, double> efficiencyWithError;
458 efficiencyWithError = asymm.efficiency((
int)hReco->GetBinContent(
i),
459 (int)hSim->GetBinContent(
i));
460 double effVal = efficiencyWithError.first;
461 double errVal = efficiencyWithError.second;
462 if ((
int)hSim->GetBinContent(
i) > 0) {
463 efficHist->SetBinContent(
i, effVal);
464 efficHist->SetBinEntries(
i, 1);
465 efficHist->SetBinError(
i,
sqrt(effVal * effVal + errVal * errVal));
469 theDQM->bookProfile(newEfficMEName.c_str(),efficHist);
475 TH1* efficHist = (TH1*)hSim->Clone(newEfficMEName.c_str());
476 efficHist->SetTitle(efficMETitle.c_str());
485 TClass * myHistClass = efficHist->IsA();
486 TString histClassName = myHistClass->GetName();
488 if (histClassName ==
"TH1F"){
489 efficME = theDQM->book1D(newEfficMEName, (TH1F*)efficHist);
490 }
else if (histClassName ==
"TH2F"){
491 efficME = theDQM->book2D(newEfficMEName, (TH2F*)efficHist);
492 }
else if (histClassName ==
"TH3F"){
493 efficME = theDQM->book3D(newEfficMEName, (TH3F*)efficHist);
498 LogInfo(
"DQMGenericClient") <<
"computeEfficiency() : "
499 <<
"Cannot book effic-ME from the DQM\n";
507 generic_eff (hSim, hReco, efficME, type);
520 efficME->setEntries(simME->getEntries());
525 ME* globalEfficME = theDQM->get(efficDir+
"/globalEfficiencies");
526 if ( !globalEfficME ) globalEfficME = theDQM->book1D(
"globalEfficiencies",
"Global efficiencies", 1, 0, 1);
527 if ( !globalEfficME ) {
528 LogInfo(
"DQMGenericClient") <<
"computeEfficiency() : "
529 <<
"Cannot book globalEffic-ME from the DQM\n";
532 TH1F* hGlobalEffic = globalEfficME->getTH1F();
533 if ( !hGlobalEffic ) {
534 LogInfo(
"DQMGenericClient") <<
"computeEfficiency() : "
535 <<
"Cannot create TH1F from ME, globalEfficME\n";
539 const float nSimAll = hSim->GetEntries();
540 const float nRecoAll = hReco->GetEntries();
542 if ( type == 1 ) efficAll = nSimAll ? nRecoAll/nSimAll : 0;
543 else if ( type == 2 ) efficAll = nSimAll ? 1-nRecoAll/nSimAll : 0;
544 const float errorAll = nSimAll && efficAll < 1 ?
sqrt(efficAll*(1-efficAll)/nSimAll) : 0;
546 const int iBin = hGlobalEffic->Fill(newEfficMEName.c_str(), 0);
547 hGlobalEffic->SetBinContent(iBin, efficAll);
548 hGlobalEffic->SetBinError(iBin, errorAll);
552 const std::string& srcName)
554 if ( ! theDQM->dirExists(startDir) ) {
555 if ( verbose_ >= 2 || (verbose_ == 1 && !isWildcardUsed_) ) {
556 LogInfo(
"DQMGenericClient") <<
"computeResolution() : "
557 <<
"Cannot find sub-directory " << startDir << endl;
564 ME* srcME = theDQM->get(startDir+
"/"+srcName);
566 if ( verbose_ >= 2 || (verbose_ == 1 && !isWildcardUsed_) ) {
567 LogInfo(
"DQMGenericClient") <<
"computeResolution() : "
568 <<
"No source ME '" << srcName <<
"' found\n";
573 TH2F* hSrc = srcME->getTH2F();
575 if ( verbose_ >= 2 || (verbose_ == 1 && !isWildcardUsed_) ) {
576 LogInfo(
"DQMGenericClient") <<
"computeResolution() : "
577 <<
"Cannot create TH2F from source-ME\n";
582 const int nBin = hSrc->GetNbinsX();
583 const double xMin = hSrc->GetXaxis()->GetXmin();
584 const double xMax = hSrc->GetXaxis()->GetXmax();
586 string newDir = startDir;
587 string newPrefix = namePrefix;
589 if ( string::npos != (shiftPos = namePrefix.rfind(
'/')) ) {
590 newDir +=
"/"+namePrefix.substr(0, shiftPos);
591 newPrefix.erase(0, shiftPos+1);
594 theDQM->setCurrentFolder(newDir);
596 ME* meanME = theDQM->book1D(newPrefix+
"_Mean", titlePrefix+
" Mean", nBin, xMin, xMax);
597 ME* sigmaME = theDQM->book1D(newPrefix+
"_Sigma", titlePrefix+
" Sigma", nBin, xMin, xMax);
600 if (! resLimitedFit_ ) {
606 limitedFit(srcME,meanME,sigmaME);
612 if ( ! theDQM->dirExists(startDir) ) {
613 if ( verbose_ >= 2 || (verbose_ == 1 && !isWildcardUsed_) ) {
614 LogInfo(
"DQMGenericClient") <<
"normalizeToEntries() : "
615 <<
"Cannot find sub-directory " << startDir << endl;
622 ME* element = theDQM->get(startDir+
"/"+histName);
623 ME* normME = theDQM->get(startDir+
"/"+normHistName);
626 if ( verbose_ >= 2 || (verbose_ == 1 && !isWildcardUsed_) ) {
627 LogInfo(
"DQMGenericClient") <<
"normalizeToEntries() : "
628 <<
"No such element '" << histName <<
"' found\n";
634 if ( verbose_ >= 2 || (verbose_ == 1 && !isWildcardUsed_) ) {
635 LogInfo(
"DQMGenericClient") <<
"normalizeToEntries() : "
636 <<
"No such element '" << normHistName <<
"' found\n";
641 TH1F*
hist = element->getTH1F();
643 if ( verbose_ >= 2 || (verbose_ == 1 && !isWildcardUsed_) ) {
644 LogInfo(
"DQMGenericClient") <<
"normalizeToEntries() : "
645 <<
"Cannot create TH1F from ME\n";
650 TH1F* normHist = normME->getTH1F();
652 if ( verbose_ >= 2 || (verbose_ == 1 && !isWildcardUsed_) ) {
653 LogInfo(
"DQMGenericClient") <<
"normalizeToEntries() : "
654 <<
"Cannot create TH1F from ME\n";
659 const double entries = normHist->GetEntries();
660 if ( entries != 0 ) {
661 hist->Scale(1./entries);
664 LogInfo(
"DQMGenericClient") <<
"normalizeToEntries() : "
665 <<
"Zero entries in histogram\n";
673 if ( ! theDQM->dirExists(startDir) ) {
674 if ( verbose_ >= 2 || (verbose_ == 1 && !isWildcardUsed_) ) {
675 LogInfo(
"DQMGenericClient") <<
"makeCumulativeDist() : "
676 <<
"Cannot find sub-directory " << startDir << endl;
683 ME* element_cd = theDQM->get(startDir+
"/"+cdName);
686 if ( verbose_ >= 2 || (verbose_ == 1 && !isWildcardUsed_) ) {
687 LogInfo(
"DQMGenericClient") <<
"makeCumulativeDist() : "
688 <<
"No such element '" << cdName <<
"' found\n";
693 TH1F* cd = element_cd->getTH1F();
696 if ( verbose_ >= 2 || (verbose_ == 1 && !isWildcardUsed_) ) {
697 LogInfo(
"DQMGenericClient") <<
"makeCumulativeDist() : "
698 <<
"Cannot create TH1F from ME\n";
703 int n_bins = cd->GetNbinsX() + 1;
705 for (
int i = 1;
i <= n_bins;
i++) {
706 cd->SetBinContent(
i,cd->GetBinContent(
i) + cd->GetBinContent(
i-1));
720 double cont_min = 100;
721 Int_t binx = histo->GetXaxis()->GetNbins();
723 for (
int i = 1; i <= binx ; i++) {
725 TH1 *histoY = histo->ProjectionY(
" ", i, i);
726 double cont = histoY->GetEntries();
728 if (cont >= cont_min) {
729 float minfit = histoY->GetMean() - histoY->GetRMS();
730 float maxfit = histoY->GetMean() + histoY->GetRMS();
732 TF1 *fitFcn =
new TF1(TString(
"g")+histo->GetName()+iString,
"gaus",minfit,maxfit);
734 fitFcn->GetRange(x1,x2);
736 histoY->Fit(fitFcn,
"QR0",
"",x1,x2);
739 double *
par = fitFcn->GetParameters();
740 double *err = fitFcn->GetParErrors();
747 if(fitFcn)
delete fitFcn;
748 if(histoY)
delete histoY;
751 if(histoY)
delete histoY;
765 vector <string> foundDirs = theDQM->getSubdirs();
766 for(vector<string>::const_iterator iDir = foundDirs.begin();
767 iDir != foundDirs.end(); ++iDir) {
768 TString
dirName = iDir->substr(iDir->rfind(
'/') + 1, iDir->length());
769 if (dirName.Contains(regexp))
770 findAllSubdirectories ( *iDir, myList);
774 else if (theDQM->dirExists(dir)){
779 findAllSubdirectories (dir, myList,
"*");
783 LogInfo (
"DQMGenericClient") <<
"Trying to find sub-directories of " << dir
784 <<
" failed because " << dir <<
" does not exist";
792 for (
int iBinX = 1; iBinX < denom->GetNbinsX()+1; iBinX++){
793 for (
int iBinY = 1; iBinY < denom->GetNbinsY()+1; iBinY++){
794 for (
int iBinZ = 1; iBinZ < denom->GetNbinsZ()+1; iBinZ++){
796 int globalBinNum = denom->GetBin(iBinX, iBinY, iBinZ);
798 float numerVal = numer->GetBinContent(globalBinNum);
799 float denomVal = denom->GetBinContent(globalBinNum);
805 effVal = denomVal ? (1 - numerVal / denomVal) : 0;
807 effVal = denomVal ? numerVal / denomVal : 0;
810 float errVal = (denomVal && (effVal <=1)) ?
sqrt(effVal*(1-effVal)/denomVal) : 0;
812 LogDebug (
"DQMGenericClient") <<
"(iBinX, iBinY, iBinZ) = "
815 << iBinZ <<
"), global bin = " << globalBinNum
816 <<
"eff = " << numerVal <<
" / " << denomVal
818 <<
" ... setting the error for that bin ... " << endl
T getParameter(std::string const &) const
T getUntrackedParameter(std::string const &, T const &) const
void setBinContent(int binx, double content)
set content of bin (1-D)
The Signals That Services Can Subscribe To This is based on ActivityRegistry and is current per Services can connect to the signals distributed by the ActivityRegistry in order to monitor the activity of the application Each possible callback has some defined which we here list in angle e< void, edm::EventIDconst &, edm::Timestampconst & > We also list in braces which AR_WATCH_USING_METHOD_ is used for those or
std::vector< std::string > vstring
TPRegexp metacharacters("[\\^\\$\\.\\*\\+\\?\\|\\(\\)\\{\\}\\[\\]]")
void endRun(const edm::Run &r, const edm::EventSetup &c)
EndRun.
void makeCumulativeDist(const std::string &startDir, const std::string &cdName)
void findAllSubdirectories(std::string dir, std::set< std::string > *myList, TString pattern)
void computeResolution(const std::string &startDir, const std::string &fitMEPrefix, const std::string &fitMETitlePrefix, const std::string &srcMEName)
void setBinError(int binx, double error)
set uncertainty on content of bin (1-D)
TPRegexp nonPerlWildcard("\\w\\*|^\\*")
void computeEfficiency(const std::string &startDir, const std::string &efficMEName, const std::string &efficMETitle, const std::string &recoMEName, const std::string &simMEName, const int type=1, const bool makeProfile=false)
DQMGenericClient(const edm::ParameterSet &pset)
TH2F * getTH2F(void) const
void normalizeToEntries(const std::string &startDir, const std::string &histName, const std::string &normHistName)
void limitedFit(MonitorElement *srcME, MonitorElement *meanME, MonitorElement *sigmaME)
void generic_eff(TH1 *denom, TH1 *numer, MonitorElement *efficiencyHist, const int type=1)
const double par[8 *NPar][4]