ProvenanceCheckerOutput_module.cc
Go to the documentation of this file.
1 // ======================================================================
2 //
3 // ProvenanceCheckerOutput: Check the consistency of provenance stored
4 // in the framework
5 //
6 // ======================================================================
7 
14 #include "cetlib_except/exception.h"
17 
18 namespace art {
19 
21  public:
22  struct Config {
24  };
25 
26  using Parameters =
28  explicit ProvenanceCheckerOutput(Parameters const&);
29 
30  private:
31  void write(EventPrincipal& e) override;
32  void
34  {}
35  void
37  {}
38  }; // ProvenanceCheckerOutput
39 
40  //
41  // constructors and destructor
42  //
45  : OutputModule{ps().omConfig, ps.get_PSet()}
46  {}
47 
48  //
49  // member functions
50  //
51  static void
54  std::map<ProductID, bool>& oMap,
55  std::set<ProductID>& oMapperMissing)
56  {
57  for (art::ProductID const parent : iInfo.parentage().parents()) {
58  // Don't look for parents if we've previously looked at the parents
59  if (oMap.find(parent) == oMap.end()) {
60  // use side effect of calling operator[] which is if the item isn't
61  // there it will add it as 'false'
62  oMap[parent];
65  if (pInfo.get()) {
66  markAncestors(*pInfo, e, oMap, oMapperMissing);
67  } else {
68  oMapperMissing.insert(parent);
69  }
70  }
71  }
72  }
73 
74  void
76  {
77  // Check ProductProvenance's parents to see if they are in the
78  // ProductProvenance list
79 
80  std::map<ProductID, bool> seenParentInPrincipal;
81  std::set<ProductID> missingFromMapper;
82  std::set<ProductID> missingProductProvenance;
83 
84  for (auto const& group : e) {
85  auto const pid = group.first;
86  auto const& pd = group.second;
87  if (pd && pd->productAvailable()) {
88  e.getForOutput(pid, false);
89  if (not pd->productProvenance().get()) {
90  missingProductProvenance.insert(pid);
91  continue;
92  }
93  auto pInfo = e.branchToProductProvenance(pid);
94  if (!pInfo) {
95  missingFromMapper.insert(pid);
96  }
97  markAncestors(*(pd->productProvenance()),
98  e,
99  seenParentInPrincipal,
100  missingFromMapper);
101  }
102  seenParentInPrincipal[pid] = true;
103  }
104 
105  // Determine what ProductIDs are missing from the principal,
106  // vs. which ProductIDs are not even accessible to the principal
107  // via the product tables.
108  std::set<ProductID> missingFromPrincipal;
109  std::set<ProductID> missingFromTables;
110  for (auto const& seenParent : seenParentInPrincipal) {
111  if (!seenParent.second) {
112  missingFromPrincipal.insert(seenParent.first);
113  }
114  ProductID const pid{seenParent.first};
115  auto found = e.getProductDescription(pid);
116  if (found == nullptr) {
117  missingFromTables.insert(pid);
118  }
119  }
120 
121  auto logProductID = [](auto const& missing) {
122  mf::LogProblem("ProvenanceChecker") << missing;
123  };
124 
125  if (missingFromMapper.size()) {
126  mf::LogError("ProvenanceChecker")
127  << "Missing the following ProductIDs from BranchMapper\n";
128  cet::for_all(missingFromMapper, logProductID);
129  }
130 
131  if (missingFromPrincipal.size()) {
132  mf::LogError("ProvenanceChecker")
133  << "Missing the following ProductIDs from EventPrincipal\n";
134  cet::for_all(missingFromPrincipal, logProductID);
135  }
136 
137  if (missingProductProvenance.size()) {
138  mf::LogError("ProvenanceChecker") << "The Groups for the following "
139  "ProductIDs have no "
140  "ProductProvenance\n";
141  cet::for_all(missingProductProvenance, logProductID);
142  }
143 
144  if (missingFromTables.size()) {
145  mf::LogError("ProvenanceChecker") << "Missing the following ProductIDs "
146  "from the principal's product "
147  "tables\n";
148  cet::for_all(missingFromTables, logProductID);
149  }
150 
151  if (missingFromMapper.size() or missingFromPrincipal.size() or
152  missingProductProvenance.size() or missingFromTables.size()) {
153  throw cet::exception("ProvenanceError")
154  << (missingFromMapper.size() or missingFromPrincipal.size() ?
155  "Having missing ancestors" :
156  "")
157  << (missingFromMapper.size() ? " from BranchMapper" : "")
158  << (missingFromMapper.size() and missingFromPrincipal.size() ? " and" :
159  "")
160  << (missingFromPrincipal.size() ? " from EventPrincipal" : "")
161  << (missingFromMapper.size() or missingFromPrincipal.size() ? ".\n" :
162  "")
163  << (missingProductProvenance.size() ? " Have missing "
164  "ProductProvenance's from Group "
165  "in EventPrincipal.\n" :
166  "")
167  << (missingFromTables.size() ?
168  " Have missing info from the principal's product tables.\n" :
169  "");
170  }
171  }
172 
173 } // namespace art
174 
175 // ======================================================================
176 
178 
179 // ======================================================================
static void markAncestors(ProductProvenance const &iInfo, EventPrincipal &e, std::map< ProductID, bool > &oMap, std::set< ProductID > &oMapperMissing)
auto const & get_PSet() const
void writeSubRun(SubRunPrincipal &) override
std::vector< ProductID > const & parents() const
Definition: Parentage.cc:36
constexpr pointer get() const noexcept
Definition: exempt_ptr.h:148
MaybeLogger_< ELseverityLevel::ELsev_error, false > LogError
MaybeLogger_< ELseverityLevel::ELsev_error, true > LogProblem
const double e
#define DEFINE_ART_MODULE(klass)
Definition: ModuleMacros.h:67
Parentage const & parentage() const
fhicl::TableFragment< OutputModule::Config > omConfig
static constexpr double ps
Definition: Units.h:99
cet::exempt_ptr< ProductProvenance const > branchToProductProvenance(ProductID const &) const
Definition: Principal.cc:438
void writeRun(RunPrincipal &) override
void write(EventPrincipal &e) override
auto for_all(FwdCont &, Func)
def parent(G, child, parent_type)
Definition: graph.py:67
cet::coded_exception< error, detail::translate > exception
Definition: exception.h:33