109 if (TString(key.GetName()).Contains(
"/")) {
110 cout <<
"IGNORE: " << key.GetName() <<
" contains '/'" << endl;
114 std::unique_ptr<TObject> obj(key.ReadObj());
117 TString dirName(dir.GetPath());
118 dirName.Replace(0,dirName.First(
":")+2,0);
121 TString keyPath(dirName+
"/"+key.GetName());
128 TObject* refObj =
m_refFile->Get(keyPath);
130 cout <<
"Cannot find " << keyPath <<
" in reference file" << endl;
135 if (obj->Class()!=refObj->Class()) {
136 cout << key.GetName() <<
" is of different type in file and reference file." << endl;
140 if (obj->IsA()->InheritsFrom(
"TH1")) {
141 TH1&
h = *
static_cast<TH1*
>(obj.get());
142 TH1& href = *
static_cast<TH1*
>(refObj);
163 m_can->cd(1)->SetPad(0,1,1,0.90);
164 m_can->cd(2)->SetPad(0,0.90,1,0);
165 TVirtualPad* pad =
m_can->cd(2);
168 m_can->SetName(
h.GetName());
169 m_can->SetTitle(
h.GetTitle());
173 if (href.Integral()) href.Scale(1/href.Integral());
174 if (
h.Integral())
h.Scale(1/
h.Integral());
177 Double_t
ymax = 1.05*
max(
h.GetMaximum(),href.GetMaximum());
179 h.SetLineColor(kBlue);
182 TPaveStats* st1 = (TPaveStats*)gPad->GetPrimitive(
"stats");
184 st1->SetName(
"stats1");
185 st1->SetLineColor(kBlue);
188 href.SetLineColor(kRed);
191 TPaveStats* st2 = (TPaveStats*)gPad->GetPrimitive(
"stats");
194 Double_t x1 = st1->GetX1NDC()-0.01;
195 st2->SetName(
"stats2");
196 Double_t w = st2->GetX2NDC()-st2->GetX1NDC();
199 st2->SetLineColor(kRed);
205 hdiff = (TH1*)
h.Clone();
207 if (hdiff->GetDimension()==1 &&
208 hdiff->GetNbinsX()==href.GetNbinsX()) {
211 hdiff->SetName(TString(href.GetName())+
" (diff)");
212 hdiff->SetTitle(TString(href.GetTitle())+
" (diff)");
213 hdiff->SetLineColor(kBlack);
214 hdiff->Add(&href,-1);
216 TPaveStats* st = (TPaveStats*)gPad->GetPrimitive(
"stats1");
217 if (st) st->SetLineColor(kBlack);
219 if(hdiff->GetDimension()==2 &&
220 hdiff->GetNbinsX()==href.GetNbinsX() &&
221 hdiff->GetNbinsY()==href.GetNbinsY()) {
223 hdiff->SetName(TString(href.GetName())+
" (diff)");
224 hdiff->SetTitle(TString(href.GetTitle())+
" (diff)");
225 hdiff->SetLineColor(kBlack);
226 hdiff->Add(&href,-1);
227 if(hdiff->GetXaxis()->GetLabels()!=0 && hdiff->GetNbinsX()>100) {
228 TH1 * hdiffred = (TH1*)hdiff->Clone();
229 hdiffred->GetXaxis()->GetLabels()->Delete();
231 hdiffred->SetName(TString(href.GetName())+
" (diff reduced)");
232 hdiffred->SetTitle(TString(href.GetTitle())+
" (diff reduced)");
234 for(
int x=1;
x<=hdiff->GetNbinsX(); ++
x) {
236 for(
int y=1;
y<=hdiff->GetNbinsY();++
y) {
237 if(hdiff->GetBinContent(
x,
y)!=0) { isEmpty=
false;
break; }
240 for(
int y=1;
y<=hdiff->GetNbinsY();++
y) {
241 if(hdiff->GetBinContent(
x,
y)!=0)
242 hdiffred->SetBinContent(targetbin,
y,hdiff->GetBinContent(
x,
y));
244 hdiffred->GetXaxis()->SetBinLabel(targetbin,hdiff->GetXaxis()->GetBinLabel(
x));
248 hdiffred->LabelsDeflate();
249 hdiffred->Draw(
"text");
253 TPaveStats* st = (TPaveStats*)gPad->GetPrimitive(
"stats1");
254 if (st) st->SetLineColor(kBlack);
261 text.SetTextSize(0.03);
262 text.SetTextAlign(22);
263 TString page(
"page ");
265 text.DrawTextNDC(0.5,0.03,page);
267 TString title(dir.GetName());
269 title+=href.GetName();
270 text.DrawTextNDC(0.5,0.99,title);
272 const int maxchars = 120;
274 text.SetTextColor(kBlue);
275 string s(
m_file->GetName());
276 text.DrawTextNDC(0.5,0.93,s.substr(
max(0,
int(s.size()-maxchars))).c_str());
279 text.SetTextColor(kRed);
281 text.DrawTextNDC(0.5,0.96,s.substr(
max(0,
int(s.size()-maxchars))).c_str());
292 if (hdiff)
delete hdiff;
295 else if (obj->IsA()->InheritsFrom(
"TEfficiency")) {
296 auto h =
static_cast<TEfficiency*
>(obj.get());
297 auto href =
static_cast<TEfficiency*
>(refObj);
298 Bool_t
match =
compareHist(*
h->GetTotalHistogram(),*href->GetTotalHistogram()) &&
299 compareHist(*
h->GetPassedHistogram(),*href->GetPassedHistogram());
304 else m_noMatch.push_back(keyPath.Data());
374 cout <<
"Comparing " <<
h.GetName() <<
" using ";
378 if (
verbose()) cout <<
"BIN: ";
380 if (
h.GetNbinsX()!=href.GetNbinsX() ||
381 h.GetNbinsY()!=href.GetNbinsY() ||
382 h.GetNbinsZ()!=href.GetNbinsZ()) {
383 cout <<
h.GetName() <<
" has different number of bins: ("
384 <<
h.GetNbinsX() <<
"," <<
h.GetNbinsY() <<
"," <<
h.GetNbinsZ() <<
") vs ("
385 << href.GetNbinsX() <<
"," << href.GetNbinsY() <<
"," << href.GetNbinsZ() <<
")" << endl;
389 for (Int_t
z=1;
z<=
h.GetNbinsZ() &&
result;
z++) {
390 for (Int_t
y=1;
y<=
h.GetNbinsY() &&
result;
y++) {
391 for (Int_t
x=1;
x<=
h.GetNbinsX() &&
result;
x++) {
392 Double_t binDiff = fabs(
h.GetBinContent(
x,
y,
z)-href.GetBinContent(
x,
y,
z));
401 if (
verbose()) cout <<
"AXIS: ";
402 const TAxis *xa(
h.GetXaxis()), *xaref(href.GetXaxis());
403 const TAxis *ya(
h.GetXaxis()), *yaref(href.GetXaxis());
404 const TAxis *za(
h.GetXaxis()), *zaref(href.GetXaxis());
405 if( xa->GetNbins() != xaref->GetNbins() )
result = kFALSE;
406 if(
result && (ya->GetNbins() != yaref->GetNbins()) )
result = kFALSE;
407 if(
result && (za->GetNbins() != zaref->GetNbins()) )
result = kFALSE;
411 if(
result )
for (Int_t i=0; i<=xa->GetNbins() &&
result; i++)
412 if( fabs (xa->GetBinUpEdge(i) - xaref->GetBinUpEdge(i)) >
m_threshold )
result = kFALSE;
413 if(
result )
for (Int_t i=0; i<=ya->GetNbins() &&
result; i++)
414 if( fabs (ya->GetBinUpEdge(i) - yaref->GetBinUpEdge(i)) >
m_threshold )
result = kFALSE;
415 if(
result )
for (Int_t i=0; i<=za->GetNbins() &&
result; i++)
416 if( fabs (za->GetBinUpEdge(i) - zaref->GetBinUpEdge(i)) >
m_threshold )
result = kFALSE;
419 if (
verbose()) cout <<
"CHI2: ";
422 if (
h.GetEntries()==0 && href.GetEntries()==0)
result = kTRUE;
423 else if (
h.Integral()==0 && href.Integral()==0)
result = kTRUE;
424 else if (
h.Integral()*href.Integral()==0)
result = kFALSE;
429 Double_t p =
h.Chi2TestX(&href,
chi2,ndf,igood);
431 if (ndf==0)
result = kTRUE;
437 cout <<
"ERROR: Invalid algorithm." << endl;