CMS 3D CMS Logo

/data/refman/pasoursint/CMSSW_4_4_5_patch3/src/FWCore/Modules/src/ProvenanceCheckerOutputModule.cc

Go to the documentation of this file.
00001 // -*- C++ -*-
00002 //
00003 // Package:     Modules
00004 // Class  :     ProvenanceCheckerOutputModule
00005 //
00006 // Implementation:
00007 //     Checks the consistency of provenance stored in the framework
00008 //
00009 // Original Author:  Chris Jones
00010 //         Created:  Thu Sep 11 19:24:13 EDT 2008
00011 //
00012 
00013 // system include files
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 // user include files
00025 
00026 namespace edm {
00027    class ParameterSet;
00028    class ProvenanceCheckerOutputModule : public OutputModule {
00029    public:
00030       // We do not take ownership of passed stream.
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 // constants, enums and typedefs
00044 //
00045 
00046 //
00047 // static data member definitions
00048 //
00049 
00050 //
00051 // constructors and destructor
00052 //
00053    ProvenanceCheckerOutputModule::ProvenanceCheckerOutputModule(ParameterSet const& pset) :
00054    OutputModule(pset)
00055    {
00056    }
00057 
00058 // ProvenanceCheckerOutputModule::ProvenanceCheckerOutputModule(ProvenanceCheckerOutputModule const& rhs)
00059 // {
00060 //    // do actual copying here;
00061 // }
00062 
00063    ProvenanceCheckerOutputModule::~ProvenanceCheckerOutputModule()
00064    {
00065    }
00066 
00067 //
00068 // assignment operators
00069 //
00070 // ProvenanceCheckerOutputModule const& ProvenanceCheckerOutputModule::operator=(ProvenanceCheckerOutputModule const& rhs)
00071 // {
00072 //   //An exception safe implementation is
00073 //   ProvenanceCheckerOutputModule temp(rhs);
00074 //   swap(rhs);
00075 //
00076 //   return *this;
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          //Don't look for parents if we've previously looked at the parents
00089          if(oMap.find(*it) == oMap.end()) {
00090             //use side effect of calling operator[] which is if the item isn't there it will add it as 'false'
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       //check ProductProvenance's parents to see if they are in the ProductProvenance list
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                //This call seems to have a side effect of filling the 'ProductProvenance' in the Group
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       //Determine what BranchIDs are in the product registry
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 // const member functions
00207 //
00208 
00209 //
00210 // static member functions
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);