22 #include <TDirectory.h>
23 #include <TEfficiency.h>
30 #include <boost/tokenizer.hpp>
87 const bool makeProfile =
false);
110 bool ascending =
true);
144 std::set<std::string>*
myList,
156 const bool oldAddDir = TH1::AddDirectoryStatus();
157 TH1::AddDirectory(
true);
159 TH2F*
h =
me->getTH2F();
160 h->FitSlicesY(
nullptr, 0, -1, 0,
"QNR SERIAL");
161 string name(
h->GetName());
162 h0 = (TH1*)gDirectory->Get((
name +
"_0").c_str());
163 h1 = (TH1*)gDirectory->Get((
name +
"_1").c_str());
164 h2 = (TH1*)gDirectory->Get((
name +
"_2").c_str());
165 h3 = (TH1*)gDirectory->Get((
name +
"_chi2").c_str());
166 TH1::AddDirectory(oldAddDir);
179 throw cms::Exception(
"FitSlicesYTool") <<
"Pointer =0 : h1=" << h1 <<
" me=" <<
me;
180 if (h1->GetNbinsX() ==
me->getNbinsX()) {
181 for (
int bin = 0;
bin != h1->GetNbinsX();
bin++) {
182 me->setBinContent(
bin + 1, h1->GetBinContent(
bin + 1));
186 throw cms::Exception(
"FitSlicesYTool") <<
"Different number of bins!";
192 throw cms::Exception(
"FitSlicesYTool") <<
"Pointer =0 : h1=" << h1 <<
" me=" <<
me;
193 if (h2->GetNbinsX() ==
me->getNbinsX()) {
194 for (
int bin = 0;
bin != h2->GetNbinsX();
bin++) {
195 me->setBinContent(
bin + 1, h2->GetBinContent(
bin + 1));
199 throw cms::Exception(
"FitSlicesYTool") <<
"Different number of bins!";
205 throw cms::Exception(
"FitSlicesYTool") <<
"Pointer =0 : h1=" << h1 <<
" me=" <<
me;
206 if (h1->GetNbinsX() ==
me->getNbinsX()) {
207 for (
int bin = 0;
bin != h1->GetNbinsX();
bin++) {
208 me->setBinContent(
bin + 1, h1->GetBinContent(
bin + 1));
210 me->setBinError(
bin + 1, h1->GetBinError(
bin + 1));
213 throw cms::Exception(
"FitSlicesYTool") <<
"Different number of bins!";
219 throw cms::Exception(
"FitSlicesYTool") <<
"Pointer =0 : h1=" << h1 <<
" me=" <<
me;
220 if (h2->GetNbinsX() ==
me->getNbinsX()) {
221 for (
int bin = 0;
bin != h2->GetNbinsX();
bin++) {
222 me->setBinContent(
bin + 1, h2->GetBinContent(
bin + 1));
224 me->setBinError(
bin + 1, h2->GetBinError(
bin + 1));
227 throw cms::Exception(
"FitSlicesYTool") <<
"Different number of bins!";
241 : metacharacters_(
"[\\^\\$\\.\\*\\+\\?\\|\\(\\)\\{\\}\\[\\]]"), nonPerlWildcard_(
"\\w\\*|^\\*") {
242 typedef std::vector<edm::ParameterSet>
VPSet;
243 typedef std::vector<std::string>
vstring;
244 typedef boost::escaped_list_separator<char> elsc;
246 elsc commonEscapes(
"\\",
" \t",
"\'");
248 verbose_ =
pset.getUntrackedParameter<
unsigned int>(
"verbose", 0);
255 for (vstring::const_iterator effCmd = effCmds.begin(); effCmd != effCmds.end(); ++effCmd) {
259 boost::tokenizer<elsc> tokens(*effCmd, commonEscapes);
262 for (boost::tokenizer<elsc>::const_iterator iToken = tokens.begin(); iToken != tokens.end(); ++iToken) {
265 args.push_back(*iToken);
268 if (
args.size() < 4) {
269 LogInfo(
"DQMGenericClient") <<
"Wrong input to effCmds\n";
278 opt.isProfile =
false;
296 opt.name =
efficSet->getUntrackedParameter<
string>(
"name");
297 opt.title =
efficSet->getUntrackedParameter<
string>(
"title");
298 opt.numerator =
efficSet->getUntrackedParameter<
string>(
"numerator");
299 opt.denominator =
efficSet->getUntrackedParameter<
string>(
"denominator");
300 opt.isProfile =
false;
302 const string typeName =
efficSet->getUntrackedParameter<
string>(
"typeName",
"eff");
317 for (vstring::const_iterator effProfileCmd = effProfileCmds.begin(); effProfileCmd != effProfileCmds.end();
319 if (effProfileCmd->empty())
322 boost::tokenizer<elsc> tokens(*effProfileCmd, commonEscapes);
325 for (boost::tokenizer<elsc>::const_iterator iToken = tokens.begin(); iToken != tokens.end(); ++iToken) {
328 args.push_back(*iToken);
331 if (
args.size() < 4) {
332 LogInfo(
"DQMGenericClient") <<
"Wrong input to effProfileCmds\n";
341 opt.isProfile =
true;
356 VPSet effProfileSets =
pset.getUntrackedParameter<
VPSet>(
"efficiencyProfileSets",
VPSet());
357 for (VPSet::const_iterator effProfileSet = effProfileSets.begin(); effProfileSet != effProfileSets.end();
360 opt.name = effProfileSet->getUntrackedParameter<
string>(
"name");
361 opt.title = effProfileSet->getUntrackedParameter<
string>(
"title");
362 opt.numerator = effProfileSet->getUntrackedParameter<
string>(
"numerator");
363 opt.denominator = effProfileSet->getUntrackedParameter<
string>(
"denominator");
364 opt.isProfile =
true;
366 const string typeName = effProfileSet->getUntrackedParameter<
string>(
"typeName",
"eff");
381 for (vstring::const_iterator resCmd = resCmds.begin(); resCmd != resCmds.end(); ++resCmd) {
384 boost::tokenizer<elsc> tokens(*resCmd, commonEscapes);
387 for (boost::tokenizer<elsc>::const_iterator iToken = tokens.begin(); iToken != tokens.end(); ++iToken) {
390 args.push_back(*iToken);
393 if (
args.size() != 3) {
394 LogInfo(
"DQMGenericClient") <<
"Wrong input to resCmds\n";
407 for (VPSet::const_iterator resolSet = resolSets.begin(); resolSet != resolSets.end(); ++resolSet) {
409 opt.namePrefix = resolSet->getUntrackedParameter<
string>(
"namePrefix");
410 opt.titlePrefix = resolSet->getUntrackedParameter<
string>(
"titlePrefix");
411 opt.srcName = resolSet->getUntrackedParameter<
string>(
"srcName");
418 for (
const auto& profileCmd : profileCmds) {
419 boost::tokenizer<elsc> tokens(profileCmd, commonEscapes);
422 for (boost::tokenizer<elsc>::const_iterator iToken = tokens.begin(); iToken != tokens.end(); ++iToken) {
425 args.push_back(*iToken);
428 if (
args.size() != 3) {
429 LogInfo(
"DQMGenericClient") <<
"Wrong input to profileCmds\n";
442 for (
const auto& profileSet : profileSets) {
444 opt.name = profileSet.getUntrackedParameter<
string>(
"name");
445 opt.title = profileSet.getUntrackedParameter<
string>(
"title");
446 opt.srcName = profileSet.getUntrackedParameter<
string>(
"srcName");
453 for (vstring::const_iterator normCmd = normCmds.begin(); normCmd != normCmds.end(); ++normCmd) {
454 if (normCmd->empty())
456 boost::tokenizer<elsc> tokens(*normCmd, commonEscapes);
459 for (boost::tokenizer<elsc>::const_iterator iToken = tokens.begin(); iToken != tokens.end(); ++iToken) {
462 args.push_back(*iToken);
466 LogInfo(
"DQMGenericClient") <<
"Wrong input to normCmds\n";
478 for (VPSet::const_iterator normSet = normSets.begin(); normSet != normSets.end(); ++normSet) {
480 opt.name = normSet->getUntrackedParameter<
string>(
"name");
481 opt.normHistName = normSet->getUntrackedParameter<
string>(
"normalizedTo",
opt.name);
488 for (vstring::const_iterator cdCmd = cdCmds.begin(); cdCmd != cdCmds.end(); ++cdCmd) {
491 boost::tokenizer<elsc> tokens(*cdCmd, commonEscapes);
494 for (boost::tokenizer<elsc>::const_iterator iToken = tokens.begin(); iToken != tokens.end(); ++iToken) {
497 args.push_back(*iToken);
500 if (
args.empty() ||
args.size() > 2) {
501 LogInfo(
"DQMGenericClient") <<
"Wrong input to cdCmds\n";
507 opt.ascending =
args.size() == 2 ? (
args[1] !=
"descending") :
true;
513 for (VPSet::const_iterator cdSet = cdSets.begin(); cdSet != cdSets.end(); ++cdSet) {
515 opt.name = cdSet->getUntrackedParameter<
string>(
"name");
516 opt.ascending = cdSet->getUntrackedParameter<
bool>(
"ascending",
true);
523 for (vstring::const_iterator noFlowCmd = noFlowCmds.begin(); noFlowCmd != noFlowCmds.end(); ++noFlowCmd) {
524 if (noFlowCmd->empty())
526 boost::tokenizer<elsc> tokens(*noFlowCmd, commonEscapes);
529 for (boost::tokenizer<elsc>::const_iterator iToken = tokens.begin(); iToken != tokens.end(); ++iToken) {
532 args.push_back(*iToken);
535 if (
args.empty() ||
args.size() > 2) {
536 LogInfo(
"DQMGenericClient") <<
"Wrong input to noFlowCmds\n";
547 for (VPSet::const_iterator noFlowSet = noFlowSets.begin(); noFlowSet != noFlowSets.end(); ++noFlowSet) {
549 opt.name = noFlowSet->getUntrackedParameter<
string>(
"name");
599 typedef vector<string>
vstring;
602 set<string> subDirSet;
604 for (vstring::const_iterator iSubDir =
subDirs_.begin(); iSubDir !=
subDirs_.end(); ++iSubDir) {
614 const string searchPath =
subDir.substr(0, shiftPos);
625 for (set<string>::const_iterator iSubDir = subDirSet.begin(); iSubDir != subDirSet.end(); ++iSubDir) {
626 const string&
dirName = *iSubDir;
636 for (vector<NoFlowOption>::const_iterator noFlowOption =
noFlowOptions_.begin();
642 for (vector<CDOption>::const_iterator cdOption =
cdOptions_.begin(); cdOption !=
cdOptions_.end(); ++cdOption) {
653 efficOption->numerator,
654 efficOption->denominator,
656 efficOption->isProfile);
662 ibooker, igetter,
dirName, resolOption->namePrefix, resolOption->titlePrefix, resolOption->srcName);
666 computeProfile(ibooker, igetter,
dirName, profileOption.name, profileOption.title, profileOption.srcName);
673 const string& startDir,
674 const string& efficMEName,
675 const string& efficMETitle,
676 const string& recoMEName,
677 const string& simMEName,
679 const bool makeProfile) {
682 LogInfo(
"DQMGenericClient") <<
"computeEfficiency() : "
683 <<
"Cannot find sub-directory " << startDir << endl;
690 ME* simME = igetter.
get(startDir +
"/" + simMEName);
691 ME* recoME = igetter.
get(startDir +
"/" + recoMEName);
695 LogInfo(
"DQMGenericClient") <<
"computeEfficiency() : "
696 <<
"No sim-ME '" << simMEName <<
"' found\n";
703 LogInfo(
"DQMGenericClient") <<
"computeEfficiency() : "
704 <<
"No reco-ME '" << recoMEName <<
"' found\n";
711 TH1* hSim = simME->getTH1();
712 TH1* hReco = recoME->getTH1();
714 if (!hSim || !hReco) {
716 LogInfo(
"DQMGenericClient") <<
"computeEfficiency() : "
717 <<
"Cannot create TH1 from ME\n";
722 string efficDir = startDir;
723 string newEfficMEName = efficMEName;
725 if (string::npos != (shiftPos = efficMEName.rfind(
'/'))) {
726 efficDir +=
"/" + efficMEName.substr(0, shiftPos);
727 newEfficMEName.erase(0, shiftPos + 1);
732 TProfile* efficHist = (hReco->GetXaxis()->GetXbins()->GetSize() == 0)
733 ?
new TProfile(newEfficMEName.c_str(),
734 efficMETitle.c_str(),
735 hReco->GetXaxis()->GetNbins(),
736 hReco->GetXaxis()->GetXmin(),
737 hReco->GetXaxis()->GetXmax())
738 :
new TProfile(newEfficMEName.c_str(),
739 efficMETitle.c_str(),
740 hReco->GetXaxis()->GetNbins(),
741 hReco->GetXaxis()->GetXbins()->GetArray());
743 efficHist->GetXaxis()->SetTitle(hSim->GetXaxis()->GetTitle());
744 efficHist->GetYaxis()->SetTitle(hSim->GetYaxis()->GetTitle());
746 for (
int i = 1;
i <= hReco->GetNbinsX();
i++) {
747 const double nReco = hReco->GetBinContent(
i);
748 const double nSim = hSim->GetBinContent(
i);
751 efficHist->GetXaxis()->SetBinLabel(
i, hSim->GetXaxis()->GetBinLabel(
i));
753 if (nSim == 0
or nReco < 0 or nReco > nSim)
755 const double effVal = nReco / nSim;
756 const double errLo = TEfficiency::ClopperPearson(nSim, nReco, 0.683,
false);
757 const double errUp = TEfficiency::ClopperPearson(nSim, nReco, 0.683,
true);
758 const double errVal = (effVal - errLo > errUp - effVal) ? effVal - errLo : errUp - effVal;
759 efficHist->SetBinContent(
i, effVal);
760 efficHist->SetBinEntries(
i, 1);
761 efficHist->SetBinError(
i, std::hypot(effVal, errVal));
768 TH1* efficHist = (TH1*)hSim->Clone(newEfficMEName.c_str());
769 efficHist->SetTitle(efficMETitle.c_str());
774 ME* efficME =
nullptr;
778 TClass* myHistClass = efficHist->IsA();
779 TString histClassName = myHistClass->GetName();
781 if (histClassName ==
"TH1F") {
782 efficME = ibooker.
book1D(newEfficMEName, (TH1F*)efficHist);
783 }
else if (histClassName ==
"TH2F") {
784 efficME = ibooker.
book2D(newEfficMEName, (TH2F*)efficHist);
785 }
else if (histClassName ==
"TH3F") {
786 efficME = ibooker.
book3D(newEfficMEName, (TH3F*)efficHist);
792 LogInfo(
"DQMGenericClient") <<
"computeEfficiency() : "
793 <<
"Cannot book effic-ME from the DQM\n";
814 efficME->setEntries(simME->getEntries());
819 ME* globalEfficME = igetter.
get(efficDir +
"/globalEfficiencies");
821 globalEfficME = ibooker.
book1D(
"globalEfficiencies",
"Global efficiencies", 1, 0, 1);
822 if (!globalEfficME) {
823 LogInfo(
"DQMGenericClient") <<
"computeEfficiency() : "
824 <<
"Cannot book globalEffic-ME from the DQM\n";
827 globalEfficME->setEfficiencyFlag();
828 TH1F* hGlobalEffic = globalEfficME->getTH1F();
830 LogInfo(
"DQMGenericClient") <<
"computeEfficiency() : "
831 <<
"Cannot create TH1F from ME, globalEfficME\n";
835 const float nSimAll = hSim->GetEntries();
836 const float nRecoAll = hReco->GetEntries();
839 efficAll = nSimAll ? nRecoAll / nSimAll : 0;
841 efficAll = nSimAll ? 1 - nRecoAll / nSimAll : 0;
845 const float x = nRecoAll / nSimAll;
849 errorAll = nSimAll && efficAll < 1 ?
sqrt(efficAll * (1 - efficAll) / nSimAll) : 0;
851 const int iBin = hGlobalEffic->Fill(newEfficMEName.c_str(), 0);
852 hGlobalEffic->SetBinContent(iBin, efficAll);
853 hGlobalEffic->SetBinError(iBin, errorAll);
859 const string& startDir,
865 LogInfo(
"DQMGenericClient") <<
"computeResolution() : "
866 <<
"Cannot find sub-directory " << startDir << endl;
876 LogInfo(
"DQMGenericClient") <<
"computeResolution() : "
877 <<
"No source ME '" <<
srcName <<
"' found\n";
882 TH2F* hSrc = srcME->getTH2F();
885 LogInfo(
"DQMGenericClient") <<
"computeResolution() : "
886 <<
"Cannot create TH2F from source-ME\n";
891 const int nBin = hSrc->GetNbinsX();
893 string newDir = startDir;
896 if (string::npos != (shiftPos =
namePrefix.rfind(
'/'))) {
897 newDir +=
"/" +
namePrefix.substr(0, shiftPos);
898 newPrefix.erase(0, shiftPos + 1);
903 float* lowedgesfloats =
new float[
nBin + 1];
906 if (hSrc->GetXaxis()->GetXbins()->GetSize()) {
907 for (
int j = 0;
j <
nBin + 1; ++
j)
908 lowedgesfloats[
j] = (
float)hSrc->GetXaxis()->GetXbins()->GetAt(
j);
913 newPrefix +
"_Mean",
titlePrefix +
" Mean",
nBin, hSrc->GetXaxis()->GetXmin(), hSrc->GetXaxis()->GetXmax());
915 newPrefix +
"_Sigma",
titlePrefix +
" Sigma",
nBin, hSrc->GetXaxis()->GetXmin(), hSrc->GetXaxis()->GetXmax());
918 if (meanME && sigmaME) {
919 meanME->setEfficiencyFlag();
920 sigmaME->setEfficiencyFlag();
931 delete[] lowedgesfloats;
942 LogInfo(
"DQMGenericClient") <<
"computeProfile() : "
943 <<
"Cannot find sub-directory " << startDir << endl;
950 ME* srcME = igetter.
get(startDir +
"/" + srcMEName);
953 LogInfo(
"DQMGenericClient") <<
"computeProfile() : "
954 <<
"No source ME '" << srcMEName <<
"' found\n";
959 TH2F* hSrc = srcME->getTH2F();
962 LogInfo(
"DQMGenericClient") <<
"computeProfile() : "
963 <<
"Cannot create TH2F from source-ME\n";
968 string profileDir = startDir;
969 string newProfileMEName = profileMEName;
971 if (string::npos != (shiftPos = profileMEName.rfind(
'/'))) {
972 profileDir +=
"/" + profileMEName.substr(0, shiftPos);
973 newProfileMEName.erase(0, shiftPos + 1);
977 std::unique_ptr<TProfile>
profile(hSrc->ProfileX());
978 profile->SetTitle(profileMETitle.c_str());
989 LogInfo(
"DQMGenericClient") <<
"normalizeToEntries() : "
990 <<
"Cannot find sub-directory " << startDir << endl;
997 ME* element = igetter.
get(startDir +
"/" + histName);
998 ME* normME = igetter.
get(startDir +
"/" + normHistName);
1002 LogInfo(
"DQMGenericClient") <<
"normalizeToEntries() : "
1003 <<
"No such element '" << histName <<
"' found\n";
1010 LogInfo(
"DQMGenericClient") <<
"normalizeToEntries() : "
1011 <<
"No such element '" << normHistName <<
"' found\n";
1016 TH1F*
hist = element->getTH1F();
1019 LogInfo(
"DQMGenericClient") <<
"normalizeToEntries() : "
1020 <<
"Cannot create TH1F from ME\n";
1025 TH1F* normHist = normME->getTH1F();
1028 LogInfo(
"DQMGenericClient") <<
"normalizeToEntries() : "
1029 <<
"Cannot create TH1F from ME\n";
1034 const double entries = normHist->GetEntries();
1036 hist->Scale(1. / entries);
1038 LogInfo(
"DQMGenericClient") <<
"normalizeToEntries() : "
1039 <<
"Zero entries in histogram\n";
1052 LogInfo(
"DQMGenericClient") <<
"makeCumulativeDist() : "
1053 <<
"Cannot find sub-directory " << startDir << endl;
1060 ME* element_cd = igetter.
get(startDir +
"/" + cdName);
1064 LogInfo(
"DQMGenericClient") <<
"makeCumulativeDist() : "
1065 <<
"No such element '" << cdName <<
"' found\n";
1070 TH1F*
cd = element_cd->getTH1F();
1074 LogInfo(
"DQMGenericClient") <<
"makeCumulativeDist() : "
1075 <<
"Cannot create TH1F from ME\n";
1080 int n_bins =
cd->GetNbinsX() + 1;
1083 for (
int i = 1;
i <= n_bins;
i++) {
1084 cd->SetBinContent(
i,
cd->GetBinContent(
i) +
cd->GetBinContent(
i - 1));
1087 for (
int i = n_bins - 1;
i >= 0;
i--) {
1088 cd->SetBinContent(
i,
cd->GetBinContent(
i) +
cd->GetBinContent(
i + 1));
1101 LogInfo(
"DQMGenericClient") <<
"makeNoFlowDist() : "
1102 <<
"Cannot find sub-directory " << startDir << endl;
1109 ME* element_noFlow = igetter.
get(startDir +
"/" + noFlowName);
1111 if (!element_noFlow) {
1113 LogInfo(
"DQMGenericClient") <<
"makeNoFlowDist() : "
1114 <<
"No such element '" << noFlowName <<
"' found\n";
1119 TH1F* noFlow = element_noFlow->getTH1F();
1123 LogInfo(
"DQMGenericClient") <<
"makeNoFlowDist() : "
1124 <<
"Cannot create TH1F from ME\n";
1129 noFlow->AddBinContent(1, noFlow->GetBinContent(0));
1130 noFlow->SetBinContent(0, 0.);
1132 const auto lastBin = noFlow->GetNbinsX();
1133 noFlow->AddBinContent(lastBin, noFlow->GetBinContent(lastBin + 1));
1134 noFlow->SetBinContent(lastBin + 1, 0.);
1144 double cont_min = 100;
1145 Int_t binx =
histo->GetXaxis()->GetNbins();
1147 for (
int i = 1;
i <= binx;
i++) {
1149 TH1* histoY =
histo->ProjectionY(
" ",
i,
i);
1150 double cont = histoY->GetEntries();
1152 if (
cont >= cont_min) {
1153 float minfit = histoY->GetMean() - histoY->GetRMS();
1154 float maxfit = histoY->GetMean() + histoY->GetRMS();
1156 TF1* fitFcn =
new TF1(TString(
"g") +
histo->GetName() + iString,
"gaus", minfit, maxfit);
1158 fitFcn->GetRange(
x1,
x2);
1160 histoY->Fit(fitFcn,
"QR0 SERIAL",
"",
x1,
x2);
1163 double* par = fitFcn->GetParameters();
1164 const double*
err = fitFcn->GetParErrors();
1193 std::set<std::string>*
myList,
1194 const TString& _pattern = TString(
"")) {
1197 LogError(
"DQMGenericClient") <<
" DQMGenericClient::findAllSubdirectories ==> Missing folder " <<
dir <<
" !!!";
1202 pattern.ReplaceAll(
"*",
".*");
1205 vector<string> foundDirs = igetter.
getSubdirs();
1206 for (vector<string>::const_iterator iDir = foundDirs.begin(); iDir != foundDirs.end(); ++iDir) {
1207 TString
dirName = iDir->substr(iDir->rfind(
'/') + 1, iDir->length());
1222 LogInfo(
"DQMGenericClient") <<
"Trying to find sub-directories of " <<
dir <<
" failed because " <<
dir
1223 <<
" does not exist";
1229 for (
int iBinX = 1; iBinX <
denom->GetNbinsX() + 1; iBinX++) {
1230 for (
int iBinY = 1; iBinY <
denom->GetNbinsY() + 1; iBinY++) {
1231 for (
int iBinZ = 1; iBinZ <
denom->GetNbinsZ() + 1; iBinZ++) {
1232 int globalBinNum =
denom->GetBin(iBinX, iBinY, iBinZ);
1234 float numerVal = numer->GetBinContent(globalBinNum);
1235 float denomVal =
denom->GetBinContent(globalBinNum);
1241 effVal = denomVal ? (1 - numerVal / denomVal) : 0;
1243 effVal = denomVal ? numerVal / denomVal : 0;
1249 float numerErr = numer->GetBinError(globalBinNum);
1250 float denomErr =
denom->GetBinError(globalBinNum);
1251 float denomsq = denomVal * denomVal;
1252 errVal = denomVal ?
sqrt(
pow(1.
f / denomVal * numerErr, 2.0) +
pow(numerVal / denomsq * denomErr, 2)) : 0;
1254 errVal = (denomVal && (effVal <= 1)) ?
sqrt(effVal * (1 - effVal) / denomVal) : 0;
1257 LogDebug(
"DQMGenericClient") <<
"(iBinX, iBinY, iBinZ) = " << iBinX <<
", " << iBinY <<
", " << iBinZ
1258 <<
"), global bin = " << globalBinNum <<
"eff = " << numerVal <<
" / "
1259 << denomVal <<
" = " << effVal <<
" ... setting the error for that bin ... "
1264 efficiencyHist->
setBinError(globalBinNum, errVal);