File indexing completed on 2024-04-06 12:13:11
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015 #include "FWCore/TFWLiteSelector/interface/TFWLiteSelectorBasic.h"
0016
0017 #include "DataFormats/Common/interface/RefCoreStreamer.h"
0018 #include "DataFormats/Common/interface/setIsMergeable.h"
0019 #include "DataFormats/Provenance/interface/BranchDescription.h"
0020 #include "DataFormats/Provenance/interface/BranchIDList.h"
0021 #include "DataFormats/Provenance/interface/BranchIDListHelper.h"
0022 #include "DataFormats/Provenance/interface/BranchListIndex.h"
0023 #include "FWCore/Framework/interface/ProductProvenanceRetriever.h"
0024 #include "DataFormats/Provenance/interface/BranchType.h"
0025 #include "DataFormats/Provenance/interface/EventAuxiliary.h"
0026 #include "DataFormats/Provenance/interface/EventEntryDescription.h" // kludge to allow compilation
0027 #include "DataFormats/Provenance/interface/EventSelectionID.h"
0028 #include "DataFormats/Provenance/interface/EventToProcessBlockIndexes.h"
0029 #include "DataFormats/Provenance/interface/FileFormatVersion.h"
0030 #include "DataFormats/Provenance/interface/LuminosityBlockAuxiliary.h"
0031 #include "DataFormats/Provenance/interface/ModuleDescription.h"
0032 #include "DataFormats/Provenance/interface/ParameterSetBlob.h"
0033 #include "DataFormats/Provenance/interface/ProcessConfiguration.h"
0034 #include "DataFormats/Provenance/interface/ProcessHistory.h"
0035 #include "DataFormats/Provenance/interface/ProcessHistoryRegistry.h"
0036 #include "DataFormats/Provenance/interface/ProductRegistry.h"
0037 #include "DataFormats/Provenance/interface/RunAuxiliary.h"
0038 #include "DataFormats/Provenance/interface/ThinnedAssociationsHelper.h"
0039 #include "FWCore/Framework/interface/DelayedReader.h"
0040 #include "FWCore/Framework/interface/Event.h"
0041 #include "FWCore/Framework/interface/EventPrincipal.h"
0042 #include "FWCore/Framework/interface/LuminosityBlockPrincipal.h"
0043 #include "FWCore/Framework/interface/RunPrincipal.h"
0044 #include "FWCore/ParameterSet/interface/Registry.h"
0045 #include "FWCore/Utilities/interface/EDMException.h"
0046 #include "FWCore/Utilities/interface/FriendlyName.h"
0047 #include "FWCore/Reflection/interface/ObjectWithDict.h"
0048 #include "FWCore/Reflection/interface/TypeWithDict.h"
0049 #include "FWCore/Utilities/interface/WrappedClassName.h"
0050 #include "FWCore/Utilities/interface/get_underlying_safe.h"
0051
0052
0053 #include "TBranch.h"
0054 #include "TChain.h"
0055 #include "TFile.h"
0056 #include "TTree.h"
0057
0058 #include <iostream>
0059 #include <memory>
0060 #include <string>
0061 #include <vector>
0062 #include <unordered_map>
0063
0064 namespace edm {
0065 namespace root {
0066 class FWLiteDelayedReader : public DelayedReader {
0067 public:
0068 FWLiteDelayedReader() : entry_(-1), eventTree_(nullptr) {}
0069 void setEntry(Long64_t iEntry) { entry_ = iEntry; }
0070 void setTree(TTree* iTree) { eventTree_ = iTree; }
0071 void set(std::shared_ptr<std::unordered_map<unsigned int, BranchDescription const*>> iMap) {
0072 bidToDesc_ = std::move(iMap);
0073 }
0074
0075 private:
0076 std::unique_ptr<WrapperBase> getTheProduct(BranchID const& k) const;
0077 std::shared_ptr<WrapperBase> getProduct_(BranchID const& k, EDProductGetter const* ep) override;
0078 virtual std::unique_ptr<EventEntryDescription> getProvenance_(BranchKey const&) const {
0079 return std::unique_ptr<EventEntryDescription>();
0080 }
0081 void mergeReaders_(DelayedReader*) override {}
0082 void reset_() override {}
0083
0084 signalslot::Signal<void(StreamContext const&, ModuleCallingContext const&)> const* preEventReadFromSourceSignal()
0085 const override {
0086 return nullptr;
0087 }
0088 signalslot::Signal<void(StreamContext const&, ModuleCallingContext const&)> const* postEventReadFromSourceSignal()
0089 const override {
0090 return nullptr;
0091 };
0092
0093 Long64_t entry_;
0094 TTree* eventTree_;
0095 std::shared_ptr<std::unordered_map<unsigned int, BranchDescription const*>> bidToDesc_;
0096 };
0097
0098 std::shared_ptr<WrapperBase> FWLiteDelayedReader::getProduct_(BranchID const& k, EDProductGetter const* ) {
0099 return getTheProduct(k);
0100 }
0101
0102 std::unique_ptr<WrapperBase> FWLiteDelayedReader::getTheProduct(BranchID const& k) const {
0103 auto itFind = bidToDesc_->find(k.id());
0104 if (itFind == bidToDesc_->end()) {
0105 throw Exception(errors::ProductNotFound) << "could not find entry for product " << k;
0106 }
0107 BranchDescription const& bDesc = *(itFind->second);
0108
0109 TBranch* branch = eventTree_->GetBranch(bDesc.branchName().c_str());
0110 if (nullptr == branch) {
0111 throw cms::Exception("MissingBranch") << "could not find branch named '" << bDesc.branchName() << "'"
0112 << "\n Perhaps the data being requested was not saved in this file?";
0113 }
0114
0115 std::string const fullName = wrappedClassName(bDesc.className());
0116 TypeWithDict classType = TypeWithDict::byName(fullName);
0117 if (!bool(classType)) {
0118 throw cms::Exception("MissingDictionary") << "could not find dictionary for type '" << fullName << "'"
0119 << "\n Please make sure all the necessary libraries are available.";
0120 }
0121
0122
0123 ObjectWithDict wrapperObj = classType.construct();
0124 if (nullptr == wrapperObj.address()) {
0125 throw cms::Exception("FailedToCreate") << "could not create an instance of '" << fullName << "'";
0126 }
0127 void* address = wrapperObj.address();
0128 branch->SetAddress(&address);
0129 ObjectWithDict edProdObj = wrapperObj.castObject(TypeWithDict::byName("edm::WrapperBase"));
0130
0131 WrapperBase* prod = reinterpret_cast<WrapperBase*>(edProdObj.address());
0132
0133 if (nullptr == prod) {
0134 throw cms::Exception("FailedConversion") << "failed to convert a '" << fullName << "' to a edm::WrapperBase."
0135 << "Please contact developers since something is very wrong.";
0136 }
0137 branch->GetEntry(entry_);
0138 return std::unique_ptr<WrapperBase>(prod);
0139 }
0140
0141 struct TFWLiteSelectorMembers {
0142 TFWLiteSelectorMembers()
0143 : tree_(nullptr),
0144 reg_(new ProductRegistry()),
0145 bidToDesc_(std::make_shared<std::unordered_map<unsigned int, BranchDescription const*>>()),
0146 phreg_(new ProcessHistoryRegistry()),
0147 branchIDListHelper_(new BranchIDListHelper()),
0148
0149
0150
0151
0152
0153
0154 thinnedAssociationsHelper_(new ThinnedAssociationsHelper()),
0155 processNames_(),
0156 reader_(new FWLiteDelayedReader),
0157 prov_(),
0158 pointerToBranchBuffer_(),
0159 provRetriever_(new edm::ProductProvenanceRetriever(0)) {
0160 reader_->set(get_underlying_safe(bidToDesc_));
0161 }
0162 void setTree(TTree* iTree) {
0163 tree_ = iTree;
0164 reader_->setTree(iTree);
0165 }
0166
0167 TTree const* tree() const { return get_underlying_safe(tree_); }
0168 TTree*& tree() { return get_underlying_safe(tree_); }
0169 std::shared_ptr<ProductRegistry const> reg() const { return get_underlying_safe(reg_); }
0170 std::shared_ptr<ProductRegistry>& reg() { return get_underlying_safe(reg_); }
0171 std::shared_ptr<BranchIDListHelper const> branchIDListHelper() const {
0172 return get_underlying_safe(branchIDListHelper_);
0173 }
0174 std::shared_ptr<BranchIDListHelper>& branchIDListHelper() { return get_underlying_safe(branchIDListHelper_); }
0175 std::shared_ptr<ThinnedAssociationsHelper const> thinnedAssociationsHelper() const {
0176 return get_underlying_safe(thinnedAssociationsHelper_);
0177 }
0178 std::shared_ptr<ThinnedAssociationsHelper>& thinnedAssociationsHelper() {
0179 return get_underlying_safe(thinnedAssociationsHelper_);
0180 }
0181
0182 edm::propagate_const<TTree*> tree_;
0183 edm::propagate_const<std::shared_ptr<ProductRegistry>> reg_;
0184 edm::propagate_const<std::shared_ptr<std::unordered_map<unsigned int, BranchDescription const*>>> bidToDesc_;
0185 edm::propagate_const<std::shared_ptr<ProcessHistoryRegistry>> phreg_;
0186 edm::propagate_const<std::shared_ptr<BranchIDListHelper>> branchIDListHelper_;
0187 edm::propagate_const<std::shared_ptr<ThinnedAssociationsHelper>> thinnedAssociationsHelper_;
0188 ProcessHistory processNames_;
0189 edm::propagate_const<std::shared_ptr<FWLiteDelayedReader>> reader_;
0190 std::vector<EventEntryDescription> prov_;
0191 std::vector<EventEntryDescription const*> pointerToBranchBuffer_;
0192 FileFormatVersion fileFormatVersion_;
0193
0194 edm::propagate_const<std::shared_ptr<edm::ProductProvenanceRetriever>> provRetriever_;
0195 edm::ProcessConfiguration pc_;
0196 edm::propagate_const<std::shared_ptr<edm::EventPrincipal>> ep_;
0197 edm::ModuleDescription md_;
0198 };
0199 }
0200 }
0201
0202
0203
0204
0205
0206
0207
0208
0209
0210
0211
0212
0213 TFWLiteSelectorBasic::TFWLiteSelectorBasic() : m_(new edm::root::TFWLiteSelectorMembers), everythingOK_(false) {}
0214
0215
0216
0217
0218
0219
0220 TFWLiteSelectorBasic::~TFWLiteSelectorBasic() {}
0221
0222
0223
0224
0225
0226
0227
0228
0229
0230
0231
0232
0233
0234
0235
0236
0237 void TFWLiteSelectorBasic::Begin(TTree* iTree) {
0238 Init(iTree);
0239 begin(fInput);
0240 }
0241
0242 void TFWLiteSelectorBasic::SlaveBegin(TTree* iTree) {
0243 Init(iTree);
0244 preProcessing(fInput, *fOutput);
0245 }
0246
0247 void TFWLiteSelectorBasic::Init(TTree* iTree) {
0248 if (iTree == nullptr)
0249 return;
0250 m_->setTree(iTree);
0251 }
0252
0253 Bool_t TFWLiteSelectorBasic::Notify() {
0254
0255
0256
0257 if (nullptr == m_->tree_) {
0258 std::cout << "No tree" << std::endl;
0259 return kFALSE;
0260 }
0261 TFile* file = m_->tree_->GetCurrentFile();
0262 if (nullptr == file) {
0263
0264 TChain* chain = dynamic_cast<TChain*>(m_->tree());
0265 if (nullptr == chain) {
0266 std::cout << "No file" << std::endl;
0267 return kFALSE;
0268 }
0269 file = chain->GetFile();
0270 if (nullptr == file) {
0271 std::cout << "No file" << std::endl;
0272 return kFALSE;
0273 }
0274 }
0275 setupNewFile(*file);
0276 return everythingOK_ ? kTRUE : kFALSE;
0277 }
0278
0279 namespace {
0280 struct Operate {
0281 Operate(edm::EDProductGetter const* iGetter) : old_(setRefCoreStreamer(iGetter)) {}
0282
0283 ~Operate() { setRefCoreStreamer(old_); }
0284
0285 private:
0286 edm::EDProductGetter const* old_;
0287 };
0288 }
0289
0290 Bool_t TFWLiteSelectorBasic::Process(Long64_t iEntry) {
0291
0292 if (everythingOK_) {
0293 std::unique_ptr<edm::EventAuxiliary> eaux = std::make_unique<edm::EventAuxiliary>();
0294 edm::EventAuxiliary& aux = *eaux;
0295 edm::EventAuxiliary* pAux = eaux.get();
0296 TBranch* branch = m_->tree_->GetBranch(edm::BranchTypeToAuxiliaryBranchName(edm::InEvent).c_str());
0297
0298 branch->SetAddress(&pAux);
0299 branch->GetEntry(iEntry);
0300
0301
0302
0303
0304
0305
0306
0307
0308 edm::EventSelectionIDVector eventSelectionIDs;
0309 edm::EventSelectionIDVector* pEventSelectionIDVector = &eventSelectionIDs;
0310 TBranch* eventSelectionsBranch = m_->tree_->GetBranch(edm::poolNames::eventSelectionsBranchName().c_str());
0311 if (!eventSelectionsBranch) {
0312 throw edm::Exception(edm::errors::FatalRootError) << "Failed to find event Selections branch in event tree";
0313 }
0314 eventSelectionsBranch->SetAddress(&pEventSelectionIDVector);
0315 eventSelectionsBranch->GetEntry(iEntry);
0316
0317 edm::BranchListIndexes branchListIndexes;
0318 edm::BranchListIndexes* pBranchListIndexes = &branchListIndexes;
0319 TBranch* branchListIndexBranch = m_->tree_->GetBranch(edm::poolNames::branchListIndexesBranchName().c_str());
0320 if (!branchListIndexBranch) {
0321 throw edm::Exception(edm::errors::FatalRootError) << "Failed to find branch list index branch in event tree";
0322 }
0323 branchListIndexBranch->SetAddress(&pBranchListIndexes);
0324 branchListIndexBranch->GetEntry(iEntry);
0325 m_->branchIDListHelper_->fixBranchListIndexes(branchListIndexes);
0326 edm::EventToProcessBlockIndexes dummyEventToProcessBlockIndexes;
0327
0328 try {
0329 m_->reader_->setEntry(iEntry);
0330 auto rp = std::make_shared<edm::RunPrincipal>(m_->reg(), m_->pc_, nullptr, 0);
0331 rp->setAux(edm::RunAuxiliary(aux.run(), aux.time(), aux.time()));
0332 auto lbp = std::make_shared<edm::LuminosityBlockPrincipal>(m_->reg(), m_->pc_, nullptr, 0);
0333 lbp->setAux(edm::LuminosityBlockAuxiliary(rp->run(), 1, aux.time(), aux.time()));
0334 auto history = m_->phreg_->getMapped(eaux->processHistoryID());
0335 m_->ep_->fillEventPrincipal(*eaux,
0336 history,
0337 std::move(eventSelectionIDs),
0338 std::move(branchListIndexes),
0339 dummyEventToProcessBlockIndexes,
0340 *(m_->provRetriever_),
0341 m_->reader_.get());
0342 lbp->setRunPrincipal(rp);
0343 m_->ep_->setLuminosityBlockPrincipal(lbp.get());
0344 m_->processNames_ = m_->ep_->processHistory();
0345
0346 edm::Event event(*m_->ep_, m_->md_, nullptr);
0347
0348
0349 Operate sentry(m_->ep_->prodGetter());
0350 process(event);
0351 } catch (std::exception const& iEx) {
0352 std::cout << "While processing entry " << iEntry << " the following exception was caught \n"
0353 << iEx.what() << std::endl;
0354 } catch (...) {
0355 std::cout << "While processing entry " << iEntry << " an unknown exception was caught" << std::endl;
0356 }
0357 }
0358 return everythingOK_ ? kTRUE : kFALSE;
0359 }
0360
0361 void TFWLiteSelectorBasic::SlaveTerminate() { postProcessing(*fOutput); }
0362
0363 void TFWLiteSelectorBasic::Terminate() { terminate(*fOutput); }
0364
0365 void TFWLiteSelectorBasic::setupNewFile(TFile& iFile) {
0366
0367
0368
0369
0370 TTree* metaDataTree = dynamic_cast<TTree*>(iFile.Get(edm::poolNames::metaDataTreeName().c_str()));
0371 if (!metaDataTree) {
0372 std::cout << "could not find TTree " << edm::poolNames::metaDataTreeName() << std::endl;
0373 everythingOK_ = false;
0374 return;
0375 }
0376 edm::FileFormatVersion* fftPtr = &(m_->fileFormatVersion_);
0377 if (metaDataTree->FindBranch(edm::poolNames::fileFormatVersionBranchName().c_str()) != nullptr) {
0378 metaDataTree->SetBranchAddress(edm::poolNames::fileFormatVersionBranchName().c_str(), &fftPtr);
0379 }
0380
0381 edm::ProductRegistry* pReg = &(*m_->reg_);
0382 metaDataTree->SetBranchAddress(edm::poolNames::productDescriptionBranchName().c_str(), &(pReg));
0383
0384 typedef std::map<edm::ParameterSetID, edm::ParameterSetBlob> PsetMap;
0385 PsetMap psetMap;
0386 PsetMap* psetMapPtr = &psetMap;
0387 if (metaDataTree->FindBranch(edm::poolNames::parameterSetMapBranchName().c_str()) != nullptr) {
0388 metaDataTree->SetBranchAddress(edm::poolNames::parameterSetMapBranchName().c_str(), &psetMapPtr);
0389 } else {
0390 TTree* psetTree = dynamic_cast<TTree*>(iFile.Get(edm::poolNames::parameterSetsTreeName().c_str()));
0391 if (nullptr == psetTree) {
0392 throw edm::Exception(edm::errors::FileReadError)
0393 << "Could not find tree " << edm::poolNames::parameterSetsTreeName() << " in the input file.\n";
0394 }
0395 typedef std::pair<edm::ParameterSetID, edm::ParameterSetBlob> IdToBlobs;
0396 IdToBlobs idToBlob;
0397 IdToBlobs* pIdToBlob = &idToBlob;
0398 psetTree->SetBranchAddress(edm::poolNames::idToParameterSetBlobsBranchName().c_str(), &pIdToBlob);
0399 for (long long i = 0; i != psetTree->GetEntries(); ++i) {
0400 psetTree->GetEntry(i);
0401 psetMap.insert(idToBlob);
0402 }
0403 }
0404
0405 edm::ProcessHistoryRegistry::vector_type pHistVector;
0406 edm::ProcessHistoryRegistry::vector_type* pHistVectorPtr = &pHistVector;
0407 if (metaDataTree->FindBranch(edm::poolNames::processHistoryBranchName().c_str()) != nullptr) {
0408 metaDataTree->SetBranchAddress(edm::poolNames::processHistoryBranchName().c_str(), &pHistVectorPtr);
0409 }
0410
0411 edm::ProcessConfigurationVector procConfigVector;
0412 edm::ProcessConfigurationVector* procConfigVectorPtr = &procConfigVector;
0413 if (metaDataTree->FindBranch(edm::poolNames::processConfigurationBranchName().c_str()) != nullptr) {
0414 metaDataTree->SetBranchAddress(edm::poolNames::processConfigurationBranchName().c_str(), &procConfigVectorPtr);
0415 }
0416
0417 auto branchIDListsHelper = std::make_shared<edm::BranchIDListHelper>();
0418 edm::BranchIDLists const* branchIDListsPtr = &branchIDListsHelper->branchIDLists();
0419 if (metaDataTree->FindBranch(edm::poolNames::branchIDListBranchName().c_str()) != nullptr) {
0420 metaDataTree->SetBranchAddress(edm::poolNames::branchIDListBranchName().c_str(), &branchIDListsPtr);
0421 }
0422
0423 metaDataTree->GetEntry(0);
0424
0425 for (auto& prod : m_->reg_->productListUpdator()) {
0426 prod.second.init();
0427 setIsMergeable(prod.second);
0428 }
0429
0430
0431 edm::pset::Registry& psetRegistry = *edm::pset::Registry::instance();
0432 for (auto const& entry : psetMap) {
0433 edm::ParameterSet pset(entry.second.pset());
0434 pset.setID(entry.first);
0435 psetRegistry.insertMapped(pset);
0436 }
0437
0438 for (auto const& ph : pHistVector) {
0439 m_->phreg_->registerProcessHistory(ph);
0440 }
0441
0442 m_->pointerToBranchBuffer_.erase(m_->pointerToBranchBuffer_.begin(), m_->pointerToBranchBuffer_.end());
0443
0444 std::unique_ptr<edm::ProductRegistry> newReg = std::make_unique<edm::ProductRegistry>();
0445
0446 edm::ProductRegistry::ProductList& prodList = m_->reg_->productListUpdator();
0447 {
0448 for (auto& item : prodList) {
0449 edm::BranchDescription& prod = item.second;
0450
0451 std::string newFriendlyName = edm::friendlyname::friendlyName(prod.className());
0452 if (newFriendlyName == prod.friendlyClassName()) {
0453 newReg->copyProduct(prod);
0454 } else {
0455 if (m_->fileFormatVersion_.splitProductIDs()) {
0456 throw edm::Exception(edm::errors::UnimplementedFeature)
0457 << "Cannot change friendly class name algorithm without more development work\n"
0458 << "to update BranchIDLists. Contact the framework group.\n";
0459 }
0460 edm::BranchDescription newBD(prod);
0461 newBD.updateFriendlyClassName();
0462 newReg->copyProduct(newBD);
0463 }
0464 prod.init();
0465 }
0466
0467 m_->reg().reset(newReg.release());
0468 }
0469
0470 edm::ProductRegistry::ProductList& prodList2 = m_->reg_->productListUpdator();
0471 std::vector<edm::EventEntryDescription> temp(prodList2.size(), edm::EventEntryDescription());
0472 m_->prov_.swap(temp);
0473 m_->pointerToBranchBuffer_.reserve(prodList2.size());
0474
0475 for (auto& item : prodList2) {
0476 edm::BranchDescription& prod = item.second;
0477 if (prod.branchType() == edm::InEvent) {
0478 prod.init();
0479
0480 if (m_->tree_->GetBranch(prod.branchName().c_str()) == nullptr) {
0481 prod.setDropped(true);
0482 }
0483 prod.setOnDemand(true);
0484
0485
0486
0487
0488
0489
0490
0491 }
0492 }
0493 m_->branchIDListHelper_->updateFromInput(*branchIDListsPtr);
0494 m_->reg_->setFrozen();
0495 m_->bidToDesc_->clear();
0496 for (auto const& p : m_->reg_->productList()) {
0497 m_->bidToDesc_->emplace(p.second.branchID().id(), &p.second);
0498 }
0499 m_->ep_ = std::make_shared<edm::EventPrincipal>(
0500 m_->reg(), m_->branchIDListHelper(), m_->thinnedAssociationsHelper(), m_->pc_, nullptr);
0501 everythingOK_ = true;
0502 }
0503
0504
0505
0506
0507
0508
0509
0510