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