CMS 3D CMS Logo

ProvenanceCheckerOutputModule.cc
Go to the documentation of this file.
1 // -*- C++ -*-
2 //
3 // Package: Modules
4 // Class : ProvenanceCheckerOutputModule
5 //
6 // Implementation:
7 // Checks the consistency of provenance stored in the framework
8 //
9 // Original Author: Chris Jones
10 // Created: Thu Sep 11 19:24:13 EDT 2008
11 //
12 
13 // system include files
24 
25 // user include files
26 
27 namespace edm {
28 
29  class ModuleCallingContext;
30  class ParameterSet;
31 
33  public:
34  // We do not take ownership of passed stream.
37  static void fillDescriptions(ConfigurationDescriptions& descriptions);
38 
39  private:
40  void write(EventForOutput const& e) override;
42  void writeRun(RunForOutput const&) override {}
43  };
44 
45  //
46  // constants, enums and typedefs
47  //
48 
49  //
50  // static data member definitions
51  //
52 
53  //
54  // constructors and destructor
55  //
57 
58  // ProvenanceCheckerOutputModule::ProvenanceCheckerOutputModule(ProvenanceCheckerOutputModule const& rhs)
59  // {
60  // // do actual copying here;
61  // }
62 
64 
65  //
66  // assignment operators
67  //
68  // ProvenanceCheckerOutputModule const& ProvenanceCheckerOutputModule::operator=(ProvenanceCheckerOutputModule const& rhs)
69  // {
70  // //An exception safe implementation is
71  // ProvenanceCheckerOutputModule temp(rhs);
72  // swap(rhs);
73  //
74  // return *this;
75  // }
76 
77  namespace {
78  void markAncestors(EventForOutput const& e,
79  ProductProvenance const& iInfo,
80  std::map<BranchID, bool>& oMap,
81  std::set<BranchID>& oMapperMissing) {
82  for (BranchID const id : iInfo.parentage().parents()) {
83  //Don't look for parents if we've previously looked at the parents
84  if (oMap.find(id) == oMap.end()) {
85  //use side effect of calling operator[] which is if the item isn't there it will add it as 'false'
86  oMap[id];
87  ProductProvenance const* pInfo = e.getProvenance(id).productProvenance();
88  if (pInfo) {
89  markAncestors(e, *pInfo, oMap, oMapperMissing);
90  } else {
91  oMapperMissing.insert(id);
92  }
93  }
94  }
95  }
96  } // namespace
97 
99  //check ProductProvenance's parents to see if they are in the ProductProvenance list
100 
101  std::map<BranchID, bool> seenParentInPrincipal;
102  std::set<BranchID> missingFromMapper;
103  std::set<BranchID> missingProductProvenance;
104 
105  std::map<BranchID, const BranchDescription*> idToBranchDescriptions;
106  for (auto const product : keptProducts()[InEvent]) {
107  BranchDescription const* branchDescription = product.first;
108  BranchID branchID = branchDescription->branchID();
109  idToBranchDescriptions[branchID] = branchDescription;
110  TypeID const& tid(branchDescription->unwrappedTypeID());
111  EDGetToken const& token = product.second;
112  BasicHandle bh = e.getByToken(token, tid);
113  bool cannotFindProductProvenance = false;
114  if (!(bh.provenance() and bh.provenance()->productProvenance())) {
115  missingProductProvenance.insert(branchID);
116  cannotFindProductProvenance = true;
117  }
118  ProductProvenance const* pInfo = e.getProvenance(branchID).productProvenance();
119  if (!pInfo) {
120  missingFromMapper.insert(branchID);
121  continue;
122  }
123  if (cannotFindProductProvenance) {
124  continue;
125  }
126  markAncestors(e, *(bh.provenance()->productProvenance()), seenParentInPrincipal, missingFromMapper);
127  seenParentInPrincipal[branchID] = true;
128  }
129 
130  //Determine what BranchIDs are in the product registry
132  ProductRegistry::ProductList const& prodList = reg->productList();
133  std::set<BranchID> branchesInReg;
134  for (auto const& product : prodList) {
135  branchesInReg.insert(product.second.branchID());
136  idToBranchDescriptions[product.second.branchID()] = &product.second;
137  }
138 
139  std::set<BranchID> missingFromReg;
140  for (auto const& item : seenParentInPrincipal) {
141  if (branchesInReg.find(item.first) == branchesInReg.end()) {
142  missingFromReg.insert(item.first);
143  }
144  }
145 
146  if (!missingFromMapper.empty()) {
147  LogError("ProvenanceChecker") << "Missing the following BranchIDs from ProductProvenanceRetriever\n";
148  for (std::set<BranchID>::iterator it = missingFromMapper.begin(), itEnd = missingFromMapper.end(); it != itEnd;
149  ++it) {
150  LogProblem("ProvenanceChecker") << *it << " " << *(idToBranchDescriptions[*it]);
151  }
152  }
153 
154  if (!missingProductProvenance.empty()) {
155  LogError("ProvenanceChecker") << "The ProductResolvers for the following BranchIDs have no ProductProvenance\n";
156  for (std::set<BranchID>::iterator it = missingProductProvenance.begin(), itEnd = missingProductProvenance.end();
157  it != itEnd;
158  ++it) {
159  LogProblem("ProvenanceChecker") << *it << " " << *(idToBranchDescriptions[*it]);
160  }
161  }
162 
163  if (!missingFromReg.empty()) {
164  LogError("ProvenanceChecker") << "Missing the following BranchIDs from ProductRegistry\n";
165  for (auto const& item : missingFromReg) {
166  LogProblem("ProvenanceChecker") << item << " " << *(idToBranchDescriptions[item]);
167  }
168  }
169 
170  if (!missingFromMapper.empty() || !missingProductProvenance.empty() || !missingFromReg.empty()) {
171  throw cms::Exception("ProvenanceError")
172  << (!missingFromMapper.empty() ? "Having missing ancestors from ProductProvenanceRetriever.\n" : "")
173  << (!missingProductProvenance.empty() ? " Have missing ProductProvenance's from ProductResolver in Event.\n"
174  : "")
175  << (!missingFromReg.empty() ? " Have missing info from ProductRegistry.\n" : "");
176  }
177  }
178 
179  //
180  // const member functions
181  //
182 
183  //
184  // static member functions
185  //
189  descriptions.add("provenanceChecker", desc);
190  }
191 } // namespace edm
BasicHandle getByToken(EDGetToken token, TypeID const &typeID) const
std::map< BranchKey, BranchDescription > ProductList
Provenance const * provenance() const (true)
Definition: BasicHandle.h:86
ProductProvenance const * productProvenance() const
Definition: Provenance.cc:35
SelectedProductsForBranchType const & keptProducts() const
Definition: OutputModule.h:82
std::vector< BranchID > const & parents() const
Definition: Parentage.h:44
#define DEFINE_FWK_MODULE(type)
Definition: MakerMacros.h:16
static void fillDescription(ParameterSetDescription &desc, std::vector< std::string > const &iDefaultOutputCommands=ProductSelectorRules::defaultSelectionStrings())
TypeID unwrappedTypeID() const
BranchID const & branchID() const
Provenance getProvenance(BranchID const &theID) const
void write(EventForOutput const &e) override
void add(std::string const &label, ParameterSetDescription const &psetDescription)
ProvenanceCheckerOutputModule(ParameterSet const &pset)
HLT enums.
static void fillDescriptions(ConfigurationDescriptions &descriptions)
Parentage const & parentage() const
void writeLuminosityBlock(LuminosityBlockForOutput const &) override
void writeRun(RunForOutput const &) override