298 TIter next( dir->GetListOfKeys() );
300 while((key=(TKey*)next())) {
301 const char* name=key->GetName();
302 const char* classname=key->GetClassName();
303 if (
m_dbg) std::cout <<
"Found name " << name <<
", classname=" << classname << std::endl;
304 const std::string newName=dirName+
"/"+name;
307 std::cout <<
"Path " << newName <<
" excluded" << std::endl;
311 if (!strncmp(classname,
"TH1",3) || !strncmp(classname,
"TH2",3) || !strncmp(classname,
"TProfile",8)) {
312 auto mIt=
m_data.find(
"dirName");
315 TTree* md=(TTree*)dir->Get(
"metadata");
316 if (!md) std::cout <<
"ERROR: Did not find metadata tree in directroy " << dirName << std::endl;
323 for (
auto it1=mIt->second.histos.begin(); it1!=mIt->second.histos.end();++it1) {
324 if( it1->name == name){
330 mIt->second.histos.push_back(std::move(histo));
334 else if (!strncmp(classname,
"TDirectory",10)) {
335 TObject* obj = key->ReadObj();
336 TDirectory* subdir =
dynamic_cast<TDirectory*
>( obj );
341 else if (!strcmp(classname,
"TTree") && (!strcmp(name,
"metadata"))) {
345 std::cout <<
"Ignored objects '" << name <<
"' of type "<< classname << std::endl;
355 for(;it!=it_e;++it) {
356 const std::string& dirName=it->first;
358 std::vector<histPerDir_t>::const_iterator it1=hd.
histos.begin();
359 std::vector<histPerDir_t>::const_iterator it1_e=hd.
histos.end();
360 for (;it1!=it1_e;++it1) {
361 const std::string fullName=dirName+
"/"+it1->name;
363 std::cout <<
"Object " << fullName <<
" not properly set up. Not merged." << std::endl;
366 TObject* obj=in->Get(fullName.c_str());
368 std::cout <<
"ERROR: Could not access path " << fullName <<
" in file " << in->GetName() << std::endl;
371 (*it1->mergeMethod)(it1->obj,obj);
380 TDirectory* histDir=
nullptr;
384 for(;it!=it_e;++it) {
385 const std::string fulldir=it->first +
"/";
387 std::string::size_type j=0,j1=0;
388 while (j1!=std::string::npos) {
391 j1=fulldir.find(
'/',j);
394 while(j1!=std::string::npos && !fulldir.compare(0,j1,lastDir,0,j1));
395 const std::string currDirAtLevel(fulldir.substr(j,j1-j));
396 const std::string currFullDir(fulldir.substr(0,j1));
397 const std::string currBaseDir(fulldir.substr(0,j));
399 lastDir=std::move(currFullDir);
400 out->cd(currBaseDir.c_str());
401 gDirectory->mkdir(currDirAtLevel.c_str());
404 out->cd(fulldir.c_str());
405 it->second.md->SetDirectory(histDir);
406 it->second.md->Write(
nullptr,TObject::kOverwrite);
407 std::vector<histPerDir_t>::const_iterator ith=it->second.histos.begin();
408 std::vector<histPerDir_t>::const_iterator ith_e=it->second.histos.end();
409 for (;ith!=ith_e;++ith) {
412 std::cout <<
"Writing " << ith->name <<
" to dir " << fulldir << std::endl;
416 std::cout <<
"NOT writing " << ith->name <<
". Invalid." << std::endl;
421 std::cout <<
"Wrote " << nWritten <<
" histograms to output file.";
423 std::cout <<
" Omitting " << nIgnored <<
" histograms." << std::endl;
425 std::cout << std::endl;
429std::vector<std::string>
splitString(
const std::string& in, std::string_view delim) {
430 std::vector<std::string> retvec;
431 size_t pos1=0,pos2=0;
432 while (pos2!=std::string::npos) {
433 pos2=in.find_first_of(delim,pos1);
434 const std::string sub=in.substr(pos1,pos2-pos1);
436 retvec.push_back(std::move(sub));
443 std::ifstream ifs (filename, std::ifstream::in );
445 std::cout <<
"Failed to open file " << filename <<
" for reading." << std::endl;
452 const std::vector<std::string> linetok=
splitString(line,
" ,;\t\n");
453 std::vector<std::string>::const_iterator it=linetok.begin();
454 std::vector<std::string>::const_iterator it_e=linetok.end();
455 for(;it!=it_e;++it) {
456 if ((*it)[0]==
'#')
break;
467int main(
int argc,
char** argv) {
469 if (argc<2 || (argc>1 && (!strcmp(argv[1],
"-h") || !strcmp(argv[1],
"--help")))) {
470 std::cout <<
"Syntax:\n" << argv[0] <<
" [-v ] [-i inputTextFile] [-d directroy] <outfile> <infile1> <infile2> .... " << std::endl;
471 std::cout <<
" -v verbose " << std::endl;
476 std::string outFileName;
477 std::vector<std::string> inFileNames;
478 std::vector<std::string> baseDirs;
480 for(
int iArg=1;iArg<argc;++iArg) {
481 if (!strcmp(argv[iArg],
"-v")) {
486 if (!strcmp(argv[iArg],
"-d")) {
489 std::cout <<
"ERROR: Expected a parameter (directory name) after '-d'" << std::endl;
492 baseDirs.push_back(std::string(argv[iArg]));
497 if (!strcmp(argv[iArg],
"-i")) {
500 std::cout <<
"ERROR: Expected text file name after '-i'" << std::endl;
506 if (outFileName.empty())
507 outFileName=argv[iArg];
509 inFileNames.push_back(std::string(argv[iArg]));
513 if (outFileName.empty()) {
514 std::cout <<
"ERROR: No output file name given!" << std::endl;
518 if (!gSystem->AccessPathName(outFileName.c_str())) {
519 std::cout <<
"ERROR: Output file " << outFileName <<
" exists already!" << std::endl;
523 if (inFileNames.empty()) {
524 std::cout <<
"WARNING: No input files given! Will produce empty output file" << std::endl;
528 std::cout <<
"Number of input files: " << inFileNames.size() << std::endl;
529 std::cout <<
"Output file: " << outFileName << std::endl;
531 if (baseDirs.empty()) {
532 baseDirs.push_back(
"LAr");
533 baseDirs.push_back(
"CaloMonitoring/LArCellMon_NoTrigSel");
534 baseDirs.push_back(
"CaloTopoClusters/CalBAR");
535 baseDirs.push_back(
"CaloTopoClusters/CalECA");
536 baseDirs.push_back(
"CaloTopoClusters/CalECC");
537 baseDirs.push_back(
"CaloTopoClusters/CalEMBAR");
538 baseDirs.push_back(
"CaloTopoClusters/CalEMECA");
539 baseDirs.push_back(
"CaloTopoClusters/CalEMECC");
544 for (
size_t i=0;i<baseDirs.size();++i) {
545 const std::vector<std::string> & dirtok=
splitString(baseDirs[i],
"/");
546 if (dirtok.empty()) {
550 baseDirs[i]=dirtok[0];
551 for (
size_t j=1;j<dirtok.size();++j) {
552 baseDirs[i]+=
"/"+dirtok[j];
558 std::vector<std::string> foundDirs;
561 listOfHists.
addExclusion(
"/CaloMonitoring/LArCellMon_NoTrigSel/Sporadic");
564 std::string runDir(
"/");
566 unsigned nSkippedFiles=0;
568 const size_t nFiles=inFileNames.size();
572 for (;fileIndex<nFiles && foundDirs.size()!=baseDirs.size() ;++fileIndex) {
576 std::cout <<
"ERROR: Could not open first file " << inFileNames[fileIndex] <<
"after all attempts" << std::endl;
578 std::cout <<
"Failed to read " << nSkippedFiles <<
" input files. Abort job ..." << std::endl;
582 std::cout <<
"Failed to read " << 100.0*nSkippedFiles/nFiles <<
"% of input files. Abort job ..." << std::endl;
586 std::cout <<
"Continue without this file. Skipped " << nSkippedFiles <<
" input files so far." << std::endl;
590 std::cout <<
"First loop: Working on file " << inFileNames[fileIndex] <<std::endl;
592 TIter next(in1->GetListOfKeys() );
594 while((key=(TKey*)next())) {
595 const char* name=key->GetName();
596 if (!strncmp(name,
"run_",4)) {
597 if (runDir.size()>1) {
598 std::cout <<
"ERROR More than one run_XXX directory found! Ignoring " << name << std::endl;
605 if (runDir.size()==1) {
606 std::cout <<
"WARNING: No run_XXXX directory found. Empty File? Ignored." << std::endl;
612 std::vector<std::string>::const_iterator dIt=baseDirs.begin();
613 std::vector<std::string>::const_iterator dIt_e=baseDirs.end();
615 for (;dIt!=dIt_e;++dIt) {
616 std::string dirName=runDir+
"/"+(*dIt);
619 TDirectory* dir=
dynamic_cast<TDirectory*
>(in1->Get(dirName.c_str()));
621 std::cout <<
"Did not find directory " << dirName <<
" in file "<<inFileNames[fileIndex].c_str()<<
" !" << std::endl;
624 if (std::find(foundDirs.begin(), foundDirs.end(), dirName) != foundDirs.end())
626 std::cout<<
"Already found "<<dirName<<
" before"<<std::endl;
629 foundDirs.push_back(dirName);
631 if (
debug) std::cout <<
"Found directory " << dirName <<
" in file "<<inFileNames[fileIndex].c_str()<<
" !" << std::endl;
635 std::cout <<
"Number of directories: " << listOfHists.
size() << std::endl;
636 std::cout<<
"SIZE "<< listOfHists.
size() <<std::endl;
645 for (;fileIndex<nFiles;++fileIndex) {
646 const char* filename=inFileNames[fileIndex].c_str();
650 std::cout <<
"ERROR: Could not open file " << filename <<
"after all attempts" << std::endl;
652 std::cout <<
"Failed to read " << nSkippedFiles <<
" input files. Abort job ..." << std::endl;
656 std::cout <<
"Failed to read " << 100.0*nSkippedFiles/nFiles <<
"% of input files. Abort job ..." << std::endl;
660 std::cout <<
"Continue without this file. Skipped " << nSkippedFiles <<
" input files so far." << std::endl;
663 std::cout <<
"Working on file " << filename << std::endl;
664 TObject* dirObj=in->Get(runDir.c_str()+1);
666 std::cout <<
"Directory " << runDir <<
" not found. Ignoring apprently empty file" << std::endl;
674 TFile* out=
new TFile(outFileName.c_str(),
"NEW");
675 if (!out || !out->IsOpen()) {
676 std::cout <<
"ERROR: Failed to open output file " << outFileName <<
" for writing" << std::endl;
679 listOfHists.
write(out);
683 if (in1 && in1->IsOpen()) {
688 if (nSkippedFiles>0) {
689 std::cout <<
"WARNING: Skipped " << nSkippedFiles <<
" input file(s)." << std::endl;