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