22#include "FileMapper.hh"
25#include "BDSOutputROOTEventHeader.hh"
37int main(
int argc,
char* argv[])
41 std::cout <<
"usage: bdsimCombine result.root file1.root file2.root ..." << std::endl;
46 std::vector<std::string> inputFiles;
47 for (
int i = 2; i < argc; ++i)
48 {inputFiles.emplace_back(std::string(argv[i]));}
50 if (inputFiles[0].find(
'*') != std::string::npos)
52 std::vector<std::string> fileNamesTemp;
54 glob(inputFiles[0].c_str(),GLOB_TILDE,
nullptr,&glob_result);
55 for (
unsigned int i=0; i<glob_result.gl_pathc; ++i)
56 {fileNamesTemp.emplace_back(glob_result.gl_pathv[i]);}
57 globfree(&glob_result);
58 inputFiles = fileNamesTemp;
62 if (inputFiles.size() == 1)
64 std::cout <<
"Only one input file provided \"" << inputFiles[0] <<
"\" - no point." << std::endl;
68 std::string outputFile = std::string(argv[1]);
69 if (outputFile.find(
'*') != std::string::npos)
71 std::cerr <<
"First argument for output file \"" << outputFile <<
"\" contains an *." << std::endl;
72 std::cerr <<
"Should only be a singular file - check order of arguments." << std::endl;
77 TChain* eventsMerged =
new TChain(
"Event");
78 for (
const auto& filename : inputFiles)
79 {eventsMerged->Add(filename.c_str());}
80 std::cout <<
"Beginning merge of Event Tree" << std::endl;
81 Long64_t operationCode = eventsMerged->Merge(outputFile.c_str());
82 if (operationCode == 0)
84 std::cerr <<
"Problem in TTree::Merge opening output file \"" << outputFile <<
"\"" << std::endl;
88 {std::cout <<
"Finished merge of Event Tree" << std::endl;}
91 unsigned long long int nOriginalEvents = 0;
92 bool skimmedFile =
false;
93 unsigned long int i = 0;
94 std::cout <<
"Counting number of original events from headers of files" << std::endl;
95 for (
const auto& filename : inputFiles)
97 TFile* f =
new TFile(filename.c_str(),
"READ");
100 std::cout <<
"File \"" << filename <<
"\" skipped as not a valid BDSIM file" << std::endl;
106 std::cout <<
"Accumulating> " << filename << std::endl;
107 TTree* headerTree =
dynamic_cast<TTree*
>(f->Get(
"Header"));
110 std::cerr <<
"Problem getting header from file " << filename << std::endl;
117 headerTree->GetEntry(0);
123 TTree* eventTree =
dynamic_cast<TTree*
>(f->Get(
"Event"));
126 Long64_t nEntries = eventTree->GetEntries();
127 nOriginalEvents += (
unsigned long long int)nEntries;
130 {std::cerr <<
"Problem getting Event tree in file " << filename << std::endl;}
140 {std::cerr <<
"No valid files found" << std::endl;
return 1;}
144 TFile* input =
nullptr;
145 bool validFile =
false;
149 if (i > (
unsigned long int)inputFiles.size())
151 input =
new TFile(inputFiles[i].c_str(),
"READ");
156 TFile* output =
new TFile(outputFile.c_str(),
"UPDATE");
157 if (output->IsZombie())
158 {std::cerr <<
"Could not reopen output file to add other trees";
return 1;}
161 headerOut->
Fill(std::vector<std::string>(), inputFiles);
165 TTree* headerTree =
new TTree(
"Header",
"BDSIM Header");
166 headerTree->Branch(
"Header.",
"BDSOutputROOTEventHeader", headerOut);
168 output->Write(
nullptr,TObject::kOverwrite);
171 std::cout <<
"Merging rest of file contents" << std::endl;
172 std::vector<std::string> treeNames = {
"ParticleData",
"Beam",
"Options",
"Model",
"Run"};
173 for (
const auto& tn : treeNames)
175 TTree* original =
dynamic_cast<TTree*
>(input->Get(tn.c_str()));
178 std::cerr <<
"Failed to load Tree named " << tn << std::endl;
183 auto clone = original->CloneTree();
190 std::cout <<
"Combined result of " << inputFiles.size() <<
" files written to: " << outputFile << std::endl;
191 std::cout <<
"Run histograms are not summed" << std::endl;
bool IsBDSIMOutputFile(TFile *file, int *dataVersion=nullptr)