ATLAS Offline Software
Loading...
Searching...
No Matches
TRootCompare Class Reference

Class to compare the histograms in two root files. More...

#include <TRootCompare.h>

Inheritance diagram for TRootCompare:
Collaboration diagram for TRootCompare:

Public Types

enum  ALG { BIN , CHI2 , AXIS }

Public Member Functions

 TRootCompare ()
virtual ~TRootCompare ()
virtual void processKey (TDirectory &dir, TKey &key)
 Method called for every key.
virtual void beginJob ()
virtual void endJob ()
Bool_t setReferenceFile (const char *filename, const char *baseDir=0)
Bool_t setOutputFile (const char *filename)
Bool_t setPsFile (const char *filename)
void setAlg (TRootCompare::ALG alg, Double_t threshold)
void drawNormalized (Bool_t norm=kTRUE)
void drawDiff (Bool_t diff=kTRUE)
void sortLabels (Bool_t sort=kTRUE)
Int_t matchingHist () const
Int_t totalHist () const
Int_t missingHist () const
virtual Int_t run (const char *filename, const char *rootDir=0)
 Start processing.

Private Member Functions

Bool_t compareHist (const TH1 &h, const TH1 &href)
void sortAndDeflate (TH1 &h)
void createDirectory (TFile *f, const char *dirpath)
void printCanvas (const char *filename)

Private Attributes

TFile * m_refFile
TFile * m_outFile
TString m_refRootDir
TString m_psFile
TCanvas * m_can
ALG m_alg
Double_t m_threshold
Int_t m_histMatch
Int_t m_histTotal
Int_t m_histMissing
Bool_t m_drawNormalized
Bool_t m_drawDiff
Bool_t m_sortLabels
std::vector< std::string > m_noMatch

Processing hooks

virtual void beforeFile ()
virtual void afterFile ()
virtual void beforeDir ()
virtual void afterDir ()
virtual void beforeObj ()
virtual void afterObj ()
void setDirsToSkip (const char *skipDirs)
 Skip this comma separated list of directories.
void addFailRegexp (const char *regexp)
 Skip keys that match this regexp.
void addPassRegexp (const char *regexp)
 Never skip keys that match this regexp.
void passBeforeFailRegexp (Bool_t passBeforeFail=kTRUE)
 Reverse pass/fail logic. First check on pass then on fail.
void setVerbose (Bool_t verbose=kTRUE)
 Set verbose mode.
Bool_t verbose () const
 Query verbose mode.
const TFile * file () const
 Current ROOT file.
TString rootDir () const
 Current directory.
TFile * m_file {nullptr}
TString m_rootDir
TString m_skipDirs
Bool_t m_verbose {kFALSE}
Bool_t m_passBeforeFail {kFALSE}
Int_t m_errorCode {0}
std::vector< TPRegexp > m_failRE
std::vector< TPRegexp > m_passRE
std::vector< std::string > m_skippedObjects
TString getPathFromDir (const TDirectory &dir)
TString getKeyPath (const TDirectory &dir, const TKey &key)
void processDir (TDirectory &dir)
void processFile (const char *filename, const char *rootDir=0)
Bool_t skipDir (const TDirectory &dir)
Bool_t skipObject (const char *name)
TString getDrawOptions (const TH1 &h)

Detailed Description

Class to compare the histograms in two root files.

Author
Frank Winklmeier

Compare histograms in two root files. Statistics of differences is printed as well as a PS file with histograms overlayed.

Definition at line 28 of file TRootCompare.h.

Member Enumeration Documentation

◆ ALG

Enumerator
BIN 
CHI2 
AXIS 

Definition at line 30 of file TRootCompare.h.

Constructor & Destructor Documentation

◆ TRootCompare()

TRootCompare::TRootCompare ( )

Definition at line 35 of file TRootCompare.cxx.

35 :
36 m_refFile(0),
37 m_outFile(0),
38 m_refRootDir(""),
39 m_psFile(""),
40 m_can(0),
41 m_alg(BIN),
42 m_threshold(1e-6),
43 m_histMatch(0),
44 m_histTotal(0),
46 m_drawNormalized(kFALSE),
47 m_drawDiff(kTRUE)
48{
49}
TString m_refRootDir
TFile * m_outFile
Int_t m_histTotal
TFile * m_refFile
TCanvas * m_can
Double_t m_threshold
Bool_t m_drawNormalized
Int_t m_histMatch
Bool_t m_drawDiff
TString m_psFile
Int_t m_histMissing

◆ ~TRootCompare()

TRootCompare::~TRootCompare ( )
virtual

Definition at line 51 of file TRootCompare.cxx.

52{
53 delete m_refFile;
54}

Member Function Documentation

◆ addFailRegexp()

void TFileLooper::addFailRegexp ( const char * regexp)
inherited

Skip keys that match this regexp.

Definition at line 160 of file TFileLooper.cxx.

161{
162 if (regexp) {
163 m_failRE.emplace_back(regexp);
164 }
165}
std::vector< TPRegexp > m_failRE
Definition TFileLooper.h:96

◆ addPassRegexp()

void TFileLooper::addPassRegexp ( const char * regexp)
inherited

Never skip keys that match this regexp.

Definition at line 169 of file TFileLooper.cxx.

170{
171 if (regexp) {
172 m_passRE.emplace_back(regexp);
173 }
174}
std::vector< TPRegexp > m_passRE
Definition TFileLooper.h:97

◆ afterDir()

virtual void TFileLooper::afterDir ( )
inlinevirtualinherited

Definition at line 59 of file TFileLooper.h.

59{}

◆ afterFile()

virtual void TFileLooper::afterFile ( )
inlinevirtualinherited

Definition at line 57 of file TFileLooper.h.

57{}

◆ afterObj()

virtual void TFileLooper::afterObj ( )
inlinevirtualinherited

Definition at line 61 of file TFileLooper.h.

61{}

◆ beforeDir()

virtual void TFileLooper::beforeDir ( )
inlinevirtualinherited

Definition at line 58 of file TFileLooper.h.

58{}

◆ beforeFile()

virtual void TFileLooper::beforeFile ( )
inlinevirtualinherited

Definition at line 56 of file TFileLooper.h.

56{}

◆ beforeObj()

virtual void TFileLooper::beforeObj ( )
inlinevirtualinherited

Definition at line 60 of file TFileLooper.h.

60{}

◆ beginJob()

void TRootCompare::beginJob ( )
virtual

Reimplemented from TFileLooper.

Definition at line 56 of file TRootCompare.cxx.

57{
58 m_histMatch = 0;
59 m_histTotal = 0;
60 m_histMissing = 0;
61
62 Int_t canvasWidth = 1000;
63 Int_t canvasHeight = 580;
64
65 if (!m_drawDiff) canvasWidth = canvasHeight;
66
67 m_can = new TCanvas("can","can",canvasWidth,canvasHeight);
68 if (m_psFile!="") printCanvas(m_psFile+"[");
69}
void printCanvas(const char *filename)

◆ compareHist()

Bool_t TRootCompare::compareHist ( const TH1 & h,
const TH1 & href )
private

Definition at line 382 of file TRootCompare.cxx.

383{
384 Bool_t result = kTRUE;
385
386 if (verbose()) {
387 cout << "Comparing " << h.GetName() << " using ";
388 }
389
391 if (verbose()) cout << "BIN: ";
392
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;
399 }
400
401 // This will work for histograms of all dimensions
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));
406 if (binDiff>m_threshold) {
407 result = kFALSE;
408 }
409 }
410 }
411 }
412 }
413 else if (m_alg==TRootCompare::AXIS) {
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;
421 if( result && (fabs( xa->GetBinLowEdge(0) - xaref->GetBinLowEdge(0) ) > m_threshold ) ) result = kFALSE;
422 if( result && (fabs( ya->GetBinLowEdge(0) - yaref->GetBinLowEdge(0) ) > m_threshold ) ) result = kFALSE;
423 if( result && (fabs( za->GetBinLowEdge(0) - zaref->GetBinLowEdge(0) ) > m_threshold ) ) 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;
430 }
431 else if (m_alg==TRootCompare::CHI2) {
432 if (verbose()) cout << "CHI2: ";
433
434 // Don't compare empty histograms
435 if (h.GetEntries()==0 && href.GetEntries()==0) result = kTRUE; // both empty
436 else if (h.Integral()==0 && href.Integral()==0) result = kTRUE; // both empty
437 else if (h.Integral()*href.Integral()==0) result = kFALSE; // one empty
438 else {
439 Double_t chi2;
440 Int_t igood;
441 Int_t ndf;
442 Double_t p = h.Chi2TestX(&href,chi2,ndf,igood);
443 // this is because of a bug in root
444 if (ndf==0) result = kTRUE;
445 else if (p>m_threshold) result = kTRUE;
446 else result = kFALSE;
447 }
448 }
449 else {
450 cout << "ERROR: Invalid algorithm." << endl;
451 }
452
453 if (verbose()) cout << result << endl;
454 return result;
455}
#define y
#define x
#define z
Bool_t verbose() const
Query verbose mode.
Definition TFileLooper.h:80
double chi2(TH1 *h0, TH1 *h1)

◆ createDirectory()

void TRootCompare::createDirectory ( TFile * f,
const char * dirpath )
private

Definition at line 471 of file TRootCompare.cxx.

472{
473 if ((f==0) || (dirpath==0)) return;
474
475 f->cd();
476 TString s(dirpath);
477 TObjArray* a = s.Tokenize("/");
478 for (int i=0; i<a->GetEntries(); i++) {
479 const char* dir = a->At(i)->GetName();
480 if (gDirectory->GetDirectory(dir)==0) gDirectory->mkdir(dir); // create if it doesn't exist
481 gDirectory->cd(dir);
482 }
483
484}
static Double_t a

◆ drawDiff()

void TRootCompare::drawDiff ( Bool_t diff = kTRUE)
inline

Definition at line 47 of file TRootCompare.h.

47{ m_drawDiff = diff; }
void diff(const Jet &rJet1, const Jet &rJet2, std::map< std::string, double > varDiff)
Difference between jets - Non-Class function required by trigger.
Definition Jet.cxx:631

◆ drawNormalized()

void TRootCompare::drawNormalized ( Bool_t norm = kTRUE)
inline

Definition at line 46 of file TRootCompare.h.

◆ endJob()

void TRootCompare::endJob ( )
virtual

Reimplemented from TFileLooper.

Definition at line 71 of file TRootCompare.cxx.

72{
73 cout << endl;
74 cout << "Summary:" << endl;
75 cout << "========" << endl;
76 cout << "Total histograms compared: " << m_histTotal << endl;
77 cout << "Missing references: " << m_histMissing << endl;
78 cout << "Matching histograms: " << m_histMatch << endl;
79 cout << "Different histograms: " << m_histTotal-m_histMatch << endl;
80 cout << "Ignored histograms: " << m_skippedObjects.size() << endl;
81
83 cout << "List of different histograms:" << endl;
84 vector<string>::iterator iter;
85 int i = 0;
86 for (iter=m_noMatch.begin(); iter!=m_noMatch.end(); ++iter) {
87 i++;
88 cout << setw(2) << i << ") " << *iter << endl;
89 }
90 }
91
92 if (verbose() && !m_skippedObjects.empty()) {
93 cout << endl << "List of ignored histograms:" << endl;
94 vector<string>::iterator iter;
95 int i = 0;
96 for (iter=m_skippedObjects.begin(); iter!=m_skippedObjects.end(); ++iter) {
97 i++;
98 cout << setw(2) << i << ") " << *iter << endl;
99 }
100 }
101 cout << endl;
102
103 if (m_outFile) {
104 cout << "Comparison results written to " << m_outFile->GetName() << endl;
105 delete m_outFile;
106 }
107
108 if (m_psFile!="") {
110 cout << "Comparison results written to " << m_psFile << endl;
111 }
112
113 delete m_can;
114}
std::vector< std::string > m_skippedObjects
Definition TFileLooper.h:99
std::vector< std::string > m_noMatch

◆ file()

const TFile * TFileLooper::file ( ) const
inlineinherited

Current ROOT file.

Definition at line 83 of file TFileLooper.h.

83{ return m_file; }
TFile * m_file
Definition TFileLooper.h:89

◆ getDrawOptions()

TString TFileLooper::getDrawOptions ( const TH1 & h)
protectedinherited

◆ getKeyPath()

TString TFileLooper::getKeyPath ( const TDirectory & dir,
const TKey & key )
protectedinherited

Definition at line 188 of file TFileLooper.cxx.

189{
190 TString s(dir.GetPath()+TString("/")+key.GetName());
191 // Remove all chars from beginning including ":/"
192 s.Replace(0,s.First(":")+2,0);
193
194 return s;
195}

◆ getPathFromDir()

TString TFileLooper::getPathFromDir ( const TDirectory & dir)
protectedinherited

Definition at line 178 of file TFileLooper.cxx.

179{
180 TString s(dir.GetPath());
181 if (s.Index("../")==0) s.Remove(0,3);
182 s.ReplaceAll(":","");
183 return s;
184}

◆ matchingHist()

Int_t TRootCompare::matchingHist ( ) const
inline

Definition at line 50 of file TRootCompare.h.

50{ return m_histMatch; }

◆ missingHist()

Int_t TRootCompare::missingHist ( ) const
inline

Definition at line 52 of file TRootCompare.h.

52{ return m_histMissing; }

◆ passBeforeFailRegexp()

void TFileLooper::passBeforeFailRegexp ( Bool_t passBeforeFail = kTRUE)
inlineinherited

Reverse pass/fail logic. First check on pass then on fail.

Definition at line 74 of file TFileLooper.h.

74{ m_passBeforeFail = passBeforeFail; }
Bool_t m_passBeforeFail
Definition TFileLooper.h:93

◆ printCanvas()

void TRootCompare::printCanvas ( const char * filename)
private

Definition at line 370 of file TRootCompare.cxx.

371{
372 if (m_can==0) return;
373 if (filename==0) return;
374
375 if (TString(filename).EndsWith(".ps"))
376 m_can->Print(filename,"Landscape");
377 else
378 m_can->Print(filename);
379}

◆ processDir()

void TFileLooper::processDir ( TDirectory & dir)
protectedinherited

Definition at line 73 of file TFileLooper.cxx.

74{
75 TString s(getPathFromDir(dir));
76
77 if (skipDir(dir)) {
78 cout << "Skipping " << s << endl;
79 return;
80 }
81
82 if (m_verbose) cout << "Reading directory "<< dir.GetPath() << endl;
83
84 // Sort directory content
85 TList* dirList = dir.GetListOfKeys();
86 dirList->Sort();
87
88 TIter next(dirList);
89 TKey* key;
90 while ((key = (TKey*)next())) {
91 // if (skipObject(getKeyPath(dir,*key))) continue;
92
93 TString className(key->GetClassName());
94 if (className=="TDirectoryFile" || className=="TDirectory") {
95 dir.cd(key->GetName());
96 beforeDir();
97 processDir(*gDirectory);
98 afterDir();
99 }
100 else {
101 if (skipObject(getKeyPath(dir,*key))) {
102 m_skippedObjects.push_back(getKeyPath(dir,*key).Data());
103 continue;
104 }
105 processKey(dir, *key);
106 }
107 }
108}
@ Data
Definition BaseObject.h:11
void processDir(TDirectory &dir)
TString getKeyPath(const TDirectory &dir, const TKey &key)
Bool_t m_verbose
Definition TFileLooper.h:92
virtual void beforeDir()
Definition TFileLooper.h:58
Bool_t skipObject(const char *name)
Bool_t skipDir(const TDirectory &dir)
TString getPathFromDir(const TDirectory &dir)
virtual void afterDir()
Definition TFileLooper.h:59
virtual void processKey(TDirectory &dir, TKey &key)
Method called for every key.

◆ processFile()

void TFileLooper::processFile ( const char * filename,
const char * rootDir = 0 )
protectedinherited

Definition at line 44 of file TFileLooper.cxx.

45{
46 m_file = new TFile(filename);
47 if (m_file->IsZombie()) {
48 cout << "Cannot open "<<filename << endl;
49 m_errorCode = 1;
50 delete m_file;
51 return;
52 }
53
54 if (rootDir) {
55 if (!m_file->cd(rootDir)) {
56 cout << "Cannot change to directory " << rootDir << endl;
57 m_errorCode = 1;
58 return;
59 }
61 }
62 else m_file->cd();
63
64 beforeFile();
65 processDir(*gDirectory);
66 afterFile();
67
68 delete m_file; // calls Close()
69}
virtual void afterFile()
Definition TFileLooper.h:57
TString m_rootDir
Definition TFileLooper.h:90
TString rootDir() const
Current directory.
Definition TFileLooper.h:86
virtual void beforeFile()
Definition TFileLooper.h:56
Int_t m_errorCode
Definition TFileLooper.h:94

◆ processKey()

void TRootCompare::processKey ( TDirectory & dir,
TKey & key )
virtual

Method called for every key.

Only dummy implementation. Needs to be implemented in derived classes.

Reimplemented from TFileLooper.

Definition at line 116 of file TRootCompare.cxx.

117{
118 dir.cd();
119
120 if (m_refFile==0) return;
121
122 if (TString(key.GetName()).Contains("/")) {
123 cout << "IGNORE: " << key.GetName() << " contains '/'" << endl;
124 return;
125 }
126
127 std::unique_ptr<TObject> obj(key.ReadObj());
128
129 // Extract directory name
130 TString dirName(dir.GetPath());
131 dirName.Replace(0,dirName.First(":")+2,0);
132 if (rootDir()!="") dirName.ReplaceAll(rootDir(),m_refRootDir);
133 else dirName = m_refRootDir+"/"+dirName;
134 TString keyPath(dirName+"/"+key.GetName());
135
136 if (!m_refFile->cd(dirName)) { // could not cd() into directory of histogram
138 return;
139 }
140
141 TObject* refObj = m_refFile->Get(keyPath);
142 if (!refObj) { // histogram not found
143 cout << "Cannot find " << keyPath << " in reference file" << endl;
145 return;
146 }
147
148 if (obj->Class()!=refObj->Class()) { // class types do not agree
149 cout << key.GetName() << " is of different type in file and reference file." << endl;
150 return;
151 }
152
153 if (obj->IsA()->InheritsFrom("TH1")) {
154 TH1& h = *static_cast<TH1*>(obj.get());
155 TH1& href = *static_cast<TH1*>(refObj);
156
157 // For alphanumeric axes, sort and deflate
158 if (m_sortLabels) {
160 sortAndDeflate(href);
161 }
162
163 Bool_t match = compareHist(h,href);
164 m_histTotal++;
165 if (match) {
166 m_histMatch++;
167 }
168 else { // histograms do not match
169 m_noMatch.push_back(keyPath.Data());
170
171 // Skip drawing if no output was requested
172 if (!m_outFile && m_psFile.Length()==0) return;
173
174 m_can->Clear();
175 m_can->Divide(2,1);
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);
179
180 if (m_drawDiff) pad->Divide(2,1);
181 m_can->SetName(h.GetName());
182 m_can->SetTitle(h.GetTitle());
183 // Overlayed
184 pad->cd(1);
185 if (m_drawNormalized) {
186 if (href.Integral()) href.Scale(1/href.Integral());
187 if (h.Integral()) h.Scale(1/h.Integral());
188 }
189
190 Double_t ymax = 1.05*max(h.GetMaximum(),href.GetMaximum());
191 h.SetMaximum(ymax);
192 h.SetLineColor(kBlue);
193 h.Draw();
194 m_can->Update();
195 TPaveStats* st1 = (TPaveStats*)gPad->GetPrimitive("stats");
196 if (st1) {
197 st1->SetName("stats1");
198 st1->SetLineColor(kBlue);
199 }
200
201 href.SetLineColor(kRed);
202 href.Draw("sames");
203 m_can->Update();
204 TPaveStats* st2 = (TPaveStats*)gPad->GetPrimitive("stats");
205 if (st1 && st2) {
206 // Move stat box
207 Double_t x1 = st1->GetX1NDC()-0.01;
208 st2->SetName("stats2");
209 Double_t w = st2->GetX2NDC()-st2->GetX1NDC();
210 st2->SetX1NDC(x1-w);
211 st2->SetX2NDC(x1);
212 st2->SetLineColor(kRed);
213 m_can->Modified();
214 }
215
216 TH1* hdiff = 0;
217 if (m_drawDiff) {
218 hdiff = (TH1*)h.Clone();
219 // Too many problems with difference of 2D histograms
220 if (hdiff->GetDimension()==1 &&
221 hdiff->GetNbinsX()==href.GetNbinsX()) {
222 // Difference
223 pad->cd(2);
224 hdiff->SetName(TString(href.GetName())+" (diff)");
225 hdiff->SetTitle(TString(href.GetTitle())+" (diff)");
226 hdiff->SetLineColor(kBlack);
227 hdiff->Add(&href,-1);
228 hdiff->Draw();
229 TPaveStats* st = (TPaveStats*)gPad->GetPrimitive("stats1");
230 if (st) st->SetLineColor(kBlack);
231 }
232 if(hdiff->GetDimension()==2 &&
233 hdiff->GetNbinsX()==href.GetNbinsX() &&
234 hdiff->GetNbinsY()==href.GetNbinsY()) {
235 pad->cd(2);
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();
243 hdiffred->Reset();
244 hdiffred->SetName(TString(href.GetName())+" (diff reduced)");
245 hdiffred->SetTitle(TString(href.GetTitle())+" (diff reduced)");
246 int targetbin=1;
247 for(int x=1; x<=hdiff->GetNbinsX(); ++x) {
248 bool isEmpty(true);
249 for(int y=1;y<=hdiff->GetNbinsY();++y) {
250 if(hdiff->GetBinContent(x,y)!=0) { isEmpty=false; break; }
251 }
252 if(!isEmpty) {
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));
256 }
257 hdiffred->GetXaxis()->SetBinLabel(targetbin,hdiff->GetXaxis()->GetBinLabel(x));
258 targetbin++;
259 }
260 }
261 hdiffred->LabelsDeflate();
262 hdiffred->Draw("text");
263 } else {
264 hdiff->Draw("text");
265 }
266 TPaveStats* st = (TPaveStats*)gPad->GetPrimitive("stats1");
267 if (st) st->SetLineColor(kBlack);
268 }
269 }
270
271 // Some more cosmetics before saving to ps file
272 m_can->cd(0);
273 TText text;
274 text.SetTextSize(0.03);
275 text.SetTextAlign(22);
276 TString page("page ");
277 page += m_noMatch.size();
278 text.DrawTextNDC(0.5,0.03,page);
279
280 TString title(dir.GetName());
281 title+="/";
282 title+=href.GetName();
283 text.DrawTextNDC(0.5,0.99,title);
284
285 const int maxchars = 120; // max #chars for title
286 if (m_file) {
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());
290 }
291 if (m_refFile) {
292 text.SetTextColor(kRed);
293 string s(m_refFile->GetName());
294 text.DrawTextNDC(0.5,0.96,s.substr(max(0,int(s.size()-maxchars))).c_str());
295 }
296
297 if (m_psFile!="") printCanvas(m_psFile);
298
299 // Save canvas to root file
300 if (m_outFile) {
301 createDirectory(m_outFile,dirName); // now we are in dirName
302 m_can->Write();
303 }
304
305 if (hdiff) delete hdiff;
306 }
307 }
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());
313 m_histTotal++;
314
315 // We only count (mis)matches but do not draw the difference for TEfficiency (yet)
316 if (match) m_histMatch++;
317 else m_noMatch.push_back(keyPath.Data());
318 }
319}
#define max(a, b)
Definition cfImp.cxx:41
void createDirectory(TFile *f, const char *dirpath)
Bool_t compareHist(const TH1 &h, const TH1 &href)
void sortAndDeflate(TH1 &h)
Bool_t m_sortLabels
bool match(std::string s1, std::string s2)
match the individual directories of two strings
Definition hcg.cxx:357
double ymax
Definition listroot.cxx:64

◆ rootDir()

TString TFileLooper::rootDir ( ) const
inlineinherited

Current directory.

Definition at line 86 of file TFileLooper.h.

86{ return m_rootDir; }

◆ run()

Int_t TFileLooper::run ( const char * filename,
const char * rootDir = 0 )
virtualinherited

Start processing.

Reimplemented in TMultiFileLooper.

Definition at line 26 of file TFileLooper.cxx.

27{
28 m_errorCode = 0;
29
30 if (filename==0) {
31 cout << "Invalid file name (0)" << endl;
32 m_errorCode = 1;
33 return m_errorCode;
34 }
35
36 beginJob();
37 processFile(filename,rootDir);
38 endJob();
39 return m_errorCode;
40}
virtual void beginJob()
Definition TFileLooper.h:54
virtual void endJob()
Definition TFileLooper.h:55
void processFile(const char *filename, const char *rootDir=0)

◆ setAlg()

void TRootCompare::setAlg ( TRootCompare::ALG alg,
Double_t threshold )
inline

◆ setDirsToSkip()

void TFileLooper::setDirsToSkip ( const char * skipDirs)
inlineinherited

Skip this comma separated list of directories.

Definition at line 65 of file TFileLooper.h.

65{if (skipDirs) m_skipDirs = skipDirs;}
TString m_skipDirs
Definition TFileLooper.h:91

◆ setOutputFile()

Bool_t TRootCompare::setOutputFile ( const char * filename)

Definition at line 343 of file TRootCompare.cxx.

344{
345 if (filename==0) {
346 cout << "Invalid file name" << endl;
347 return kFALSE;
348 }
349
350 m_outFile = new TFile(filename,"recreate");
351 if (m_outFile->IsZombie()) {
352 cout << "Cannot open file " << filename << endl;
353 delete m_outFile;
354 m_outFile = 0;
355 return kFALSE;
356 }
357 return kTRUE;
358}

◆ setPsFile()

Bool_t TRootCompare::setPsFile ( const char * filename)

Definition at line 360 of file TRootCompare.cxx.

361{
362 if (filename==0) {
363 cout << "Invalid file name" << endl;
364 return kFALSE;
365 }
367 return kTRUE;
368}

◆ setReferenceFile()

Bool_t TRootCompare::setReferenceFile ( const char * filename,
const char * baseDir = 0 )

Definition at line 322 of file TRootCompare.cxx.

324{
325 if (filename==0) {
326 cout << "Invalid file name" << endl;
327 return kFALSE;
328 }
329
330 m_refFile = new TFile(filename);
331 if (m_refFile->IsZombie()) {
332 cout << "Cannot open reference file " << filename << endl;
333 delete m_refFile;
334 m_refFile = 0;
335 return kFALSE;
336 }
337
339 return kTRUE;
340}

◆ setVerbose()

void TFileLooper::setVerbose ( Bool_t verbose = kTRUE)
inlineinherited

Set verbose mode.

Definition at line 77 of file TFileLooper.h.

◆ skipDir()

Bool_t TFileLooper::skipDir ( const TDirectory & dir)
protectedinherited

Definition at line 118 of file TFileLooper.cxx.

119{
120 if (m_skipDirs.Contains(dir.GetName())) return kTRUE;
121 else return kFALSE;
122}

◆ skipObject()

Bool_t TFileLooper::skipObject ( const char * name)
protectedinherited

Definition at line 129 of file TFileLooper.cxx.

130{
131 Bool_t failMatch(kFALSE);
132 Bool_t passMatch(kFALSE);
133
134 for (auto& re : m_failRE) {
135 if (re.Match(name)>0) {
136 failMatch = kTRUE;
137 break;
138 }
139 }
140
141 // give object another chance to match any of the m_passRE
142 for (auto& re : m_passRE) {
143 if (re.Match(name)>0) {
144 passMatch = kTRUE;
145 break;
146 }
147 }
148
149 bool result;
150 if (m_passBeforeFail) result = (!passMatch || failMatch);
151 else result = (failMatch && !passMatch);
152
153 if (m_verbose && result) cout << "Skipping " << name << endl;
154 return result;
155
156}
const boost::regex re(r_e)

◆ sortAndDeflate()

void TRootCompare::sortAndDeflate ( TH1 & h)
private

Definition at line 458 of file TRootCompare.cxx.

459{
460 if (h.GetXaxis()->IsAlphanumeric()) {
461 h.GetXaxis()->LabelsOption("a");
462 h.LabelsDeflate("X");
463 }
464 if (h.GetYaxis()->IsAlphanumeric()) {
465 h.GetYaxis()->LabelsOption("a");
466 h.LabelsDeflate("Y");
467 }
468}

◆ sortLabels()

void TRootCompare::sortLabels ( Bool_t sort = kTRUE)
inline

Definition at line 48 of file TRootCompare.h.

48{ m_sortLabels = sort; }
void sort(typename DataModel_detail::iterator< DVL > beg, typename DataModel_detail::iterator< DVL > end)
Specialization of sort for DataVector/List.

◆ totalHist()

Int_t TRootCompare::totalHist ( ) const
inline

Definition at line 51 of file TRootCompare.h.

51{ return m_histTotal; }

◆ verbose()

Bool_t TFileLooper::verbose ( ) const
inlineinherited

Query verbose mode.

Definition at line 80 of file TFileLooper.h.

80{return m_verbose;}

Member Data Documentation

◆ m_alg

ALG TRootCompare::m_alg
private

Definition at line 67 of file TRootCompare.h.

◆ m_can

TCanvas* TRootCompare::m_can
private

Definition at line 65 of file TRootCompare.h.

◆ m_drawDiff

Bool_t TRootCompare::m_drawDiff
private

Definition at line 73 of file TRootCompare.h.

◆ m_drawNormalized

Bool_t TRootCompare::m_drawNormalized
private

Definition at line 72 of file TRootCompare.h.

◆ m_errorCode

Int_t TFileLooper::m_errorCode {0}
protectedinherited

Definition at line 94 of file TFileLooper.h.

94{0};

◆ m_failRE

std::vector<TPRegexp> TFileLooper::m_failRE
protectedinherited

Definition at line 96 of file TFileLooper.h.

◆ m_file

TFile* TFileLooper::m_file {nullptr}
protectedinherited

Definition at line 89 of file TFileLooper.h.

89{nullptr};

◆ m_histMatch

Int_t TRootCompare::m_histMatch
private

Definition at line 69 of file TRootCompare.h.

◆ m_histMissing

Int_t TRootCompare::m_histMissing
private

Definition at line 71 of file TRootCompare.h.

◆ m_histTotal

Int_t TRootCompare::m_histTotal
private

Definition at line 70 of file TRootCompare.h.

◆ m_noMatch

std::vector<std::string> TRootCompare::m_noMatch
private

Definition at line 76 of file TRootCompare.h.

◆ m_outFile

TFile* TRootCompare::m_outFile
private

Definition at line 62 of file TRootCompare.h.

◆ m_passBeforeFail

Bool_t TFileLooper::m_passBeforeFail {kFALSE}
protectedinherited

Definition at line 93 of file TFileLooper.h.

93{kFALSE};

◆ m_passRE

std::vector<TPRegexp> TFileLooper::m_passRE
protectedinherited

Definition at line 97 of file TFileLooper.h.

◆ m_psFile

TString TRootCompare::m_psFile
private

Definition at line 64 of file TRootCompare.h.

◆ m_refFile

TFile* TRootCompare::m_refFile
private

Definition at line 61 of file TRootCompare.h.

◆ m_refRootDir

TString TRootCompare::m_refRootDir
private

Definition at line 63 of file TRootCompare.h.

◆ m_rootDir

TString TFileLooper::m_rootDir
protectedinherited

Definition at line 90 of file TFileLooper.h.

◆ m_skipDirs

TString TFileLooper::m_skipDirs
protectedinherited

Definition at line 91 of file TFileLooper.h.

◆ m_skippedObjects

std::vector<std::string> TFileLooper::m_skippedObjects
protectedinherited

Definition at line 99 of file TFileLooper.h.

◆ m_sortLabels

Bool_t TRootCompare::m_sortLabels
private

Definition at line 74 of file TRootCompare.h.

◆ m_threshold

Double_t TRootCompare::m_threshold
private

Definition at line 68 of file TRootCompare.h.

◆ m_verbose

Bool_t TFileLooper::m_verbose {kFALSE}
protectedinherited

Definition at line 92 of file TFileLooper.h.

92{kFALSE};

The documentation for this class was generated from the following files: