17Bool_t IsBinOverflow(
const TH1& hist, Int_t
bin)
20 Int_t binx, biny, binz;
21 hist.GetBinXYZ(
bin, binx, biny, binz);
22 Int_t
dim =
hist.GetDimension();
25 return binx >=
hist.GetNbinsX() + 1;
27 return (binx >=
hist.GetNbinsX() + 1) ||
28 (biny >=
hist.GetNbinsY() + 1);
30 return (binx >=
hist.GetNbinsX() + 1) ||
31 (biny >=
hist.GetNbinsY() + 1) ||
32 (binz >=
hist.GetNbinsZ() + 1);
37Bool_t IsBinUnderflow(
const TH1& hist, Int_t
bin)
41 Int_t binx, biny, binz;
42 hist.GetBinXYZ(
bin, binx, biny, binz);
43 Int_t
dim =
hist.GetDimension();
48 return (binx <= 0 || biny <= 0);
50 return (binx <= 0 || biny <= 0 || binz <= 0);
62 Int_t dim = hist.GetDimension();
64 return (hist.GetNbinsX()+2);
67 return (hist.GetNbinsX()+2)*(hist.GetNbinsY()+2);
70 return (hist.GetNbinsX()+2)*(hist.GetNbinsY()+2)*(hist.GetNbinsZ()+2);
89 for (
int ix = 1; ix <=
a.GetNbinsX(); ix++){
90 for (
int iy = 1; iy <=
a.GetNbinsY(); iy++){
93 float efficiencyA =
a.GetBinContent(ix,iy)/100.;
94 float efficiencyB = b.GetBinContent(ix,iy)/100.;
95 float efficiencyErrA =
a.GetBinError(ix,iy)/100.;
96 float efficiencyErrB = b.GetBinError(ix,iy)/100.;
99 if (efficiencyErrA != 0 && efficiencyA != 0 && denA == 0) denA = efficiencyA*(1-efficiencyA)/efficiencyErrA/efficiencyErrA;
100 if (efficiencyErrB != 0 && efficiencyB != 0 && denB == 0) denB = efficiencyB*(1-efficiencyB)/efficiencyErrB/efficiencyErrB;
104 float denTot = denA + denB;
105 const double nEntries =
a.GetEntries() + b.GetEntries();
107 for (
int ix = 1; ix <=
a.GetNbinsX(); ix++){
108 for (
int iy = 1; iy <=
a.GetNbinsY(); iy++){
111 float efficiencyA =
a.GetBinContent(ix,iy)/100.;
112 float efficiencyB = b.GetBinContent(ix,iy)/100.;
117 float numA = denA * efficiencyA;
118 float numB = denB * efficiencyB;
121 float numTot = numA + numB;
122 float efficiencyTot = 0.;
123 float efficiencyErrTot = 0.;
125 if (denTot != 0.) efficiencyTot = numTot/denTot*100.;
126 if (denTot != 0.) efficiencyErrTot = std::sqrt(numTot*denTot*(denTot-numTot))/denTot/denTot*100.;
128 a.SetBinContent(ix,iy,efficiencyTot);
129 a.SetBinError(ix,iy,efficiencyErrTot);
132 a.SetEntries( nEntries );
149 constexpr double OneSigOneSided = 0.159;
151 if (
a.GetDimension() != b.GetDimension()) {
152 std::cerr<<
"merge_perBinEffPerCent \""<<
a.GetName() <<
"\": attempt to merge histograms of different dimensionality" << std::endl;
159 std::cerr<<
"merge_perBinEffPerCent \""<<
a.GetName() <<
"\": attempt to merge histograms of different sizes\n";
164 a.SetCanExtend(TH1::kNoAxis);
166 const double nEntries =
a.GetEntries() + b.GetEntries();
168 for(
int bin = 0;
bin < ncells;
bin++ ) {
169 if (IsBinUnderflow(
a,
bin) || IsBinOverflow(
a,
bin))
continue;
170 float efficiencyA =
a.GetBinContent(
bin)/100.;
171 float efficiencyB = b.GetBinContent(
bin)/100.;
172 float efficiencyErrA =
a.GetBinError(
bin)/100.;
173 float efficiencyErrB = b.GetBinError(
bin)/100.;
175 float efficiencyTot = 0.;
176 float efficiencyErrTot = 0.;
177 if ( efficiencyErrA == 0. ) {
178 efficiencyTot = efficiencyB;
179 efficiencyErrTot = efficiencyErrB;
182 if ( efficiencyErrB == 0. ) {
183 efficiencyTot = efficiencyA;
184 efficiencyErrTot = efficiencyErrA;
188 if ( efficiencyA == 0. ){
189 denomA = std::log(OneSigOneSided)/std::log(1.-efficiencyErrA);
192 if ( efficiencyA > 0.99) {
193 denomA = std::log(OneSigOneSided)/std::log(1.-efficiencyErrA);
196 denomA = efficiencyA*(1.-efficiencyA)/(efficiencyErrA*efficiencyErrA);
201 if ( efficiencyB == 0. ){
202 denomB = std::log(OneSigOneSided)/std::log(1.-efficiencyErrB);
205 if ( efficiencyB > 0.99) {
206 denomB = std::log(OneSigOneSided)/std::log(1.-efficiencyErrB);
209 denomB = efficiencyB*(1.-efficiencyB)/(efficiencyErrB*efficiencyErrB);
213 float denom = denomA + denomB;
214 efficiencyTot = (denomA*efficiencyA + denomB*efficiencyB)/denom;
215 efficiencyErrTot = std::sqrt(efficiencyTot*(1.-efficiencyTot)/denom);
216 if ( efficiencyTot == 0. ) efficiencyErrTot = 1.0-std::pow(OneSigOneSided,1.0/denom);
217 if ( efficiencyTot > 0.99 ) efficiencyErrTot = 1.0-std::pow(OneSigOneSided,1.0/denom);
220 a.SetBinContent(
bin,efficiencyTot*100.);
221 a.SetBinError(
bin,efficiencyErrTot*100.);
223 a.SetEntries( nEntries );
236 if (
a.GetDimension() != b.GetDimension()) {
237 std::cerr<<
"merge_effAsPerCentAlt \"" <<
a.GetName() <<
"\": attempt to merge histograms of different dimensionality\n";
244 std::cerr<<
"merge_effAsPerCentAlt \""<<
a.GetName() <<
"\": attempt to merge histograms of different bin counts\n";
249 a.SetCanExtend(TH1::kNoAxis);
258 for(
int bin = 0;
bin < ncells;
bin++ ) {
259 if (IsBinUnderflow(
a,
bin) || IsBinOverflow(
a,
bin))
continue;
262 float efficiencyA =
a.GetBinContent(
bin)/100.;
263 float efficiencyB = b.GetBinContent(
bin)/100.;
264 float efficiencyErrA =
a.GetBinError(
bin)/100.;
265 float efficiencyErrB = b.GetBinError(
bin)/100.;
268 if (efficiencyErrA != 0 && efficiencyA != 0 && denA == 0) denA = efficiencyA*(1-efficiencyA)/efficiencyErrA/efficiencyErrA;
269 if (efficiencyErrB != 0 && efficiencyB != 0 && denB == 0) denB = efficiencyB*(1-efficiencyB)/efficiencyErrB/efficiencyErrB;
272 float denTot = denA + denB;
273 const double nEntries =
a.GetEntries() + b.GetEntries();
275 for(
int bin = 0;
bin < ncells;
bin++ ) {
276 if (IsBinUnderflow(
a,
bin) || IsBinOverflow(
a,
bin))
continue;
279 float efficiencyA =
a.GetBinContent(
bin)/100.;
280 float efficiencyB = b.GetBinContent(
bin)/100.;
285 float numA = denA * efficiencyA;
286 float numB = denB * efficiencyB;
289 float numTot = numA + numB;
290 float efficiencyTot = 0.;
291 float efficiencyErrTot = 0.;
293 if (denTot != 0.) efficiencyTot = numTot/denTot*100.;
294 if (denTot != 0.) efficiencyErrTot = std::sqrt(numTot*denTot*(denTot-numTot))/denTot/denTot*100.;
296 a.SetBinContent(
bin,efficiencyTot);
297 a.SetBinError(
bin,efficiencyErrTot);
299 a.SetEntries( nEntries );
308 if (
a.GetDimension() != b.GetDimension()) {
309 std::cerr<<
"merge_weightedAverage \"" <<
a.GetName() <<
"\": attempt to merge histograms of different dimensionality\n";
316 std::cerr<<
"merge_weightedAverage \"" <<
a.GetName() <<
"\": attempt to merge histograms of different sizes\n";
321 a.SetCanExtend(TH1::kNoAxis);
323 double nEntries =
a.GetEntries();
324 nEntries += b.GetEntries();
327 for(
int bin = 0;
bin < ncells;
bin++ ) {
328 double y1 =
a.GetBinContent(
bin);
329 double y2 = b.GetBinContent(
bin);
330 double e1 =
a.GetBinError(
bin);
331 double e2 = b.GetBinError(
bin);
332 double w1 = 1., w2 = 1.;
333 if (e1 > 0) w1 = 1./(e1*e1);
334 if (e2 > 0) w2 = 1./(e2*e2);
337 if (e1 > 0 && e2 > 0){
338 a.SetBinContent(
bin, (w1*y1 + w2*y2)/(w1 + w2));
339 a.SetBinError(
bin, 1./std::sqrt(w1 + w2));
343 a.SetBinContent(
bin, y2);
344 a.SetBinError(
bin, e2);
348 a.SetBinContent(
bin, y1);
349 a.SetBinError(
bin, e1);
353 a.SetBinContent(
bin, (y1 + y2)/2.);
354 a.SetBinError(
bin, 0.);
358 a.SetEntries( nEntries );
383 for(
int binx = 0; binx <=
a.GetNbinsX()+1; binx++ ) {
384 for(
int biny = 0; biny <=
a.GetNbinsY()+1; biny++ ) {
386 int bin =
a.GetBin(binx,biny);
388 double y1 =
a.GetBinContent(
bin);
389 double y2 = b.GetBinContent(
bin);
390 double e1 =
a.GetBinError(
bin);
391 double e2 = b.GetBinError(
bin);
392 double w1 = 1., w2 = 1.;
393 if (e1 > 0) w1 = 1./(e1*e1);
394 if (e2 > 0) w2 = 1./(e2*e2);
397 if (e1 > 0 && e2 > 0){
398 a.SetBinContent(
bin, (w1*y1 + w2*y2)/(w1 + w2));
399 a.SetBinError(
bin, 1./std::sqrt(w1 + w2));
403 a.SetBinContent(
bin, y2);
404 a.SetBinError(
bin, e2);
408 a.SetBinContent(
bin, y1);
409 a.SetBinError(
bin, e1);
413 a.SetBinContent(
bin, (y1 + y2)/2.);
414 a.SetBinError(
bin, 0.);
434 double entries_a =
a.GetEntries();
435 double entries_b = b.GetEntries();
437 double weight_a = 0.0;
438 double weight_b = 0.0;
440 if (
a.GetDimension() != b.GetDimension()) {
441 std::cerr<<
"merge_weightedEff \""<<
a.GetName()<<
"\": attempt to merge histograms of different dimensionality\n";
446 bool sumw2 = (
a.GetSumw2N() != 0) && (b.GetSumw2N() != 0);
451 std::cerr<<
"merge_weightedEff \""<<
a.GetName() <<
"\": attempt to merge histograms of different sizes\n";
455 if (entries_b == 0) {
459 if (entries_a == 0) {
466 a.SetCanExtend(TH1::kNoAxis);
468 if (entries_a + entries_b > 0)
470 weight_a = entries_a / (entries_a + entries_b);
471 weight_b = entries_b / (entries_a + entries_b);
473 for(
int bin = 0;
bin < ncells;
bin++ ) {
474 double binContent_a =
a.GetBinContent(
bin);
475 double binContent_b = b.GetBinContent(
bin);
479 double binError_a =
a.GetBinError(
bin);
480 double binError_b = b.GetBinError(
bin);
483 float weightedEff = binContent_a * weight_a + binContent_b * weight_b;
484 a.SetBinContent(
bin, weightedEff);
487 float weightedError = std::sqrt( std::pow(binError_a * weight_a,2) + std::pow(binError_b * weight_b,2) );
488 a.SetBinError(
bin, weightedError);
495 if (!sumw2) (
a.GetSumw2())->Set(0);
497 a.SetEntries(entries_a + entries_b);
515 if(
a.InheritsFrom(
"TProfile2D") && b.InheritsFrom(
"TProfile2D") &&
a.GetDimension()==b.GetDimension()) {
516 auto binsFunc = [](TH1&
h,
int ax) {
517 if(ax==0)
return h.GetNbinsX();
518 if(ax==1)
return h.GetNbinsY();
519 if(ax==2)
return h.GetNbinsZ();
522 for(
int i=0;i<
a.GetDimension();i++) {
523 int n1 = binsFunc(
a,i);
524 int n2 = binsFunc(b,i);
525 if ((n1 == 0) or (n2 == 0)) {
526 throw std::runtime_error(
"MonitoringFile::merge_Rebinned; nbins is zero.");
528 if((n2 % n1 == 0) && std::bitset<
sizeof(
int)>(n2/n1).
count()==1) {
529 while(binsFunc(
a,i) != binsFunc(b,i)) {
530 a.LabelsInflate((i==0) ?
"x" : ( (i==1) ?
"y" :
"z"));
532 }
else if((n1 % n2 == 0) && std::bitset<
sizeof(
int)>(n1/n2).
count()==1) {
533 while(binsFunc(
a,i) != binsFunc(b,i)) {
534 b.LabelsInflate((i==0) ?
"x" : ( (i==1) ?
"y" :
"z"));
541 TList *list =
new TList;
555 int nbinsx =
a.GetNbinsX();
556 int nbinsy =
a.GetNbinsY();
557 if (b.GetNbinsX() != nbinsx || b.GetNbinsY() != nbinsy)
return;
559 for(
int biny = 1; biny <= nbinsy; biny++ ) {
560 for(
int binx = 1; binx <= nbinsx; binx++ ) {
561 double bVal = b.GetBinContent(binx, biny);
562 if (bVal == 0)
break;
563 for(
int binxa = 1; binxa <= nbinsx; binxa++ ) {
564 double aVal =
a.GetBinContent(binxa, biny);
566 a.SetBinContent(binxa, biny, bVal);
569 }
else if (bVal < aVal) {
570 for(
int bx = nbinsx; bx > binxa; bx-- ) {
571 double v1 =
a.GetBinContent(bx-1, biny);
572 if (v1 == 0)
continue;
573 double v2 =
a.GetBinContent(bx, biny);
575 a.SetBinContent(bx, biny, v1);
577 a.SetBinContent(binxa, biny, bVal);
579 }
else if (aVal == bVal)
break;
594 if (
a.GetDimension() != b.GetDimension()) {
595 std::cerr<<
"merge_RMS \""<<
a.GetName() <<
"\": attempt to merge histograms of different dimensionality\n";
602 std::cerr<<
"merge_RMS \""<<
a.GetName() <<
"\": attempt to merge histograms of different sizes\n";
607 a.SetCanExtend(TH1::kNoAxis);
609 double nEntries =
a.GetEntries();
610 nEntries += b.GetEntries();
612 for(
int bin = 0;
bin < ncells;
bin++ ) {
613 double rms1 =
a.GetBinContent(
bin);
614 double rms2 = b.GetBinContent(
bin);
615 double e1 =
a.GetBinError(
bin);
616 double e2 = b.GetBinError(
bin);
622 n1 = std::pow( rms1 / e1, 2) / 2;
625 n2 = std::pow( rms2 / e2, 2) / 2;
628 double ntot = n1 + n2;
630 a.SetBinContent(
bin, std::sqrt( (rms1*rms1) + (rms2*rms2) ) );
631 a.SetBinError(
bin, std::sqrt( (e1*e1) + (e2*e2) ) );
634 double rmstot = std::sqrt( ( (std::pow(n1 * rms1,2) / (n1 - 1)) + (std::pow(n2 * rms2, 2) / (n2 - 1)) ) * (ntot - 1) / std::pow(ntot,2) );
635 a.SetBinContent(
bin, rmstot );
636 a.SetBinError(
bin, rmstot / std::sqrt( 2 * ntot ) );
640 a.SetEntries(nEntries);
657 if (
a.GetDimension() != b.GetDimension()) {
658 std::cerr<<
"merge_RMSpercentDeviation \"" <<
a.GetName() <<
"\": attempt to merge histograms of different dimensionality\n";
665 std::cerr<<
"merge_RMSpercentDeviation \"" <<
a.GetName() <<
"\": attempt to merge histograms of different sizes\n";
669 double nEntries =
a.GetEntries();
670 nEntries += b.GetEntries();
672 for(
int bin = 0;
bin < ncells;
bin++ ) {
673 double y1 =
a.GetBinContent(
bin) + 100;
674 double y2 = b.GetBinContent(
bin) + 100;
675 double e1 =
a.GetBinError(
bin);
676 double e2 = b.GetBinError(
bin);
682 n1 =
pow( y1 / e1, 2) / 2;
685 n2 =
pow( y2 / e2, 2) / 2;
688 double ntot = n1 + n2;
690 a.SetBinContent(
bin, std::sqrt( (y1*y1) + (y2*y2) ) - 100 );
691 a.SetBinError(
bin, std::sqrt( (e1*e1) + (e2*e2) ) );
694 double ytot = std::sqrt( ( (std::pow(n1 * y1,2) / (n1 - 1)) + (std::pow(n2 * y2, 2) / (n2 - 1)) ) * (ntot - 1) / std::pow(ntot,2) );
695 a.SetBinContent(
bin, ytot - 100);
696 a.SetBinError(
bin, ytot / std::sqrt( 2 * ntot ) );
700 a.SetEntries(nEntries);
714 if (
a.GetDimension() != b.GetDimension()) {
715 std::cerr<<
"merge_lowerLB \"" <<
a.GetName() <<
"\": attempt to merge histograms of different dimensionality\n";
722 std::cerr<<
"merge_lowerLB \"" <<
a.GetName() <<
"\": attempt to merge histograms of different sizes\n";
727 a.SetCanExtend(TH1::kNoAxis);
729 if (strcmp(
a.GetTitle(),b.GetTitle())>0){
732 a.SetTitle(b.GetTitle());
763 if (
a.GetDimension() != b.GetDimension()) {
764 std::cerr<<
"merge_identical \"" <<
a.GetName() <<
"\": attempt to merge histograms of different dimensionality\n";
771 std::cerr<<
"merge_identical \"" <<
a.GetName() <<
"\": attempt to merge histograms of different sizes\n";
776 for (Int_t icell = 0; icell < ncells; ++icell) {
777 if ((
a.GetBinContent(icell) != b.GetBinContent(icell))
778 || (
a.GetBinError(icell) != b.GetBinError(icell))) {
779 std::cerr<<
"merge_identical \"" <<
a.GetName() <<
"\" and \"" << b.GetName() <<
"\" have different content\n";
constexpr int pow(int base, int exp) noexcept
Header file for AthHistogramAlgorithm.
static void merge_identical(TH1 &a, const TH1 &b)
static void merge_weightedAverage(TH1 &a, const TH1 &b)
static void merge_effAsPerCentAlt(TH1 &a, const TH1 &b)
static void merge_RMS(TH1 &a, const TH1 &b)
static void merge_eventSample(TH2 &a, const TH2 &b)
static void merge_RMSpercentDeviation(TH1 &a, const TH1 &b)
static void merge_weightedAverage2D(TH2 &a, const TH2 &b)
static void merge_lowerLB(TH1 &a, const TH1 &b)
static Int_t getNumBins(const TH1 &hist)
static void merge_weightedEff(TH1 &a, const TH1 &b)
static void merge_perBinEffPerCent(TH1 &a, const TH1 &b)
static void merge_Rebinned(TH1 &a, TH1 &b)
static void merge_effAsPerCent(TH2 &a, const TH2 &b)
int count(std::string s, const std::string ®x)
count how many occurances of a regx are in a string