File indexing completed on 2024-08-22 04:57:38
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018 #include "FWCore/FWLite/interface/BareRootProductGetterBase.h"
0019 #include "DataFormats/Common/interface/ThinnedAssociation.h"
0020 #include "DataFormats/Common/interface/Wrapper.h"
0021 #include "DataFormats/Common/interface/getThinned_implementation.h"
0022 #include "DataFormats/Provenance/interface/BranchDescription.h"
0023 #include "DataFormats/Provenance/interface/BranchID.h"
0024 #include "DataFormats/Provenance/interface/BranchType.h"
0025 #include "DataFormats/Provenance/interface/ThinnedAssociationsHelper.h"
0026 #include "FWCore/Utilities/interface/Exception.h"
0027 #include "FWCore/Reflection/interface/TypeWithDict.h"
0028 #include "FWCore/Utilities/interface/WrappedClassName.h"
0029
0030
0031
0032 #include "TBranch.h"
0033 #include "TClass.h"
0034 #include "TFile.h"
0035 #include "TTree.h"
0036
0037
0038
0039
0040 BareRootProductGetterBase::BareRootProductGetterBase() = default;
0041 BareRootProductGetterBase::~BareRootProductGetterBase() = default;
0042
0043
0044
0045
0046 edm::WrapperBase const* BareRootProductGetterBase::getIt(edm::ProductID const& pid) const {
0047
0048 if (branchMap_.updateFile(currentFile())) {
0049 idToBuffers_.clear();
0050 }
0051 TTree* eventTree = branchMap_.getEventTree();
0052
0053 if (nullptr == eventTree) {
0054 throw cms::Exception("NoEventsTree")
0055 << "unable to find the TTree '" << edm::poolNames::eventTreeName() << "' in the last open file, \n"
0056 << "file: '" << branchMap_.getFile()->GetName()
0057 << "'\n Please check that the file is a standard CMS ROOT format.\n"
0058 << "If the above is not the file you expect then please open your data file after all other files.";
0059 }
0060 Long_t eventEntry = eventTree->GetReadEntry();
0061
0062 branchMap_.updateEvent(eventEntry);
0063 if (eventEntry < 0) {
0064 throw cms::Exception("GetEntryNotCalled")
0065 << "please call GetEntry for the 'Events' TTree for each event in order to make edm::Ref's work."
0066 << "\n Also be sure to call 'SetAddress' for all Branches after calling the GetEntry.";
0067 }
0068
0069 edm::BranchID branchID = branchMap_.productToBranchID(pid);
0070
0071 return getIt(branchID, eventEntry);
0072 }
0073
0074 edm::WrapperBase const* BareRootProductGetterBase::getIt(edm::BranchID const& branchID, Long_t eventEntry) const {
0075 Buffer* buffer = nullptr;
0076 IdToBuffers::iterator itBuffer = idToBuffers_.find(branchID);
0077
0078
0079 if (itBuffer == idToBuffers_.end()) {
0080 buffer = createNewBuffer(branchID);
0081
0082 if (nullptr == buffer) {
0083 return nullptr;
0084 }
0085 } else {
0086 buffer = &(itBuffer->second);
0087 }
0088 if (nullptr == buffer) {
0089 throw cms::Exception("NullBuffer") << "Found a null buffer which is supposed to hold the data item."
0090 << "\n Please contact developers since this message should not happen.";
0091 }
0092 if (nullptr == buffer->branch_) {
0093 throw cms::Exception("NullBranch") << "The TBranch which should hold the data item is null."
0094 << "\n Please contact the developers since this message should not happen.";
0095 }
0096 if (buffer->eventEntry_ != eventEntry) {
0097
0098
0099
0100
0101 void* address = buffer->class_->New();
0102
0103 static TClass const* edproductTClass = TClass::GetClass(typeid(edm::WrapperBase));
0104 edm::WrapperBase const* prod =
0105 static_cast<edm::WrapperBase const*>(buffer->class_->DynamicCast(edproductTClass, address, true));
0106
0107 if (nullptr == prod) {
0108 cms::Exception("FailedConversion") << "failed to convert a '" << buffer->class_->GetName()
0109 << "' to a edm::WrapperBase."
0110 << "Please contact developers since something is very wrong.";
0111 }
0112 buffer->address_ = address;
0113 buffer->product_ = std::shared_ptr<edm::WrapperBase const>(prod);
0114
0115
0116 address = &(buffer->address_);
0117 buffer->branch_->SetAddress(address);
0118
0119 buffer->branch_->GetEntry(eventEntry);
0120 buffer->eventEntry_ = eventEntry;
0121 }
0122 if (!buffer->product_) {
0123 throw cms::Exception("BranchGetEntryFailed")
0124 << "Calling GetEntry with index " << eventEntry << "for branch " << buffer->branch_->GetName() << " failed.";
0125 }
0126
0127 return buffer->product_.get();
0128 }
0129
0130 std::optional<std::tuple<edm::WrapperBase const*, unsigned int>> BareRootProductGetterBase::getThinnedProduct(
0131 edm::ProductID const& pid, unsigned int key) const {
0132 Long_t eventEntry = branchMap_.getEventTree()->GetReadEntry();
0133 return edm::detail::getThinnedProduct(
0134 pid,
0135 key,
0136 branchMap_.thinnedAssociationsHelper(),
0137 [this](edm::ProductID const& p) { return branchMap_.productToBranchID(p); },
0138 [this, eventEntry](edm::BranchID const& b) { return getThinnedAssociation(b, eventEntry); },
0139 [this](edm::ProductID const& p) { return getIt(p); });
0140 }
0141
0142 void BareRootProductGetterBase::getThinnedProducts(edm::ProductID const& pid,
0143 std::vector<edm::WrapperBase const*>& foundContainers,
0144 std::vector<unsigned int>& keys) const {
0145 Long_t eventEntry = branchMap_.getEventTree()->GetReadEntry();
0146 edm::detail::getThinnedProducts(
0147 pid,
0148 branchMap_.thinnedAssociationsHelper(),
0149 [this](edm::ProductID const& p) { return branchMap_.productToBranchID(p); },
0150 [this, eventEntry](edm::BranchID const& b) { return getThinnedAssociation(b, eventEntry); },
0151 [this](edm::ProductID const& p) { return getIt(p); },
0152 foundContainers,
0153 keys);
0154 }
0155
0156 edm::OptionalThinnedKey BareRootProductGetterBase::getThinnedKeyFrom(edm::ProductID const& parentID,
0157 unsigned int key,
0158 edm::ProductID const& thinnedID) const {
0159 Long_t eventEntry = branchMap_.getEventTree()->GetReadEntry();
0160 edm::BranchID parent = branchMap_.productToBranchID(parentID);
0161 if (!parent.isValid())
0162 return std::monostate{};
0163 edm::BranchID thinned = branchMap_.productToBranchID(thinnedID);
0164 if (!thinned.isValid())
0165 return std::monostate{};
0166 try {
0167 auto ret = edm::detail::getThinnedKeyFrom_implementation(
0168 parentID,
0169 parent,
0170 key,
0171 thinnedID,
0172 thinned,
0173 branchMap_.thinnedAssociationsHelper(),
0174 [this, eventEntry](edm::BranchID const& branchID) { return getThinnedAssociation(branchID, eventEntry); });
0175 if (auto factory = std::get_if<edm::detail::GetThinnedKeyFromExceptionFactory>(&ret)) {
0176 return [func = *factory]() {
0177 auto ex = func();
0178 ex.addContext("Calling BareRootProductGetterBase::getThinnedKeyFrom()");
0179 return ex;
0180 };
0181 } else {
0182 return ret;
0183 }
0184 } catch (edm::Exception& ex) {
0185 ex.addContext("Calling BareRootProductGetterBase::getThinnedKeyFrom()");
0186 throw ex;
0187 }
0188 }
0189
0190 BareRootProductGetterBase::Buffer* BareRootProductGetterBase::createNewBuffer(edm::BranchID const& branchID) const {
0191
0192 edm::BranchDescription const& bdesc = branchMap_.branchIDToBranch(branchID);
0193
0194 TBranch* branch = branchMap_.getEventTree()->GetBranch(bdesc.branchName().c_str());
0195 if (nullptr == branch) {
0196
0197 return nullptr;
0198 }
0199
0200 std::string const fullName = edm::wrappedClassName(bdesc.className());
0201 edm::TypeWithDict classType(edm::TypeWithDict::byName(fullName));
0202 if (!bool(classType)) {
0203 throw cms::Exception("MissingDictionary") << "could not find dictionary for type '" << fullName << "'"
0204 << "\n Please make sure all the necessary libraries are available.";
0205 return nullptr;
0206 }
0207
0208 TClass* rootClassType = TClass::GetClass(classType.typeInfo());
0209 if (nullptr == rootClassType) {
0210 throw cms::Exception("MissingRootDictionary") << "could not find a ROOT dictionary for type '" << fullName << "'"
0211 << "\n Please make sure all the necessary libraries are available.";
0212 return nullptr;
0213 }
0214 void* address = rootClassType->New();
0215
0216 static TClass const* edproductTClass = TClass::GetClass(typeid(edm::WrapperBase));
0217 edm::WrapperBase const* prod =
0218 static_cast<edm::WrapperBase const*>(rootClassType->DynamicCast(edproductTClass, address, true));
0219 if (nullptr == prod) {
0220 throw cms::Exception("FailedConversion") << "failed to convert a '" << fullName << "' to a edm::WrapperBase."
0221 << "Please contact developers since something is very wrong.";
0222 }
0223
0224
0225
0226 Buffer b(prod, branch, address, rootClassType);
0227 idToBuffers_[branchID] = std::move(b);
0228
0229
0230
0231 address = &(idToBuffers_[branchID].address_);
0232 branch->SetAddress(address);
0233
0234 return &(idToBuffers_[branchID]);
0235 }
0236
0237 edm::ThinnedAssociation const* BareRootProductGetterBase::getThinnedAssociation(edm::BranchID const& branchID,
0238 Long_t eventEntry) const {
0239 edm::WrapperBase const* wrapperBase = getIt(branchID, eventEntry);
0240 if (wrapperBase == nullptr) {
0241 throw edm::Exception(edm::errors::LogicError)
0242 << "BareRootProductGetterBase::getThinnedAssociation, product ThinnedAssociation not found.\n";
0243 }
0244 if (!(typeid(edm::ThinnedAssociation) == wrapperBase->dynamicTypeInfo())) {
0245 throw edm::Exception(edm::errors::LogicError)
0246 << "BareRootProductGetterBase::getThinnedAssociation, product has wrong type, not a ThinnedAssociation.\n";
0247 }
0248 edm::Wrapper<edm::ThinnedAssociation> const* wrapper =
0249 static_cast<edm::Wrapper<edm::ThinnedAssociation> const*>(wrapperBase);
0250
0251 edm::ThinnedAssociation const* thinnedAssociation = wrapper->product();
0252 return thinnedAssociation;
0253 }