XIAEventBuilder/JakeStuff/sumOutputs.cpp

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;
}