LArSoft  v07_13_02
Liquid Argon Software toolkit - http://larsoft.org/
ProvenanceDumperImpl.h
Go to the documentation of this file.
1 #ifndef art_Framework_Modules_detail_ProvenanceDumperImpl_h
2 #define art_Framework_Modules_detail_ProvenanceDumperImpl_h
3 // ProvenanceDumperImpl
5 //
6 // Provides main implementation for ProvenanceDumper
7 //
8 // Uses A LOT of metaprogramming.
9 //
10 // The process_() function will loop over the Groups in a particular
11 // Principal, attempt to resolve the product if possible and then
12 // construct a Provenance to pass to the correct callback function func.
13 //
19 #include "cetlib/metaprogramming.h"
20 #include "fhiclcpp/ParameterSet.h"
21 
22 namespace art {
23  namespace detail {
24 
25  template <typename DETAIL>
27  public:
28  PrincipalProcessor(DETAIL& detail,
29  bool const wantPresentOnly,
30  bool const resolveProducts,
31  bool const wantResolvedOnly)
32  : detail_(detail)
33  , wantPresentOnly_(wantPresentOnly)
34  , resolveProducts_(resolveProducts)
35  , wantResolvedOnly_(wantResolvedOnly)
36  {}
37 
38  void operator()(art::Principal const& p,
39  void (DETAIL::*func)(art::Provenance const&)) const;
40 
41  private:
42  DETAIL& detail_;
43  bool const wantPresentOnly_;
44  bool const resolveProducts_;
45  bool const wantResolvedOnly_;
46  };
47 
48  template <typename DETAIL>
49  void
51  art::Principal const& p,
52  void (DETAIL::*func)(art::Provenance const&)) const
53  {
54  for (auto const& pr : p) {
55  Group const& g = *pr.second;
56  if (resolveProducts_) {
57  try {
58  if (!g.resolveProduct(g.producedWrapperType())) {
59  throw Exception(errors::DataCorruption, "data corruption");
60  }
61  }
62  catch (art::Exception const& e) {
63  if (e.category() != "ProductNotFound") {
64  throw;
65  }
66  if (g.anyProduct())
67  throw art::Exception(errors::LogicError, "ProvenanceDumper", e)
68  << "Product reported as not present, but is pointed to "
69  "nonetheless!";
70  }
71  }
72  bool wantCallFunc = true;
73  Provenance const prov{cet::make_exempt_ptr(&g)};
74  if (wantResolvedOnly_) {
75  wantCallFunc = (g.anyProduct() != nullptr);
76  } else if (wantPresentOnly_) {
77  // Unfortunately, there are files in which the product
78  // provenance has not been appropriately stored for dropped
79  // products. The first check below on the product
80  // provenance pointer is a precondition to calling
81  // prov.isPresent(), getting around this incorrect
82  // persistency behavior.
83  wantCallFunc =
84  (g.productProvenancePtr() != nullptr) && prov.isPresent();
85  }
86 
87  if (wantCallFunc) {
88  (detail_.*func)(prov);
89  }
90  }
91  }
92 
94  // Metaprogramming to provide default function if optional
95  // functions do not exist.
96 
97  template <typename T>
99 
100  template <typename R, typename... ARGS>
101  struct default_invocation<R(ARGS...)> {
102  static R
103  invoke(ARGS...)
104  {}
105  };
106 
108  // Metaprogramming to deal with optional pre/post and begin/end
109  // job functions.
110  using cet::enable_if_function_exists_t;
111 
112  // void DETAIL::beginJob();
113  template <typename DETAIL, typename Enable = void>
114  struct maybe_beginJob : default_invocation<void(DETAIL&)> {
115  };
116 
117  template <typename DETAIL>
119  DETAIL,
120  enable_if_function_exists_t<void (DETAIL::*)(), &DETAIL::beginJob>> {
121  static void
122  invoke(DETAIL& detail)
123  {
124  detail.beginJob();
125  }
126  };
127 
128  // void DETAIL::preProcessEvent();
129  template <typename DETAIL, typename Enable = void>
130  struct maybe_preProcessEvent : default_invocation<void(DETAIL&)> {
131  };
132 
133  template <typename DETAIL>
135  DETAIL,
136  enable_if_function_exists_t<void (DETAIL::*)(),
137  &DETAIL::preProcessEvent>> {
138  static void
139  invoke(DETAIL& detail)
140  {
141  detail.preProcessEvent();
142  }
143  };
144 
145  // void DETAIL::postProcessEvent();
146  template <typename DETAIL, typename Enable = void>
147  struct maybe_postProcessEvent : default_invocation<void(DETAIL&)> {
148  };
149 
150  template <typename DETAIL>
152  DETAIL,
153  enable_if_function_exists_t<void (DETAIL::*)(),
154  &DETAIL::postProcessEvent>> {
155  static void
156  invoke(DETAIL& detail)
157  {
158  detail.postProcessEvent();
159  }
160  };
161 
162  // void DETAIL::preProcessSubRun();
163  template <typename DETAIL, typename Enable = void>
164  struct maybe_preProcessSubRun : default_invocation<void(DETAIL&)> {
165  };
166 
167  template <typename DETAIL>
169  DETAIL,
170  enable_if_function_exists_t<void (DETAIL::*)(),
171  &DETAIL::preProcessSubRun>> {
172  static void
173  invoke(DETAIL& detail)
174  {
175  detail.preProcessSubRun();
176  }
177  };
178 
179  // void DETAIL::postProcessSubRun();
180  template <typename DETAIL, typename Enable = void>
181  struct maybe_postProcessSubRun : default_invocation<void(DETAIL&)> {
182  };
183 
184  template <typename DETAIL>
186  DETAIL,
187  enable_if_function_exists_t<void (DETAIL::*)(),
188  &DETAIL::postProcessSubRun>> {
189  static void
190  invoke(DETAIL& detail)
191  {
192  detail.postProcessSubRun();
193  }
194  };
195 
196  // void DETAIL::preProcessRun();
197  template <typename DETAIL, typename Enable = void>
198  struct maybe_preProcessRun : default_invocation<void(DETAIL&)> {
199  };
200 
201  template <typename DETAIL>
203  DETAIL,
204  enable_if_function_exists_t<void (DETAIL::*)(), &DETAIL::preProcessRun>> {
205  static void
206  invoke(DETAIL& detail)
207  {
208  detail.preProcessRun();
209  }
210  };
211 
212  // void DETAIL::postProcessRun();
213  template <typename DETAIL, typename Enable = void>
214  struct maybe_postProcessRun : default_invocation<void(DETAIL&)> {
215  };
216 
217  template <typename DETAIL>
219  DETAIL,
220  enable_if_function_exists_t<void (DETAIL::*)(),
221  &DETAIL::postProcessRun>> {
222  static void
223  invoke(DETAIL& detail)
224  {
225  detail.postProcessRun();
226  }
227  };
228 
229  // void DETAIL::endJob();
230  template <typename DETAIL, typename Enable = void>
231  struct maybe_endJob : default_invocation<void(DETAIL&)> {
232  };
233 
234  template <typename DETAIL>
235  struct maybe_endJob<
236  DETAIL,
237  enable_if_function_exists_t<void (DETAIL::*)(), &DETAIL::endJob>> {
238  static void
239  invoke(DETAIL& detail)
240  {
241  detail.endJob();
242  }
243  };
245 
247  // Metaprogramming to deal with optional per-provenance functions.
248 
249  // void DETAIL::processSubRunProvenance(art:Provenance const &);
250  template <typename DETAIL, typename Enable = void>
252  : default_invocation<void(PrincipalProcessor<DETAIL> const&,
253  EventPrincipal const&)> {
254  };
255 
256  template <typename DETAIL>
258  DETAIL,
259  enable_if_function_exists_t<void (DETAIL::*)(Provenance const&),
260  &DETAIL::processEventProvenance>> {
261  static void
263  {
264  pp(p, &DETAIL::processEventProvenance);
265  }
266  };
267 
268  // void DETAIL::processSubRunProvenance(art:Provenance const &);
269  template <typename DETAIL, typename Enable = void>
271  : default_invocation<void(PrincipalProcessor<DETAIL> const&,
272  SubRunPrincipal const&)> {
273  };
274 
275  template <typename DETAIL>
277  DETAIL,
278  enable_if_function_exists_t<void (DETAIL::*)(Provenance const&),
279  &DETAIL::processSubRunProvenance>> {
280  static void
282  {
283  pp(p, &DETAIL::processSubRunProvenance);
284  }
285  };
286 
287  // void DETAIL::processRunProvenance(art:Provenance const &);
288  template <typename DETAIL, typename Enable = void>
290  : default_invocation<void(PrincipalProcessor<DETAIL> const&,
291  RunPrincipal const&)> {
292  };
293 
294  template <typename DETAIL>
296  DETAIL,
297  enable_if_function_exists_t<void (DETAIL::*)(Provenance const&),
298  &DETAIL::processRunProvenance>> {
299  static void
301  {
302  pp(p, &DETAIL::processRunProvenance);
303  }
304  };
305 
307 
308  template <typename DETAIL>
310 
311  DETAIL& detail_;
313 
314  public:
316  : detail_{detail}, pp_{pp}
317  {}
318 
319  void
321  {
323  }
324 
325  void
327  {
331  }
332 
333  void
335  {
339  }
340 
341  void
343  {
347  }
348 
349  void
351  {
353  }
354  };
355 
356  } // detail
357 } // art
358 
359 #endif /* art_Framework_Modules_detail_ProvenanceDumperImpl_h */
360 
361 // Local Variables:
362 // mode: c++
363 // End:
void operator()(art::Principal const &p, void(DETAIL::*func)(art::Provenance const &)) const
void beginJob()
Definition: Breakpoints.cc:14
TypeID const & producedWrapperType() const
Definition: Group.h:162
cet::exempt_ptr< ProductProvenance const > productProvenancePtr() const
Definition: Group.cc:96
void writeSubRun(SubRunPrincipal &sr)
Double_t R
cet::coded_exception< errors::ErrorCodes, ExceptionDetail::translate > Exception
Definition: Exception.h:66
HLT enums.
PrincipalProcessor(DETAIL &detail, bool const wantPresentOnly, bool const resolveProducts, bool const wantResolvedOnly)
bool isPresent() const
Definition: Provenance.h:125
bool resolveProduct(TypeID const &) const override
Definition: Group.cc:45
Float_t e
Definition: plot.C:34
EDProduct const * anyProduct() const override
Definition: Group.h:97
ProvenanceDumperImpl(DETAIL &detail, PrincipalProcessor< DETAIL > &pp)
PrincipalProcessor< DETAIL > & pp_