LArSoft  v06_85_00
Liquid Argon Software toolkit - http://larsoft.org/
RootInputTree.h
Go to the documentation of this file.
1 #ifndef art_Framework_IO_Root_RootInputTree_h
2 #define art_Framework_IO_Root_RootInputTree_h
3 // vim: set sw=2:
4 
5 //
6 // RootInputTree
7 //
8 // Used by ROOT input sources.
9 //
10 
25 #include "cetlib/exempt_ptr.h"
26 
27 #include "TBranch.h"
28 #include "TTree.h"
29 
30 #include <memory>
31 #include <string>
32 #include <vector>
33 
34 class TFile;
35 struct sqlite3;
36 
37 namespace art {
38 
39  namespace detail {
40 
41  template <typename AUX>
42  void
43  mergeAuxiliary(AUX& left, AUX const& right)
44  {
45  left.mergeAuxiliary(right);
46  }
47 
48  template <>
49  inline void
51  {}
52 
53  template <BranchType, typename ID>
54  RangeSet makeFullRangeSet(ID const&);
55 
56  template <>
57  inline RangeSet
59  {
60  return RangeSet::forSubRun(id);
61  }
62 
63  template <>
64  inline RangeSet
66  {
67  return RangeSet::forRun(id);
68  }
69  }
70 
71  class DelayedReader;
72  class Principal;
73 
74  class RootInputTree {
75  public:
79 
80  RootInputTree(cet::exempt_ptr<TFile>,
81  BranchType,
82  int64_t saveMemoryObjectThreshold,
83  cet::exempt_ptr<RootInputFile>,
84  bool compactSubRunRanges = false,
85  bool missingOK = false);
86  RootInputTree(RootInputTree const&) = delete;
87  RootInputTree& operator=(RootInputTree const&) = delete;
88 
89  explicit operator bool() const { return isValid(); }
90 
91  bool isValid() const;
92  bool hasBranch(std::string const& branchName) const;
93  void addBranch(BranchKey const&, BranchDescription const&);
94  void dropBranch(std::string const& branchName);
95 
96  bool
97  next()
98  {
99  return ++entryNumber_ < entries_;
100  }
101  bool
103  {
104  return --entryNumber_ >= 0;
105  }
106 
107  bool
108  current(EntryNumbers const& numbers)
109  {
110  assert(!numbers.empty());
111  return std::all_of(numbers.cbegin(), numbers.cend(), [this](auto entry) {
112  return (entry < entries_) && (entry >= 0);
113  });
114  }
115 
116  void
118  {
119  entryNumber_ = 0;
120  }
122  entryNumber() const
123  {
124  return entryNumber_;
125  }
127  entries() const
128  {
129  return entries_;
130  }
131 
132  void setEntryNumber(EntryNumber theEntryNumber);
133 
134  void
136  {
137  if ((metaTree_ == nullptr) || (metaTree_->GetNbranches() == 0)) {
138  return;
139  }
140  // Loop over provenance
141  for (auto const& b : branches_) {
142  p.fillGroup(b.second.branchDescription_);
143  }
144  }
145 
146  // The BranchIDLists are passed so we can configure the
147  // ProductIDStreamer, which is necessary for backwards
148  // compatibility with ProductIDs from older files.
149 
150  // FIXME: Since in older files ProductIDs (and therefore the
151  // BranchIDLists) were only meaningfully used for events, we
152  // should not need to worry about passing the BranchIDLists in the
153  // SQLite-based makeDelayedReader overload used for (Sub)Runs.
154 
155  std::unique_ptr<DelayedReader> makeDelayedReader(
157  cet::exempt_ptr<BranchIDLists const> branchIDLists,
158  BranchType,
159  std::vector<EntryNumber> const& entrySet,
160  EventID);
161 
162  std::unique_ptr<DelayedReader> makeDelayedReader(
164  sqlite3* inputDB,
165  cet::exempt_ptr<BranchIDLists const> branchIDLists,
166  BranchType,
167  std::vector<EntryNumber> const& entrySet,
168  EventID);
169 
170  std::unique_ptr<BranchMapper> makeBranchMapper() const;
171 
172  template <typename AUX>
173  AUX
174  getAux(EntryNumber const entry)
175  {
176  auto aux = std::make_unique<AUX>();
177  auto pAux = aux.get();
178  auxBranch_->SetAddress(&pAux);
179  setEntryNumber(entry);
180  input::getEntry(auxBranch_, entry);
181  return *aux;
182  }
183 
184  template <typename AUX>
185  std::unique_ptr<RangeSetHandler>
186  fillAux(FileFormatVersion const fileFormatVersion,
187  EntryNumbers const& entries,
188  FileIndex const& fileIndex,
189  sqlite3* db,
190  std::string const& filename,
191  AUX& aux)
192  {
193  auto auxResult = getAux<AUX>(entries[0]);
194  if (fileFormatVersion.value_ < 9) {
195  auxResult.setRangeSetID(-1u);
196  auto const& rs = detail::rangeSetFromFileIndex(
197  fileIndex, auxResult.id(), compactSubRunRanges_);
198  std::swap(aux, auxResult);
199  return std::make_unique<ClosedRangeSetHandler>(rs);
200  }
201 
202  auto resolve_info = [db, &filename](auto const id,
203  bool const compactSubRunRanges) {
205  db, filename, AUX::branch_type, id, compactSubRunRanges);
206  };
207 
208  auto rangeSetInfo =
209  resolve_info(auxResult.rangeSetID(), compactSubRunRanges_);
210  for (auto i = entries.cbegin() + 1, e = entries.cend(); i != e; ++i) {
211  auto const& tmpAux = getAux<AUX>(*i);
212  detail::mergeAuxiliary(auxResult, tmpAux);
213  rangeSetInfo.update(
214  resolve_info(tmpAux.rangeSetID(), compactSubRunRanges_),
215  compactSubRunRanges_);
216  }
217 
218  auxResult.setRangeSetID(-1u); // Range set of new auxiliary is invalid
219  std::swap(aux, auxResult);
220  return std::make_unique<ClosedRangeSetHandler>(
221  resolveRangeSet(rangeSetInfo));
222  }
223 
224  TTree const*
225  tree() const
226  {
227  return tree_;
228  }
229  TTree const*
230  metaTree() const
231  {
232  return metaTree_;
233  }
234 
235  void setCacheSize(unsigned int cacheSize) const;
236  void setTreeMaxVirtualSize(int treeMaxVirtualSize);
237 
238  TBranch*
240  {
241  return productProvenanceBranch_;
242  }
243 
244  private:
245  cet::exempt_ptr<TFile> filePtr_;
246  // We use bare pointers for pointers to some ROOT entities.
247  // Root owns them and uses bare pointers internally,
248  // therefore, using smart pointers here will do no good.
249  TTree* tree_{nullptr};
250  TTree* metaTree_{nullptr};
253  TBranch* auxBranch_{nullptr};
254  TBranch* productProvenanceBranch_{nullptr};
255  EntryNumber entries_{0};
256  EntryNumber entryNumber_{-1};
257  BranchMap branches_{};
258  cet::exempt_ptr<RootInputFile> primaryFile_;
260  };
261 
262 } // namespace art
263 
264 // Local Variables:
265 // mode: c++
266 // End:
267 #endif /* art_Framework_IO_Root_RootInputTree_h */
RangeSet makeFullRangeSet(ID const &)
constexpr auto const & right(const_AssnsIter< L, R, D, Dir > const &a, const_AssnsIter< L, R, D, Dir > const &b)
Definition: AssnsIter.h:112
cet::exempt_ptr< TFile > filePtr_
RangeSetInfo resolveRangeSetInfo(sqlite3 *, std::string const &filename, BranchType, unsigned RangeSetID, bool compact)
RangeSet makeFullRangeSet< InSubRun, SubRunID >(SubRunID const &id)
Definition: RootInputTree.h:58
RangeSet rangeSetFromFileIndex(FileIndex const &fileIndex, RunID runID, bool compactRanges)
EntryNumber entries() const
int64_t const saveMemoryObjectThreshold_
RangeSet resolveRangeSet(RangeSetInfo const &rs)
input::EntryNumbers EntryNumbers
Definition: RootInputTree.h:78
input::BranchMap BranchMap
Definition: RootInputTree.h:76
TTree const * metaTree() const
void mergeAuxiliary(AUX &left, AUX const &right)
Definition: RootInputTree.h:43
BranchType branchType_
RangeSet makeFullRangeSet< InRun, RunID >(RunID const &id)
Definition: RootInputTree.h:65
std::vector< EntryNumber > EntryNumbers
Definition: Inputfwd.h:47
EntryNumber entryNumber() const
TTree const * tree() const
void fillGroups(Principal &p)
cet::exempt_ptr< RootInputFile > primaryFile_
std::map< BranchKey const, BranchInfo > BranchMap
Definition: Inputfwd.h:45
static RangeSet forRun(RunID)
Definition: RangeSet.cc:52
virtual void fillGroup(BranchDescription const &)=0
input::EntryNumber EntryNumber
Definition: RootInputTree.h:77
Long64_t EntryNumber
Definition: Inputfwd.h:46
constexpr auto const & left(const_AssnsIter< L, R, D, Dir > const &a, const_AssnsIter< L, R, D, Dir > const &b)
Definition: AssnsIter.h:104
static RangeSet forSubRun(SubRunID)
Definition: RangeSet.cc:58
TBranch * productProvenanceBranch() const
AUX getAux(EntryNumber const entry)
BranchType
Definition: BranchType.h:18
HLT enums.
Int_t getEntry(TBranch *branch, EntryNumber entryNumber)
Definition: getEntry.cc:12
bool const compactSubRunRanges_
Float_t e
Definition: plot.C:34
std::unique_ptr< RangeSetHandler > fillAux(FileFormatVersion const fileFormatVersion, EntryNumbers const &entries, FileIndex const &fileIndex, sqlite3 *db, std::string const &filename, AUX &aux)
bool current(EntryNumbers const &numbers)