30 #define MAXSKIPPEDFILES 10
31 #define MAXSKIPPEDFILESFRACTION 0.1
36 unsigned sleepSeconds=30;
37 while (!
f && iTry<nTrys) {
38 f=TFile::Open(
path,
"READ");
39 if (!
f || !(
f->IsOpen())) {
41 std::cout <<
"WARNING: Failed to open file " <<
path <<
" on " << iTry <<
". attempt." << std::endl;
43 std::cout <<
"Will re-try after " << sleepSeconds <<
" seconds..." << std::endl;
49 std::cout <<
"No more retrys" << std::endl;
72 histPerDir_t(
const std::string& nameIn, TObject* objIn, TTree* md,
bool dbg=
false);
87 std::map<std::string,histDir_t>
m_data;
101 const size_t firstSlash=
dir.find(
'/',1);
102 if (firstSlash==std::string::npos)
return false;
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();
110 if (
dir.compare(firstSlash,
s,excl)==0) {
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) {
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();
127 std::cout <<
"\t" <<
it1->name << std::endl;
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;
141 ((HIST*)
a)->Add((HIST*)
b);
146 TH1* a1=(
dynamic_cast<TH1*
>(
a));
147 const TH1* b1=
dynamic_cast<const TH1*
>(
b);
149 std::cout <<
"ERROR in weightedAverageTH1: Object not of type TH1" << std::endl;
156 TH2* a1=(
dynamic_cast<TH2*
>(
a));
157 const TH2* b1=(
dynamic_cast<const TH2*
>(
b));
159 std::cout <<
"ERROR in weightedAverageTH2: Object not of type TH2" << std::endl;
166 TH1* a1=(
dynamic_cast<TH1*
>(
a));
167 const TH1* b1=(
dynamic_cast<const TH1*
>(
b));
169 std::cout <<
"ERROR in weightedEff: Object not of type TH1" << std::endl;
176 TH1* a1=(
dynamic_cast<TH1*
>(
a));
177 const TH1* b1=
dynamic_cast<const TH1*
>(
b);
179 std::cout <<
"ERROR in mergeRMS: Object not of type TH1" << std::endl;
186 TH1* a1=(
dynamic_cast<TH1*
>(
a));
187 const TH1* b1=
dynamic_cast<const TH1*
>(
b);
189 std::cout <<
"ERROR in RMSpercentDeviation: Object not of type TH1" << std::endl;
196 TH1* a1=(
dynamic_cast<TH1*
>(
a));
197 const TH1* b1=
dynamic_cast<const TH1*
>(
b);
199 std::cout <<
"ERROR in getBinEffPerCent: Object not of type TH1" << std::endl;
206 TH1* a1=(
dynamic_cast<TH1*
>(
a));
207 const TH1* b1=
dynamic_cast<const TH1*
>(
b);
209 std::cout <<
"ERROR in lowerLB: Object not of type TH1" << std::endl;
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);
222 }
else if (
c1 and
d1){
225 std::cout <<
"ERROR in identical: Object not of type THist" << std::endl;
226 std::cout << a1 <<
" " << b1 <<
" " <<
c1 <<
" " <<
d1 <<std::endl;
240 std::cout <<
"ERROR while adding " << nameIn <<
": Histogram pointer is NULL" << std::endl;
244 char howToMerge[256]={};
246 strcpy(howToMerge,
"<default>");
248 std::cout <<
"ERROR while adding " << nameIn <<
": No metadata tree. Use default merging method" << std::endl;
251 md->SetBranchAddress(
"MergeMethod", howToMerge);
252 md->SetBranchAddress(
"Name", mdName);
253 unsigned nEntries = md->GetEntries();
256 if (
name.compare(mdName)==0)
break;
260 if (
dbg) std::cout <<
"Name:" << mdName <<
" mergeMethod=" << howToMerge << std::endl;
261 if (
nullptr!=
dynamic_cast<TH1*
>(
obj)) {
262 if (!strcmp(howToMerge,
"<default>"))
264 else if (!strcmp(howToMerge,
"weightedAverage"))
266 else if (!strcmp(howToMerge,
"weightedEff"))
268 else if (!strcmp(howToMerge,
"mergeRMS"))
270 else if (!strcmp(howToMerge,
"RMSpercentDeviation"))
272 else if (!strcmp(howToMerge,
"perBinEffPerCent"))
274 else if (!strcmp(howToMerge,
"lowerLB"))
276 else if (!strcmp(howToMerge,
"identical"))
280 std::cout <<
"ERROR: Unknown merging method (" << howToMerge <<
") for object of type TH1 named " << nameIn << std::endl;
284 else if (
nullptr!=
dynamic_cast<TH2*
>(
obj)) {
285 if (!strcmp(howToMerge,
"<default>"))
287 else if (!strcmp(howToMerge,
"weightedAverage"))
290 std::cout <<
"ERROR: Unknown merging method (" << howToMerge <<
") for object of type TH2 named " << nameIn << std::endl;
296 std::cout <<
"Object "<<
name <<
" has unkown type" << std::endl;
303 TIter
next(
dir->GetListOfKeys() );
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;
312 std::cout <<
"Path " <<
newName <<
" excluded" << std::endl;
316 if (!strncmp(classname,
"TH1",3) || !strncmp(classname,
"TH2",3) || !strncmp(classname,
"TProfile",8)) {
320 TTree* md=(TTree*)
dir->Get(
"metadata");
321 if (!md) std::cout <<
"ERROR: Did not find metadata tree in directroy " << dirName << std::endl;
328 for (
auto it1=mIt->second.histos.begin();
it1!=mIt->second.histos.end();++
it1) {
335 mIt->second.histos.push_back(
histo);
339 else if (!strncmp(classname,
"TDirectory",10)) {
340 TObject*
obj =
key->ReadObj();
341 TDirectory*
subdir =
dynamic_cast<TDirectory*
>(
obj );
346 else if (!strcmp(classname,
"TTree") && (!strcmp(
name,
"metadata"))) {
350 std::cout <<
"Ignored objects '" <<
name <<
"' of type "<< classname << std::endl;
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;
363 std::vector<histPerDir_t>::const_iterator
it1=hd.
histos.begin();
364 std::vector<histPerDir_t>::const_iterator it1_e=hd.
histos.end();
368 std::cout <<
"Object " <<
fullName <<
" not properly set up. Not merged." << std::endl;
373 std::cout <<
"ERROR: Could not access path " <<
fullName <<
" in file " << in->GetName() << std::endl;
385 TDirectory* histDir=
nullptr;
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 +
"/";
392 std::string::size_type j=0,
j1=0;
393 while (
j1!=std::string::npos) {
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));
405 out->cd(currBaseDir.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) {
417 std::cout <<
"Writing " << ith->name <<
" to dir " <<
fulldir << std::endl;
421 std::cout <<
"NOT writing " << ith->name <<
". Invalid." << std::endl;
426 std::cout <<
"Wrote " <<
nWritten <<
" histograms to output file.";
428 std::cout <<
" Omitting " << nIgnored <<
" histograms." << std::endl;
430 std::cout << std::endl;
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);
441 retvec.push_back(sub);
448 std::ifstream ifs (
filename, std::ifstream::in );
450 std::cout <<
"Failed to open file " <<
filename <<
" for reading." << std::endl;
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;
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;
483 std::vector<std::string> baseDirs;
485 for(
int iArg=1;iArg<
argc;++iArg) {
486 if (!strcmp(
argv[iArg],
"-v")) {
491 if (!strcmp(
argv[iArg],
"-d")) {
494 std::cout <<
"ERROR: Expected a parameter (directory name) after '-d'" << std::endl;
497 baseDirs.push_back(std::string(
argv[iArg]));
502 if (!strcmp(
argv[iArg],
"-i")) {
505 std::cout <<
"ERROR: Expected text file name after '-i'" << std::endl;
519 std::cout <<
"ERROR: No output file name given!" << std::endl;
523 if (!gSystem->AccessPathName(
outFileName.c_str())) {
524 std::cout <<
"ERROR: Output file " <<
outFileName <<
" exists already!" << std::endl;
529 std::cout <<
"WARNING: No input files given! Will produce empty output file" << std::endl;
533 std::cout <<
"Number of input files: " <<
inFileNames.size() << std::endl;
534 std::cout <<
"Output file: " <<
outFileName << std::endl;
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");
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()) {
555 baseDirs[
i]=dirtok[0];
556 for (
size_t j=1;j<dirtok.size();++j) {
557 baseDirs[
i]+=
"/"+dirtok[j];
563 std::vector<std::string> foundDirs;
566 listOfHists.
addExclusion(
"/CaloMonitoring/LArCellMon_NoTrigSel/Sporadic");
569 std::string runDir(
"/");
571 unsigned nSkippedFiles=0;
577 for (;fileIndex<
nFiles && foundDirs.size()!=baseDirs.size() ;++fileIndex) {
581 std::cout <<
"ERROR: Could not open first file " <<
inFileNames[fileIndex] <<
"after all attempts" << std::endl;
583 std::cout <<
"Failed to read " << nSkippedFiles <<
" input files. Abort job ..." << std::endl;
587 std::cout <<
"Failed to read " << 100.0*nSkippedFiles/
nFiles <<
"% of input files. Abort job ..." << std::endl;
591 std::cout <<
"Continue without this file. Skipped " << nSkippedFiles <<
" input files so far." << std::endl;
595 std::cout <<
"First loop: Working on file " <<
inFileNames[fileIndex] <<std::endl;
597 TIter
next(in1->GetListOfKeys() );
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;
610 if (runDir.size()==1) {
611 std::cout <<
"WARNING: No run_XXXX directory found. Empty File? Ignored." << std::endl;
617 std::vector<std::string>::const_iterator dIt=baseDirs.begin();
618 std::vector<std::string>::const_iterator dIt_e=baseDirs.end();
620 for (;dIt!=dIt_e;++dIt) {
621 std::string dirName=runDir+
"/"+(*dIt);
624 TDirectory*
dir=
dynamic_cast<TDirectory*
>(in1->Get(dirName.c_str()));
626 std::cout <<
"Did not find directory " << dirName <<
" in file "<<
inFileNames[fileIndex].c_str()<<
" !" << std::endl;
629 if (
std::find(foundDirs.begin(), foundDirs.end(), dirName) != foundDirs.end())
631 std::cout<<
"Already found "<<dirName<<
" before"<<std::endl;
634 foundDirs.push_back(dirName);
636 if (
debug) std::cout <<
"Found directory " << dirName <<
" in file "<<
inFileNames[fileIndex].c_str()<<
" !" << std::endl;
640 std::cout <<
"Number of directories: " << listOfHists.
size() << std::endl;
641 std::cout<<
"SIZE "<< listOfHists.
size() <<std::endl;
650 for (;fileIndex<
nFiles;++fileIndex) {
655 std::cout <<
"ERROR: Could not open file " <<
filename <<
"after all attempts" << std::endl;
657 std::cout <<
"Failed to read " << nSkippedFiles <<
" input files. Abort job ..." << std::endl;
661 std::cout <<
"Failed to read " << 100.0*nSkippedFiles/
nFiles <<
"% of input files. Abort job ..." << std::endl;
665 std::cout <<
"Continue without this file. Skipped " << nSkippedFiles <<
" input files so far." << std::endl;
668 std::cout <<
"Working on file " <<
filename << std::endl;
669 TObject* dirObj=in->Get(runDir.c_str()+1);
671 std::cout <<
"Directory " << runDir <<
" not found. Ignoring apprently empty file" << std::endl;
680 if (!
out || !
out->IsOpen()) {
681 std::cout <<
"ERROR: Failed to open output file " <<
outFileName <<
" for writing" << std::endl;
688 if (in1 && in1->IsOpen()) {
693 if (nSkippedFiles>0) {
694 std::cout <<
"WARNING: Skipped " << nSkippedFiles <<
" input file(s)." << std::endl;