LArSoft  v07_13_02
Liquid Argon Software toolkit - http://larsoft.org/
RootDelayedReader.cc
Go to the documentation of this file.
2 // vim: sw=2:
3 
4 #include "TBranch.h"
5 #include "TBranchElement.h"
6 #include "TClass.h"
13 #include "canvas_root_io/Streamers/ProductIDStreamer.h"
14 #include "canvas_root_io/Streamers/RefCoreStreamer.h"
15 #include "cetlib/crc32.h"
16 
17 #include <cassert>
18 
19 using namespace std;
20 
21 namespace art {
22 
23  RootDelayedReader::RootDelayedReader(
24  FileFormatVersion const version,
25  sqlite3* db,
26  std::vector<input::EntryNumber> const& entrySet,
27  input::BranchMap const& branches,
28  cet::exempt_ptr<RootInputTree> tree,
29  int64_t const saveMemoryObjectThreshold,
30  cet::exempt_ptr<RootInputFile> primaryFile,
31  cet::exempt_ptr<BranchIDLists const> bidLists,
32  BranchType const branchType,
33  EventID const eID,
34  bool const compactSubRunRanges)
35  : fileFormatVersion_{version}
36  , db_{db}
37  , entrySet_{entrySet}
38  , branches_{branches}
39  , tree_{tree}
40  , saveMemoryObjectThreshold_{saveMemoryObjectThreshold}
41  , primaryFile_{primaryFile}
42  , branchIDLists_{bidLists}
43  , branchType_{branchType}
44  , eventID_{eID}
45  , compactSubRunRanges_{compactSubRunRanges}
46  {}
47 
48  void
50  cet::exempt_ptr<EDProductGetterFinder const> groupFinder)
51  {
52  groupFinder_ = groupFinder;
53  }
54 
55  unique_ptr<EDProduct>
57  TypeID const& ty,
58  RangeSet& rs) const
59  {
60  auto iter = branches_.find(bk);
61  assert(iter != branches_.end());
62 
63  input::BranchInfo const& branchInfo = iter->second;
64  TBranch* br{branchInfo.productBranch_};
65  assert(br != nullptr);
66 
67  configureProductIDStreamer(branchIDLists_);
68  configureRefCoreStreamer(groupFinder_);
69  TClass* cl{TClass::GetClass(ty.typeInfo())};
70 
71  auto get_product = [this, cl, br](auto entry) {
72  tree_->setEntryNumber(entry);
73  unique_ptr<EDProduct> p{static_cast<EDProduct*>(cl->New())};
74  EDProduct* pp{p.get()};
75  br->SetAddress(&pp);
76  auto const bytesRead = input::getEntry(br, entry);
77  if ((saveMemoryObjectThreshold_ > -1) &&
78  (bytesRead > saveMemoryObjectThreshold_)) {
79  br->DropBaskets("all");
80  }
81  return p;
82  };
83 
84  // Retrieve first product
85  auto result = get_product(entrySet_[0]);
86 
87  // Retrieve and aggregate subsequent products (if they exist)
88  if (branchType_ == InSubRun || branchType_ == InRun) {
89 
90  // Products from files that did not support RangeSets are
91  // assigned RangeSets that correspond to the entire run/subrun.
92  if (fileFormatVersion_.value_ < 9) {
93  if (branchType_ == InRun) {
95  } else {
97  }
98  configureProductIDStreamer();
99  configureRefCoreStreamer();
100  return result;
101  }
102 
103  // Unfortunately, we cannot use detail::resolveRangeSetInfo in
104  // this case because products that represent a full (Sub)Run are
105  // allowed to be duplicated in an input file. The behavior in
106  // such a case is a NOP.
107  RangeSet mergedRangeSet = detail::resolveRangeSet(db_,
108  "SomeInput"s,
109  branchType_,
110  result->getRangeSetID(),
112 
113  for (auto it = entrySet_.cbegin() + 1, e = entrySet_.cend(); it != e;
114  ++it) {
115  auto p = get_product(*it);
116  auto const id = p->getRangeSetID();
117 
118  RangeSet const& newRS = detail::resolveRangeSet(
119  db_, "SomeInput"s, branchType_, id, compactSubRunRanges_);
120  if (!mergedRangeSet.is_valid() && newRS.is_valid()) {
121  mergedRangeSet = newRS;
122  std::swap(result, p);
123  } else if (art::disjoint_ranges(mergedRangeSet, newRS)) {
124  result->combine(p.get());
125  mergedRangeSet.merge(newRS);
126  } else if (art::same_ranges(mergedRangeSet, newRS)) {
127  // The ranges are the same, so the behavior is a NOP. If
128  // the stakeholders decide that products with the same
129  // ranges should be checked for equality, the condition
130  // will be added here.
131  } else if (art::overlapping_ranges(mergedRangeSet, newRS)) {
133  "RootDelayedReader::getProduct_"}
134  << "\nThe following ranges corresponding to the product:\n"
135  << " '" << bk << "'"
136  << "\ncannot be aggregated\n"
137  << mergedRangeSet << " and\n"
138  << newRS << "\nPlease contact artists@fnal.gov.\n";
139  }
140  // NOP when both RangeSets are invalid
141  }
142  std::swap(rs, mergedRangeSet);
143  }
144 
145  configureProductIDStreamer();
146  configureRefCoreStreamer();
147  return result;
148  }
149 
150  // FIXME: This should be a member of RootInputFileSequence.
151  int
153  {
154  // idx being a number we can actually use is a precondition of
155  // this function.
156  assert(!(idx < 0));
157 
158  // Note:
159  //
160  // Return code of -2 means stop, -1 means event-not-found,
161  // otherwise 0 for success.
162  //
163  auto const& sfnm = primaryFile_->secondaryFileNames();
164  assert(!(static_cast<decltype(sfnm.size())>(idx) > sfnm.size()));
165  if (sfnm.empty()) { // No configured secondary files.
166  return -2;
167  }
168  auto const& sf = primaryFile_->secondaryFiles();
169  if (static_cast<decltype(sfnm.size())>(idx) == sfnm.size()) {
170  // We're done.
171  return -2;
172  }
173 
174  if (!sf[idx]) {
175  primaryFile_->openSecondaryFile(idx);
176  }
177 
178  switch (branchType_) {
179  case InEvent: {
180  if (!sf[idx]->readEventForSecondaryFile(eventID_)) {
181  return -1;
182  }
183  } break;
184  case InSubRun: {
185  if (!sf[idx]->readSubRunForSecondaryFile(eventID_.subRunID())) {
186  return -1;
187  }
188  } break;
189  case InRun: {
190  if (!sf[idx]->readRunForSecondaryFile(eventID_.runID())) {
191  return -1;
192  }
193  } break;
194  default: {
195  assert(false && "RootDelayedReader encountered an unknown BranchType!");
196  return -2;
197  }
198  }
199  return 0;
200  }
201 
202 } // namespace art
RunID const & runID() const
Definition: EventID.h:93
SubRunID const & subRunID() const
Definition: EventID.h:105
Float_t s
Definition: plot.C:23
std::unique_ptr< EDProduct > getProduct_(BranchKey const &, TypeID const &, RangeSet &) const override
STL namespace.
RangeSet resolveRangeSet(RangeSetInfo const &rs)
RangeSet & merge(RangeSet const &other)
Definition: RangeSet.cc:134
int openNextSecondaryFile_(int idx) override
std::enable_if_t< detail::are_handles< T, U >::value, bool > disjoint_ranges(T const &a, U const &b)
std::type_info const & typeInfo() const
Definition: TypeID.h:114
std::map< BranchKey const, BranchInfo > BranchMap
Definition: Inputfwd.h:45
std::vector< input::EntryNumber > const entrySet_
static RangeSet forRun(RunID)
Definition: RangeSet.cc:52
void swap(art::HLTGlobalStatus &lhs, art::HLTGlobalStatus &rhs)
bool is_valid() const
Definition: RangeSet.cc:230
cet::coded_exception< errors::ErrorCodes, ExceptionDetail::translate > Exception
Definition: Exception.h:66
static RangeSet forSubRun(SubRunID)
Definition: RangeSet.cc:58
cet::exempt_ptr< RootInputFile > primaryFile_
cet::exempt_ptr< EDProductGetterFinder const > groupFinder_
cet::exempt_ptr< RootInputTree > tree_
std::enable_if_t< detail::are_handles< T, U >::value, bool > overlapping_ranges(T const &a, U const &b)
std::enable_if_t< detail::are_handles< T, U >::value, bool > same_ranges(T const &a, U const &b)
BranchType
Definition: BranchType.h:18
HLT enums.
Int_t getEntry(TBranch *branch, EntryNumber entryNumber)
Definition: getEntry.cc:12
input::BranchMap const & branches_
cet::exempt_ptr< BranchIDLists const > branchIDLists_
TBranch * productBranch_
Definition: Inputfwd.h:42
void setGroupFinder_(cet::exempt_ptr< EDProductGetterFinder const >) override
Float_t e
Definition: plot.C:34
FileFormatVersion fileFormatVersion_