ATLAS Offline Software
Classes | Macros | Functions | Variables
LArQuickHistMerge.cxx File Reference
#include "CxxUtils/checker_macros.h"
#include "TSystem.h"
#include "TH1.h"
#include "TH2.h"
#include "TFile.h"
#include "TKey.h"
#include "TTree.h"
#include <iostream>
#include <string>
#include <vector>
#include <fstream>
#include "DataQualityUtils/MonitoringFile.h"

Go to the source code of this file.

Classes

class  histCollection
 
class  histCollection::histPerDir_t
 
struct  histCollection::histDir_t
 

Macros

#define MAXSKIPPEDFILES   5
 
#define MAXSKIPPEDFILESFRACTION   0.1
 

Functions

TFile * openWithRetry (const char *path, const unsigned nTrys=3)
 
template<class HIST >
void defaultMerge (TObject *a, const TObject *b)
 
void weightedAverageTH1 ATLAS_NOT_THREAD_SAFE (TObject *a, const TObject *b)
 
void identical (TObject *a, const TObject *b)
 
std::vector< std::string > splitString (const std::string &in, const std::string &delim)
 
bool readFromTextFile (const char *filename, std::vector< std::string > &out)
 
int main (int argc, char **argv)
 

Variables

 ATLAS_NO_CHECK_FILE_THREAD_SAFETY
 

Macro Definition Documentation

◆ MAXSKIPPEDFILES

#define MAXSKIPPEDFILES   5

Definition at line 31 of file LArQuickHistMerge.cxx.

◆ MAXSKIPPEDFILESFRACTION

#define MAXSKIPPEDFILESFRACTION   0.1

Definition at line 32 of file LArQuickHistMerge.cxx.

Function Documentation

◆ ATLAS_NOT_THREAD_SAFE()

void lowerLB ATLAS_NOT_THREAD_SAFE ( TObject *  a,
const TObject *  b 
)

Definition at line 144 of file LArQuickHistMerge.cxx.

144  {
145  TH1* a1=(dynamic_cast<TH1*>(a));
146  const TH1* b1=dynamic_cast<const TH1*>(b);
147  if (!b1 || !a1)
148  std::cout << "ERROR in weightedAverageTH1: Object not of type TH1" << std::endl;
149  else
151  return;
152 }

◆ defaultMerge()

template<class HIST >
void defaultMerge ( TObject *  a,
const TObject *  b 
)

Definition at line 139 of file LArQuickHistMerge.cxx.

139  {
140  ((HIST*)a)->Add((HIST*)b);
141  return;
142 }

◆ identical()

void identical ( TObject *  a,
const TObject *  b 
)

Definition at line 214 of file LArQuickHistMerge.cxx.

214  {
215  TH1* a1=(dynamic_cast<TH1*>(a));
216  const TH1* b1=dynamic_cast<const TH1*>(b);
217  TH2* c1=(dynamic_cast<TH2*>(a));
218  const TH2* d1=dynamic_cast<const TH2*>(b);
219  if (a1 and b1){
221  } else if (c1 and d1){
223  } else {
224  std::cout << "ERROR in identical: Object not of type THist" << std::endl;
225  std::cout << a1 << " " << b1 << " " << c1 << " " <<d1 <<std::endl;
226  }
227  return;
228 }

◆ main()

int main ( int  argc,
char **  argv 
)

Definition at line 472 of file LArQuickHistMerge.cxx.

472  {
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 
563  histCollection listOfHists(debug);
564  listOfHists.addExclusion("/CaloMonitoring/LArCellMon_NoTrigSel/Sporadic");
565 
566  TFile* in1=nullptr;
567  std::string runDir("/");
568  size_t fileIndex=0;
569  unsigned nSkippedFiles=0;
570 
571  const size_t nFiles=inFileNames.size();
572 
573  //Loop to find the first non-empty file
574  for (;fileIndex<nFiles && runDir.size()==1;++fileIndex) {
575  //in1=TFile::Open(inFileNames[fileIndex].c_str(),"READ");
576  in1=openWithRetry(inFileNames[fileIndex].c_str());
577  if (!in1) {
578  std::cout << "ERROR: Could not open first file " << inFileNames[fileIndex] << "after all attempts" << std::endl;
579  if (nSkippedFiles>MAXSKIPPEDFILES) {
580  std::cout << "Failed to read " << nSkippedFiles << " input files. Abort job ..." << std::endl;
581  return -1;
582  }
583  if (nSkippedFiles>nFiles*MAXSKIPPEDFILESFRACTION) {
584  std::cout << "Failed to read " << 100.0*nSkippedFiles/nFiles << "% of input files. Abort job ..." << std::endl;
585  return -1;
586  }
587  ++nSkippedFiles;
588  std::cout << "Continue without this file. Skipped " << nSkippedFiles << " input files so far." << std::endl;
589  continue;
590  }
591 
592  std::cout << "Working on file " << inFileNames[fileIndex] << std::endl;
593  //Get run_XXXX directory name
594  TIter next(in1->GetListOfKeys() );
595  TKey* key;
596  while((key=(TKey*)next())) {
597  const char* name=key->GetName();
598  if (!strncmp(name,"run_",4)) {
599  if (runDir.size()>1) {
600  std::cout << "ERROR More than one run_XXX directory found! Ignoring " << name << std::endl;
601  }
602  else
603  runDir.append(name);
604  }
605  }
606 
607  if (runDir.size()==1) {
608  std::cout << "WARNING: No run_XXXX directory found. Empty File? Ignored." << std::endl;
609  in1->Close();
610  continue;
611  }
612 
613  //Collect histogram directories
614  std::vector<std::string>::const_iterator dIt=baseDirs.begin();
615  std::vector<std::string>::const_iterator dIt_e=baseDirs.end();
616  for (;dIt!=dIt_e;++dIt) {
617  std::string dirName=runDir+"/"+(*dIt);
618  TDirectory* dir=dynamic_cast<TDirectory*>(in1->Get(dirName.c_str()));
619  if (!dir) {
620  std::cout << "Did not find directory " << dirName <<"!" << std::endl;
621  continue;
622  }
623  listOfHists.addDirectory(dir,dirName);
624  }
625 
626  std::cout << "Number of directories: " << listOfHists.size() << std::endl;
627 
628  if (debug) listOfHists.print();
629 
630  //std::cout << "Closing first file" << std::endl;
631  //in1->Close("R");
632  //delete in1;
633  }//end loop to find first non-empty file
634 
635  for (;fileIndex<nFiles;++fileIndex) { // Loop over remaining files
636  const char* filename=inFileNames[fileIndex].c_str();
637  //TFile* in=TFile::Open(filename,"READ");
638  TFile* in=openWithRetry(filename);
639  if (!in) {
640  std::cout << "ERROR: Could not open file " << filename << "after all attempts" << std::endl;
641  if (nSkippedFiles>MAXSKIPPEDFILES) {
642  std::cout << "Failed to read " << nSkippedFiles << " input files. Abort job ..." << std::endl;
643  return -1;
644  }
645  if (nSkippedFiles>nFiles*MAXSKIPPEDFILESFRACTION) {
646  std::cout << "Failed to read " << 100.0*nSkippedFiles/nFiles << "% of input files. Abort job ..." << std::endl;
647  return -1;
648  }
649  ++nSkippedFiles;
650  std::cout << "Continue without this file. Skipped " << nSkippedFiles << " input files so far." << std::endl;
651  continue;
652  }
653  std::cout << "Working on file " << filename << std::endl;
654  TObject* dirObj=in->Get(runDir.c_str()+1);
655  if (!dirObj) {
656  std::cout << "Directory " << runDir << " not found. Ignoring apprently empty file" << std::endl;
657  }
658  else
659  listOfHists.addFile(in);
660  in->Close();
661  delete in;
662  }
663 
664  TFile* out=new TFile(outFileName.c_str(),"NEW");
665  if (!out || !out->IsOpen()) {
666  std::cout << "ERROR: Failed to open output file " << outFileName << " for writing" << std::endl;
667  return -1;
668  }
669  listOfHists.write(out);
670  out->Close();
671  delete out;
672 
673  if (in1 && in1->IsOpen()) {
674  in1->Close();
675  delete in1;
676  }
677 
678  if (nSkippedFiles>0) {
679  std::cout << "WARNING: Skipped " << nSkippedFiles << " input file(s)." << std::endl;
680  }
681 
682  return 0;
683 }

◆ openWithRetry()

TFile* openWithRetry ( const char *  path,
const unsigned  nTrys = 3 
)

Definition at line 33 of file LArQuickHistMerge.cxx.

33  {
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 }

◆ readFromTextFile()

bool readFromTextFile ( const char *  filename,
std::vector< std::string > &  out 
)

Definition at line 441 of file LArQuickHistMerge.cxx.

441  {
442 
443  std::ifstream ifs (filename, std::ifstream::in );
444  if (!ifs.good()) {
445  std::cout << "Failed to open file " << filename << " for reading." << std::endl;
446  return false;
447  }
448 
449  while (ifs.good()) {
450  std::string line;
451  getline(ifs,line);
452  //Bit of cleaning and splitting:
453  const std::vector<std::string> linetok=splitString(line," ,;\t\n");
454  std::vector<std::string>::const_iterator it=linetok.begin();
455  std::vector<std::string>::const_iterator it_e=linetok.end();
456  for(;it!=it_e;++it) {
457  if ((*it)[0]=='#') break; //ingore all characters behind '#'
458  out.push_back(*it);
459  }
460  //if (!line.size()) continue;
461  //out.push_back(line);
462  }
463  ifs.close();
464  return true;
465 }

◆ splitString()

std::vector<std::string> splitString ( const std::string &  in,
const std::string &  delim 
)

Definition at line 426 of file LArQuickHistMerge.cxx.

426  {
427  std::vector<std::string> retvec;
428  size_t pos1=0,pos2=0;
429  while (pos2!=std::string::npos) {
430  pos2=in.find_first_of(delim,pos1);
431  const std::string sub=in.substr(pos1,pos2-pos1);
432  if (!sub.empty())
433  retvec.push_back(sub);
434  pos1=pos2+1;
435  }
436  return retvec;
437 }

Variable Documentation

◆ ATLAS_NO_CHECK_FILE_THREAD_SAFETY

ATLAS_NO_CHECK_FILE_THREAD_SAFETY

Definition at line 7 of file LArQuickHistMerge.cxx.

histCollection
Definition: LArQuickHistMerge.cxx:56
python.CaloRecoConfig.f
f
Definition: CaloRecoConfig.py:127
checkFileSG.line
line
Definition: checkFileSG.py:75
splitString
std::vector< std::string > splitString(const std::string &in, const std::string &delim)
Definition: LArQuickHistMerge.cxx:426
athena.path
path
python interpreter configuration --------------------------------------—
Definition: athena.py:126
openWithRetry
TFile * openWithRetry(const char *path, const unsigned nTrys=3)
Definition: LArQuickHistMerge.cxx:33
MAXSKIPPEDFILESFRACTION
#define MAXSKIPPEDFILESFRACTION
Definition: LArQuickHistMerge.cxx:31
extractSporadic.c1
c1
Definition: extractSporadic.py:134
skel.it
it
Definition: skel.GENtoEVGEN.py:423
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
LArCellConditions.argv
argv
Definition: LArCellConditions.py:112
CombineRootFiles.inFileNames
inFileNames
Definition: CombineRootFiles.py:22
DumpGeoConfig.outFileName
string outFileName
Definition: DumpGeoConfig.py:238
fillPileUpNoiseLumi.next
next
Definition: fillPileUpNoiseLumi.py:52
lumiFormat.i
int i
Definition: lumiFormat.py:92
DQHistogramMergeRegExp.argc
argc
Definition: DQHistogramMergeRegExp.py:20
TH2
Definition: rootspy.cxx:373
beamspotman.dir
string dir
Definition: beamspotman.py:623
dqutils::MonitoringFile::merge_weightedAverage
static void merge_weightedAverage(TH1 &a, const TH1 &b)
Definition: MonitoringFile_MergeAlgs.cxx:290
name
std::string name
Definition: Control/AthContainers/Root/debug.cxx:195
debug
const bool debug
Definition: MakeUncertaintyPlots.cxx:53
plotBeamSpotMon.b
b
Definition: plotBeamSpotMon.py:77
a
TList * a
Definition: liststreamerinfos.cxx:10
dqutils::MonitoringFile::merge_identical
static void merge_identical(TH1 &a, const TH1 &b)
Definition: MonitoringFile_MergeAlgs.cxx:694
TH1
Definition: rootspy.cxx:268
CaloCellTimeCorrFiller.filename
filename
Definition: CaloCellTimeCorrFiller.py:24
readFromTextFile
bool readFromTextFile(const char *filename, std::vector< std::string > &out)
Definition: LArQuickHistMerge.cxx:441
CscCalibQuery.nFiles
int nFiles
Definition: CscCalibQuery.py:332
mapkey::key
key
Definition: TElectronEfficiencyCorrectionTool.cxx:37