Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014 #include "FWCore/Framework/interface/OutputModule.h"
00015 #include "FWCore/Framework/interface/MakerMacros.h"
00016 #include "FWCore/Framework/interface/EventPrincipal.h"
00017 #include "FWCore/Utilities/interface/Exception.h"
00018 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00019 #include "DataFormats/Common/interface/OutputHandle.h"
00020 #include "DataFormats/Provenance/interface/ProductRegistry.h"
00021 #include "FWCore/ParameterSet/interface/ConfigurationDescriptions.h"
00022 #include "FWCore/ParameterSet/interface/ParameterSetDescription.h"
00023
00024
00025
00026 namespace edm {
00027 class ParameterSet;
00028 class ProvenanceCheckerOutputModule : public OutputModule {
00029 public:
00030
00031 explicit ProvenanceCheckerOutputModule(ParameterSet const& pset);
00032 virtual ~ProvenanceCheckerOutputModule();
00033 static void fillDescriptions(ConfigurationDescriptions& descriptions);
00034
00035 private:
00036 virtual void write(EventPrincipal const& e);
00037 virtual void writeLuminosityBlock(LuminosityBlockPrincipal const&){}
00038 virtual void writeRun(RunPrincipal const&){}
00039 };
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053 ProvenanceCheckerOutputModule::ProvenanceCheckerOutputModule(ParameterSet const& pset) :
00054 OutputModule(pset)
00055 {
00056 }
00057
00058
00059
00060
00061
00062
00063 ProvenanceCheckerOutputModule::~ProvenanceCheckerOutputModule()
00064 {
00065 }
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079 namespace {
00080 void markAncestors(ProductProvenance const& iInfo,
00081 BranchMapper const& iMapper,
00082 std::map<BranchID, bool>& oMap,
00083 std::set<BranchID>& oMapperMissing) {
00084 for(std::vector<BranchID>::const_iterator it = iInfo.parentage().parents().begin(),
00085 itEnd = iInfo.parentage().parents().end();
00086 it != itEnd;
00087 ++it) {
00088
00089 if(oMap.find(*it) == oMap.end()) {
00090
00091 oMap[*it];
00092 ProductProvenance const* pInfo = iMapper.branchIDToProvenance(*it);
00093 if(pInfo) {
00094 markAncestors(*pInfo, iMapper, oMap, oMapperMissing);
00095 } else {
00096 oMapperMissing.insert(*it);
00097 }
00098 }
00099 }
00100 }
00101 }
00102
00103 void
00104 ProvenanceCheckerOutputModule::write(EventPrincipal const& e) {
00105
00106 boost::shared_ptr<BranchMapper> mapperPtr = e.branchMapperPtr();
00107
00108 std::map<BranchID, bool> seenParentInPrincipal;
00109 std::set<BranchID> missingFromMapper;
00110 std::set<BranchID> missingProductProvenance;
00111
00112 for(EventPrincipal::const_iterator it = e.begin(), itEnd = e.end();
00113 it != itEnd;
00114 ++it) {
00115 if(*it) {
00116 BranchID branchID = (*it)->branchDescription().branchID();
00117 if((*it)->productUnavailable()) {
00118
00119 OutputHandle const oh = e.getForOutput(branchID, false);
00120
00121 if(!(*it)->productProvenancePtr()) {
00122 missingProductProvenance.insert(branchID);
00123 continue;
00124 }
00125 ProductProvenance const* pInfo = mapperPtr->branchIDToProvenance(branchID);
00126 if(!pInfo) {
00127 missingFromMapper.insert(branchID);
00128 }
00129 markAncestors(*((*it)->productProvenancePtr()), *mapperPtr, seenParentInPrincipal, missingFromMapper);
00130 }
00131 seenParentInPrincipal[branchID] = true;
00132 }
00133 }
00134
00135
00136 ProductRegistry const& reg = e.productRegistry();
00137 ProductRegistry::ProductList const prodList = reg.productList();
00138 std::set<BranchID> branchesInReg;
00139 for(ProductRegistry::ProductList::const_iterator it = prodList.begin(), itEnd = prodList.end();
00140 it != itEnd;
00141 ++it) {
00142 branchesInReg.insert(it->second.branchID());
00143 }
00144
00145 std::set<BranchID> missingFromPrincipal;
00146 std::set<BranchID> missingFromReg;
00147 for(std::map<BranchID, bool>::iterator it = seenParentInPrincipal.begin(), itEnd = seenParentInPrincipal.end();
00148 it != itEnd;
00149 ++it) {
00150 if(!it->second) {
00151 missingFromPrincipal.insert(it->first);
00152 }
00153 if(branchesInReg.find(it->first) == branchesInReg.end()) {
00154 missingFromReg.insert(it->first);
00155 }
00156 }
00157
00158 if(missingFromMapper.size()) {
00159 LogError("ProvenanceChecker") << "Missing the following BranchIDs from BranchMapper\n";
00160 for(std::set<BranchID>::iterator it = missingFromMapper.begin(), itEnd = missingFromMapper.end();
00161 it != itEnd;
00162 ++it) {
00163 LogProblem("ProvenanceChecker") << *it;
00164 }
00165 }
00166 if(missingFromPrincipal.size()) {
00167 LogError("ProvenanceChecker") << "Missing the following BranchIDs from EventPrincipal\n";
00168 for(std::set<BranchID>::iterator it = missingFromPrincipal.begin(), itEnd = missingFromPrincipal.end();
00169 it != itEnd;
00170 ++it) {
00171 LogProblem("ProvenanceChecker") << *it;
00172 }
00173 }
00174
00175 if(missingProductProvenance.size()) {
00176 LogError("ProvenanceChecker") << "The Groups for the following BranchIDs have no ProductProvenance\n";
00177 for(std::set<BranchID>::iterator it = missingProductProvenance.begin(), itEnd = missingProductProvenance.end();
00178 it != itEnd;
00179 ++it) {
00180 LogProblem("ProvenanceChecker") << *it;
00181 }
00182 }
00183
00184 if(missingFromReg.size()) {
00185 LogError("ProvenanceChecker") << "Missing the following BranchIDs from ProductRegistry\n";
00186 for(std::set<BranchID>::iterator it = missingFromReg.begin(), itEnd = missingFromReg.end();
00187 it != itEnd;
00188 ++it) {
00189 LogProblem("ProvenanceChecker") << *it;
00190 }
00191 }
00192
00193 if(missingFromMapper.size() || missingFromPrincipal.size() || missingProductProvenance.size() || missingFromReg.size()) {
00194 throw cms::Exception("ProvenanceError")
00195 << (missingFromMapper.size() || missingFromPrincipal.size() ? "Having missing ancestors" : "")
00196 << (missingFromMapper.size() ? " from BranchMapper" : "")
00197 << (missingFromMapper.size() && missingFromPrincipal.size() ? " and" : "")
00198 << (missingFromPrincipal.size() ? " from EventPrincipal" : "")
00199 << (missingFromMapper.size() || missingFromPrincipal.size() ? ".\n" : "")
00200 << (missingProductProvenance.size() ? " Have missing ProductProvenance's from Group in EventPrincipal.\n" : "")
00201 << (missingFromReg.size() ? " Have missing info from ProductRegistry.\n" : "");
00202 }
00203 }
00204
00205
00206
00207
00208
00209
00210
00211
00212 void
00213 ProvenanceCheckerOutputModule::fillDescriptions(ConfigurationDescriptions& descriptions) {
00214 ParameterSetDescription desc;
00215 OutputModule::fillDescription(desc);
00216 descriptions.add("provenanceChecker", desc);
00217 }
00218 }
00219 using edm::ProvenanceCheckerOutputModule;
00220 DEFINE_FWK_MODULE(ProvenanceCheckerOutputModule);