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 
81  BranchType,
82  int64_t saveMemoryObjectThreshold,
84  bool compactSubRunRanges = false,
85  bool missingOK = false,
86  bool rangesEnabled = true);
87  RootInputTree(RootInputTree const&) = delete;
88  RootInputTree& operator=(RootInputTree const&) = delete;
89 
90  explicit operator bool() const { return isValid(); }
91 
92  bool isValid() const;
93  bool hasBranch(std::string const& branchName) const;
94  void addBranch(BranchKey const&, BranchDescription const&);
95  void dropBranch(std::string const& branchName);
96 
97  bool
98  next()
99  {
100  return ++entryNumber_ < entries_;
101  }
102  bool
104  {
105  return --entryNumber_ >= 0;
106  }
107 
108  bool
110  {
111  assert(!numbers.empty());
112  return std::all_of(numbers.cbegin(), numbers.cend(), [this](auto entry) {
113  return (entry < entries_) && (entry >= 0);
114  });
115  }
116 
117  void
119  {
120  entryNumber_ = 0;
121  }
123  entryNumber() const
124  {
125  return entryNumber_;
126  }
128  entries() const
129  {
130  return entries_;
131  }
132 
133  void setEntryNumber(EntryNumber theEntryNumber);
134 
135  void
137  {
138  if ((metaTree_ == nullptr) || (metaTree_->GetNbranches() == 0)) {
139  return;
140  }
141  // Loop over provenance
142  for (auto const& b : branches_) {
143  p.fillGroup(b.second.branchDescription_);
144  }
145  }
146 
147  // The BranchIDLists are passed so we can configure the
148  // ProductIDStreamer, which is necessary for backwards
149  // compatibility with ProductIDs from older files.
150 
151  // FIXME: Since in older files ProductIDs (and therefore the
152  // BranchIDLists) were only meaningfully used for events, we
153  // should not need to worry about passing the BranchIDLists in the
154  // SQLite-based makeDelayedReader overload used for (Sub)Runs.
155 
156  std::unique_ptr<DelayedReader> makeDelayedReader(
159  BranchType,
160  std::vector<EntryNumber> const& entrySet,
161  EventID);
162 
163  std::unique_ptr<DelayedReader> makeDelayedReader(
165  sqlite3* inputDB,
167  BranchType,
168  std::vector<EntryNumber> const& entrySet,
169  EventID);
170 
171  std::unique_ptr<BranchMapper> makeBranchMapper() const;
172 
173  template <typename AUX>
174  AUX
176  {
177  auto aux = std::make_unique<AUX>();
178  auto pAux = aux.get();
179  auxBranch_->SetAddress(&pAux);
180  setEntryNumber(entry);
181  input::getEntry(auxBranch_, entry);
182  auxBranch_->ResetAddress();
183  return *aux;
184  }
185 
186  template <typename AUX>
187  std::unique_ptr<RangeSetHandler>
188  fillAux(FileFormatVersion const fileFormatVersion,
189  EntryNumbers const& entries,
190  FileIndex const& fileIndex,
191  sqlite3* db,
192  std::string const& filename,
193  AUX& aux)
194  {
195  auto auxResult = getAux<AUX>(entries[0]);
196  if ((fileFormatVersion.value_ < 9) || (db == nullptr)) {
197  auxResult.setRangeSetID(-1u);
198  auto const& rs = detail::rangeSetFromFileIndex(
199  fileIndex, auxResult.id(), compactSubRunRanges_);
200  std::swap(aux, auxResult);
201  return std::make_unique<ClosedRangeSetHandler>(rs);
202  }
203 
204  auto resolve_info = [db, &filename](auto const id,
205  bool const compactSubRunRanges) {
207  db, filename, AUX::branch_type, id, compactSubRunRanges);
208  };
209 
210  auto rangeSetInfo =
211  resolve_info(auxResult.rangeSetID(), compactSubRunRanges_);
212  for (auto i = entries.cbegin() + 1, e = entries.cend(); i != e; ++i) {
213  auto const& tmpAux = getAux<AUX>(*i);
214  detail::mergeAuxiliary(auxResult, tmpAux);
215  rangeSetInfo.update(
216  resolve_info(tmpAux.rangeSetID(), compactSubRunRanges_),
217  compactSubRunRanges_);
218  }
219 
220  auxResult.setRangeSetID(-1u); // Range set of new auxiliary is invalid
221  std::swap(aux, auxResult);
222  return std::make_unique<ClosedRangeSetHandler>(
223  resolveRangeSet(rangeSetInfo));
224  }
225 
226  TTree const*
227  tree() const
228  {
229  return tree_;
230  }
231  TTree const*
232  metaTree() const
233  {
234  return metaTree_;
235  }
236 
237  void setCacheSize(unsigned int cacheSize) const;
238  void setTreeMaxVirtualSize(int treeMaxVirtualSize);
239 
240  TBranch*
242  {
243  return productProvenanceBranch_;
244  }
245 
246  private:
248  // We use bare pointers for pointers to some ROOT entities.
249  // Root owns them and uses bare pointers internally,
250  // therefore, using smart pointers here will do no good.
251  TTree* tree_{nullptr};
252  TTree* metaTree_{nullptr};
255  TBranch* auxBranch_{nullptr};
256  TBranch* productProvenanceBranch_{nullptr};
257  EntryNumber entries_{0};
258  EntryNumber entryNumber_{-1};
259  BranchMap branches_{};
262  bool const rangesEnabled_{true};
263  };
264 
265 } // namespace art
266 
267 // Local Variables:
268 // mode: c++
269 // End:
270 #endif /* art_Framework_IO_Root_RootInputTree_h */
::xsd::cxx::tree::id< char, ncname > id
Definition: Database.h:165
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_
RangeSet resolveRangeSet(RangeSetInfo const &rs)
static RangeSet forSubRun(SubRunID)
const char * p
Definition: xmltok.h:285
RangeSet makeFullRangeSet< InSubRun, SubRunID >(SubRunID const &id)
Definition: RootInputTree.h:58
RangeSet rangeSetFromFileIndex(FileIndex const &fileIndex, RunID runID, bool compactRanges)
EntryNumber entries() const
string filename
Definition: shutoffs.py:106
int64_t const saveMemoryObjectThreshold_
input::EntryNumbers EntryNumbers
Definition: RootInputTree.h:78
input::BranchMap BranchMap
Definition: RootInputTree.h:76
TTree const * metaTree() const
static RangeSet forRun(RunID)
void mergeAuxiliary(AUX &left, AUX const &right)
Definition: RootInputTree.h:43
void swap(art::HLTGlobalStatus &lhs, art::HLTGlobalStatus &rhs)
BranchType branchType_
RangeSet makeFullRangeSet< InRun, RunID >(RunID const &id)
Definition: RootInputTree.h:65
std::vector< EntryNumber > EntryNumbers
Definition: Inputfwd.h:48
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:46
virtual void fillGroup(BranchDescription const &)=0
RangeSetInfo resolveRangeSetInfo(sqlite3 *, std::string const &filename, BranchType, unsigned RangeSetID, bool compact)
void dropBranch(TTree *tree, std::string const &branchName)
input::EntryNumber EntryNumber
Definition: RootInputTree.h:77
Long64_t EntryNumber
Definition: Inputfwd.h:47
constexpr auto const & left(const_AssnsIter< L, R, D, Dir > const &a, const_AssnsIter< L, R, D, Dir > const &b)
Definition: AssnsIter.h:104
TBranch * productProvenanceBranch() const
AUX getAux(EntryNumber const entry)
const hit & b
Definition: hits.cxx:21
BranchType
Definition: BranchType.h:18
assert(nhit_max >=nhit_nbins)
Service to store calibration data products (CDP) in the SQLite3 metadatabase of a file...
Definition: FillParentInfo.h:8
Int_t getEntry(TBranch *branch, EntryNumber entryNumber)
bool const compactSubRunRanges_
Float_t e
Definition: plot.C:35
std::unique_ptr< RangeSetHandler > fillAux(FileFormatVersion const fileFormatVersion, EntryNumbers const &entries, FileIndex const &fileIndex, sqlite3 *db, std::string const &filename, AUX &aux)
def entry(str)
Definition: HTMLTools.py:26
bool current(EntryNumbers const &numbers)
enum BeamMode string