CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
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
23 
24 // user include files
25 
26 namespace edm {
27  class ParameterSet;
29  public:
30  // We do not take ownership of passed stream.
33  static void fillDescriptions(ConfigurationDescriptions& descriptions);
34 
35  private:
36  virtual void write(EventPrincipal const& e);
38  virtual void writeRun(RunPrincipal const&){}
39  };
40 
41 
42 //
43 // constants, enums and typedefs
44 //
45 
46 //
47 // static data member definitions
48 //
49 
50 //
51 // constructors and destructor
52 //
54  OutputModule(pset)
55  {
56  }
57 
58 // ProvenanceCheckerOutputModule::ProvenanceCheckerOutputModule(ProvenanceCheckerOutputModule const& rhs)
59 // {
60 // // do actual copying here;
61 // }
62 
64  {
65  }
66 
67 //
68 // assignment operators
69 //
70 // ProvenanceCheckerOutputModule const& ProvenanceCheckerOutputModule::operator=(ProvenanceCheckerOutputModule const& rhs)
71 // {
72 // //An exception safe implementation is
73 // ProvenanceCheckerOutputModule temp(rhs);
74 // swap(rhs);
75 //
76 // return *this;
77 // }
78 
79  namespace {
80  void markAncestors(ProductProvenance const& iInfo,
81  BranchMapper const& iMapper,
82  std::map<BranchID, bool>& oMap,
83  std::set<BranchID>& oMapperMissing) {
84  for(std::vector<BranchID>::const_iterator it = iInfo.parentage().parents().begin(),
85  itEnd = iInfo.parentage().parents().end();
86  it != itEnd;
87  ++it) {
88  //Don't look for parents if we've previously looked at the parents
89  if(oMap.find(*it) == oMap.end()) {
90  //use side effect of calling operator[] which is if the item isn't there it will add it as 'false'
91  oMap[*it];
92  boost::shared_ptr<ProductProvenance> pInfo = iMapper.branchIDToProvenance(*it);
93  if(pInfo.get()) {
94  markAncestors(*pInfo, iMapper, oMap, oMapperMissing);
95  } else {
96  oMapperMissing.insert(*it);
97  }
98  }
99  }
100  }
101  }
102 
103  void
105  //check ProductProvenance's parents to see if they are in the ProductProvenance list
106  boost::shared_ptr<BranchMapper> mapperPtr = e.branchMapperPtr();
107 
108  std::map<BranchID, bool> seenParentInPrincipal;
109  std::set<BranchID> missingFromMapper;
110  std::set<BranchID> missingProductProvenance;
111 
112  for(EventPrincipal::const_iterator it = e.begin(), itEnd = e.end();
113  it != itEnd;
114  ++it) {
115  if(*it) {
116  BranchID branchID = (*it)->branchDescription().branchID();
117  if((*it)->productUnavailable()) {
118  //This call seems to have a side effect of filling the 'ProductProvenance' in the Group
119  OutputHandle const oh = e.getForOutput(branchID, false);
120 
121  if(!(*it)->productProvenancePtr().get() ) {
122  missingProductProvenance.insert(branchID);
123  continue;
124  }
125  boost::shared_ptr<ProductProvenance> pInfo = mapperPtr->branchIDToProvenance(branchID);
126  if(!pInfo.get()) {
127  missingFromMapper.insert(branchID);
128  }
129  markAncestors(*((*it)->productProvenancePtr()),*mapperPtr, seenParentInPrincipal, missingFromMapper);
130  }
131  seenParentInPrincipal[branchID] = true;
132  }
133  }
134 
135  //Determine what BranchIDs are in the product registry
136  ProductRegistry const& reg = e.productRegistry();
137  ProductRegistry::ProductList const prodList = reg.productList();
138  std::set<BranchID> branchesInReg;
139  for(ProductRegistry::ProductList::const_iterator it = prodList.begin(), itEnd = prodList.end();
140  it != itEnd;
141  ++it) {
142  branchesInReg.insert(it->second.branchID());
143  }
144 
145  std::set<BranchID> missingFromPrincipal;
146  std::set<BranchID> missingFromReg;
147  for(std::map<BranchID, bool>::iterator it = seenParentInPrincipal.begin(), itEnd = seenParentInPrincipal.end();
148  it != itEnd;
149  ++it) {
150  if(!it->second) {
151  missingFromPrincipal.insert(it->first);
152  }
153  if(branchesInReg.find(it->first) == branchesInReg.end()) {
154  missingFromReg.insert(it->first);
155  }
156  }
157 
158  if(missingFromMapper.size()) {
159  LogError("ProvenanceChecker") << "Missing the following BranchIDs from BranchMapper\n";
160  for(std::set<BranchID>::iterator it = missingFromMapper.begin(), itEnd = missingFromMapper.end();
161  it != itEnd;
162  ++it) {
163  LogProblem("ProvenanceChecker") << *it;
164  }
165  }
166  if(missingFromPrincipal.size()) {
167  LogError("ProvenanceChecker") << "Missing the following BranchIDs from EventPrincipal\n";
168  for(std::set<BranchID>::iterator it = missingFromPrincipal.begin(), itEnd = missingFromPrincipal.end();
169  it != itEnd;
170  ++it) {
171  LogProblem("ProvenanceChecker") << *it;
172  }
173  }
174 
175  if(missingProductProvenance.size()) {
176  LogError("ProvenanceChecker") << "The Groups for the following BranchIDs have no ProductProvenance\n";
177  for(std::set<BranchID>::iterator it = missingProductProvenance.begin(), itEnd = missingProductProvenance.end();
178  it != itEnd;
179  ++it) {
180  LogProblem("ProvenanceChecker") << *it;
181  }
182  }
183 
184  if(missingFromReg.size()) {
185  LogError("ProvenanceChecker") << "Missing the following BranchIDs from ProductRegistry\n";
186  for(std::set<BranchID>::iterator it = missingFromReg.begin(), itEnd = missingFromReg.end();
187  it != itEnd;
188  ++it) {
189  LogProblem("ProvenanceChecker") << *it;
190  }
191  }
192 
193  if(missingFromMapper.size() || missingFromPrincipal.size() || missingProductProvenance.size() || missingFromReg.size()) {
194  throw cms::Exception("ProvenanceError")
195  << (missingFromMapper.size() || missingFromPrincipal.size() ? "Having missing ancestors" : "")
196  << (missingFromMapper.size() ? " from BranchMapper" : "")
197  << (missingFromMapper.size() && missingFromPrincipal.size() ? " and" : "")
198  << (missingFromPrincipal.size() ? " from EventPrincipal" : "")
199  << (missingFromMapper.size() || missingFromPrincipal.size() ? ".\n" : "")
200  << (missingProductProvenance.size() ? " Have missing ProductProvenance's from Group in EventPrincipal.\n" : "")
201  << (missingFromReg.size() ? " Have missing info from ProductRegistry.\n" : "");
202  }
203  }
204 
205 //
206 // const member functions
207 //
208 
209 //
210 // static member functions
211 //
212  void
216  descriptions.add("provenanceChecker", desc);
217  }
218 }
ProductRegistry const & productRegistry() const
Definition: Principal.h:122
const_iterator end() const
Definition: Principal.h:131
#define DEFINE_FWK_MODULE(type)
Definition: MakerMacros.h:17
std::map< BranchKey, BranchDescription > ProductList
virtual void writeRun(RunPrincipal const &)
std::vector< BranchID > const & parents() const
Definition: Parentage.h:39
ProductList const & productList() const
OutputHandle getForOutput(BranchID const &bid, bool getProd) const
Definition: Principal.cc:523
tuple pset
Definition: CrabTask.py:85
virtual void writeLuminosityBlock(LuminosityBlockPrincipal const &)
boost::shared_ptr< ProductProvenance > branchIDToProvenance(BranchID const &bid) const
Definition: BranchMapper.cc:44
virtual void write(EventPrincipal const &e)
const_iterator begin() const
Definition: Principal.h:130
void add(std::string const &label, ParameterSetDescription const &psetDescription)
ProvenanceCheckerOutputModule(ParameterSet const &pset)
static void fillDescription(ParameterSetDescription &desc)
boost::filter_iterator< FilledGroupPtr, GroupCollection::const_iterator > const_iterator
Definition: Principal.h:48
author Stefano ARGIRO author Bill Tanenbaum
boost::shared_ptr< BranchMapper > branchMapperPtr() const
Definition: Principal.h:139
static void fillDescriptions(ConfigurationDescriptions &descriptions)
Parentage const & parentage() const