30 unsigned sleepSeconds=30;
31 while (!
f && iTry<nTrys) {
32 f=TFile::Open(
path,
"READ");
33 if (!
f || !(
f->IsOpen())) {
35 std::cout <<
"WARNING: Failed to open file " <<
path <<
" on " << iTry <<
". attempt." << std::endl;
37 std::cout <<
"Will re-try after " << sleepSeconds <<
" seconds..." << std::endl;
43 std::cout <<
"No more retrys" << std::endl;
66 histPerDir_t(
const std::string& nameIn, TObject* objIn, TTree* md,
bool dbg=
false);
81 std::map<std::string,histDir_t>
m_data;
95 const size_t firstSlash=
dir.find(
'/',1);
96 if (firstSlash==std::string::npos)
return false;
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();
104 if (
dir.compare(firstSlash,
s,excl)==0) {
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) {
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();
121 std::cout <<
"\t" <<
it1->name << std::endl;
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;
135 ((HIST*)
a)->Add((HIST*)
b);
140 TH1* a1=(
dynamic_cast<TH1*
>(
a));
141 const TH1* b1=
dynamic_cast<const TH1*
>(
b);
143 std::cout <<
"ERROR in weightedAverageTH1: Object not of type TH1" << std::endl;
150 TH2* a1=(
dynamic_cast<TH2*
>(
a));
151 const TH2* b1=(
dynamic_cast<const TH2*
>(
b));
153 std::cout <<
"ERROR in weightedAverageTH2: Object not of type TH2" << std::endl;
160 TH1* a1=(
dynamic_cast<TH1*
>(
a));
161 const TH1* b1=(
dynamic_cast<const TH1*
>(
b));
163 std::cout <<
"ERROR in weightedEff: Object not of type TH1" << std::endl;
170 TH1* a1=(
dynamic_cast<TH1*
>(
a));
171 const TH1* b1=
dynamic_cast<const TH1*
>(
b);
173 std::cout <<
"ERROR in mergeRMS: Object not of type TH1" << std::endl;
180 TH1* a1=(
dynamic_cast<TH1*
>(
a));
181 const TH1* b1=
dynamic_cast<const TH1*
>(
b);
183 std::cout <<
"ERROR in RMSpercentDeviation: Object not of type TH1" << std::endl;
190 TH1* a1=(
dynamic_cast<TH1*
>(
a));
191 const TH1* b1=
dynamic_cast<const TH1*
>(
b);
193 std::cout <<
"ERROR in getBinEffPerCent: Object not of type TH1" << std::endl;
200 TH1* a1=(
dynamic_cast<TH1*
>(
a));
201 const TH1* b1=
dynamic_cast<const TH1*
>(
b);
203 std::cout <<
"ERROR in lowerLB: Object not of type TH1" << std::endl;
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);
216 }
else if (
c1 and
d1){
219 std::cout <<
"ERROR in identical: Object not of type THist" << std::endl;
220 std::cout << a1 <<
" " << b1 <<
" " <<
c1 <<
" " <<
d1 <<std::endl;
234 std::cout <<
"ERROR while adding " << nameIn <<
": Histogram pointer is NULL" << std::endl;
238 char howToMerge[256]={};
240 strcpy(howToMerge,
"<default>");
242 std::cout <<
"ERROR while adding " << nameIn <<
": No metadata tree. Use default merging method" << std::endl;
245 md->SetBranchAddress(
"MergeMethod", howToMerge);
246 md->SetBranchAddress(
"Name", mdName);
247 unsigned nEntries = md->GetEntries();
250 if (
name.compare(mdName)==0)
break;
254 if (
dbg) std::cout <<
"Name:" << mdName <<
" mergeMethod=" << howToMerge << std::endl;
255 if (
nullptr!=
dynamic_cast<TH1*
>(
obj)) {
256 if (!strcmp(howToMerge,
"<default>"))
258 else if (!strcmp(howToMerge,
"weightedAverage"))
260 else if (!strcmp(howToMerge,
"weightedEff"))
262 else if (!strcmp(howToMerge,
"mergeRMS"))
264 else if (!strcmp(howToMerge,
"RMSpercentDeviation"))
266 else if (!strcmp(howToMerge,
"perBinEffPerCent"))
268 else if (!strcmp(howToMerge,
"lowerLB"))
270 else if (!strcmp(howToMerge,
"identical"))
274 std::cout <<
"ERROR: Unknown merging method (" << howToMerge <<
") for object of type TH1 named " << nameIn << std::endl;
278 else if (
nullptr!=
dynamic_cast<TH2*
>(
obj)) {
279 if (!strcmp(howToMerge,
"<default>"))
281 else if (!strcmp(howToMerge,
"weightedAverage"))
284 std::cout <<
"ERROR: Unknown merging method (" << howToMerge <<
") for object of type TH2 named " << nameIn << std::endl;
290 std::cout <<
"Object "<<
name <<
" has unkown type" << std::endl;
297 TIter
next(
dir->GetListOfKeys() );
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;
306 std::cout <<
"Path " <<
newName <<
" excluded" << std::endl;
310 if (!strncmp(classname,
"TH1",3) || !strncmp(classname,
"TH2",3) || !strncmp(classname,
"TProfile",8)) {
314 TTree* md=(TTree*)
dir->Get(
"metadata");
315 if (!md) std::cout <<
"ERROR: Did not find metadata tree in directroy " <<
dirName << std::endl;
322 for (
auto it1=mIt->second.histos.begin();
it1!=mIt->second.histos.end();++
it1) {
329 mIt->second.histos.push_back(
histo);
333 else if (!strncmp(classname,
"TDirectory",10)) {
334 TObject*
obj =
key->ReadObj();
335 TDirectory*
subdir =
dynamic_cast<TDirectory*
>(
obj );
340 else if (!strcmp(classname,
"TTree") && (!strcmp(
name,
"metadata"))) {
344 std::cout <<
"Ignored objects '" <<
name <<
"' of type "<< classname << std::endl;
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) {
357 std::vector<histPerDir_t>::const_iterator
it1=hd.
histos.begin();
358 std::vector<histPerDir_t>::const_iterator it1_e=hd.
histos.end();
362 std::cout <<
"Object " <<
fullName <<
" not properly set up. Not merged." << std::endl;
367 std::cout <<
"ERROR: Could not access path " <<
fullName <<
" in file " << in->GetName() << std::endl;
379 TDirectory* histDir=
nullptr;
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 +
"/";
386 std::string::size_type j=0,
j1=0;
387 while (
j1!=std::string::npos) {
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));
399 out->cd(currBaseDir.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) {
411 std::cout <<
"Writing " << ith->name <<
" to dir " <<
fulldir << std::endl;
415 std::cout <<
"NOT writing " << ith->name <<
". Invalid." << std::endl;
420 std::cout <<
"Wrote " <<
nWritten <<
" histograms to output file.";
422 std::cout <<
" Omitting " << nIgnored <<
" histograms." << std::endl;
424 std::cout << std::endl;
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);
435 retvec.push_back(sub);
442 std::ifstream ifs (
filename, std::ifstream::in );
444 std::cout <<
"Failed to open file " <<
filename <<
" for reading." << std::endl;
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;
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;
477 std::vector<std::string> baseDirs;
479 for(
int iArg=1;iArg<
argc;++iArg) {
480 if (!strcmp(
argv[iArg],
"-v")) {
485 if (!strcmp(
argv[iArg],
"-d")) {
488 std::cout <<
"ERROR: Expected a parameter (directory name) after '-d'" << std::endl;
491 baseDirs.push_back(std::string(
argv[iArg]));
496 if (!strcmp(
argv[iArg],
"-i")) {
499 std::cout <<
"ERROR: Expected text file name after '-i'" << std::endl;
513 std::cout <<
"ERROR: No output file name given!" << std::endl;
517 if (!gSystem->AccessPathName(
outFileName.c_str())) {
518 std::cout <<
"ERROR: Output file " <<
outFileName <<
" exists already!" << std::endl;
523 std::cout <<
"WARNING: No input files given! Will produce empty output file" << std::endl;
527 std::cout <<
"Number of input files: " <<
inFileNames.size() << std::endl;
528 std::cout <<
"Output file: " <<
outFileName << std::endl;
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");
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()) {
549 baseDirs[
i]=dirtok[0];
550 for (
size_t j=1;j<dirtok.size();++j) {
551 baseDirs[
i]+=
"/"+dirtok[j];
557 std::vector<std::string> foundDirs;
560 listOfHists.
addExclusion(
"/CaloMonitoring/LArCellMon_NoTrigSel/Sporadic");
563 std::string runDir(
"/");
565 unsigned nSkippedFiles=0;
571 for (;fileIndex<
nFiles && foundDirs.size()!=baseDirs.size() ;++fileIndex) {
575 std::cout <<
"ERROR: Could not open first file " <<
inFileNames[fileIndex] <<
"after all attempts" << std::endl;
577 std::cout <<
"Failed to read " << nSkippedFiles <<
" input files. Abort job ..." << std::endl;
581 std::cout <<
"Failed to read " << 100.0*nSkippedFiles/
nFiles <<
"% of input files. Abort job ..." << std::endl;
585 std::cout <<
"Continue without this file. Skipped " << nSkippedFiles <<
" input files so far." << std::endl;
589 std::cout <<
"First loop: Working on file " <<
inFileNames[fileIndex] <<std::endl;
591 TIter
next(in1->GetListOfKeys() );
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;
604 if (runDir.size()==1) {
605 std::cout <<
"WARNING: No run_XXXX directory found. Empty File? Ignored." << std::endl;
611 std::vector<std::string>::const_iterator dIt=baseDirs.begin();
612 std::vector<std::string>::const_iterator dIt_e=baseDirs.end();
614 for (;dIt!=dIt_e;++dIt) {
615 std::string
dirName=runDir+
"/"+(*dIt);
618 TDirectory*
dir=
dynamic_cast<TDirectory*
>(in1->Get(
dirName.c_str()));
620 std::cout <<
"Did not find directory " <<
dirName <<
" in file "<<
inFileNames[fileIndex].c_str()<<
" !" << std::endl;
623 if (
std::find(foundDirs.begin(), foundDirs.end(),
dirName) != foundDirs.end())
625 std::cout<<
"Already found "<<
dirName<<
" before"<<std::endl;
630 if (
debug) std::cout <<
"Found directory " <<
dirName <<
" in file "<<
inFileNames[fileIndex].c_str()<<
" !" << std::endl;
634 std::cout <<
"Number of directories: " << listOfHists.
size() << std::endl;
635 std::cout<<
"SIZE "<< listOfHists.
size() <<std::endl;
644 for (;fileIndex<
nFiles;++fileIndex) {
649 std::cout <<
"ERROR: Could not open file " <<
filename <<
"after all attempts" << std::endl;
651 std::cout <<
"Failed to read " << nSkippedFiles <<
" input files. Abort job ..." << std::endl;
655 std::cout <<
"Failed to read " << 100.0*nSkippedFiles/
nFiles <<
"% of input files. Abort job ..." << std::endl;
659 std::cout <<
"Continue without this file. Skipped " << nSkippedFiles <<
" input files so far." << std::endl;
662 std::cout <<
"Working on file " <<
filename << std::endl;
663 TObject* dirObj=in->Get(runDir.c_str()+1);
665 std::cout <<
"Directory " << runDir <<
" not found. Ignoring apprently empty file" << std::endl;
674 if (!
out || !
out->IsOpen()) {
675 std::cout <<
"ERROR: Failed to open output file " <<
outFileName <<
" for writing" << std::endl;
682 if (in1 && in1->IsOpen()) {
687 if (nSkippedFiles>0) {
688 std::cout <<
"WARNING: Skipped " << nSkippedFiles <<
" input file(s)." << std::endl;