Loading [MathJax]/jax/output/SVG/config.js
ATLAS Offline Software
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Modules Pages
LArQuickHistMerge.cxx
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2025 CERN for the benefit of the ATLAS collaboration
3 */
4 
5 //Standalone compilation:
6 //g++ -g -o mergetest.exe `root-config --libs --cflags` -L InstallArea/i686-slc5-gcc43-opt/lib/ -l DataQualityUtils LArHistMerge.version2.cxx
7 
8 #include "TSystem.h"
9 #include "TH1.h"
10 #include "TH2.h"
11 #include "TFile.h"
12 #include "TKey.h"
13 #include "TTree.h"
14 
15 #include <iostream>
16 #include <string>
17 #include <vector>
18 #include <fstream>
19 
22 
23 const int MAXSKIPPEDFILES = 10;
24 const float MAXSKIPPEDFILESFRACTION = 0.1;
25 
26 
27 TFile* openWithRetry(const char* path, const unsigned nTrys=3) {
28  TFile* f=nullptr;
29  unsigned iTry=0;
30  unsigned sleepSeconds=30;
31  while (!f && iTry<nTrys) {
32  f=TFile::Open(path,"READ");
33  if (!f || !(f->IsOpen())) {
34  ++iTry;
35  std::cout << "WARNING: Failed to open file " << path << " on " << iTry << ". attempt." << std::endl;
36  if (iTry<nTrys) {
37  std::cout << "Will re-try after " << sleepSeconds << " seconds..." << std::endl;
38  sleep(sleepSeconds);
39  f=nullptr;
40  sleepSeconds*=2;
41  }
42  else {//no more attempts
43  std::cout << "No more retrys" << std::endl;
44  }
45  }//end if file not open
46  }// end while
47  return f;
48 }
49 
51 
52 public:
53 
54  explicit histCollection(bool debug=false) : m_dbg(debug) {};
55  void addDirectory(TDirectory* dir, const std::string& dirName);
56  size_t size() {return m_data.size();};
57  void addFile(TFile* in);
58  void print();
59  void write(TFile* out);
60 
61  void addExclusion(const std::string& dir);
62 
63 private:
64  class histPerDir_t {
65  public:
66  histPerDir_t(const std::string& nameIn, TObject* objIn, TTree* md, bool dbg=false);
67  std::string name;
68  TObject* obj;
69  void (*mergeMethod)(TObject* a, const TObject* b);
70  };
71 
72  struct histDir_t {
73  explicit histDir_t(TTree* mdIn): md(mdIn) {};
74  std::vector<histPerDir_t> histos;
75  TTree* md;
76  };
77 
78 
79 private:
80  bool isExcluded(const std::string& dir);
81  std::map<std::string,histDir_t> m_data;
82  bool m_dbg;
83  std::vector<std::string> m_exclusion;
84 
85 };
86 
87 
88 void histCollection::addExclusion(const std::string& dir) {
89  m_exclusion.push_back(dir);
90  return;
91 }
92 
93 bool histCollection::isExcluded(const std::string& dir) {
94 
95  const size_t firstSlash=dir.find('/',1);
96  if (firstSlash==std::string::npos) return false;
97 
98  std::vector<std::string>::const_iterator it=m_exclusion.begin();
99  std::vector<std::string>::const_iterator it_e=m_exclusion.end();
100  for(;it!=it_e;++it) {
101  const std::string& excl=*it;
102  const size_t s=excl.size();
103  //std::cout << "Comparing " << dir << " (index "<< firstSlash <<") with " << excl << std::endl;
104  if (dir.compare(firstSlash,s,excl)==0) {
105  return true;
106  }
107  }
108  return false;
109 }
110 
111 
113  std::map<std::string,histDir_t>::const_iterator it=m_data.begin();
114  std::map<std::string,histDir_t>::const_iterator it_e=m_data.end();
115  for(;it!=it_e;++it) {
116  const histDir_t& hd=it->second;
117  std::cout << "Dir: " << it->first <<" has "<<hd.histos.size()<<" histos"<<std::endl;
118  std::vector<histPerDir_t>::const_iterator it1=hd.histos.begin();
119  std::vector<histPerDir_t>::const_iterator it1_e=hd.histos.end();
120  for (;it1!=it1_e;++it1)
121  std::cout << "\t" << it1->name << std::endl;
122  }
123 
124  std::cout << "\nExclusion List: " << std::endl;
125  std::vector<std::string>::const_iterator sit=m_exclusion.begin();
126  std::vector<std::string>::const_iterator sit_e=m_exclusion.end();
127  for(;sit!=sit_e;++sit)
128  std::cout << "\t" << *sit << std::endl;
129 
130  return;
131 }
132 
133 template<class HIST>
134 void defaultMerge(TObject* a, const TObject* b) {
135  ((HIST*)a)->Add((HIST*)b);
136  return;
137 }
138 
139 void weightedAverageTH1 ATLAS_NOT_THREAD_SAFE (TObject* a, const TObject* b) {
140  TH1* a1=(dynamic_cast<TH1*>(a));
141  const TH1* b1=dynamic_cast<const TH1*>(b);
142  if (!b1 || !a1)
143  std::cout << "ERROR in weightedAverageTH1: Object not of type TH1" << std::endl;
144  else
146  return;
147 }
148 
149 void weightedAverageTH2 ATLAS_NOT_THREAD_SAFE (TObject* a, const TObject* b) {
150  TH2* a1=(dynamic_cast<TH2*>(a));
151  const TH2* b1=(dynamic_cast<const TH2*>(b));
152  if (!b1 || !a1)
153  std::cout << "ERROR in weightedAverageTH2: Object not of type TH2" << std::endl;
154  else
156  return;
157 }
158 
159 void weightedEff ATLAS_NOT_THREAD_SAFE (TObject* a, const TObject* b) {
160  TH1* a1=(dynamic_cast<TH1*>(a));
161  const TH1* b1=(dynamic_cast<const TH1*>(b));
162  if (!b1 || !a1)
163  std::cout << "ERROR in weightedEff: Object not of type TH1" << std::endl;
164  else
166  return;
167 }
168 
169 void mergeRMS ATLAS_NOT_THREAD_SAFE (TObject* a, const TObject* b) {
170  TH1* a1=(dynamic_cast<TH1*>(a));
171  const TH1* b1=dynamic_cast<const TH1*>(b);
172  if (!b1 || !a1)
173  std::cout << "ERROR in mergeRMS: Object not of type TH1" << std::endl;
174  else
176  return;
177 }
178 
179 void RMSpercentDeviation ATLAS_NOT_THREAD_SAFE (TObject* a, const TObject* b) {
180  TH1* a1=(dynamic_cast<TH1*>(a));
181  const TH1* b1=dynamic_cast<const TH1*>(b);
182  if (!b1 || !a1)
183  std::cout << "ERROR in RMSpercentDeviation: Object not of type TH1" << std::endl;
184  else
186  return;
187 }
188 
189 void perBinEffPerCent ATLAS_NOT_THREAD_SAFE (TObject* a, const TObject* b) {
190  TH1* a1=(dynamic_cast<TH1*>(a));
191  const TH1* b1=dynamic_cast<const TH1*>(b);
192  if (!b1 || !a1)
193  std::cout << "ERROR in getBinEffPerCent: Object not of type TH1" << std::endl;
194  else
196  return;
197 }
198 
199 void lowerLB ATLAS_NOT_THREAD_SAFE (TObject* a, const TObject* b) {
200  TH1* a1=(dynamic_cast<TH1*>(a));
201  const TH1* b1=dynamic_cast<const TH1*>(b);
202  if (!b1 || !a1)
203  std::cout << "ERROR in lowerLB: Object not of type TH1" << std::endl;
204  else
206  return;
207 }
208 
209 void identical ATLAS_NOT_THREAD_SAFE (TObject* a, const TObject* b) {
210  TH1* a1=(dynamic_cast<TH1*>(a));
211  const TH1* b1=dynamic_cast<const TH1*>(b);
212  TH2* c1=(dynamic_cast<TH2*>(a));
213  const TH2* d1=dynamic_cast<const TH2*>(b);
214  if (a1 and b1){
216  } else if (c1 and d1){
218  } else {
219  std::cout << "ERROR in identical: Object not of type THist" << std::endl;
220  std::cout << a1 << " " << b1 << " " << c1 << " " <<d1 <<std::endl;
221  }
222  return;
223 }
224 
225 
226 histCollection::histPerDir_t::histPerDir_t(const std::string& nameIn, TObject* objIn, TTree* md, bool dbg) :
227  name (nameIn),
228  obj(objIn),
229  mergeMethod(nullptr)
230 {
231 
232  //Some sanity checks:
233  if (!objIn) {
234  std::cout << "ERROR while adding " << nameIn << ": Histogram pointer is NULL" << std::endl;
235  return;
236  }
237 
238  char howToMerge[256]={};
239  char mdName[256]={};
240  strcpy(howToMerge,"<default>");
241  if (!md) {
242  std::cout << "ERROR while adding " << nameIn << ": No metadata tree. Use default merging method" << std::endl;
243  }
244  else {
245  md->SetBranchAddress("MergeMethod", howToMerge);
246  md->SetBranchAddress("Name", mdName);
247  unsigned nEntries = md->GetEntries();
248  for (unsigned i=0;i<nEntries;++i) {
249  md->GetEntry(i);
250  if (name.compare(mdName)==0) break;
251  }
252  }
253 
254  if (dbg) std::cout << "Name:" << mdName << " mergeMethod=" << howToMerge << std::endl;
255  if (nullptr!=dynamic_cast<TH1*>(obj)) {
256  if (!strcmp(howToMerge,"<default>"))
257  mergeMethod=&defaultMerge<TH1>;
258  else if (!strcmp(howToMerge,"weightedAverage"))
259  mergeMethod=&weightedAverageTH1;
260  else if (!strcmp(howToMerge,"weightedEff"))
261  mergeMethod=&weightedEff;
262  else if (!strcmp(howToMerge,"mergeRMS"))
263  mergeMethod=&mergeRMS;
264  else if (!strcmp(howToMerge,"RMSpercentDeviation"))
265  mergeMethod=&RMSpercentDeviation;
266  else if (!strcmp(howToMerge,"perBinEffPerCent"))
267  mergeMethod=&perBinEffPerCent;
268  else if (!strcmp(howToMerge,"lowerLB"))
270  else if (!strcmp(howToMerge,"identical"))
272 
273  else {
274  std::cout << "ERROR: Unknown merging method (" << howToMerge << ") for object of type TH1 named " << nameIn << std::endl;
275  obj=nullptr;
276  }
277  }// end if TH1
278  else if (nullptr!=dynamic_cast<TH2*>(obj)) {
279  if (!strcmp(howToMerge,"<default>"))
280  mergeMethod=&defaultMerge<TH2>;
281  else if (!strcmp(howToMerge,"weightedAverage"))
282  mergeMethod=&weightedAverageTH2;
283  else {
284  std::cout << "ERROR: Unknown merging method (" << howToMerge << ") for object of type TH2 named " << nameIn << std::endl;
285  obj=nullptr;
286  }
287 
288  }// end if TH2
289  else {
290  std::cout << "Object "<< name << " has unkown type" << std::endl;
291  obj=nullptr;
292  }
293 }
294 
295 
296 void histCollection::addDirectory(TDirectory* dir, const std::string& dirName) {
297  TIter next( dir->GetListOfKeys() );
298  TKey* key;
299  while((key=(TKey*)next())) {
300  const char* name=key->GetName();
301  const char* classname=key->GetClassName();
302  if (m_dbg) std::cout << "Found name " << name << ", classname=" << classname << std::endl;
303  const std::string newName=dirName+"/"+name;
304 
305  if (this->isExcluded(newName)) {
306  std::cout << "Path " << newName << " excluded" << std::endl;
307  return;
308  }
309 
310  if (!strncmp(classname,"TH1",3) || !strncmp(classname,"TH2",3) || !strncmp(classname,"TProfile",8)) {
312 
313  if (mIt==m_data.end()) { // New top-level directory
314  TTree* md=(TTree*)dir->Get("metadata");
315  if (!md) std::cout << "ERROR: Did not find metadata tree in directroy " << dirName << std::endl;
316  mIt=m_data.insert(std::make_pair(dirName,histDir_t(md))).first;
317  }
318  histPerDir_t histo(name,key->ReadObj(),mIt->second.md,m_dbg);
319 
320  // Check if we already have this histogram in the list
321  bool found = 0;
322  for (auto it1=mIt->second.histos.begin(); it1!=mIt->second.histos.end();++it1) {
323  if( it1->name == name){
324  found=1;
325  break;
326  }
327  }
328  if ( found == 0 ){ // Add the histrogam if we didn't already have it
329  mIt->second.histos.push_back(histo);
330  }
331 
332  }
333  else if (!strncmp(classname,"TDirectory",10)) {
334  TObject* obj = key->ReadObj();
335  TDirectory* subdir = dynamic_cast<TDirectory*>( obj );
336  if (subdir) {
337  this->addDirectory(subdir,newName);
338  }
339  }
340  else if (!strcmp(classname,"TTree") && (!strcmp(name,"metadata"))) {
341  //std::cout << "Found Metadata tree" << std::endl;
342  }
343  else {
344  std::cout << "Ignored objects '" << name << "' of type "<< classname << std::endl;
345  }
346  }
347  return;
348 }
349 
350 
351 void histCollection::addFile(TFile* in) {
352  std::map<std::string,histDir_t>::const_iterator it=m_data.begin();
353  std::map<std::string,histDir_t>::const_iterator it_e=m_data.end();
354  for(;it!=it_e;++it) {
355  const std::string& dirName=it->first;
356  const histDir_t& hd=it->second;
357  std::vector<histPerDir_t>::const_iterator it1=hd.histos.begin();
358  std::vector<histPerDir_t>::const_iterator it1_e=hd.histos.end();
359  for (;it1!=it1_e;++it1) {
360  const std::string fullName=dirName+"/"+it1->name;
361  if (!it1->obj) {
362  std::cout << "Object " << fullName << " not properly set up. Not merged." << std::endl;
363  continue;
364  }
365  TObject* obj=in->Get(fullName.c_str());
366  if (!obj) {
367  std::cout << "ERROR: Could not access path " << fullName <<" in file " << in->GetName() << std::endl;
368  }
369  else
370  (*it1->mergeMethod)(it1->obj,obj);
371  }//End loop over histograms in directory
372  }//End loop over directory names
373  return;
374 }
375 
377  unsigned nWritten=0;
378  unsigned nIgnored=0;
379  TDirectory* histDir=nullptr;
380  std::string lastDir;
381  std::map<std::string,histDir_t>::const_iterator it=m_data.begin();
382  std::map<std::string,histDir_t>::const_iterator it_e=m_data.end();
383  for(;it!=it_e;++it) {
384  const std::string fulldir=it->first + "/";
385  //Create dirs if necessary
386  std::string::size_type j=0,j1=0;
387  while (j1!=std::string::npos) {
388  do {
389  j=j1+1;
390  j1=fulldir.find('/',j);
391  //std::cout << "Inner loop " << fulldir.substr(0,j1) << " << ==? " << lastDir.substr(0,j1) << std::endl;
392  }
393  while(j1!=std::string::npos && !fulldir.compare(0,j1,lastDir,0,j1));
394  const std::string currDirAtLevel(fulldir.substr(j,j1-j));
395  const std::string currFullDir(fulldir.substr(0,j1));
396  const std::string currBaseDir(fulldir.substr(0,j));
397  //std::cout << "Working on dir " << fulldir << " [" << currFullDir << " " << currBaseDir << " " << currDirAtLevel << std::endl;
398  lastDir=currFullDir;
399  out->cd(currBaseDir.c_str());
400  gDirectory->mkdir(currDirAtLevel.c_str());
401  }//End outer while loop - full directory created
402  //std::cout << "Done creating " << fulldir << std::endl;
403  out->cd(fulldir.c_str());
404  it->second.md->SetDirectory(histDir);
405  it->second.md->Write(nullptr,TObject::kOverwrite);
406  std::vector<histPerDir_t>::const_iterator ith=it->second.histos.begin();
407  std::vector<histPerDir_t>::const_iterator ith_e=it->second.histos.end();
408  for (;ith!=ith_e;++ith) {
409  if (ith->obj) {
410  ith->obj->Write();
411  std::cout << "Writing " << ith->name << " to dir " << fulldir << std::endl;
412  ++nWritten;
413  }
414  else {
415  std::cout << "NOT writing " << ith->name << ". Invalid." << std::endl;
416  ++nIgnored;
417  }
418  }//End loop over histograms in one directory
419  }//End loop over directories;
420  std::cout << "Wrote " << nWritten << " histograms to output file.";
421  if (nIgnored)
422  std::cout << " Omitting " << nIgnored << " histograms." << std::endl;
423  else
424  std::cout << std::endl;
425  return;
426 }
427 
428 std::vector<std::string> splitString(const std::string& in, const std::string& delim) {
429  std::vector<std::string> retvec;
430  size_t pos1=0,pos2=0;
431  while (pos2!=std::string::npos) {
432  pos2=in.find_first_of(delim,pos1);
433  const std::string sub=in.substr(pos1,pos2-pos1);
434  if (!sub.empty())
435  retvec.push_back(sub);
436  pos1=pos2+1;
437  }
438  return retvec;
439 }
440 
441 bool readFromTextFile(const char* filename, std::vector<std::string>& out) {
442  std::ifstream ifs (filename, std::ifstream::in );
443  if (!ifs.good()) {
444  std::cout << "Failed to open file " << filename << " for reading." << std::endl;
445  return false;
446  }
447  while (ifs.good()) {
448  std::string line;
449  getline(ifs,line);
450  //Bit of cleaning and splitting:
451  const std::vector<std::string> linetok=splitString(line," ,;\t\n");
452  std::vector<std::string>::const_iterator it=linetok.begin();
453  std::vector<std::string>::const_iterator it_e=linetok.end();
454  for(;it!=it_e;++it) {
455  if ((*it)[0]=='#') break; //ingore all characters behind '#'
456  out.push_back(*it);
457  }
458  //if (!line.size()) continue;
459  //out.push_back(line);
460  }
461  ifs.close();
462  return true;
463 }
464 
465 // =================================================================================================
466 int main(int argc, char** argv) {
467 
468  if (argc<2 || (argc>1 && (!strcmp(argv[1],"-h") || !strcmp(argv[1],"--help")))) {
469  std::cout << "Syntax:\n" << argv[0] << " [-v ] [-i inputTextFile] [-d directroy] <outfile> <infile1> <infile2> .... " << std::endl;
470  std::cout << " -v verbose " << std::endl;
471  return -1;
472  }
473 
474  bool debug=false;
475  std::string outFileName;
476  std::vector<std::string> inFileNames;
477  std::vector<std::string> baseDirs;
478 
479  for(int iArg=1;iArg<argc;++iArg) {
480  if (!strcmp(argv[iArg],"-v")) {
481  debug=true;
482  continue;
483  }
484 
485  if (!strcmp(argv[iArg],"-d")) {
486  ++iArg;
487  if (argc<=iArg) {
488  std::cout << "ERROR: Expected a parameter (directory name) after '-d'" << std::endl;
489  return -1;
490  }
491  baseDirs.push_back(std::string(argv[iArg]));
492  continue;
493  }
494 
495 
496  if (!strcmp(argv[iArg],"-i")) {
497  ++iArg;
498  if (argc<=iArg) {
499  std::cout << "ERROR: Expected text file name after '-i'" << std::endl;
500  return -1;
501  }
503  continue;
504  }
505  if (outFileName.empty())
506  outFileName=argv[iArg];
507  else
508  inFileNames.push_back(std::string(argv[iArg]));
509  }//end loop over arguments
510 
511 
512  if (outFileName.empty()) {
513  std::cout << "ERROR: No output file name given!" << std::endl;
514  return -1;
515  }
516 
517  if (!gSystem->AccessPathName(outFileName.c_str())) {
518  std::cout << "ERROR: Output file " << outFileName << " exists already!" << std::endl;
519  return -1;
520  }
521 
522  if (inFileNames.empty()) {
523  std::cout << "WARNING: No input files given! Will produce empty output file" << std::endl;
524  }
525 
526 
527  std::cout << "Number of input files: " << inFileNames.size() << std::endl;
528  std::cout << "Output file: " << outFileName << std::endl;
529 
530  if (baseDirs.empty()) {
531  baseDirs.push_back("LAr");
532  baseDirs.push_back("CaloMonitoring/LArCellMon_NoTrigSel");
533  baseDirs.push_back("CaloTopoClusters/CalBAR");
534  baseDirs.push_back("CaloTopoClusters/CalECA");
535  baseDirs.push_back("CaloTopoClusters/CalECC");
536  baseDirs.push_back("CaloTopoClusters/CalEMBAR");
537  baseDirs.push_back("CaloTopoClusters/CalEMECA");
538  baseDirs.push_back("CaloTopoClusters/CalEMECC");
539 
540  }
541  else {
542  //clean superfluos slash characters
543  for (size_t i=0;i<baseDirs.size();++i) {
544  std::vector<std::string> dirtok=splitString(baseDirs[i],std::string("/"));
545  if (dirtok.empty()) {
546  baseDirs[i].clear();
547  continue;
548  }
549  baseDirs[i]=dirtok[0];
550  for (size_t j=1;j<dirtok.size();++j) {
551  baseDirs[i]+="/"+dirtok[j];
552  }//eld loop over dir tokens
553  }//end loop over directories
554  }
555 
556  // Keeping track of which directories we found
557  std::vector<std::string> foundDirs;
558 
559  histCollection listOfHists(debug);
560  listOfHists.addExclusion("/CaloMonitoring/LArCellMon_NoTrigSel/Sporadic");
561 
562  TFile* in1=nullptr;
563  std::string runDir("/");
564  size_t fileIndex=0;
565  unsigned nSkippedFiles=0;
566 
567  const size_t nFiles=inFileNames.size();
568 
569  //Loop to find the first non-empty file
570  //for (;fileIndex<nFiles && runDir.size()==1;++fileIndex) {
571  for (;fileIndex<nFiles && foundDirs.size()!=baseDirs.size() ;++fileIndex) {
572  //in1=TFile::Open(inFileNames[fileIndex].c_str(),"READ");
573  in1=openWithRetry(inFileNames[fileIndex].c_str());
574  if (!in1) {
575  std::cout << "ERROR: Could not open first file " << inFileNames[fileIndex] << "after all attempts" << std::endl;
576  if (nSkippedFiles>MAXSKIPPEDFILES) {
577  std::cout << "Failed to read " << nSkippedFiles << " input files. Abort job ..." << std::endl;
578  return -1;
579  }
580  if (nSkippedFiles>nFiles*MAXSKIPPEDFILESFRACTION) {
581  std::cout << "Failed to read " << 100.0*nSkippedFiles/nFiles << "% of input files. Abort job ..." << std::endl;
582  return -1;
583  }
584  ++nSkippedFiles;
585  std::cout << "Continue without this file. Skipped " << nSkippedFiles << " input files so far." << std::endl;
586  continue;
587  }
588 
589  std::cout << "First loop: Working on file " << inFileNames[fileIndex] <<std::endl;
590  //Get run_XXXX directory name
591  TIter next(in1->GetListOfKeys() );
592  TKey* key;
593  while((key=(TKey*)next())) {
594  const char* name=key->GetName();
595  if (!strncmp(name,"run_",4)) {
596  if (runDir.size()>1) {
597  std::cout << "ERROR More than one run_XXX directory found! Ignoring " << name << std::endl;
598  }
599  else
600  runDir.append(name);
601  }
602  }
603 
604  if (runDir.size()==1) {
605  std::cout << "WARNING: No run_XXXX directory found. Empty File? Ignored." << std::endl;
606  in1->Close();
607  continue;
608  }
609 
610  //Collect histogram directories
611  std::vector<std::string>::const_iterator dIt=baseDirs.begin();
612  std::vector<std::string>::const_iterator dIt_e=baseDirs.end();
613 
614  for (;dIt!=dIt_e;++dIt) {
615  std::string dirName=runDir+"/"+(*dIt);
616  // In case we are looping over more files to find the directory
617 
618  TDirectory* dir=dynamic_cast<TDirectory*>(in1->Get(dirName.c_str()));
619  if (!dir) {
620  std::cout << "Did not find directory " << dirName <<" in file "<<inFileNames[fileIndex].c_str()<<" !" << std::endl;
621  continue;
622  }
623  if (std::find(foundDirs.begin(), foundDirs.end(), dirName) != foundDirs.end())
624  {
625  std::cout<<"Already found "<<dirName<<" before"<<std::endl;
626  //continue;
627  }else{
628  foundDirs.push_back(dirName);
629  }
630  if (debug) std::cout << "Found directory " << dirName <<" in file "<<inFileNames[fileIndex].c_str()<<" !" << std::endl;
631  listOfHists.addDirectory(dir,dirName);
632  }
633 
634  std::cout << "Number of directories: " << listOfHists.size() << std::endl;
635  std::cout<<"SIZE "<< listOfHists.size() <<std::endl;
636 
637  if (debug) listOfHists.print();
638 
639  //std::cout << "Closing first file" << std::endl;
640  //in1->Close("R");
641  //delete in1;
642  }//end loop to find first non-empty file
643 
644  for (;fileIndex<nFiles;++fileIndex) { // Loop over remaining files
645  const char* filename=inFileNames[fileIndex].c_str();
646  //TFile* in=TFile::Open(filename,"READ");
647  TFile* in=openWithRetry(filename);
648  if (!in) {
649  std::cout << "ERROR: Could not open file " << filename << "after all attempts" << std::endl;
650  if (nSkippedFiles>MAXSKIPPEDFILES) {
651  std::cout << "Failed to read " << nSkippedFiles << " input files. Abort job ..." << std::endl;
652  return -1;
653  }
654  if (nSkippedFiles>nFiles*MAXSKIPPEDFILESFRACTION) {
655  std::cout << "Failed to read " << 100.0*nSkippedFiles/nFiles << "% of input files. Abort job ..." << std::endl;
656  return -1;
657  }
658  ++nSkippedFiles;
659  std::cout << "Continue without this file. Skipped " << nSkippedFiles << " input files so far." << std::endl;
660  continue;
661  }
662  std::cout << "Working on file " << filename << std::endl;
663  TObject* dirObj=in->Get(runDir.c_str()+1);
664  if (!dirObj) {
665  std::cout << "Directory " << runDir << " not found. Ignoring apprently empty file" << std::endl;
666  }
667  else
668  listOfHists.addFile(in);
669  in->Close();
670  delete in;
671  }
672 
673  TFile* out=new TFile(outFileName.c_str(),"NEW");
674  if (!out || !out->IsOpen()) {
675  std::cout << "ERROR: Failed to open output file " << outFileName << " for writing" << std::endl;
676  return -1;
677  }
678  listOfHists.write(out);
679  out->Close();
680  delete out;
681 
682  if (in1 && in1->IsOpen()) {
683  in1->Close();
684  delete in1;
685  }
686 
687  if (nSkippedFiles>0) {
688  std::cout << "WARNING: Skipped " << nSkippedFiles << " input file(s)." << std::endl;
689  }
690 
691  return 0;
692 }
xAOD::iterator
JetConstituentVector::iterator iterator
Definition: JetConstituentVector.cxx:68
histCollection
Definition: LArQuickHistMerge.cxx:50
histCollection::addExclusion
void addExclusion(const std::string &dir)
Definition: LArQuickHistMerge.cxx:88
fitman.nWritten
int nWritten
Definition: fitman.py:420
python.SystemOfUnits.s
int s
Definition: SystemOfUnits.py:131
splitString
std::vector< std::string > splitString(const std::string &in, const std::string &delim)
Definition: LArQuickHistMerge.cxx:428
athena.path
path
python interpreter configuration --------------------------------------—
Definition: athena.py:128
openWithRetry
TFile * openWithRetry(const char *path, const unsigned nTrys=3)
Definition: LArQuickHistMerge.cxx:27
find
std::string find(const std::string &s)
return a remapped string
Definition: hcg.cxx:135
collListGuids.line
string line
Definition: collListGuids.py:77
histCollection::print
void print()
Definition: LArQuickHistMerge.cxx:112
WriteCellNoiseToCool.fullName
fullName
Definition: WriteCellNoiseToCool.py:461
histCollection::histDir_t::histos
std::vector< histPerDir_t > histos
Definition: LArQuickHistMerge.cxx:73
extractSporadic.c1
c1
Definition: extractSporadic.py:134
histCollection::write
void write(TFile *out)
Definition: LArQuickHistMerge.cxx:376
skel.it
it
Definition: skel.GENtoEVGEN.py:407
dqutils::MonitoringFile::merge_lowerLB
static void merge_lowerLB(TH1 &a, const TH1 &b)
Definition: MonitoringFile_MergeAlgs.cxx:673
python.AthDsoLogger.out
out
Definition: AthDsoLogger.py:71
MAXSKIPPEDFILESFRACTION
const float MAXSKIPPEDFILESFRACTION
Definition: LArQuickHistMerge.cxx:24
dq_defect_virtual_defect_validation.d1
d1
Definition: dq_defect_virtual_defect_validation.py:79
PrintTrkAnaSummary.dirName
dirName
Definition: PrintTrkAnaSummary.py:126
BchCleanup.identical
identical
Definition: BchCleanup.py:304
defaultMerge
void defaultMerge(TObject *a, const TObject *b)
Definition: LArQuickHistMerge.cxx:134
histCollection::size
size_t size()
Definition: LArQuickHistMerge.cxx:56
histCollection::histCollection
histCollection(bool debug=false)
Definition: LArQuickHistMerge.cxx:54
histCollection::m_exclusion
std::vector< std::string > m_exclusion
Definition: LArQuickHistMerge.cxx:83
histCollection::histDir_t::histDir_t
histDir_t(TTree *mdIn)
Definition: LArQuickHistMerge.cxx:73
CombineRootFiles.inFileNames
inFileNames
Definition: CombineRootFiles.py:22
main
int main(int argc, char **argv)
Definition: LArQuickHistMerge.cxx:466
doubleTestComp.j1
j1
Definition: doubleTestComp.py:21
fillPileUpNoiseLumi.next
next
Definition: fillPileUpNoiseLumi.py:52
ParseInputs.gDirectory
gDirectory
Definition: Final2012/ParseInputs.py:133
lumiFormat.i
int i
Definition: lumiFormat.py:85
LArCellNtuple.argv
argv
Definition: LArCellNtuple.py:152
DetDescrDictionaryDict::it1
std::vector< HWIdentifier >::iterator it1
Definition: DetDescrDictionaryDict.h:17
histCollection::m_dbg
bool m_dbg
Definition: LArQuickHistMerge.cxx:82
histCollection::histPerDir_t::obj
TObject * obj
Definition: LArQuickHistMerge.cxx:68
histCollection::histDir_t
Definition: LArQuickHistMerge.cxx:72
histCollection::m_data
std::map< std::string, histDir_t > m_data
Definition: LArQuickHistMerge.cxx:81
hist_file_dump.f
f
Definition: hist_file_dump.py:141
hotSpotInTAG.lowerLB
int lowerLB
Definition: hotSpotInTAG.py:175
MAXSKIPPEDFILES
const int MAXSKIPPEDFILES
Definition: LArQuickHistMerge.cxx:23
DQHistogramMergeRegExp.argc
argc
Definition: DQHistogramMergeRegExp.py:20
histCollection::isExcluded
bool isExcluded(const std::string &dir)
Definition: LArQuickHistMerge.cxx:93
beamspotman.dir
string dir
Definition: beamspotman.py:623
dqutils::MonitoringFile::merge_RMS
static void merge_RMS(TH1 &a, const TH1 &b)
Definition: MonitoringFile_MergeAlgs.cxx:556
dqutils::MonitoringFile::merge_weightedAverage
static void merge_weightedAverage(TH1 &a, const TH1 &b)
Definition: MonitoringFile_MergeAlgs.cxx:301
dbg
Definition: SGImplSvc.cxx:69
name
std::string name
Definition: Control/AthContainers/Root/debug.cxx:240
debug
const bool debug
Definition: MakeUncertaintyPlots.cxx:53
plotBeamSpotMon.b
b
Definition: plotBeamSpotMon.py:77
MakeNewFileFromOldAndSubstitution.newName
dictionary newName
Definition: ICHEP2016/MakeNewFileFromOldAndSubstitution.py:95
dumpNswErrorDb.outFileName
string outFileName
Definition: dumpNswErrorDb.py:131
checkTriggerxAOD.found
found
Definition: checkTriggerxAOD.py:328
histCollection::addFile
void addFile(TFile *in)
Definition: LArQuickHistMerge.cxx:351
MonitoringFile.h
dqutils::MonitoringFile::merge_weightedAverage2D
static void merge_weightedAverage2D(TH2 &a, const TH2 &b)
Definition: MonitoringFile_MergeAlgs.cxx:378
a
TList * a
Definition: liststreamerinfos.cxx:10
dqutils::MonitoringFile::merge_identical
static void merge_identical(TH1 &a, const TH1 &b)
Definition: MonitoringFile_MergeAlgs.cxx:722
DeMoScan.first
bool first
Definition: DeMoScan.py:536
ATLAS_NOT_THREAD_SAFE
void weightedAverageTH1 ATLAS_NOT_THREAD_SAFE(TObject *a, const TObject *b)
Definition: LArQuickHistMerge.cxx:139
CaloCellTimeCorrFiller.filename
filename
Definition: CaloCellTimeCorrFiller.py:24
histCollection::histDir_t::md
TTree * md
Definition: LArQuickHistMerge.cxx:75
dqutils::MonitoringFile::merge_perBinEffPerCent
static void merge_perBinEffPerCent(TH1 &a, const TH1 &b)
Definition: MonitoringFile_MergeAlgs.cxx:133
readFromTextFile
bool readFromTextFile(const char *filename, std::vector< std::string > &out)
Definition: LArQuickHistMerge.cxx:441
python.envutil.fulldir
fulldir
Definition: envutil.py:153
python.LumiCalcRecover.subdir
subdir
Definition: LumiCalcRecover.py:25
histCollection::histPerDir_t::name
std::string name
Definition: LArQuickHistMerge.cxx:67
plotBeamSpotCompare.histo
histo
Definition: plotBeamSpotCompare.py:415
checker_macros.h
Define macros for attributes used to control the static checker.
dqBeamSpot.nEntries
int nEntries
Definition: dqBeamSpot.py:73
python.PyAthena.obj
obj
Definition: PyAthena.py:132
dqutils::MonitoringFile::merge_weightedEff
static void merge_weightedEff(TH1 &a, const TH1 &b)
Definition: MonitoringFile_MergeAlgs.cxx:419
histCollection::histPerDir_t
Definition: LArQuickHistMerge.cxx:64
dqutils::MonitoringFile::merge_RMSpercentDeviation
static void merge_RMSpercentDeviation(TH1 &a, const TH1 &b)
Definition: MonitoringFile_MergeAlgs.cxx:613
histCollection::addDirectory
void addDirectory(TDirectory *dir, const std::string &dirName)
Definition: LArQuickHistMerge.cxx:296
histCollection::histPerDir_t::histPerDir_t
histPerDir_t(const std::string &nameIn, TObject *objIn, TTree *md, bool dbg=false)
Definition: LArQuickHistMerge.cxx:226
histCollection::histPerDir_t::mergeMethod
void(* mergeMethod)(TObject *a, const TObject *b)
Definition: LArQuickHistMerge.cxx:69
CscCalibQuery.nFiles
int nFiles
Definition: CscCalibQuery.py:332
mapkey::key
key
Definition: TElectronEfficiencyCorrectionTool.cxx:37