46 bpo::options_description options(
47 "A tool to create a single TTree from a list of TTrees (each in its own file).\nMerging is "
48 "done vertically - over branches - instead over entries (like in a TChain).\nIt corresponds to the TFriend mechanism but makes a deep copy\n"
49 "(unless the friend is asked).\n\n"
52 options.add_options()(
53 "infiles,i", bpo::value<std::vector<std::string>>(&optvalues.
infilenames)->multitoken(),
"All input files to be merged")(
54 "treename,t", bpo::value<std::string>(&optvalues.
treename),
"Name of tree (assumed same in all files).")(
55 "outfile,o", bpo::value<std::string>(&optvalues.
outfilename)->default_value(
""),
"Outfile to be created with merged tree.")(
56 "asfriend",
"If merging is done using the friend mechanism.");
57 options.add_options()(
"help,h",
"Produce help message.");
59 bpo::variables_map vm;
61 bpo::store(bpo::command_line_parser(argc, argv).options(options).run(), vm);
65 if (vm.count(
"help")) {
66 std::cout << options << std::endl;
69 if (vm.count(
"asfriend")) {
73 }
catch (
const bpo::error& e) {
74 std::cerr << e.what() <<
"\n\n";
75 std::cerr <<
"Error parsing options; Available options:\n";
76 std::cerr << options << std::endl;
166 auto newfile = TFile::Open(options.
outfilename.c_str(),
"RECREATE");
167 auto newtree =
new TTree(options.
treename.c_str(),
"");
188 auto copyBranch = [](TTree* t, TBranch* br) ->
bool {
193 TClass* clptr =
nullptr;
195 if (br->GetExpectedType(clptr,
type) == 0) {
196 char*
data =
nullptr;
197 TBranch* newbr =
nullptr;
198 if (clptr !=
nullptr) {
199 newbr = ((
MyTTreeHelper*)t)->PublicBranchImp(br->GetName(), clptr, &
data, 32000, br->GetSplitLevel());
200 }
else if (
type != EDataType::kOther_t) {
202 varname.Form(
"%s/%c", br->GetName(), DataTypeToChar(
type));
203 newbr = t->Branch(br->GetName(), &
data, varname.Data());
205 std::cerr <<
"Could not retrieve class/type information. Branch " << br->GetName() <<
"cannot be copied.\n";
209 br->SetAddress(&
data);
210 for (
int e = 0; e < br->GetEntries(); ++e) {
211 auto size = br->GetEntry(e);
215 br->DropBaskets(
"all");
223 TFile outfile(options.
outfilename.c_str(),
"RECREATE");
224 auto outtree =
new TTree(options.
treename.c_str(), options.
treename.c_str());
227 TFile _tmp(
filename.c_str(),
"OPEN");
228 auto t = (TTree*)_tmp.Get(options.
treename.c_str());
229 auto brlist = t->GetListOfBranches();
230 for (
int i = 0;
i < brlist->GetEntries(); ++
i) {
231 auto br = (TBranch*)brlist->At(
i);
232 if (!copyBranch(outtree, br)) {
233 std::cerr <<
"Error copying branch " << br->GetName() <<
"\n";
236 outtree->SetEntries(t->GetEntries());