15 #include "TBranchElement.h"
16 #include "TCollection.h"
18 #include "TTreeCloner.h"
22 #include "boost/bind.hpp"
28 boost::shared_ptr<TFile> filePtr,
31 int treeMaxVirtualSize) :
37 unclonedReadBranches_(),
38 clonedReadBranchNames_(),
39 currentlyFastCloning_(),
40 fastCloneAuxBranches_(
false) {
42 if(treeMaxVirtualSize >= 0)
tree_->SetMaxVirtualSize(treeMaxVirtualSize);
47 tree->SetDirectory(filePtr);
58 <<
"Failed to create the tree: " << name <<
"\n";
61 <<
"Tree: " << name <<
" is a zombie." <<
"\n";
69 assert (inputTree != 0);
75 TBranch* outputBranch = *it;
76 if(outputBranch != 0) {
77 TBranch* inputBranch = inputTree->GetBranch(outputBranch->GetName());
79 if(inputBranch != 0) {
80 if(inputBranch->GetSplitLevel() != outputBranch->GetSplitLevel() ||
81 inputBranch->GetBasketSize() != outputBranch->GetBasketSize()) {
91 bool checkMatchingBranches(TBranchElement* inputBranch, TBranchElement* outputBranch) {
92 if(inputBranch->GetStreamerType() != outputBranch->GetStreamerType()) {
95 TObjArray* inputArray = inputBranch->GetListOfBranches();
96 TObjArray* outputArray = outputBranch->GetListOfBranches();
98 if(outputArray->GetSize() < inputArray->GetSize()) {
101 TIter
iter(outputArray);
103 while((obj =
iter.Next()) != 0) {
104 TBranchElement* outBranch =
dynamic_cast<TBranchElement*
>(
obj);
106 TBranchElement* inBranch =
dynamic_cast<TBranchElement*
>(inputArray->FindObject(outBranch->GetName()));
110 if(!checkMatchingBranches(inBranch, outBranch)) {
121 if(inputTree == 0)
return false;
125 TBranchElement* outputBranch =
dynamic_cast<TBranchElement*
>(*it);
126 if(outputBranch != 0) {
127 TBranchElement* inputBranch =
dynamic_cast<TBranchElement*
>(inputTree->GetBranch(outputBranch->GetName()));
128 if(inputBranch != 0) {
130 if(!checkMatchingBranches(inputBranch, outputBranch)) {
132 <<
"Fast Cloning disabled because a data member has been added to split branch: " << inputBranch->GetName() <<
"\n.";
143 if((*it)->GetEntries() != expectedNumberOfEntries) {
152 if(in->GetEntries() != 0) {
153 TObjArray* branches =
tree_->GetListOfBranches();
156 std::map<Int_t, TBranch *> auxIndexes;
157 bool mustRemoveSomeAuxs =
false;
161 int auxIndex = branches->IndexOf(*it);
162 assert (auxIndex >= 0);
163 auxIndexes.insert(std::make_pair(auxIndex, *it));
164 branches->RemoveAt(auxIndex);
166 mustRemoveSomeAuxs =
true;
173 int auxIndex = branches->IndexOf(*it);
174 assert (auxIndex >= 0);
175 auxIndexes.insert(std::make_pair(auxIndex, *it));
176 branches->RemoveAt(auxIndex);
177 mustRemoveSomeAuxs =
true;
180 if(mustRemoveSomeAuxs) {
181 branches->Compress();
184 TTreeCloner cloner(in,
tree_, option.c_str(), TTreeCloner::kNoWarnings|TTreeCloner::kIgnoreMissingTopLevel);
186 if(!cloner.IsValid()) {
188 static const char* okerror =
"One of the export branch";
189 if(strncmp(cloner.GetWarning(), okerror, strlen(okerror)) == 0) {
193 <<
"invalid TTreeCloner (" << cloner.GetWarning() <<
")\n";
196 tree_->SetEntries(
tree_->GetEntries() + in->GetEntries());
198 rootHandler->ignoreWarningsWhileDoing([&cloner] { cloner.Exec(); });
199 if(mustRemoveSomeAuxs) {
200 for(std::map<Int_t, TBranch *>::const_iterator it = auxIndexes.begin(), itEnd = auxIndexes.end();
203 Int_t
last = branches->GetLast();
205 branches->AddAtAndExpand(branches->At(last), last+1);
206 for(Int_t ind = last-1; ind >= it->first; --ind) {
207 branches->AddAt(branches->At(ind), ind+1);
209 branches->AddAt(it->second, it->first);
211 branches->Add(it->second);
220 if(tree->GetNbranches() != 0) {
221 tree->SetEntries(-1);
224 tree->AutoSave(
"FlushBaskets");
247 if((*it)->GetEntries() ==
tree_->GetEntries()) {
280 TBranch* branch =
tree_->Branch(branchName.c_str(),
std::set< std::string > clonedReadBranchNames_
static int const invalidSplitLevel
static int const invalidBasketSize
static void fillTTree(std::vector< TBranch * > const &branches)
bool checkSplitLevelsAndBasketSizes(TTree *inputTree) const
void setRefCoreStreamer(bool resetAll=false)
std::vector< TBranch * > unclonedAuxBranches_
bool checkIfFastClonable(TTree *inputTree) const
void addBranch(std::string const &branchName, std::string const &className, WrapperInterfaceBase const *interface, void const *&pProd, int splitLevel, int basketSize, bool produced)
std::vector< TBranch * > producedBranches_
std::vector< TBranch * > auxBranches_
Func for_all(ForwardSequence &s, Func f)
wrapper for std::for_each
boost::shared_ptr< TFile > filePtr_
static TTree * assignTTree(TFile *file, TTree *tree)
const T & max(const T &a, const T &b)
void Fill(HcalDetId &id, double val, std::vector< TH2F > &depth)
bool currentlyFastCloning_
std::vector< TBranch * > unclonedReadBranches_
bool checkEntriesInReadBranches(Long64_t expectedNumberOfEntries) const
std::string const & BranchTypeToProductTreeName(BranchType const &branchType)
static TTree * makeTTree(TFile *filePtr, std::string const &name, int splitLevel)
void deleteProduct(void const *me) const
eventsetup::produce::Produce produced
RootOutputTree(boost::shared_ptr< TFile > filePtr, BranchType const &branchType, int splitLevel, int treeMaxVirtualSize)
static void writeTTree(TTree *tree)
std::vector< TBranch * > readBranches_
volatile std::atomic< bool > shutdown_flag false
void maybeFastCloneTree(bool canFastClone, bool canFastCloneAux, TTree *tree, std::string const &option)
bool fastCloneAuxBranches_
T get(const Candidate &c)
std::string className(const T &t)
void fastCloneTTree(TTree *in, std::string const &option)