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