LArSoft  v07_13_02
Liquid Argon Software toolkit - http://larsoft.org/
art::RootOutputTree Class Reference

#include "RootOutputTree.h"

Public Member Functions

template<typename Aux >
 RootOutputTree (cet::exempt_ptr< TFile > filePtr, BranchType const branchType, Aux const *&pAux, ProductProvenances *&pProductProvenanceVector, int const bufSize, int const splitLevel, int64_t const treeMaxVirtualSize, int64_t const saveMemoryObjectThreshold)
 
 RootOutputTree (RootOutputTree const &)=delete
 
RootOutputTreeoperator= (RootOutputTree const &)=delete
 
bool isValid () const
 
void setOutputBranchAddress (BranchDescription const &pd, void const *&pProd)
 
void resetOutputBranchAddress (BranchDescription const &)
 
void addOutputBranch (BranchDescription const &, void const *&pProd)
 
bool checkSplitLevelAndBasketSize (cet::exempt_ptr< TTree const >) const
 
bool fastCloneTree (cet::exempt_ptr< TTree const >)
 
void fillTree ()
 
void writeTree () const
 
TTree * tree () const
 
TTree * metaTree () const
 
void setEntries ()
 
void beginInputFile (bool fastCloning)
 
bool uncloned (std::string const &branchName) const
 

Static Public Member Functions

static TTree * makeTTree (TFile *, std::string const &name, int splitLevel)
 
static void writeTTree (TTree *) noexcept(false)
 

Private Attributes

cet::exempt_ptr< TFile > filePtr_
 
TTree *const tree_
 
TTree *const metaTree_
 
TBranch * auxBranch_ {nullptr}
 
TBranch * productProvenanceBranch_ {nullptr}
 
std::vector< TBranch * > producedBranches_ {}
 
std::vector< TBranch * > metaBranches_ {}
 
std::vector< TBranch * > readBranches_ {}
 
std::vector< TBranch * > unclonedReadBranches_ {}
 
std::set< std::string > unclonedReadBranchNames_ {}
 
bool fastCloningEnabled_ {false}
 
int basketSize_
 
int splitLevel_
 
int64_t saveMemoryObjectThreshold_
 
int nEntries_ {0}
 

Detailed Description

Definition at line 24 of file RootOutputTree.h.

Constructor & Destructor Documentation

template<typename Aux >
art::RootOutputTree::RootOutputTree ( cet::exempt_ptr< TFile >  filePtr,
BranchType const  branchType,
Aux const *&  pAux,
ProductProvenances *&  pProductProvenanceVector,
int const  bufSize,
int const  splitLevel,
int64_t const  treeMaxVirtualSize,
int64_t const  saveMemoryObjectThreshold 
)
inline

Definition at line 35 of file RootOutputTree.h.

References addOutputBranch(), auxBranch_, basketSize_, art::BranchTypeToAuxiliaryBranchName(), art::BranchTypeToMetaDataTreeName(), art::BranchTypeToProductTreeName(), checkSplitLevelAndBasketSize(), fastCloneTree(), fillTree(), isValid(), makeTTree(), metaBranches_, metaTree_, operator=(), productProvenanceBranch_, art::productProvenanceBranchName(), readBranches_, resetOutputBranchAddress(), saveMemoryObjectThreshold_, setOutputBranchAddress(), splitLevel_, tree_, and writeTree().

43  : filePtr_{filePtr}
44  , tree_{makeTTree(filePtr.get(),
45  BranchTypeToProductTreeName(branchType),
46  splitLevel)}
47  , metaTree_{makeTTree(filePtr.get(),
48  BranchTypeToMetaDataTreeName(branchType),
49  0)}
50  , basketSize_{bufSize}
51  , splitLevel_{splitLevel}
52  , saveMemoryObjectThreshold_{saveMemoryObjectThreshold}
53  {
54  if (treeMaxVirtualSize >= 0) {
55  tree_->SetMaxVirtualSize(treeMaxVirtualSize);
56  }
57  auxBranch_ = tree_->Branch(
58  BranchTypeToAuxiliaryBranchName(branchType).c_str(), &pAux, bufSize, 0);
59  delete pAux;
60  pAux = nullptr;
61  readBranches_.push_back(auxBranch_);
63  metaTree_->Branch(productProvenanceBranchName(branchType).c_str(),
64  &pProductProvenanceVector,
65  bufSize,
66  0);
68  }
std::string const & BranchTypeToProductTreeName(BranchType const bt)
Definition: BranchType.cc:71
std::string const & productProvenanceBranchName(BranchType const bt)
Definition: BranchType.cc:91
std::vector< TBranch * > readBranches_
std::string const & BranchTypeToMetaDataTreeName(BranchType const bt)
Definition: BranchType.cc:77
cet::exempt_ptr< TFile > filePtr_
TTree *const metaTree_
std::string const & BranchTypeToAuxiliaryBranchName(BranchType const bt)
Definition: BranchType.cc:83
TBranch * productProvenanceBranch_
static TTree * makeTTree(TFile *, std::string const &name, int splitLevel)
int64_t saveMemoryObjectThreshold_
std::vector< TBranch * > metaBranches_
art::RootOutputTree::RootOutputTree ( RootOutputTree const &  )
delete

Member Function Documentation

void art::RootOutputTree::addOutputBranch ( BranchDescription const &  pd,
void const *&  pProd 
)

Definition at line 185 of file RootOutputTree.cc.

References art::BranchDescription::basketSize(), art::BranchDescription::branchName(), art::BranchDescription::compression(), art::errors::FatalRootError, art::BranchDescription::produced(), art::BranchDescription::splitLevel(), and art::BranchDescription::wrappedName().

Referenced by RootOutputTree().

187  {
188  TClassRef cls = TClass::GetClass(pd.wrappedName().c_str());
189  if (auto br = tree_->GetBranch(pd.branchName().c_str())) {
190  // Already have this branch, possibly update the branch address.
191  if (pProd == nullptr) {
192  // The OutputItem is freshly constructed and has not been
193  // passed to SetAddress yet. If selectProducts has just been
194  // called, we get here just after the branch object has been
195  // deleted with a ResetBranchAddress() to prepare for the
196  // OutputItem being replaced, and the OutputItem has just been
197  // recreated.
198  auto prod = reinterpret_cast<EDProduct*>(cls->New());
199  pProd = prod;
200  br->SetAddress(&pProd);
201  pProd = nullptr;
202  delete prod;
203  }
204  return;
205  }
206  auto bsize = pd.basketSize();
208  bsize = basketSize_;
209  }
210  auto splitlvl = pd.splitLevel();
211  if (splitlvl == BranchDescription::invalidSplitLevel) {
212  splitlvl = splitLevel_;
213  }
214  if (pProd != nullptr) {
216  << "OutputItem product pointer is not nullptr!\n";
217  }
218  auto prod = reinterpret_cast<EDProduct*>(cls->New());
219  pProd = prod;
220  TBranch* branch = tree_->Branch(pd.branchName().c_str(),
221  pd.wrappedName().c_str(),
222  &pProd,
223  bsize,
224  splitlvl);
225 
226  // Note that root will have just allocated a dummy product as the
227  // I/O buffer for the branch we have created. We will replace
228  // this I/O buffer in RootOutputFile::fillBranches() with the
229  // actual product or our own dummy using
230  // TBranchElement::SetAddress(), which will cause root to
231  // automatically delete the dummy product it allocated here.
232 
233  pProd = nullptr;
234  delete prod;
235  if (pd.compression() != BranchDescription::invalidCompression) {
236  branch->SetCompressionSettings(pd.compression());
237  }
238  if (nEntries_ > 0) {
239  // Backfill the branch with dummy entries to match the number
240  // of entries already written to the data tree.
241  std::unique_ptr<EDProduct> dummy(static_cast<EDProduct*>(cls->New()));
242  pProd = dummy.get();
243  int bytesWritten{};
244  for (auto i = nEntries_; i > 0; --i) {
245  auto cnt = branch->Fill();
246  if (cnt <= 0) {
247  // FIXME: Throw a fatal error here!
248  }
249  bytesWritten += cnt;
250  if ((saveMemoryObjectThreshold_ > -1) &&
251  (bytesWritten > saveMemoryObjectThreshold_)) {
252  branch->FlushBaskets();
253  branch->DropBaskets("all");
254  }
255  }
256  }
257  if (pd.produced()) {
258  producedBranches_.push_back(branch);
259  } else {
260  readBranches_.push_back(branch);
261  }
262  }
std::vector< TBranch * > readBranches_
static int constexpr invalidCompression
std::vector< TBranch * > producedBranches_
static int constexpr invalidSplitLevel
cet::coded_exception< errors::ErrorCodes, ExceptionDetail::translate > Exception
Definition: Exception.h:66
int64_t saveMemoryObjectThreshold_
static int constexpr invalidBasketSize
void art::RootOutputTree::beginInputFile ( bool  fastCloning)
inline

Definition at line 117 of file RootOutputTree.h.

References fastCloningEnabled_.

118  {
119  fastCloningEnabled_ = fastCloning;
120  }
bool art::RootOutputTree::checkSplitLevelAndBasketSize ( cet::exempt_ptr< TTree const >  inputTree) const

Definition at line 45 of file RootOutputTree.cc.

References GetBranch().

Referenced by RootOutputTree().

47  {
48  // Do the split level and basket size match in the input and output?
49  if (inputTree == nullptr) {
50  return false;
51  }
52  for (auto outputBranch : readBranches_) {
53  if (outputBranch == nullptr) {
54  continue;
55  }
56  TBranch* inputBranch =
57  const_cast<TTree*>(inputTree.get())->GetBranch(outputBranch->GetName());
58  if (inputBranch == nullptr) {
59  continue;
60  }
61  if ((inputBranch->GetSplitLevel() != outputBranch->GetSplitLevel()) ||
62  (inputBranch->GetBasketSize() != outputBranch->GetBasketSize())) {
63  mf::LogInfo("FastCloning")
64  << "Fast Cloning disabled because split level or basket size "
65  "do not match";
66  return false;
67  }
68  }
69  return true;
70  }
ntuple GetBranch("organID") -> SetAddress(&xx)
MaybeLogger_< ELseverityLevel::ELsev_info, false > LogInfo
std::vector< TBranch * > readBranches_
bool art::RootOutputTree::fastCloneTree ( cet::exempt_ptr< TTree const >  intree)

Definition at line 94 of file RootOutputTree.cc.

Referenced by RootOutputTree().

95  {
96  unclonedReadBranches_.clear();
98  if (!fastCloningEnabled_) {
99  return false;
100  }
101 
102  bool cloned{false};
103  if (intree->GetEntries() != 0) {
104  TTreeCloner cloner(const_cast<TTree*>(intree.get()),
105  tree_,
106  "",
107  TTreeCloner::kIgnoreMissingTopLevel |
108  TTreeCloner::kNoWarnings |
109  TTreeCloner::kNoFileCache);
110  if (cloner.IsValid()) {
111  tree_->SetEntries(tree_->GetEntries() + intree->GetEntries());
112  cloner.Exec();
113  cloned = true;
114  } else {
115  fastCloningEnabled_ = false;
116  mf::LogInfo("fastCloneTree")
117  << "INFO: Unable to fast clone tree " << intree->GetName() << '\n'
118  << "INFO: ROOT reason is:\n"
119  << "INFO: " << cloner.GetWarning() << '\n'
120  << "INFO: Processing will continue, tree will be slow cloned.";
121  }
122  }
123  for (auto const& val : readBranches_) {
124  if (val->GetEntries() != tree_->GetEntries()) {
125  unclonedReadBranches_.push_back(val);
126  unclonedReadBranchNames_.insert(string(val->GetName()));
127  }
128  }
129  return cloned;
130  }
std::set< std::string > unclonedReadBranchNames_
MaybeLogger_< ELseverityLevel::ELsev_info, false > LogInfo
std::vector< TBranch * > readBranches_
std::vector< TBranch * > unclonedReadBranches_
void art::RootOutputTree::fillTree ( )

Definition at line 148 of file RootOutputTree.cc.

References art::fillTreeBranches().

Referenced by RootOutputTree().

149  {
152  bool saveMemory = (saveMemoryObjectThreshold_ > -1);
155  if (fastCloningEnabled_) {
158  } else {
161  }
162  ++nEntries_;
163  }
std::vector< TBranch * > readBranches_
TTree *const metaTree_
static void fillTreeBranches(TTree *, vector< TBranch * > const &branches, bool saveMemory, int64_t threshold)
std::vector< TBranch * > producedBranches_
std::vector< TBranch * > unclonedReadBranches_
int64_t saveMemoryObjectThreshold_
std::vector< TBranch * > metaBranches_
bool art::RootOutputTree::isValid ( ) const

Referenced by RootOutputTree().

TTree * art::RootOutputTree::makeTTree ( TFile *  filePtr,
std::string const &  name,
int  splitLevel 
)
static

Definition at line 26 of file RootOutputTree.cc.

References art::errors::FatalRootError, and max.

Referenced by art::RootOutputFile::RootOutputFile(), and RootOutputTree().

27  {
28  auto tree = new TTree{name.c_str(), "", splitLevel};
29  if (!tree) {
31  << "Failed to create the tree: " << name << "\n";
32  }
33  if (tree->IsZombie()) {
35  << "Tree: " << name << " is a zombie.\n";
36  }
37  tree->SetDirectory(filePtr);
38  // Turn off autosave because it leaves too many deleted tree
39  // keys in the output file.
40  tree->SetAutoSave(numeric_limits<Long64_t>::max());
41  return tree;
42  }
Int_t max
Definition: plot.C:27
TTree * tree() const
cet::coded_exception< errors::ErrorCodes, ExceptionDetail::translate > Exception
Definition: Exception.h:66
TTree* art::RootOutputTree::metaTree ( ) const
inline

Definition at line 95 of file RootOutputTree.h.

References metaTree_.

96  {
97  return metaTree_;
98  }
TTree *const metaTree_
RootOutputTree& art::RootOutputTree::operator= ( RootOutputTree const &  )
delete

Referenced by RootOutputTree().

void art::RootOutputTree::resetOutputBranchAddress ( BranchDescription const &  pd)

Definition at line 166 of file RootOutputTree.cc.

References art::BranchDescription::branchName().

Referenced by RootOutputTree().

167  {
168  TBranch* br = tree_->GetBranch(pd.branchName().c_str());
169  if (br == nullptr) {
170  return;
171  }
172  tree_->ResetBranchAddress(br);
173  }
void art::RootOutputTree::setEntries ( )
inline

Definition at line 101 of file RootOutputTree.h.

References metaTree_, and tree_.

102  {
103  // The member trees are filled by filling their
104  // branches individually, which ends up not setting
105  // the tree entry count. Tell the trees to set their
106  // entry count based on their branches (all branches
107  // must have the same number of entries).
108  if (tree_->GetNbranches() != 0) {
109  tree_->SetEntries(-1);
110  }
111  if (metaTree_->GetNbranches() != 0) {
112  metaTree_->SetEntries(-1);
113  }
114  }
TTree *const metaTree_
void art::RootOutputTree::setOutputBranchAddress ( BranchDescription const &  pd,
void const *&  pProd 
)

Definition at line 176 of file RootOutputTree.cc.

References art::BranchDescription::branchName().

Referenced by RootOutputTree().

178  {
179  if (TBranch* br = tree_->GetBranch(pd.branchName().c_str())) {
180  br->SetAddress(&pProd);
181  }
182  }
TTree* art::RootOutputTree::tree ( ) const
inline

Definition at line 89 of file RootOutputTree.h.

References tree_.

90  {
91  return tree_;
92  }
bool art::RootOutputTree::uncloned ( std::string const &  branchName) const
inline

Definition at line 123 of file RootOutputTree.h.

References unclonedReadBranchNames_.

124  {
125  return unclonedReadBranchNames_.find(branchName) !=
127  }
std::set< std::string > unclonedReadBranchNames_
void art::RootOutputTree::writeTree ( ) const

Definition at line 87 of file RootOutputTree.cc.

Referenced by RootOutputTree().

88  {
91  }
TTree *const metaTree_
static void writeTTree(TTree *) noexcept(false)
void art::RootOutputTree::writeTTree ( TTree *  tree)
staticnoexcept

Definition at line 73 of file RootOutputTree.cc.

Referenced by art::RootOutputFile::writeEventHistory(), and art::RootOutputFile::writeTTrees().

74  {
75  // Update the tree-level entry count because we have been
76  // using branch fill instead of tree fill.
77  if (tree->GetNbranches() != 0) {
78  tree->SetEntries(-1);
79  }
80  // Use auto save here instead of write because it deletes
81  // the old tree key from the file, does not flush the
82  // baskets, and writes out the streamer infos, unlike write.
83  tree->AutoSave();
84  }
TTree * tree() const

Member Data Documentation

TBranch* art::RootOutputTree::auxBranch_ {nullptr}
private

Definition at line 133 of file RootOutputTree.h.

Referenced by RootOutputTree().

int art::RootOutputTree::basketSize_
private

Definition at line 147 of file RootOutputTree.h.

Referenced by RootOutputTree().

bool art::RootOutputTree::fastCloningEnabled_ {false}
private

Definition at line 145 of file RootOutputTree.h.

Referenced by beginInputFile().

cet::exempt_ptr<TFile> art::RootOutputTree::filePtr_
private

Definition at line 130 of file RootOutputTree.h.

std::vector<TBranch*> art::RootOutputTree::metaBranches_ {}
private

Definition at line 137 of file RootOutputTree.h.

Referenced by RootOutputTree().

TTree* const art::RootOutputTree::metaTree_
private

Definition at line 132 of file RootOutputTree.h.

Referenced by metaTree(), RootOutputTree(), and setEntries().

int art::RootOutputTree::nEntries_ {0}
private

Definition at line 150 of file RootOutputTree.h.

std::vector<TBranch*> art::RootOutputTree::producedBranches_ {}
private

Definition at line 136 of file RootOutputTree.h.

TBranch* art::RootOutputTree::productProvenanceBranch_ {nullptr}
private

Definition at line 134 of file RootOutputTree.h.

Referenced by RootOutputTree().

std::vector<TBranch*> art::RootOutputTree::readBranches_ {}
private

Definition at line 138 of file RootOutputTree.h.

Referenced by RootOutputTree().

int64_t art::RootOutputTree::saveMemoryObjectThreshold_
private

Definition at line 149 of file RootOutputTree.h.

Referenced by RootOutputTree().

int art::RootOutputTree::splitLevel_
private

Definition at line 148 of file RootOutputTree.h.

Referenced by RootOutputTree().

TTree* const art::RootOutputTree::tree_
private

Definition at line 131 of file RootOutputTree.h.

Referenced by RootOutputTree(), setEntries(), and tree().

std::vector<TBranch*> art::RootOutputTree::unclonedReadBranches_ {}
private

Definition at line 139 of file RootOutputTree.h.

std::set<std::string> art::RootOutputTree::unclonedReadBranchNames_ {}
private

Definition at line 140 of file RootOutputTree.h.

Referenced by uncloned().


The documentation for this class was generated from the following files: