File indexing completed on 2025-03-23 15:57:47
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014 #include "FWCore/Framework/interface/one/OutputModule.h"
0015 #include "FWCore/Framework/interface/MakerMacros.h"
0016 #include "FWCore/Framework/interface/EventForOutput.h"
0017 #include "FWCore/Utilities/interface/Exception.h"
0018 #include "FWCore/MessageLogger/interface/MessageLogger.h"
0019 #include "DataFormats/Provenance/interface/ProductRegistry.h"
0020 #include "FWCore/ParameterSet/interface/ConfigurationDescriptions.h"
0021 #include "FWCore/ParameterSet/interface/ParameterSetDescription.h"
0022 #include "FWCore/ServiceRegistry/interface/Service.h"
0023
0024
0025
0026 namespace edm {
0027
0028 class ModuleCallingContext;
0029 class ParameterSet;
0030
0031 class ProvenanceCheckerOutputModule : public one::OutputModule<> {
0032 public:
0033
0034 explicit ProvenanceCheckerOutputModule(ParameterSet const& pset);
0035 ~ProvenanceCheckerOutputModule() override;
0036 static void fillDescriptions(ConfigurationDescriptions& descriptions);
0037
0038 private:
0039 void write(EventForOutput const& e) override;
0040 void writeLuminosityBlock(LuminosityBlockForOutput const&) override {}
0041 void writeRun(RunForOutput const&) override {}
0042 };
0043
0044
0045
0046
0047
0048
0049
0050
0051
0052
0053
0054
0055 ProvenanceCheckerOutputModule::ProvenanceCheckerOutputModule(ParameterSet const& pset)
0056 : one::OutputModuleBase(pset), one::OutputModule<>(pset) {}
0057
0058
0059
0060
0061
0062
0063 ProvenanceCheckerOutputModule::~ProvenanceCheckerOutputModule() {}
0064
0065
0066
0067
0068
0069
0070
0071
0072
0073
0074
0075
0076
0077 namespace {
0078 void markAncestors(EventForOutput const& e,
0079 ProductProvenance const& iInfo,
0080 std::map<BranchID, bool>& oMap,
0081 std::set<BranchID>& oMapperMissing) {
0082 for (BranchID const id : iInfo.parentage().parents()) {
0083
0084 if (oMap.find(id) == oMap.end()) {
0085
0086 oMap[id];
0087 ProductProvenance const* pInfo = e.getProvenance(id).productProvenance();
0088 if (pInfo) {
0089 markAncestors(e, *pInfo, oMap, oMapperMissing);
0090 } else {
0091 oMapperMissing.insert(id);
0092 }
0093 }
0094 }
0095 }
0096 }
0097
0098 void ProvenanceCheckerOutputModule::write(EventForOutput const& e) {
0099
0100
0101 std::map<BranchID, bool> seenParentInPrincipal;
0102 std::set<BranchID> missingFromMapper;
0103 std::set<BranchID> missingProductProvenance;
0104
0105 std::map<BranchID, const ProductDescription*> idToProductDescriptions;
0106 for (auto const& product : keptProducts()[InEvent]) {
0107 ProductDescription const* productDescription = product.first;
0108 BranchID branchID = productDescription->branchID();
0109 idToProductDescriptions[branchID] = productDescription;
0110 TypeID const& tid(productDescription->unwrappedTypeID());
0111 EDGetToken const& token = product.second;
0112 BasicHandle bh = e.getByToken(token, tid);
0113 bool cannotFindProductProvenance = false;
0114 if (!(bh.provenance() and bh.provenance()->productProvenance())) {
0115 missingProductProvenance.insert(branchID);
0116 cannotFindProductProvenance = true;
0117 }
0118 ProductProvenance const* pInfo = e.getProvenance(branchID).productProvenance();
0119 if (!pInfo) {
0120 missingFromMapper.insert(branchID);
0121 continue;
0122 }
0123 if (cannotFindProductProvenance) {
0124 continue;
0125 }
0126 markAncestors(e, *(bh.provenance()->productProvenance()), seenParentInPrincipal, missingFromMapper);
0127 seenParentInPrincipal[branchID] = true;
0128 }
0129
0130
0131 std::set<BranchID> branchesInReg;
0132 for (auto const& product : e.productRegistry().productList()) {
0133 branchesInReg.insert(product.second.branchID());
0134 idToProductDescriptions[product.second.branchID()] = &product.second;
0135 }
0136
0137 std::set<BranchID> missingFromReg;
0138 for (auto const& item : seenParentInPrincipal) {
0139 if (branchesInReg.find(item.first) == branchesInReg.end()) {
0140 missingFromReg.insert(item.first);
0141 }
0142 }
0143
0144 if (!missingFromMapper.empty()) {
0145 LogError("ProvenanceChecker") << "Missing the following BranchIDs from ProductProvenanceRetriever\n";
0146 for (std::set<BranchID>::iterator it = missingFromMapper.begin(), itEnd = missingFromMapper.end(); it != itEnd;
0147 ++it) {
0148 LogProblem("ProvenanceChecker") << *it << " " << *(idToProductDescriptions[*it]);
0149 }
0150 }
0151
0152 if (!missingProductProvenance.empty()) {
0153 LogError("ProvenanceChecker") << "The ProductResolvers for the following BranchIDs have no ProductProvenance\n";
0154 for (std::set<BranchID>::iterator it = missingProductProvenance.begin(), itEnd = missingProductProvenance.end();
0155 it != itEnd;
0156 ++it) {
0157 LogProblem("ProvenanceChecker") << *it << " " << *(idToProductDescriptions[*it]);
0158 }
0159 }
0160
0161 if (!missingFromReg.empty()) {
0162 LogError("ProvenanceChecker") << "Missing the following BranchIDs from ProductRegistry\n";
0163 for (auto const& item : missingFromReg) {
0164 LogProblem("ProvenanceChecker") << item << " " << *(idToProductDescriptions[item]);
0165 }
0166 }
0167
0168 if (!missingFromMapper.empty() || !missingProductProvenance.empty() || !missingFromReg.empty()) {
0169 throw cms::Exception("ProvenanceError")
0170 << (!missingFromMapper.empty() ? "Having missing ancestors from ProductProvenanceRetriever.\n" : "")
0171 << (!missingProductProvenance.empty() ? " Have missing ProductProvenance's from ProductResolver in Event.\n"
0172 : "")
0173 << (!missingFromReg.empty() ? " Have missing info from ProductRegistry.\n" : "");
0174 }
0175
0176
0177 if (e.productRegistry().cacheIdentifier() != e.getRun().productRegistry().cacheIdentifier()) {
0178 throw cms::Exception("ProvenanceError")
0179 << "The registry cache id for Event ( " << e.productRegistry().cacheIdentifier()
0180 << " ) does not match the one for Run ( " << e.getRun().productRegistry().cacheIdentifier() << " )";
0181 }
0182 if (e.productRegistry().cacheIdentifier() != e.getLuminosityBlock().productRegistry().cacheIdentifier()) {
0183 throw cms::Exception("ProvenanceError")
0184 << "The registry cache id for Event ( " << e.productRegistry().cacheIdentifier()
0185 << " ) does not match the one for LuminosityBlock ( "
0186 << e.getLuminosityBlock().productRegistry().cacheIdentifier() << " )";
0187 }
0188 }
0189
0190
0191
0192
0193
0194
0195
0196
0197 void ProvenanceCheckerOutputModule::fillDescriptions(ConfigurationDescriptions& descriptions) {
0198 ParameterSetDescription desc;
0199 one::OutputModule<>::fillDescription(desc);
0200 descriptions.add("provenanceChecker", desc);
0201 }
0202 }
0203 using edm::ProvenanceCheckerOutputModule;
0204 DEFINE_FWK_MODULE(ProvenanceCheckerOutputModule);