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 std::map<BranchID, boost::shared_ptr<Group> > idToGroup;
00113 for(EventPrincipal::const_iterator it = e.begin(), itEnd = e.end();
00114 it != itEnd;
00115 ++it) {
00116 if(*it) {
00117 BranchID branchID = (*it)->branchDescription().branchID();
00118 idToGroup[branchID] = (*it);
00119 if((*it)->productUnavailable()) {
00120
00121 OutputHandle const oh = e.getForOutput(branchID, false);
00122
00123 bool cannotFindProductProvenance=false;
00124 if(!(*it)->productProvenancePtr()) {
00125 missingProductProvenance.insert(branchID);
00126 cannotFindProductProvenance=true;
00127 }
00128 ProductProvenance const* pInfo = mapperPtr->branchIDToProvenance(branchID);
00129 if(!pInfo) {
00130 missingFromMapper.insert(branchID);
00131 continue;
00132 }
00133 if(cannotFindProductProvenance) {
00134 continue;
00135 }
00136 markAncestors(*((*it)->productProvenancePtr()), *mapperPtr, seenParentInPrincipal, missingFromMapper);
00137 }
00138 seenParentInPrincipal[branchID] = true;
00139 }
00140 }
00141
00142
00143 ProductRegistry const& reg = e.productRegistry();
00144 ProductRegistry::ProductList const prodList = reg.productList();
00145 std::set<BranchID> branchesInReg;
00146 for(ProductRegistry::ProductList::const_iterator it = prodList.begin(), itEnd = prodList.end();
00147 it != itEnd;
00148 ++it) {
00149 branchesInReg.insert(it->second.branchID());
00150 }
00151
00152 std::set<BranchID> missingFromPrincipal;
00153 std::set<BranchID> missingFromReg;
00154 for(std::map<BranchID, bool>::iterator it = seenParentInPrincipal.begin(), itEnd = seenParentInPrincipal.end();
00155 it != itEnd;
00156 ++it) {
00157 if(!it->second) {
00158 missingFromPrincipal.insert(it->first);
00159 }
00160 if(branchesInReg.find(it->first) == branchesInReg.end()) {
00161 missingFromReg.insert(it->first);
00162 }
00163 }
00164
00165 if(missingFromMapper.size()) {
00166 LogError("ProvenanceChecker") << "Missing the following BranchIDs from BranchMapper\n";
00167 for(std::set<BranchID>::iterator it = missingFromMapper.begin(), itEnd = missingFromMapper.end();
00168 it != itEnd;
00169 ++it) {
00170 LogProblem("ProvenanceChecker") << *it<<" "<<idToGroup[*it]->branchDescription();
00171 }
00172 }
00173 if(missingFromPrincipal.size()) {
00174 LogError("ProvenanceChecker") << "Missing the following BranchIDs from EventPrincipal\n";
00175 for(std::set<BranchID>::iterator it = missingFromPrincipal.begin(), itEnd = missingFromPrincipal.end();
00176 it != itEnd;
00177 ++it) {
00178 LogProblem("ProvenanceChecker") << *it;
00179 }
00180 }
00181
00182 if(missingProductProvenance.size()) {
00183 LogError("ProvenanceChecker") << "The Groups for the following BranchIDs have no ProductProvenance\n";
00184 for(std::set<BranchID>::iterator it = missingProductProvenance.begin(), itEnd = missingProductProvenance.end();
00185 it != itEnd;
00186 ++it) {
00187 LogProblem("ProvenanceChecker") << *it<<" "<<idToGroup[*it]->branchDescription();
00188 }
00189 }
00190
00191 if(missingFromReg.size()) {
00192 LogError("ProvenanceChecker") << "Missing the following BranchIDs from ProductRegistry\n";
00193 for(std::set<BranchID>::iterator it = missingFromReg.begin(), itEnd = missingFromReg.end();
00194 it != itEnd;
00195 ++it) {
00196 LogProblem("ProvenanceChecker") << *it;
00197 }
00198 }
00199
00200 if(missingFromMapper.size() || missingFromPrincipal.size() || missingProductProvenance.size() || missingFromReg.size()) {
00201 throw cms::Exception("ProvenanceError")
00202 << (missingFromMapper.size() || missingFromPrincipal.size() ? "Having missing ancestors" : "")
00203 << (missingFromMapper.size() ? " from BranchMapper" : "")
00204 << (missingFromMapper.size() && missingFromPrincipal.size() ? " and" : "")
00205 << (missingFromPrincipal.size() ? " from EventPrincipal" : "")
00206 << (missingFromMapper.size() || missingFromPrincipal.size() ? ".\n" : "")
00207 << (missingProductProvenance.size() ? " Have missing ProductProvenance's from Group in EventPrincipal.\n" : "")
00208 << (missingFromReg.size() ? " Have missing info from ProductRegistry.\n" : "");
00209 }
00210 }
00211
00212
00213
00214
00215
00216
00217
00218
00219 void
00220 ProvenanceCheckerOutputModule::fillDescriptions(ConfigurationDescriptions& descriptions) {
00221 ParameterSetDescription desc;
00222 OutputModule::fillDescription(desc);
00223 descriptions.add("provenanceChecker", desc);
00224 }
00225 }
00226 using edm::ProvenanceCheckerOutputModule;
00227 DEFINE_FWK_MODULE(ProvenanceCheckerOutputModule);