CMS 3D CMS Logo

BareRootProductGetterBase.cc
Go to the documentation of this file.
1 // -*- C++ -*-
2 //
3 // Package: FWLite
4 // Class : BareRootProductGetterBase
5 //
6 // Implementation:
7 // <Notes on implementation>
8 //
9 // Description: This file was originally BareRootProductGetter.cc.
10 // It was copied to BareRootProductGetterBase.cc in order to refactor
11 // it a little bit to make it usable for FireworksWeb.
12 //
13 // Original Author: Chris Jones
14 // Created: Tue May 23 11:03:31 EDT 2006
15 //
16 
17 // user include files
29 
30 // system include files
31 
32 #include "TBranch.h"
33 #include "TClass.h"
34 #include "TFile.h"
35 #include "TTree.h"
36 
37 //
38 // constructors and destructor
39 //
42 
43 //
44 // const member functions
45 //
47  // std::cout << "getIt called " << pid << std::endl;
49  idToBuffers_.clear();
50  }
51  TTree* eventTree = branchMap_.getEventTree();
52  // std::cout << "eventTree " << eventTree << std::endl;
53  if (nullptr == eventTree) {
54  throw cms::Exception("NoEventsTree")
55  << "unable to find the TTree '" << edm::poolNames::eventTreeName() << "' in the last open file, \n"
56  << "file: '" << branchMap_.getFile()->GetName()
57  << "'\n Please check that the file is a standard CMS ROOT format.\n"
58  << "If the above is not the file you expect then please open your data file after all other files.";
59  }
60  Long_t eventEntry = eventTree->GetReadEntry();
61  // std::cout << "eventEntry " << eventEntry << std::endl;
62  branchMap_.updateEvent(eventEntry);
63  if (eventEntry < 0) {
64  throw cms::Exception("GetEntryNotCalled")
65  << "please call GetEntry for the 'Events' TTree for each event in order to make edm::Ref's work."
66  << "\n Also be sure to call 'SetAddress' for all Branches after calling the GetEntry.";
67  }
68 
70 
71  return getIt(branchID, eventEntry);
72 }
73 
74 edm::WrapperBase const* BareRootProductGetterBase::getIt(edm::BranchID const& branchID, Long_t eventEntry) const {
75  Buffer* buffer = nullptr;
76  IdToBuffers::iterator itBuffer = idToBuffers_.find(branchID);
77 
78  // std::cout << "Buffers" << std::endl;
79  if (itBuffer == idToBuffers_.end()) {
80  buffer = createNewBuffer(branchID);
81  // std::cout << "buffer " << buffer << std::endl;
82  if (nullptr == buffer) {
83  return nullptr;
84  }
85  } else {
86  buffer = &(itBuffer->second);
87  }
88  if (nullptr == buffer) {
89  throw cms::Exception("NullBuffer") << "Found a null buffer which is supposed to hold the data item."
90  << "\n Please contact developers since this message should not happen.";
91  }
92  if (nullptr == buffer->branch_) {
93  throw cms::Exception("NullBranch") << "The TBranch which should hold the data item is null."
94  << "\n Please contact the developers since this message should not happen.";
95  }
96  if (buffer->eventEntry_ != eventEntry) {
97  //NOTE: Need to reset address because user could have set the address themselves
98  //std::cout << "new event" << std::endl;
99 
100  //ROOT WORKAROUND: Create new objects so any internal data cache will get cleared
101  void* address = buffer->class_->New();
102 
103  static TClass const* edproductTClass = TClass::GetClass(typeid(edm::WrapperBase));
104  edm::WrapperBase const* prod =
105  static_cast<edm::WrapperBase const*>(buffer->class_->DynamicCast(edproductTClass, address, true));
106 
107  if (nullptr == prod) {
108  cms::Exception("FailedConversion") << "failed to convert a '" << buffer->class_->GetName()
109  << "' to a edm::WrapperBase."
110  << "Please contact developers since something is very wrong.";
111  }
112  buffer->address_ = address;
113  buffer->product_ = std::shared_ptr<edm::WrapperBase const>(prod);
114  //END WORKAROUND
115 
116  address = &(buffer->address_);
117  buffer->branch_->SetAddress(address);
118 
119  buffer->branch_->GetEntry(eventEntry);
120  buffer->eventEntry_ = eventEntry;
121  }
122  if (!buffer->product_) {
123  throw cms::Exception("BranchGetEntryFailed")
124  << "Calling GetEntry with index " << eventEntry << "for branch " << buffer->branch_->GetName() << " failed.";
125  }
126 
127  return buffer->product_.get();
128 }
129 
130 std::optional<std::tuple<edm::WrapperBase const*, unsigned int>> BareRootProductGetterBase::getThinnedProduct(
131  edm::ProductID const& pid, unsigned int key) const {
132  Long_t eventEntry = branchMap_.getEventTree()->GetReadEntry();
134  pid,
135  key,
137  [this](edm::ProductID const& p) { return branchMap_.productToBranchID(p); },
138  [this, eventEntry](edm::BranchID const& b) { return getThinnedAssociation(b, eventEntry); },
139  [this](edm::ProductID const& p) { return getIt(p); });
140 }
141 
143  std::vector<edm::WrapperBase const*>& foundContainers,
144  std::vector<unsigned int>& keys) const {
145  Long_t eventEntry = branchMap_.getEventTree()->GetReadEntry();
147  pid,
149  [this](edm::ProductID const& p) { return branchMap_.productToBranchID(p); },
150  [this, eventEntry](edm::BranchID const& b) { return getThinnedAssociation(b, eventEntry); },
151  [this](edm::ProductID const& p) { return getIt(p); },
152  foundContainers,
153  keys);
154 }
155 
157  unsigned int key,
158  edm::ProductID const& thinnedID) const {
159  Long_t eventEntry = branchMap_.getEventTree()->GetReadEntry();
161  if (!parent.isValid())
162  return std::monostate{};
163  edm::BranchID thinned = branchMap_.productToBranchID(thinnedID);
164  if (!thinned.isValid())
165  return std::monostate{};
166  try {
168  parentID,
169  parent,
170  key,
171  thinnedID,
172  thinned,
174  [this, eventEntry](edm::BranchID const& branchID) { return getThinnedAssociation(branchID, eventEntry); });
175  if (auto factory = std::get_if<edm::detail::GetThinnedKeyFromExceptionFactory>(&ret)) {
176  return [func = *factory]() {
177  auto ex = func();
178  ex.addContext("Calling BareRootProductGetterBase::getThinnedKeyFrom()");
179  return ex;
180  };
181  } else {
182  return ret;
183  }
184  } catch (edm::Exception& ex) {
185  ex.addContext("Calling BareRootProductGetterBase::getThinnedKeyFrom()");
186  throw ex;
187  }
188 }
189 
191  //find the branch
192  edm::BranchDescription const& bdesc = branchMap_.branchIDToBranch(branchID);
193 
194  TBranch* branch = branchMap_.getEventTree()->GetBranch(bdesc.branchName().c_str());
195  if (nullptr == branch) {
196  //we do not thrown on missing branches since 'getIt' should not throw under that condition
197  return nullptr;
198  }
199  //find the class type
202  if (!bool(classType)) {
203  throw cms::Exception("MissingDictionary") << "could not find dictionary for type '" << fullName << "'"
204  << "\n Please make sure all the necessary libraries are available.";
205  return nullptr;
206  }
207 
208  TClass* rootClassType = TClass::GetClass(classType.typeInfo());
209  if (nullptr == rootClassType) {
210  throw cms::Exception("MissingRootDictionary") << "could not find a ROOT dictionary for type '" << fullName << "'"
211  << "\n Please make sure all the necessary libraries are available.";
212  return nullptr;
213  }
214  void* address = rootClassType->New();
215 
216  static TClass const* edproductTClass = TClass::GetClass(typeid(edm::WrapperBase));
217  edm::WrapperBase const* prod =
218  static_cast<edm::WrapperBase const*>(rootClassType->DynamicCast(edproductTClass, address, true));
219  if (nullptr == prod) {
220  throw cms::Exception("FailedConversion") << "failed to convert a '" << fullName << "' to a edm::WrapperBase."
221  << "Please contact developers since something is very wrong.";
222  }
223 
224  //connect the instance to the branch
225  //void* address = wrapperObj.Address();
226  Buffer b(prod, branch, address, rootClassType);
227  idToBuffers_[branchID] = std::move(b);
228 
229  //As of 5.13 ROOT expects the memory address held by the pointer passed to
230  // SetAddress to be valid forever
231  address = &(idToBuffers_[branchID].address_);
232  branch->SetAddress(address);
233 
234  return &(idToBuffers_[branchID]);
235 }
236 
238  Long_t eventEntry) const {
239  edm::WrapperBase const* wrapperBase = getIt(branchID, eventEntry);
240  if (wrapperBase == nullptr) {
242  << "BareRootProductGetterBase::getThinnedAssociation, product ThinnedAssociation not found.\n";
243  }
244  if (!(typeid(edm::ThinnedAssociation) == wrapperBase->dynamicTypeInfo())) {
246  << "BareRootProductGetterBase::getThinnedAssociation, product has wrong type, not a ThinnedAssociation.\n";
247  }
249  static_cast<edm::Wrapper<edm::ThinnedAssociation> const*>(wrapperBase);
250 
251  edm::ThinnedAssociation const* thinnedAssociation = wrapper->product();
252  return thinnedAssociation;
253 }
~BareRootProductGetterBase() override
std::variant< unsigned int, detail::GetThinnedKeyFromExceptionFactory, std::monostate > OptionalThinnedKey
std::optional< std::tuple< edm::WrapperBase const *, unsigned int > > getThinnedProduct(edm::ProductID const &, unsigned int key) const override
ret
prodAgent to be discontinued
std::optional< std::tuple< WrapperBase const *, unsigned int > > getThinnedProduct(ProductID const &pid, unsigned int key, ThinnedAssociationsHelper const &thinnedAssociationsHelper, F1 pidToBid, F2 getThinnedAssociation, F3 getByProductID)
fwlite::BranchMapReader branchMap_
bool updateEvent(Long_t eventEntry)
std::variant< unsigned int, GetThinnedKeyFromExceptionFactory, std::monostate > getThinnedKeyFrom_implementation(ProductID const &parentID, BranchID const &parent, unsigned int key, ProductID const &thinnedID, BranchID thinned, ThinnedAssociationsHelper const &thinnedAssociationsHelper, F &&getThinnedAssociation)
void getThinnedProducts(edm::ProductID const &, std::vector< edm::WrapperBase const *> &foundContainers, std::vector< unsigned int > &keys) const override
bool updateFile(TFile *file)
TTree const * getEventTree() const
const edm::ThinnedAssociationsHelper & thinnedAssociationsHelper() const
edm::ThinnedAssociation const * getThinnedAssociation(edm::BranchID const &branchID, Long_t eventEntry) const
virtual TFile * currentFile() const =0
edm::OptionalThinnedKey getThinnedKeyFrom(edm::ProductID const &parent, unsigned int key, edm::ProductID const &thinned) const override
static TypeWithDict byName(std::string const &name)
Definition: TypeWithDict.cc:74
void getThinnedProducts(ProductID const &pid, ThinnedAssociationsHelper const &thinnedAssociationsHelper, F1 pidToBid, F2 getThinnedAssociation, F3 getByProductID, std::vector< WrapperBase const *> &foundContainers, std::vector< unsigned int > &keys)
bool isValid() const
Definition: BranchID.h:22
std::type_info const & dynamicTypeInfo() const
Definition: WrapperBase.h:42
std::string const & className() const
std::string const & branchName() const
const edm::BranchDescription & branchIDToBranch(const edm::BranchID &bid) const
key
prepare the HTCondor submission files and eventually submit them
TFile const * getFile() const
std::string wrappedClassName(std::string const &iFullName)
double b
Definition: hdecay.h:120
void addContext(std::string const &context)
Definition: Exception.cc:169
std::string const & eventTreeName()
Definition: BranchType.cc:220
edm::WrapperBase const * getIt(edm::ProductID const &) const override
edm::BranchID productToBranchID(const edm::ProductID &pid)
def move(src, dest)
Definition: eostools.py:511
static HepMC::HEPEVT_Wrapper wrapper
Buffer * createNewBuffer(edm::BranchID const &) const