ATLAS Offline Software
main_comphistfiles.cxx
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration
3 */
4 
5 #include "readfile.h"
6 #include "comphists.h"
8 #include <iostream>
9 #include <cassert>
10 #include <cstdlib>
11 #include <sys/stat.h>
12 
13 void classifyByKey( const KeyToHistMap& hists1,KeyToHistMap& hists2,
14  std::vector<std::pair<std::string,TH1*> >& histsOnlyIn1,
15  std::vector<std::pair<std::string,TH1*> >& histsOnlyIn2,
16  std::vector<std::pair<std::string,std::pair<TH1*,TH1*> > >& histsInBoth )
17 {
18  KeyToHistMap::const_iterator it1(hists1.begin()), it1E(hists1.end());
19  for (;it1!=it1E;++it1) {
20  KeyToHistMap::iterator it2=hists2.find(it1->first);
21  if (it2!=hists2.end()) {
22  histsInBoth.push_back(std::make_pair(it1->first,std::pair<TH1*,TH1*>(it1->second,it2->second)));
23  hists2.erase(it2);
24  } else {
25  histsOnlyIn1.push_back(*it1);
26  }
27  }
28  KeyToHistMap::const_iterator it2(hists2.begin()), it2E(hists2.end());
29  histsOnlyIn2.reserve(hists2.size());
30  for (;it2!=it2E;++it2)
31  histsOnlyIn2.push_back(*it2);
32 }
33 
35  std::cout << "Usage:"<<std::endl;
36  std::cout << ""<<std::endl;
37  std::cout << argv[0]<<" [flags] histfile1.root histfile2.root [outputfile.root]"<<std::endl;
38  std::cout <<""<<std::endl;
39  std::cout <<"Program which checks for consistency (up to floating point accuracy)"<<std::endl;
40  std::cout <<"between ROOT histograms found in two ROOT files and outputs a small report."<<std::endl;
41  std::cout <<""<<std::endl;
42  std::cout <<"Supplying an outputfile.root argument will result in copies of inconsistent"<<std::endl;
43  std::cout <<"histograms written to this file."<<std::endl;
44  std::cout <<""<<std::endl;
45  std::cout <<"Unless -h/--help is requested, exit-code 0 implies complete consistency."<<std::endl;
46  std::cout <<""<<std::endl;
47  std::cout <<"Optional flags:"<<std::endl;
48  std::cout <<" -h, --help : This help"<<std::endl;
49  std::cout <<" -v, --verbose : Verbose output"<<std::endl;
50  std::cout <<" --silentnan : Suppress warnings regarding NaN values (when in both hists compared)."<<std::endl;
51  std::cout <<" --ignore-stylevars : Ignore certain unsupported style-vars (ndivisions, ticklength, ..)."<<std::endl;
52  std::cout <<" --ignore-sumw2-nonalloc : Ignore case where one histogram has not allocated a sumw2 (error) array."<<std::endl;
53  std::cout <<""<<std::endl;
54  exit(exitcode);
55 }
56 
57 bool fileExists(const std::string& filename) {
58  struct stat stFileInfo;
59  return (stat(filename.c_str(),&stFileInfo) == 0);
60 }
61 
62 //Returns 0 if check ok, 1 if problems getting histograms from one of the files, 2 if check not ok.
64  //Decode arguments:
65  bool verbose(false);
66  std::vector<std::string> rootfiles;
67  cfg_report_NaN = true;
70  for (int i=1; i<argc;++i) {
71  std::string arg(argv[i]);
72  if (arg=="-h"||arg=="--help")
73  usage(argv,0);
74  if (arg=="-v"||arg=="--verbose") {
75  if (verbose)
76  usage(argv,1);
77  verbose = true;
78  continue;
79  }
80  if (arg=="--silentnan") {
81  if (!cfg_report_NaN)
82  usage(argv,1);
83  cfg_report_NaN = false;
84  continue;
85  }
86  if (arg=="--ignore-stylevars") {
88  usage(argv,1);
90  continue;
91  }
92  if (arg=="--ignore-sumw2-nonalloc") {
94  usage(argv,1);
96  continue;
97  }
98  if (arg.empty()||arg[0]=='-')
99  usage(argv,1);
100  rootfiles.push_back(arg);
101  }
102  if (rootfiles.size()<2||rootfiles.size()>3)
103  usage(argv,1);
104  const std::string file1 = rootfiles.at(0);
105  const std::string file2 = rootfiles.at(1);
106  const std::string outputfile = (rootfiles.size()>2 ? rootfiles.at(2): "");
107  if (!fileExists(file1)) {
108  std::cout<<"Error: File "<<file1<<" not found."<<std::endl;
109  usage(argv,1);
110  }
111  if (!fileExists(file2)) {
112  std::cout<<"Error: File "<<file2<<" not found."<<std::endl;
113  usage(argv,1);
114  }
115  if (!outputfile.empty()&&fileExists(outputfile)) {
116  std::cout<<"Error: File "<<outputfile<<" already exists."<<std::endl;
117  usage(argv,1);
118  }
119 
120  //Parameters:
121  // const char * file1 = "Monitor1.root";
122  // const char * file2 = "Monitor1_copy.root";
123  //const char * file2 = "Monitor2.root";
124  // const bool verbose = false;
125  // const std::string outputfile="";//"hists_noncompat.root";
126  //read both:
127  KeyToHistMap hists1, hists2;
128 
129  if (!getAllHistsInRootFile(file1,hists1)) {
130  std::cout<<"Problems getting histograms from file "<<file1<<std::endl;
131  return 1;
132  }
133  if (!getAllHistsInRootFile(file2,hists2)) {
134  std::cout<<"Problems getting histograms from file "<<file2<<std::endl;
135  return 1;
136  }
137  std::vector<std::pair<std::string,TH1*> > histsOnlyIn1;
138  std::vector<std::pair<std::string,TH1*> > histsOnlyIn2;
139  std::vector<std::pair<std::string,std::pair<TH1*,TH1*> > > histsInBoth;
140 
141  classifyByKey( hists1,hists2,
142  histsOnlyIn1, histsOnlyIn2, histsInBoth );
143  bool allok(true);
144  if (!histsOnlyIn1.empty()) {
145  if (verbose)
146  for (unsigned i=0;i<histsOnlyIn1.size();++i)
147  std::cout<<"Only found in "<<file1<<": "<<histsOnlyIn1.at(i).first<<std::endl;
148  allok=false;
149  }
150  if (!histsOnlyIn2.empty()) {
151  if (verbose)
152  for (unsigned i=0;i<histsOnlyIn2.size();++i)
153  std::cout<<"Only found in "<<file2<<": "<<histsOnlyIn2.at(i).first<<std::endl;
154  allok=false;
155  }
156 
157  unsigned nincompat(0);
158  std::vector<TH1*> incompathists;
159  if (!histsInBoth.empty()) {
160  for (unsigned i=0;i<histsInBoth.size();++i) {
161  if (verbose)
162  std::cout<<"Found in both files: "<<histsInBoth.at(i).first<<std::endl;
163  if (!histsCompatible(histsInBoth.at(i).second.first,histsInBoth.at(i).second.second)) {
164  std::cout<<" => Incompatibilities detected in "<<histsInBoth.at(i).first<<std::endl;
165  incompathists.push_back(histsInBoth.at(i).second.first);
166  incompathists.push_back(histsInBoth.at(i).second.second);
167  allok=false;
168  ++nincompat;
169  }
170  }
171  }
172  //Summary:
173  std::cout<<"============== Summary =============="<<std::endl;
174  if (!histsOnlyIn1.empty())
175  std::cout<<histsOnlyIn1.size()<<" histograms only found in "<<file1<<std::endl;
176  if (!histsOnlyIn2.empty())
177  std::cout<<histsOnlyIn2.size()<<" histograms only found in "<<file2<<std::endl;
178  if (histsInBoth.size()-nincompat>0)
179  std::cout<<histsInBoth.size()-nincompat<<" common and compatible histograms found in both files"<<std::endl;
180  if (nincompat>0)
181  std::cout<<nincompat<<" common but incompatible histograms found in both files"<<std::endl;
182  //nincompat
183  std::cout<<"====================================="<<std::endl;
184 
185  if (nincompat>0&&!outputfile.empty()) {
186  std::cout<<"Writing copies of the "<<nincompat<<" (both versions) incompatible histograms to file "<<outputfile<<std::endl;
187  TFile * file = new TFile(outputfile.c_str(),"NEW");
188  if (!file->IsOpen()) {
189  std::cout<<"ERROR: Problems opening file"<<std::endl;
190  return 1;
191  } else {
192  for (unsigned i=0;i<incompathists.size();++i)
193  incompathists.at(i)->Write();
194  }
195  file->Close();
196  std::cout<<"Done writing file "<<outputfile<<std::endl;
197  }
198  exit(allok ? 0 : 1);
199  return allok ? 0 : 1;
200 }
AtlCoolConsole.usage
tuple usage
Definition: AtlCoolConsole.py:443
xAOD::iterator
JetConstituentVector::iterator iterator
Definition: JetConstituentVector.cxx:68
cfg_ignore_errors_related_to_a_non_existant_sumw2_array
std::atomic< bool > cfg_ignore_errors_related_to_a_non_existant_sumw2_array
Definition: jobflags.h:11
KeyToHistMap
std::map< std::string, TH1 * > KeyToHistMap
Definition: readfile.h:10
comphists.h
athena.exitcode
int exitcode
Definition: athena.py:159
ATLAS_NOT_THREAD_SAFE
void usage ATLAS_NOT_THREAD_SAFE(char **argv, int exitcode)
Definition: main_comphistfiles.cxx:34
LArCellConditions.argv
argv
Definition: LArCellConditions.py:112
outputfile
ofstream outputfile
Definition: CellClusterLinkTool.h:25
main
int main(int, char **)
Main class for all the CppUnit test classes
Definition: CppUnit_SGtestdriver.cxx:141
lumiFormat.i
int i
Definition: lumiFormat.py:92
DetDescrDictionaryDict::it1
std::vector< HWIdentifier >::iterator it1
Definition: DetDescrDictionaryDict.h:17
file
TFile * file
Definition: tile_monitor.h:29
DQHistogramMergeRegExp.argc
argc
Definition: DQHistogramMergeRegExp.py:20
calibdata.exit
exit
Definition: calibdata.py:236
beamspotman.stat
stat
Definition: beamspotman.py:266
create_dcsc_inputs_sqlite.arg
list arg
Definition: create_dcsc_inputs_sqlite.py:48
classifyByKey
void classifyByKey(const KeyToHistMap &hists1, KeyToHistMap &hists2, std::vector< std::pair< std::string, TH1 * > > &histsOnlyIn1, std::vector< std::pair< std::string, TH1 * > > &histsOnlyIn2, std::vector< std::pair< std::string, std::pair< TH1 *, TH1 * > > > &histsInBoth)
Definition: main_comphistfiles.cxx:13
cfg_ignore_unsupported_style_vars
std::atomic< bool > cfg_ignore_unsupported_style_vars
Definition: jobflags.h:10
cfg_report_NaN
std::atomic< bool > cfg_report_NaN
Definition: jobflags.h:9
python.TriggerHandler.verbose
verbose
Definition: TriggerHandler.py:297
CaloCellTimeCorrFiller.filename
filename
Definition: CaloCellTimeCorrFiller.py:24
getAllHistsInRootFile
bool getAllHistsInRootFile(const std::string &filename, KeyToHistMap &hists)
Definition: readfile.h:36
histsCompatible
bool histsCompatible(TH1 *h1, TH1 *h2)
Definition: comphists.h:24
readfile.h
checker_macros.h
Define macros for attributes used to control the static checker.
fileExists
bool fileExists(const std::string &filename)
Definition: main_comphistfiles.cxx:57