122 if (TString(key.GetName()).Contains(
"/")) {
123 cout <<
"IGNORE: " << key.GetName() <<
" contains '/'" << endl;
127 std::unique_ptr<TObject> obj(key.ReadObj());
130 TString dirName(dir.GetPath());
131 dirName.Replace(0,dirName.First(
":")+2,0);
134 TString keyPath(dirName+
"/"+key.GetName());
141 TObject* refObj =
m_refFile->Get(keyPath);
143 cout <<
"Cannot find " << keyPath <<
" in reference file" << endl;
148 if (obj->Class()!=refObj->Class()) {
149 cout << key.GetName() <<
" is of different type in file and reference file." << endl;
153 if (obj->IsA()->InheritsFrom(
"TH1")) {
154 TH1&
h = *
static_cast<TH1*
>(obj.get());
155 TH1& href = *
static_cast<TH1*
>(refObj);
176 m_can->cd(1)->SetPad(0,1,1,0.90);
177 m_can->cd(2)->SetPad(0,0.90,1,0);
178 TVirtualPad* pad =
m_can->cd(2);
181 m_can->SetName(
h.GetName());
182 m_can->SetTitle(
h.GetTitle());
186 if (href.Integral()) href.Scale(1/href.Integral());
187 if (
h.Integral())
h.Scale(1/
h.Integral());
190 Double_t
ymax = 1.05*
max(
h.GetMaximum(),href.GetMaximum());
192 h.SetLineColor(kBlue);
195 TPaveStats* st1 = (TPaveStats*)gPad->GetPrimitive(
"stats");
197 st1->SetName(
"stats1");
198 st1->SetLineColor(kBlue);
201 href.SetLineColor(kRed);
204 TPaveStats* st2 = (TPaveStats*)gPad->GetPrimitive(
"stats");
207 Double_t x1 = st1->GetX1NDC()-0.01;
208 st2->SetName(
"stats2");
209 Double_t w = st2->GetX2NDC()-st2->GetX1NDC();
212 st2->SetLineColor(kRed);
218 hdiff = (TH1*)
h.Clone();
220 if (hdiff->GetDimension()==1 &&
221 hdiff->GetNbinsX()==href.GetNbinsX()) {
224 hdiff->SetName(TString(href.GetName())+
" (diff)");
225 hdiff->SetTitle(TString(href.GetTitle())+
" (diff)");
226 hdiff->SetLineColor(kBlack);
227 hdiff->Add(&href,-1);
229 TPaveStats* st = (TPaveStats*)gPad->GetPrimitive(
"stats1");
230 if (st) st->SetLineColor(kBlack);
232 if(hdiff->GetDimension()==2 &&
233 hdiff->GetNbinsX()==href.GetNbinsX() &&
234 hdiff->GetNbinsY()==href.GetNbinsY()) {
236 hdiff->SetName(TString(href.GetName())+
" (diff)");
237 hdiff->SetTitle(TString(href.GetTitle())+
" (diff)");
238 hdiff->SetLineColor(kBlack);
239 hdiff->Add(&href,-1);
240 if(hdiff->GetXaxis()->GetLabels()!=0 && hdiff->GetNbinsX()>100) {
241 TH1 * hdiffred = (TH1*)hdiff->Clone();
242 hdiffred->GetXaxis()->GetLabels()->Delete();
244 hdiffred->SetName(TString(href.GetName())+
" (diff reduced)");
245 hdiffred->SetTitle(TString(href.GetTitle())+
" (diff reduced)");
247 for(
int x=1;
x<=hdiff->GetNbinsX(); ++
x) {
249 for(
int y=1;
y<=hdiff->GetNbinsY();++
y) {
250 if(hdiff->GetBinContent(
x,
y)!=0) { isEmpty=
false;
break; }
253 for(
int y=1;
y<=hdiff->GetNbinsY();++
y) {
254 if(hdiff->GetBinContent(
x,
y)!=0)
255 hdiffred->SetBinContent(targetbin,
y,hdiff->GetBinContent(
x,
y));
257 hdiffred->GetXaxis()->SetBinLabel(targetbin,hdiff->GetXaxis()->GetBinLabel(
x));
261 hdiffred->LabelsDeflate();
262 hdiffred->Draw(
"text");
266 TPaveStats* st = (TPaveStats*)gPad->GetPrimitive(
"stats1");
267 if (st) st->SetLineColor(kBlack);
274 text.SetTextSize(0.03);
275 text.SetTextAlign(22);
276 TString page(
"page ");
278 text.DrawTextNDC(0.5,0.03,page);
280 TString title(dir.GetName());
282 title+=href.GetName();
283 text.DrawTextNDC(0.5,0.99,title);
285 const int maxchars = 120;
287 text.SetTextColor(kBlue);
288 string s(
m_file->GetName());
289 text.DrawTextNDC(0.5,0.93,s.substr(
max(0,
int(s.size()-maxchars))).c_str());
292 text.SetTextColor(kRed);
294 text.DrawTextNDC(0.5,0.96,s.substr(
max(0,
int(s.size()-maxchars))).c_str());
305 if (hdiff)
delete hdiff;
308 else if (obj->IsA()->InheritsFrom(
"TEfficiency")) {
309 auto h =
static_cast<TEfficiency*
>(obj.get());
310 auto href =
static_cast<TEfficiency*
>(refObj);
311 Bool_t
match =
compareHist(*
h->GetTotalHistogram(),*href->GetTotalHistogram()) &&
312 compareHist(*
h->GetPassedHistogram(),*href->GetPassedHistogram());
317 else m_noMatch.push_back(keyPath.Data());
387 cout <<
"Comparing " <<
h.GetName() <<
" using ";
391 if (
verbose()) cout <<
"BIN: ";
393 if (
h.GetNbinsX()!=href.GetNbinsX() ||
394 h.GetNbinsY()!=href.GetNbinsY() ||
395 h.GetNbinsZ()!=href.GetNbinsZ()) {
396 cout <<
h.GetName() <<
" has different number of bins: ("
397 <<
h.GetNbinsX() <<
"," <<
h.GetNbinsY() <<
"," <<
h.GetNbinsZ() <<
") vs ("
398 << href.GetNbinsX() <<
"," << href.GetNbinsY() <<
"," << href.GetNbinsZ() <<
")" << endl;
402 for (Int_t
z=1;
z<=
h.GetNbinsZ() &&
result;
z++) {
403 for (Int_t
y=1;
y<=
h.GetNbinsY() &&
result;
y++) {
404 for (Int_t
x=1;
x<=
h.GetNbinsX() &&
result;
x++) {
405 Double_t binDiff = fabs(
h.GetBinContent(
x,
y,
z)-href.GetBinContent(
x,
y,
z));
414 if (
verbose()) cout <<
"AXIS: ";
415 const TAxis *xa(
h.GetXaxis()), *xaref(href.GetXaxis());
416 const TAxis *ya(
h.GetXaxis()), *yaref(href.GetXaxis());
417 const TAxis *za(
h.GetXaxis()), *zaref(href.GetXaxis());
418 if( xa->GetNbins() != xaref->GetNbins() )
result = kFALSE;
419 if(
result && (ya->GetNbins() != yaref->GetNbins()) )
result = kFALSE;
420 if(
result && (za->GetNbins() != zaref->GetNbins()) )
result = kFALSE;
424 if(
result )
for (Int_t i=0; i<=xa->GetNbins() &&
result; i++)
425 if( fabs (xa->GetBinUpEdge(i) - xaref->GetBinUpEdge(i)) >
m_threshold )
result = kFALSE;
426 if(
result )
for (Int_t i=0; i<=ya->GetNbins() &&
result; i++)
427 if( fabs (ya->GetBinUpEdge(i) - yaref->GetBinUpEdge(i)) >
m_threshold )
result = kFALSE;
428 if(
result )
for (Int_t i=0; i<=za->GetNbins() &&
result; i++)
429 if( fabs (za->GetBinUpEdge(i) - zaref->GetBinUpEdge(i)) >
m_threshold )
result = kFALSE;
432 if (
verbose()) cout <<
"CHI2: ";
435 if (
h.GetEntries()==0 && href.GetEntries()==0)
result = kTRUE;
436 else if (
h.Integral()==0 && href.Integral()==0)
result = kTRUE;
437 else if (
h.Integral()*href.Integral()==0)
result = kFALSE;
442 Double_t p =
h.Chi2TestX(&href,
chi2,ndf,igood);
444 if (ndf==0)
result = kTRUE;
450 cout <<
"ERROR: Invalid algorithm." << endl;