117 lines
2.9 KiB
C++
Executable File
117 lines
2.9 KiB
C++
Executable File
#include <TFile.h>
|
|
#include <TKey.h>
|
|
#include <TDirectory.h>
|
|
#include <TSystem.h>
|
|
#include <TH1.h>
|
|
|
|
#include <iostream>
|
|
#include <vector>
|
|
#include <string>
|
|
#include <iomanip> // for setw
|
|
|
|
void AddDir(TDirectory* src, TDirectory* dest)
|
|
{
|
|
TIter next(src->GetListOfKeys());
|
|
TKey* key;
|
|
|
|
while ((key = (TKey*)next())) {
|
|
TObject* obj = key->ReadObj();
|
|
|
|
if (obj->InheritsFrom("TDirectory")) {
|
|
TDirectory* srcSub = (TDirectory*)obj;
|
|
TDirectory* destSub =
|
|
dest->GetDirectory(srcSub->GetName());
|
|
|
|
if (!destSub)
|
|
destSub = dest->mkdir(srcSub->GetName());
|
|
|
|
AddDir(srcSub, destSub);
|
|
}
|
|
else if (obj->InheritsFrom("TH1")) {
|
|
TH1* h = (TH1*)obj;
|
|
TH1* hsum =
|
|
(TH1*)dest->Get(h->GetName());
|
|
|
|
if (!hsum) {
|
|
hsum = (TH1*)h->Clone();
|
|
hsum->SetDirectory(dest);
|
|
hsum->Sumw2(kTRUE);
|
|
} else {
|
|
hsum->Add(h);
|
|
}
|
|
hsum->SetOption("HIST");
|
|
}
|
|
}
|
|
}
|
|
|
|
// Simple text-based progress bar
|
|
void printProgress(int current, int total, int barWidth = 50)
|
|
{
|
|
float progress = float(current) / total;
|
|
int pos = int(barWidth * progress);
|
|
|
|
std::cout << "[";
|
|
for (int i = 0; i < barWidth; ++i) {
|
|
if (i < pos) std::cout << "=";
|
|
else if (i == pos) std::cout << ">";
|
|
else std::cout << " ";
|
|
}
|
|
std::cout << "] " << int(progress * 100.0) << "%\r";
|
|
std::cout.flush();
|
|
}
|
|
|
|
int main(int argc, char** argv)
|
|
{
|
|
if (argc != 3) {
|
|
std::cerr << "Usage: " << argv[0]
|
|
<< " <directory> <output_file>\n";
|
|
return 1;
|
|
}
|
|
|
|
TString dir = argv[1];
|
|
TString outName = argv[2]; // <-- now from command-line
|
|
|
|
void* dirp = gSystem->OpenDirectory(dir);
|
|
if (!dirp) {
|
|
std::cerr << "Cannot open directory "
|
|
<< dir << std::endl;
|
|
return 1;
|
|
}
|
|
|
|
// Gather all ROOT files in a vector
|
|
std::vector<TString> files;
|
|
const char* entry;
|
|
while ((entry = gSystem->GetDirEntry(dirp))) {
|
|
TString fname(entry);
|
|
if (!fname.EndsWith(".root")) continue;
|
|
if (fname == outName) continue; // avoid overwriting output
|
|
files.push_back(fname);
|
|
}
|
|
gSystem->FreeDirectory(dirp);
|
|
|
|
if (files.empty()) {
|
|
std::cerr << "No ROOT files found in directory." << std::endl;
|
|
return 1;
|
|
}
|
|
|
|
TFile* fout = new TFile(dir + "/" + outName, "RECREATE");
|
|
|
|
// Loop over files with progress bar
|
|
int totalFiles = files.size();
|
|
for (int i = 0; i < totalFiles; ++i) {
|
|
TString full = dir + "/" + files[i];
|
|
TFile f(full, "READ");
|
|
if (!f.IsZombie())
|
|
AddDir(&f, fout);
|
|
f.Close();
|
|
|
|
printProgress(i + 1, totalFiles);
|
|
}
|
|
|
|
fout->Write();
|
|
fout->Close();
|
|
|
|
std::cout << std::endl << "Output written to " << dir + "/" + outName << std::endl;
|
|
return 0;
|
|
}
|