LArSoft  v09_90_00
Liquid Argon Software toolkit - https://larsoft.org/
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 
13 #include "cetlib_except/exception.h"
16 
17 namespace art {
18 
20  public:
21  struct Config {
23  };
24 
25  using Parameters =
27  explicit ProvenanceCheckerOutput(Parameters const&);
28 
29  private:
30  void write(EventPrincipal& e) override;
31  void
33  {}
34  void
36  {}
37  }; // ProvenanceCheckerOutput
38 
39  //
40  // constructors and destructor
41  //
44  : OutputModule{ps().omConfig}
45  {}
46 
47  //
48  // member functions
49  //
50  static void
53  std::map<ProductID, bool>& oMap,
54  std::set<ProductID>& oMapperMissing)
55  {
56  for (art::ProductID const parent : iInfo.parentage().parents()) {
57  // Don't look for parents if we've previously looked at the parents
58  if (oMap.find(parent) == oMap.end()) {
59  // use side effect of calling operator[] which is if the item isn't
60  // there it will add it as 'false'
61  oMap[parent];
62  cet::exempt_ptr<ProductProvenance const> pInfo =
63  e.branchToProductProvenance(parent);
64  if (pInfo.get()) {
65  markAncestors(*pInfo, e, oMap, oMapperMissing);
66  } else {
67  oMapperMissing.insert(parent);
68  }
69  }
70  }
71  }
72 
73  void
75  {
76  // Check ProductProvenance's parents to see if they are in the
77  // ProductProvenance list
78 
79  std::map<ProductID, bool> seenParentInPrincipal;
80  std::set<ProductID> missingFromMapper;
81  std::set<ProductID> missingProductProvenance;
82 
83  for (auto const& [pid, pd] : e) {
84  if (pd && pd->productAvailable()) {
85  e.getForOutput(pid, false);
86  if (not pd->productProvenance().get()) {
87  missingProductProvenance.insert(pid);
88  continue;
89  }
90  auto pInfo = e.branchToProductProvenance(pid);
91  if (!pInfo) {
92  missingFromMapper.insert(pid);
93  }
94  markAncestors(*(pd->productProvenance()),
95  e,
96  seenParentInPrincipal,
97  missingFromMapper);
98  }
99  seenParentInPrincipal[pid] = true;
100  }
101 
102  // Determine what ProductIDs are missing from the principal,
103  // vs. which ProductIDs are not even accessible to the principal
104  // via the product tables.
105  std::set<ProductID> missingFromPrincipal;
106  std::set<ProductID> missingFromTables;
107  for (auto const& [parent_pid, seen] : seenParentInPrincipal) {
108  if (!seen) {
109  missingFromPrincipal.insert(parent_pid);
110  }
111  auto found = e.getProductDescription(parent_pid);
112  if (found == nullptr) {
113  missingFromTables.insert(parent_pid);
114  }
115  }
116 
117  auto logProductID = [](auto const& missing) {
118  mf::LogProblem("ProvenanceChecker") << missing;
119  };
120 
121  if (missingFromMapper.size()) {
122  mf::LogError("ProvenanceChecker")
123  << "Missing the following ProductIDs from BranchMapper";
124  cet::for_all(missingFromMapper, logProductID);
125  }
126 
127  if (missingFromPrincipal.size()) {
128  mf::LogError("ProvenanceChecker")
129  << "Missing the following ProductIDs from EventPrincipal";
130  cet::for_all(missingFromPrincipal, logProductID);
131  }
132 
133  if (missingProductProvenance.size()) {
134  mf::LogError("ProvenanceChecker") << "The Groups for the following "
135  "ProductIDs have no "
136  "ProductProvenance";
137  cet::for_all(missingProductProvenance, logProductID);
138  }
139 
140  if (missingFromTables.size()) {
141  mf::LogError("ProvenanceChecker") << "Missing the following ProductIDs "
142  "from the principal's product "
143  "tables";
144  cet::for_all(missingFromTables, logProductID);
145  }
146 
147  if (missingFromMapper.size() or missingFromPrincipal.size() or
148  missingProductProvenance.size() or missingFromTables.size()) {
149  throw cet::exception("ProvenanceError")
150  << (missingFromMapper.size() or missingFromPrincipal.size() ?
151  "Having missing ancestors" :
152  "")
153  << (missingFromMapper.size() ? " from BranchMapper" : "")
154  << (missingFromMapper.size() and missingFromPrincipal.size() ? " and" :
155  "")
156  << (missingFromPrincipal.size() ? " from EventPrincipal" : "")
157  << (missingFromMapper.size() or missingFromPrincipal.size() ? ".\n" :
158  "")
159  << (missingProductProvenance.size() ? " Have missing "
160  "ProductProvenance's from Group "
161  "in EventPrincipal.\n" :
162  "")
163  << (missingFromTables.size() ?
164  " Have missing info from the principal's product tables.\n" :
165  "");
166  }
167  }
168 
169 } // namespace art
170 
static void markAncestors(ProductProvenance const &iInfo, EventPrincipal &e, std::map< ProductID, bool > &oMap, std::set< ProductID > &oMapperMissing)
void writeSubRun(SubRunPrincipal &) override
std::vector< ProductID > const & parents() const
Definition: Parentage.cc:37
MaybeLogger_< ELseverityLevel::ELsev_error, false > LogError
MaybeLogger_< ELseverityLevel::ELsev_error, true > LogProblem
#define DEFINE_ART_MODULE(klass)
Definition: ModuleMacros.h:65
Parentage const & parentage() const
fhicl::TableFragment< OutputModule::Config > omConfig
cet::exempt_ptr< ProductProvenance const > branchToProductProvenance(ProductID const &) const
Definition: Principal.cc:298
void writeRun(RunPrincipal &) override
void write(EventPrincipal &e) override
Definition: MVAAlg.h:12
Float_t e
Definition: plot.C:35
cet::coded_exception< error, detail::translate > exception
Definition: exception.h:33