30 #define MAXSKIPPEDFILES 5
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) {
118 std::map<std::string,histDir_t>::const_iterator
it=
m_data.begin();
119 std::map<std::string,histDir_t>::const_iterator it_e=
m_data.end();
120 for(;
it!=it_e;++
it) {
121 std::cout <<
"Dir: " <<
it->first << std::endl;
123 std::vector<histPerDir_t>::const_iterator
it1=hd.
histos.begin();
124 std::vector<histPerDir_t>::const_iterator it1_e=hd.
histos.end();
126 std::cout <<
"\t" <<
it1->name << std::endl;
129 std::cout <<
"\nExclusion List: " << std::endl;
130 std::vector<std::string>::const_iterator sit=
m_exclusion.begin();
131 std::vector<std::string>::const_iterator sit_e=
m_exclusion.end();
132 for(;sit!=sit_e;++sit)
133 std::cout <<
"\t" << *sit << std::endl;
140 ((HIST*)
a)->Add((HIST*)
b);
145 TH1* a1=(
dynamic_cast<TH1*
>(
a));
146 const TH1* b1=
dynamic_cast<const TH1*
>(
b);
148 std::cout <<
"ERROR in weightedAverageTH1: Object not of type TH1" << std::endl;
155 TH2* a1=(
dynamic_cast<TH2*
>(
a));
156 const TH2* b1=(
dynamic_cast<const TH2*
>(
b));
158 std::cout <<
"ERROR in weightedAverageTH2: Object not of type TH2" << std::endl;
165 TH1* a1=(
dynamic_cast<TH1*
>(
a));
166 const TH1* b1=(
dynamic_cast<const TH1*
>(
b));
168 std::cout <<
"ERROR in weightedEff: Object not of type TH1" << std::endl;
175 TH1* a1=(
dynamic_cast<TH1*
>(
a));
176 const TH1* b1=
dynamic_cast<const TH1*
>(
b);
178 std::cout <<
"ERROR in mergeRMS: Object not of type TH1" << std::endl;
185 TH1* a1=(
dynamic_cast<TH1*
>(
a));
186 const TH1* b1=
dynamic_cast<const TH1*
>(
b);
188 std::cout <<
"ERROR in RMSpercentDeviation: Object not of type TH1" << std::endl;
195 TH1* a1=(
dynamic_cast<TH1*
>(
a));
196 const TH1* b1=
dynamic_cast<const TH1*
>(
b);
198 std::cout <<
"ERROR in getBinEffPerCent: Object not of type TH1" << std::endl;
205 TH1* a1=(
dynamic_cast<TH1*
>(
a));
206 const TH1* b1=
dynamic_cast<const TH1*
>(
b);
208 std::cout <<
"ERROR in lowerLB: Object not of type TH1" << std::endl;
215 TH1* a1=(
dynamic_cast<TH1*
>(
a));
216 const TH1* b1=
dynamic_cast<const TH1*
>(
b);
218 const TH2*
d1=
dynamic_cast<const TH2*
>(
b);
221 }
else if (
c1 and
d1){
224 std::cout <<
"ERROR in identical: Object not of type THist" << std::endl;
225 std::cout << a1 <<
" " << b1 <<
" " <<
c1 <<
" " <<
d1 <<std::endl;
239 std::cout <<
"ERROR while adding " << nameIn <<
": Histogram pointer is NULL" << std::endl;
243 char howToMerge[256]={};
245 strcpy(howToMerge,
"<default>");
247 std::cout <<
"ERROR while adding " << nameIn <<
": No metadata tree. Use default merging method" << std::endl;
250 md->SetBranchAddress(
"MergeMethod", howToMerge);
251 md->SetBranchAddress(
"Name", mdName);
252 unsigned nEntries = md->GetEntries();
255 if (
name.compare(mdName)==0)
break;
259 if (
dbg) std::cout <<
"Name:" << mdName <<
" mergeMethod=" << howToMerge << std::endl;
260 if (
nullptr!=
dynamic_cast<TH1*
>(
obj)) {
261 if (!strcmp(howToMerge,
"<default>"))
263 else if (!strcmp(howToMerge,
"weightedAverage"))
265 else if (!strcmp(howToMerge,
"weightedEff"))
267 else if (!strcmp(howToMerge,
"mergeRMS"))
269 else if (!strcmp(howToMerge,
"RMSpercentDeviation"))
271 else if (!strcmp(howToMerge,
"perBinEffPerCent"))
273 else if (!strcmp(howToMerge,
"lowerLB"))
275 else if (!strcmp(howToMerge,
"identical"))
279 std::cout <<
"ERROR: Unknown merging method (" << howToMerge <<
") for object of type TH1 named " << nameIn << std::endl;
283 else if (
nullptr!=
dynamic_cast<TH2*
>(
obj)) {
284 if (!strcmp(howToMerge,
"<default>"))
286 else if (!strcmp(howToMerge,
"weightedAverage"))
289 std::cout <<
"ERROR: Unknown merging method (" << howToMerge <<
") for object of type TH2 named " << nameIn << std::endl;
295 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;
313 std::cout <<
"Path " <<
newName <<
" excluded" << std::endl;
318 if (!strncmp(classname,
"TH1",3) || !strncmp(classname,
"TH2",3) || !strncmp(classname,
"TProfile",8)) {
321 TTree* md=(TTree*)
dir->Get(
"metadata");
322 if (!md) std::cout <<
"ERROR: Did not find metadata tree in directroy " << dirName << std::endl;
326 mIt->second.histos.push_back(
histo);
328 else if (!strncmp(classname,
"TDirectory",10)) {
329 TObject*
obj =
key->ReadObj();
330 TDirectory*
subdir =
dynamic_cast<TDirectory*
>(
obj );
335 else if (!strcmp(classname,
"TTree") && (!strcmp(
name,
"metadata"))) {
339 std::cout <<
"Ignored objects '" <<
name <<
"' of type "<< classname << std::endl;
347 std::map<std::string,histDir_t>::const_iterator
it=
m_data.begin();
348 std::map<std::string,histDir_t>::const_iterator it_e=
m_data.end();
349 for(;
it!=it_e;++
it) {
350 const std::string& dirName=
it->first;
352 std::vector<histPerDir_t>::const_iterator
it1=hd.
histos.begin();
353 std::vector<histPerDir_t>::const_iterator it1_e=hd.
histos.end();
362 std::cout <<
"ERROR: Could not access path " <<
fullName <<
" in file " << in->GetName() << std::endl;
376 TDirectory* histDir=
nullptr;
378 std::map<std::string,histDir_t>::const_iterator
it=
m_data.begin();
379 std::map<std::string,histDir_t>::const_iterator it_e=
m_data.end();
380 for(;
it!=it_e;++
it) {
381 const std::string
fulldir=
it->first +
"/";
383 std::string::size_type j=0,
j1=0;
384 while (
j1!=std::string::npos) {
390 while(
j1!=std::string::npos && !
fulldir.compare(0,
j1,lastDir,0,
j1));
391 const std::string currDirAtLevel(
fulldir.substr(j,
j1-j));
392 const std::string currFullDir(
fulldir.substr(0,
j1));
393 const std::string currBaseDir(
fulldir.substr(0,j));
396 out->cd(currBaseDir.c_str());
401 it->second.md->SetDirectory(histDir);
402 it->second.md->Write(
nullptr,TObject::kOverwrite);
403 std::vector<histPerDir_t>::const_iterator ith=
it->second.histos.begin();
404 std::vector<histPerDir_t>::const_iterator ith_e=
it->second.histos.end();
405 for (;ith!=ith_e;++ith) {
408 std::cout <<
"Writing " << ith->name <<
" to dir " <<
fulldir << std::endl;
412 std::cout <<
"NOT writing " << ith->name <<
". Invalid." << std::endl;
417 std::cout <<
"Wrote " <<
nWritten <<
" histograms to output file.";
419 std::cout <<
" Omitting " << nIgnored <<
" histograms." << std::endl;
421 std::cout << std::endl;
426 std::vector<std::string>
splitString(
const std::string& in,
const std::string& delim) {
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);
433 retvec.push_back(sub);
443 std::ifstream ifs (
filename, std::ifstream::in );
445 std::cout <<
"Failed to open file " <<
filename <<
" for reading." << std::endl;
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;
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];
564 listOfHists.
addExclusion(
"/CaloMonitoring/LArCellMon_NoTrigSel/Sporadic");
567 std::string runDir(
"/");
569 unsigned nSkippedFiles=0;
574 for (;fileIndex<
nFiles && runDir.size()==1;++fileIndex) {
578 std::cout <<
"ERROR: Could not open first file " <<
inFileNames[fileIndex] <<
"after all attempts" << std::endl;
580 std::cout <<
"Failed to read " << nSkippedFiles <<
" input files. Abort job ..." << std::endl;
584 std::cout <<
"Failed to read " << 100.0*nSkippedFiles/
nFiles <<
"% of input files. Abort job ..." << std::endl;
588 std::cout <<
"Continue without this file. Skipped " << nSkippedFiles <<
" input files so far." << std::endl;
592 std::cout <<
"Working on file " <<
inFileNames[fileIndex] << std::endl;
594 TIter
next(in1->GetListOfKeys() );
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;
607 if (runDir.size()==1) {
608 std::cout <<
"WARNING: No run_XXXX directory found. Empty File? Ignored." << std::endl;
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()));
620 std::cout <<
"Did not find directory " << dirName <<
"!" << std::endl;
626 std::cout <<
"Number of directories: " << listOfHists.
size() << std::endl;
635 for (;fileIndex<
nFiles;++fileIndex) {
640 std::cout <<
"ERROR: Could not open file " <<
filename <<
"after all attempts" << std::endl;
642 std::cout <<
"Failed to read " << nSkippedFiles <<
" input files. Abort job ..." << std::endl;
646 std::cout <<
"Failed to read " << 100.0*nSkippedFiles/
nFiles <<
"% of input files. Abort job ..." << std::endl;
650 std::cout <<
"Continue without this file. Skipped " << nSkippedFiles <<
" input files so far." << std::endl;
653 std::cout <<
"Working on file " <<
filename << std::endl;
654 TObject* dirObj=in->Get(runDir.c_str()+1);
656 std::cout <<
"Directory " << runDir <<
" not found. Ignoring apprently empty file" << std::endl;
665 if (!
out || !
out->IsOpen()) {
666 std::cout <<
"ERROR: Failed to open output file " <<
outFileName <<
" for writing" << std::endl;
673 if (in1 && in1->IsOpen()) {
678 if (nSkippedFiles>0) {
679 std::cout <<
"WARNING: Skipped " << nSkippedFiles <<
" input file(s)." << std::endl;