ATLAS Offline Software
compareHIClusterGeoFiles.cxx
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2025 CERN for the benefit of the ATLAS collaboration
3 */
4 #include <iostream>
5 #include <memory>
6 #include <string>
7 
8 #include "TFile.h"
9 #include "TH1F.h"
10 #include "TH3F.h"
11 #include "TMath.h"
12 
13 void compareHIClusterGeoFiles(const std::string& file1,
14  const std::string& file2, int testOnly = 127,
15  int* result = 0, float eps = 1e-5) {
16  std::unique_ptr<TFile> f1( TFile::Open(file1.c_str()) );
17  std::unique_ptr<TFile> f2( TFile::Open(file2.c_str()) );
18 
19  if (!f1 || f1->IsZombie() || !f2 || f2->IsZombie()) {
20  if (!f1 || f1->IsZombie()) {
21  std::cout << "could not open file1 " << file1 << std::endl;
22  }
23  if (!f2 || f2->IsZombie()) {
24  std::cout << "could not open file2 " << file2 << std::endl;
25  }
26 
27  if (result) {
28  *result = 1;
29  }
30  return;
31  }
32 
33  const int hnum = 7;
34  const char hnames[hnum][100] = {
35  "h3_w", "h3_eta", "h3_phi", "h3_R",
36  "h3_eta_phi_response", "h3_eta_phi_offset",
37  "h1_run_index"};
38  // testOnly: 1-h3_w; 2-h3_eta; 4-h3_phi; 8-h3_R;
39  // 16-h3_eta_phi_response; 32-h3_eta_phi_offset,
40  // 64-h1_run_index
41  int hdiff[hnum] = {
42  0, 0, 0, 0,
43  0, 0, 0};
44  // 0-same; 1-not found; 2-different dimensions; 3-different
45  // axes; 4-different bins; 5-different bin content
46  char hresult[hnum][30] = {
47  "same", "not found", "different dimensions",
48  "different axes", "different bins", "different bin content"};
49 
50  for (int h = 0; h < hnum; h++) {
51  if (!(testOnly & (1 << h))) {
52  continue;
53  }
54 
55  // TH1 is for both TH1F and TH3F
56  TH1* h1 = (TH1*)f1->Get(hnames[h]);
57  if (h1) {
58  h1->SetDirectory(0);
59  h1->SetName(Form("%s_h1", hnames[h]));
60  }
61 
62  TH1* h2 = (TH1*)f2->Get(hnames[h]);
63  if (h2) {
64  h2->SetDirectory(0);
65  h2->SetName(Form("%s_h2", hnames[h]));
66  }
67 
68  if (!h1 || !h2) {
69  if (!h1) {
70  std::cout << "could not find histogram " << hnames[h] << " in file1 "
71  << file1 << std::endl;
72  }
73  if (!h2) {
74  std::cout << "could not find histogram " << hnames[h] << " in file2 "
75  << file2 << std::endl;
76  }
77 
78  // not found
79  hdiff[h] = 1;
80  continue;
81  }
82 
83  int dim1 = h1->GetDimension();
84  int dim2 = h2->GetDimension();
85  if (dim1 != dim2) {
86  std::cout << "h1 " << h1->GetName() << " has dimension " << dim1
87  << ", h2 " << h2->GetName() << " has dimension " << dim2
88  << std::endl;
89  // different dimensions
90  hdiff[h] = 2;
91  continue;
92  }
93 
94  if (h1->GetNbinsX() != h2->GetNbinsX() ||
95  (dim1 > 1 && h1->GetNbinsY() != h2->GetNbinsY()) ||
96  (dim1 > 2 && h1->GetNbinsZ() != h2->GetNbinsZ())) {
97  if (h1->GetNbinsX() != h2->GetNbinsX()) {
98  std::cout << "h1 " << h1->GetName() << " has " << h1->GetNbinsX()
99  << " bins in X, h2 " << h2->GetName() << " has "
100  << h2->GetNbinsX() << " bins in X" << std::endl;
101  }
102  if (h1->GetNbinsY() != h2->GetNbinsY()) {
103  std::cout << "h1 " << h1->GetName() << " has " << h1->GetNbinsY()
104  << " bins in Y, h2 " << h2->GetName() << " has "
105  << h2->GetNbinsY() << " bins in Y" << std::endl;
106  }
107  if (h1->GetNbinsZ() != h2->GetNbinsZ()) {
108  std::cout << "h1 " << h1->GetName() << " has " << h1->GetNbinsZ()
109  << " bins in Z, h2 " << h2->GetName() << " has "
110  << h2->GetNbinsZ() << " bins in Z" << std::endl;
111  }
112 
113  // different axes
114  hdiff[h] = 3;
115  continue;
116  }
117 
118  int doBreak = 0;
119  int dim = h1->GetDimension();
120  for (int d = 1; d <= dim; d++) {
121  TAxis* a1 = nullptr;
122  TAxis* a2 = nullptr;
123  if (d == 1) {
124  a1 = h1->GetXaxis();
125  a2 = h2->GetXaxis();
126  }
127  if (d == 2) {
128  a1 = h1->GetYaxis();
129  a2 = h2->GetYaxis();
130  }
131  if (d == 3) {
132  a1 = h1->GetZaxis();
133  a2 = h2->GetZaxis();
134  }
135  if((not a1) or (not a2)) {
136  std::cout << "h1 " << h1->GetName() << " has pointer to " << char('W'+d)
137  << "-axis = " << a1 << ", h2 " << h2->GetName()
138  << " has pointer to " << char('W'+d) << "-axis = " << a2
139  << std::endl;
140  // different axes
141  hdiff[h] = 3;
142  doBreak = 1;
143  break;
144  }
145  for (int b = 1; b <= a1->GetNbins() + 1; ++b) {
146  if (a1->GetBinLowEdge(b) != a2->GetBinLowEdge(b)) {
147  // different bins
148  hdiff[h] = 4;
149  std::cout << "h1 " << h1->GetName() << " has bin " << b
150  << " with low edge " << a1->GetBinLowEdge(b) << ", h2 "
151  << h2->GetName() << " has bin " << b << " with low edge "
152  << a2->GetBinLowEdge(b) << std::endl;
153  doBreak = 1;
154  break;
155  }
156  }
157  if (doBreak) {
158  break;
159  }
160  }
161  if (doBreak) {
162  continue;
163  }
164 
165  for (int bx = 1; bx <= h1->GetNbinsX(); ++bx) {
166  for (int by = 1; by <= h1->GetNbinsY(); ++by) {
167  for (int bz = 1; bz <= h1->GetNbinsZ(); ++bz) {
168  if (TMath::Abs(h1->GetBinContent(bx, by, bz) - h2->GetBinContent(bx, by, bz)) > eps) {
169  // different bin content
170  hdiff[h] = 5;
171  std::cout << "h1 " << h1->GetName() << " has "
172  << h1->GetBinContent(bx, by, bz) << " in bin " << bx
173  << "," << by << "," << bz << ", h2 " << h2->GetName()
174  << " has " << h2->GetBinContent(bx, by, bz) << std::endl;
175  std::cout << "skipping the rest of bins" << std::endl;
176  doBreak = 1;
177  }
178  if (doBreak) {
179  break;
180  }
181  }
182  if (doBreak) {
183  break;
184  }
185  }
186  if (doBreak) {
187  break;
188  }
189  }
190  }
191 
192  if (result) {
193  *result = 0;
194  }
195 
196  for (int h = 0; h < hnum; h++) {
197  if (!(testOnly & (1 << h))) {
198  continue;
199  }
200  std::cout << hnames[h] << ": " << hresult[hdiff[h]] << std::endl;
201  if (result && hdiff[h] > *result) {
202  *result = hdiff[h];
203  }
204  }
205 
206  return;
207 }
208 
209 int main(int argc, char** argv) {
210  if (argc < 3 || argc > 5) {
211  std::cout << "Syntax: " << argv[0] << " file1 file2 [testOnly [epsilon]]"
212  << std::endl;
213  return -1;
214  }
215 
216  int result = 0;
217  int testOnly = (argc > 3 ? std::stoi(argv[3]) : 127);
218  if (testOnly > 127) {
219  std::cout << "Warning: testOnly should be an integer between 1 and 127, it "
220  "is now "
221  << testOnly << ", changing to " << testOnly << "%128 = ";
222  testOnly %= 128;
223  std::cout << testOnly << std::endl;
224  }
225  if (testOnly <= 0) {
226  std::cout << "Warning: testOnly should be an integer between 1 and 127, it "
227  "is now "
228  << testOnly << ", nothing to do here" << std::endl;
229  return -1;
230  }
231 
232  float epsilon = (argc > 4 ? std::stof(argv[4]) : 1e-5);
233  if(epsilon < 0.) {
234  std::cout << "Warning: epsilon should be a possitive number, it is now "
235  << epsilon << ", changing to 0.0" << std::endl;
236  epsilon=0.;
237  }
238 
239  compareHIClusterGeoFiles(argv[1], argv[2], testOnly, &result, epsilon);
240  return result;
241 }
AllowedVariables::e
e
Definition: AsgElectronSelectorTool.cxx:37
yodamerge_tmp.dim
dim
Definition: yodamerge_tmp.py:239
get_generator_info.result
result
Definition: get_generator_info.py:21
hist_file_dump.d
d
Definition: hist_file_dump.py:142
xAOD::char
char
Definition: TrigDecision_v1.cxx:38
CaloClusterMLCalib::epsilon
constexpr float epsilon
Definition: CaloClusterMLGaussianMixture.h:16
read_hist_ntuple.h1
h1
Definition: read_hist_ntuple.py:21
read_hist_ntuple.f2
f2
Definition: read_hist_ntuple.py:20
fitman.bz
bz
Definition: fitman.py:412
LArCellNtuple.argv
argv
Definition: LArCellNtuple.py:152
extractSporadic.h
list h
Definition: extractSporadic.py:96
fitman.bx
bx
Definition: fitman.py:410
fitman.by
by
Definition: fitman.py:411
DQHistogramMergeRegExp.argc
argc
Definition: DQHistogramMergeRegExp.py:19
compareHIClusterGeoFiles
void compareHIClusterGeoFiles(const std::string &file1, const std::string &file2, int testOnly=127, int *result=0, float eps=1e-5)
Definition: compareHIClusterGeoFiles.cxx:13
plotBeamSpotMon.b
b
Definition: plotBeamSpotMon.py:76
main
int main(int argc, char **argv)
Definition: compareHIClusterGeoFiles.cxx:209
h
read_hist_ntuple.f1
f1
Definition: read_hist_ntuple.py:4