Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2024-04-06 12:12:36

0001 
0002 #include "DataFormats/Common/interface/Handle.h"
0003 #include "DataFormats/Provenance/interface/BranchID.h"
0004 #include "DataFormats/Provenance/interface/Parentage.h"
0005 #include "DataFormats/Provenance/interface/ProductProvenance.h"
0006 #include "DataFormats/Provenance/interface/ProductProvenanceLookup.h"
0007 #include "DataFormats/Provenance/interface/Provenance.h"
0008 #include "DataFormats/TestObjects/interface/ToyProducts.h"
0009 #include "FWCore/Framework/interface/ConstProductRegistry.h"
0010 #include "FWCore/Framework/interface/global/EDAnalyzer.h"
0011 #include "FWCore/Framework/interface/Event.h"
0012 #include "FWCore/Framework/interface/MakerMacros.h"
0013 #include "FWCore/ParameterSet/interface/ParameterSet.h"
0014 #include "FWCore/ServiceRegistry/interface/Service.h"
0015 #include "FWCore/Utilities/interface/InputTag.h"
0016 #include "FWCore/Utilities/interface/EDGetToken.h"
0017 
0018 #include <iostream>
0019 #include <map>
0020 #include <set>
0021 #include <string>
0022 #include <vector>
0023 
0024 namespace {
0025   void getAncestors(edm::Event const& e, edm::BranchID const& branchID, std::set<edm::BranchID>& ancestors) {
0026     const edm::Provenance& prov = e.getProvenance(branchID);
0027     if (prov.productProvenance()) {
0028       for (auto const& parent : prov.productProvenance()->parentage().parents()) {
0029         ancestors.insert(parent);
0030         getAncestors(e, parent, ancestors);
0031       }
0032     }
0033   }
0034 
0035   // Does the same thing as the previous function in a different
0036   // way. The previous function goes through the links in the
0037   // ProductsResolver which for SubProcesses could lead to a different
0038   // retriever. In SubProcesses, the following function follows the
0039   // links in the retrievers themselves. Both should give the same answer.
0040   void getAncestorsFromRetriever(edm::ProductProvenanceLookup const* retriever,
0041                                  edm::BranchID const& branchID,
0042                                  std::set<edm::BranchID>& ancestors) {
0043     edm::ProductProvenance const* productProvenance = retriever->branchIDToProvenance(branchID);
0044     if (productProvenance) {
0045       for (auto const& parent : productProvenance->parentage().parents()) {
0046         ancestors.insert(parent);
0047         getAncestorsFromRetriever(retriever, parent, ancestors);
0048       }
0049     }
0050   }
0051 }  // namespace
0052 
0053 namespace edmtest {
0054 
0055   class TestParentage : public edm::global::EDAnalyzer<> {
0056   public:
0057     explicit TestParentage(edm::ParameterSet const& pset);
0058     ~TestParentage() override = default;
0059 
0060     void analyze(edm::StreamID, edm::Event const& e, edm::EventSetup const& es) const override;
0061 
0062   private:
0063     edm::EDGetTokenT<IntProduct> token_;
0064     std::vector<std::string> expectedAncestors_;
0065     bool callGetProvenance_;
0066   };
0067 
0068   TestParentage::TestParentage(edm::ParameterSet const& pset)
0069       : token_(consumes(pset.getParameter<edm::InputTag>("inputTag"))),
0070         expectedAncestors_(pset.getParameter<std::vector<std::string> >("expectedAncestors")),
0071         callGetProvenance_(pset.getUntrackedParameter<bool>("callGetProvenance", true)) {}
0072 
0073   void TestParentage::analyze(edm::StreamID, edm::Event const& e, edm::EventSetup const&) const {
0074     edm::Handle<IntProduct> h = e.getHandle(token_);
0075 
0076     edm::Provenance const* prov = h.provenance();
0077 
0078     if (prov->originalBranchID() != prov->branchDescription().originalBranchID()) {
0079       std::cerr << "TestParentage::analyze: test of Provenance::originalBranchID function failed" << std::endl;
0080       abort();
0081     }
0082 
0083     std::set<std::string> expectedAncestors(expectedAncestors_.begin(), expectedAncestors_.end());
0084 
0085     std::map<edm::BranchID, std::string> branchIDToLabel;
0086     edm::Service<edm::ConstProductRegistry> reg;
0087     for (auto const& prod : reg->productList()) {
0088       branchIDToLabel[prod.second.branchID()] = prod.second.moduleLabel();
0089     }
0090 
0091     // Currently we need to turn off this part of the test of when calling
0092     // from a SubProcess and the parentage includes a product not kept
0093     // in the SubProcess. This might get fixed someday ...
0094     if (callGetProvenance_) {
0095       std::set<edm::BranchID> ancestors;
0096       getAncestors(e, prov->branchID(), ancestors);
0097 
0098       std::set<std::string> ancestorLabels;
0099       for (edm::BranchID const& ancestor : ancestors) {
0100         ancestorLabels.insert(branchIDToLabel[ancestor]);
0101       }
0102       if (ancestorLabels != expectedAncestors) {
0103         std::cerr << "TestParentage::analyze: ancestors do not match expected ancestors" << std::endl;
0104         abort();
0105       }
0106     }
0107 
0108     auto const* retriever = prov->store();
0109     std::set<edm::BranchID> ancestorsFromRetriever;
0110     getAncestorsFromRetriever(retriever, prov->originalBranchID(), ancestorsFromRetriever);
0111 
0112     std::set<std::string> ancestorLabels2;
0113     for (edm::BranchID const& ancestor : ancestorsFromRetriever) {
0114       ancestorLabels2.insert(branchIDToLabel[ancestor]);
0115     }
0116     if (ancestorLabels2 != expectedAncestors) {
0117       std::cerr << "TestParentage::analyze: ancestors do not match expected ancestors (parentage from retriever)"
0118                 << std::endl;
0119       abort();
0120     }
0121   }
0122 }  // namespace edmtest
0123 
0124 using edmtest::TestParentage;
0125 DEFINE_FWK_MODULE(TestParentage);