LArSoft  v09_90_00
Liquid Argon Software toolkit - https://larsoft.org/
ProductRetriever.h
Go to the documentation of this file.
1 #ifndef art_Framework_Principal_ProductRetriever_h
2 #define art_Framework_Principal_ProductRetriever_h
3 // vim: set sw=2 expandtab :
4 
23 #include "cetlib/container_algorithms.h"
24 #include "cetlib/exempt_ptr.h"
25 #include "cetlib_except/exception.h"
26 #include "fhiclcpp/fwd.h"
27 
28 #include <cassert>
29 #include <cstddef>
30 #include <memory>
31 #include <mutex>
32 #include <optional>
33 #include <ostream>
34 #include <set>
35 #include <string>
36 #include <utility>
37 #include <vector>
38 
39 namespace art {
40 
41  class EDProductGetter;
42 
43  namespace detail {
44  class Analyzer;
45  class Filter;
46  class Producer;
47  }
48 
50  public:
52  explicit ProductRetriever(BranchType bt,
53  Principal const& p,
54  ModuleContext const& mc,
55  bool recordParents);
56  ProductRetriever(ProductRetriever const&) = delete;
58  ProductRetriever& operator=(ProductRetriever const&) = delete;
59  ProductRetriever& operator=(ProductRetriever&) = delete;
60 
61  // Product retrieval
62  template <typename PROD>
63  PROD const& getProduct(InputTag const& tag) const;
64  template <typename PROD>
65  PROD const& getProduct(ProductToken<PROD> const& token) const;
66 
67  // Product retrieval with provenance access
68  template <typename PROD>
69  Handle<PROD> getHandle(SelectorBase const&) const;
70  template <typename PROD>
71  [[deprecated(
72  "\n\nart warning: The Event::getHandle<T>(id) interface is deprecated.\n"
73  " Please use a ProductPtr<T> instead, or retrieve a "
74  "parent\n"
75  " product by using "
76  "Ptr<T>::parentAs<Collection>().\n\n")]] Handle<PROD>
77  getHandle(ProductID const pid) const;
78  template <typename PROD>
79  Handle<PROD> getHandle(InputTag const& tag) const;
80  template <typename PROD>
81  Handle<PROD> getHandle(ProductToken<PROD> const& token) const;
82 
83  // Product retrieval with provenance access (guaranteed valid handle)
84  template <typename PROD>
85  ValidHandle<PROD> getValidHandle(InputTag const& tag) const;
86  template <typename PROD>
87  ValidHandle<PROD> getValidHandle(ProductToken<PROD> const& token) const;
88 
89  // Multiple product retrievals
90  template <typename PROD>
91  std::vector<InputTag> getInputTags(
92  SelectorBase const& selector = MatchAllSelector{}) const;
93  template <typename PROD>
94  std::vector<ProductToken<PROD>> getProductTokens(
95  SelectorBase const& selector = MatchAllSelector{}) const;
96  template <typename PROD>
97  std::vector<Handle<PROD>> getMany(
98  SelectorBase const& selector = MatchAllSelector{}) const;
99 
100  // Obsolete product-retrieval (will be deprecated)
101  template <typename PROD>
102  bool get(SelectorBase const&, Handle<PROD>& result) const;
103  template <typename PROD>
104  [[deprecated(
105  "\n\nart warning: The Event::get(id, handle) interface is deprecated.\n"
106  " Please use a ProductPtr<T> instead, or retrieve a "
107  "parent\n"
108  " product by using "
109  "Ptr<T>::parentAs<Collection>().\n\n")]] bool
110  get(ProductID const pid, Handle<PROD>& result) const;
111  template <typename PROD>
112  bool getByLabel(std::string const& label,
113  std::string const& instance,
114  Handle<PROD>& result) const;
115  template <typename PROD>
116  bool getByLabel(std::string const& label,
117  std::string const& instance,
118  std::string const& process,
119  Handle<PROD>& result) const;
120  template <typename PROD>
121  bool getByLabel(InputTag const& tag, Handle<PROD>& result) const;
122 
123  // View retrieval
124  template <typename ELEMENT>
125  std::size_t getView(std::string const& moduleLabel,
126  std::string const& productInstanceName,
127  std::string const& processName,
128  std::vector<ELEMENT const*>& result) const;
129  template <typename ELEMENT>
130  std::size_t getView(std::string const& moduleLabel,
131  std::string const& productInstanceName,
132  std::vector<ELEMENT const*>& result) const;
133  template <typename ELEMENT>
134  std::size_t getView(InputTag const&,
135  std::vector<ELEMENT const*>& result) const;
136  template <typename ELEMENT>
137  std::size_t getView(ViewToken<ELEMENT> const&,
138  std::vector<ELEMENT const*>& result) const;
139  template <typename ELEMENT>
140  bool getView(std::string const& moduleLabel,
141  std::string const& productInstanceName,
142  std::string const& processName,
143  View<ELEMENT>& result) const;
144  template <typename ELEMENT>
145  bool getView(std::string const& moduleLabel,
146  std::string const& productInstanceName,
147  View<ELEMENT>& result) const;
148  template <typename ELEMENT>
149  bool getView(InputTag const&, View<ELEMENT>& result) const;
150  template <typename ELEMENT>
151  bool getView(ViewToken<ELEMENT> const&, View<ELEMENT>& result) const;
152 
153  std::vector<ProductID> retrievedPIDs() const;
154 
155  // Miscellaneous functionality
156  std::optional<Provenance const> getProductProvenance(ProductID) const;
157  std::optional<fhicl::ParameterSet const> getProcessParameterSet(
158  std::string const& process) const;
159  cet::exempt_ptr<BranchDescription const> getProductDescription(
160  ProductID) const;
161 
162  EDProductGetter const* productGetter(ProductID const pid) const;
163  template <typename T>
164  ProductID getProductID(std::string const& instance_name = "") const;
165 
166  private:
167  void recordAsParent_(cet::exempt_ptr<Group const> grp) const;
168  cet::exempt_ptr<Group const> getContainerForView_(
169  TypeID const&,
170  std::string const& moduleLabel,
171  std::string const& productInstanceName,
172  ProcessTag const& processTag) const;
173  ProductID getProductID_(TypeID const& typeID,
174  std::string const& instance) const;
175  std::vector<InputTag> getInputTags_(WrappedTypeID const& wrapped,
176  SelectorBase const& selector) const;
177  GroupQueryResult getByLabel_(WrappedTypeID const& wrapped,
178  InputTag const& tag) const;
179  GroupQueryResult getBySelector_(WrappedTypeID const& wrapped,
180  SelectorBase const& selector) const;
181  GroupQueryResult getByProductID_(ProductID productID) const;
182  std::vector<GroupQueryResult> getMany_(WrappedTypeID const& wrapped,
183  SelectorBase const& sel) const;
184 
185  // Protects use of retrievedProducts_ and putProducts_.
186  mutable std::recursive_mutex mutex_{};
187 
188  // Is this an Event, a Run, a SubRun, or a Results.
190 
191  // The principal we are operating on.
193 
194  // The context of the currently processing module.
196 
197  // The module we were created for.
199 
200  // If we are constructed as a non-const Event, then we can be used
201  // to put products into the Principal, so we need to record
202  // retrieved products into retrievedProducts_ to track parentage
203  // of any products we put.
204  bool const recordParents_;
205 
206  // The set of products retrieved from the principal. We use this
207  // to track parentage of any products we put.
208  mutable std::set<ProductID> retrievedProducts_{};
209  };
210 
211  template <typename PROD>
212  ProductID
213  ProductRetriever::getProductID(std::string const& instance /* = "" */) const
214  {
215  return getProductID_(TypeID{typeid(PROD)}, instance);
216  }
217 
218  // =========================================================================
219  template <typename PROD>
220  PROD const&
222  {
223  return *getValidHandle<PROD>(tag);
224  }
225 
226  template <typename PROD>
227  PROD const&
229  {
230  return *getValidHandle(token);
231  }
232 
233  // =========================================================================
234  template <typename PROD>
237  {
238  auto qr = getBySelector_(WrappedTypeID::make<PROD>(), sel);
239  return Handle<PROD>{qr};
240  }
241 
242  template <typename PROD>
245  {
246  auto qr = getByProductID_(pid);
247  return Handle<PROD>{qr};
248  }
249 
250  template <typename PROD>
253  {
254  auto qr = getByLabel_(WrappedTypeID::make<PROD>(), tag);
255  return Handle<PROD>{qr};
256  }
257 
258  template <typename PROD>
261  {
262  return getHandle<PROD>(token.inputTag());
263  }
264 
265  // =========================================================================
266  template <typename PROD>
269  {
270  auto h = getHandle<PROD>(tag);
271  return ValidHandle{h.product(), h.productGetter(), *h.provenance()};
272  }
273 
274  template <typename PROD>
277  {
278  return getValidHandle<PROD>(token.inputTag());
279  }
280 
281  template <typename PROD>
282  std::vector<InputTag>
284  {
285  return getInputTags_(WrappedTypeID::make<PROD>(), selector);
286  }
287 
288  template <typename PROD>
289  std::vector<ProductToken<PROD>>
291  {
292  auto const tags = getInputTags<PROD>(selector);
293  std::vector<ProductToken<PROD>> tokens;
294  tokens.reserve(tags.size());
295  cet::transform_all(tags, back_inserter(tokens), [](auto const& tag) {
296  return ProductToken<PROD>{tag};
297  });
298  return tokens;
299  }
300 
301  template <typename PROD>
302  std::vector<Handle<PROD>>
304  {
305  auto const qrs = getMany_(WrappedTypeID::make<PROD>(), sel);
306  std::vector<Handle<PROD>> products;
307  products.reserve(qrs.size());
308  cet::transform_all(qrs, back_inserter(products), [](auto const& qr) {
309  return Handle<PROD>{qr};
310  });
311  return products;
312  }
313 
314  template <typename ELEMENT>
315  std::size_t
316  ProductRetriever::getView(std::string const& moduleLabel,
317  std::string const& productInstanceName,
318  std::string const& processName,
319  std::vector<ELEMENT const*>& result) const
320  {
321  std::lock_guard lock{mutex_};
322  std::size_t const orig_size = result.size();
323  auto grp = getContainerForView_(TypeID{typeid(ELEMENT)},
324  moduleLabel,
325  productInstanceName,
326  ProcessTag{processName, md_.processName()});
327  if (recordParents_) {
328  recordAsParent_(grp);
329  }
330  auto const view = grp->uniqueProduct()->getView();
331  std::vector<ELEMENT const*> castedView;
332  for (auto p : view) {
333  castedView.push_back(static_cast<ELEMENT const*>(p));
334  }
335  result = std::move(castedView);
336  return result.size() - orig_size;
337  }
338 
339  template <typename ELEMENT>
340  std::size_t
341  ProductRetriever::getView(std::string const& moduleLabel,
342  std::string const& productInstanceName,
343  std::vector<ELEMENT const*>& result) const
344  {
345  return getView(moduleLabel, productInstanceName, {}, result);
346  }
347 
348  template <typename ELEMENT>
349  std::size_t
351  std::vector<ELEMENT const*>& result) const
352  {
353  return getView(tag.label(), tag.instance(), tag.process(), result);
354  }
355 
356  template <typename ELEMENT>
357  std::size_t
359  std::vector<ELEMENT const*>& result) const
360  {
361  return getView(token.inputTag(), result);
362  }
363 
364  template <typename ELEMENT>
365  bool
366  ProductRetriever::getView(std::string const& moduleLabel,
367  std::string const& productInstanceName,
368  std::string const& processName,
369  View<ELEMENT>& result) const
370  {
371  std::lock_guard lock{mutex_};
372  auto grp = getContainerForView_(TypeID{typeid(ELEMENT)},
373  moduleLabel,
374  productInstanceName,
375  ProcessTag{processName, md_.processName()});
376  if (recordParents_) {
377  recordAsParent_(grp);
378  }
379  auto const view = grp->uniqueProduct()->getView();
380  std::vector<ELEMENT const*> castedView;
381  for (auto p : view) {
382  castedView.push_back(static_cast<ELEMENT const*>(p));
383  }
384  result =
385  View{std::move(castedView), grp->productID(), grp->uniqueProduct()};
386  return true;
387  }
388 
389  template <typename ELEMENT>
390  bool
391  ProductRetriever::getView(std::string const& moduleLabel,
392  std::string const& productInstanceName,
393  View<ELEMENT>& result) const
394  {
395  return getView(moduleLabel, productInstanceName, {}, result);
396  }
397 
398  template <typename ELEMENT>
399  bool
401  {
402  return getView(tag.label(), tag.instance(), tag.process(), result);
403  }
404 
405  template <typename ELEMENT>
406  bool
408  View<ELEMENT>& result) const
409  {
410  return getView(token.inputTag(), result);
411  }
412 
413  // =======================================================================
414  // Obsolete (will be deprecated)
415  template <typename PROD>
416  bool
418  {
419  result = getHandle<PROD>(sel);
420  return static_cast<bool>(result);
421  }
422 
423  template <typename PROD>
424  bool
426  {
427  result = getHandle<PROD>(pid);
428  return static_cast<bool>(result);
429  }
430 
431  template <typename PROD>
432  bool
433  ProductRetriever::getByLabel(std::string const& moduleLabel,
434  std::string const& productInstanceName,
435  std::string const& processName,
436  Handle<PROD>& result) const
437  {
438  result = getHandle<PROD>({moduleLabel, productInstanceName, processName});
439  return static_cast<bool>(result);
440  }
441 
442  template <typename PROD>
443  bool
444  ProductRetriever::getByLabel(std::string const& moduleLabel,
445  std::string const& instance,
446  Handle<PROD>& result) const
447  {
448  result = getHandle<PROD>({moduleLabel, instance});
449  return static_cast<bool>(result);
450  }
451 
452  template <typename PROD>
453  bool
455  {
456  result = getHandle<PROD>(tag);
457  return static_cast<bool>(result);
458  }
459 
460  template <typename PROD>
461  std::ostream&
462  operator<<(std::ostream& os, Handle<PROD> const& h)
463  {
464  os << h.product() << " " << h.provenance() << " " << h.id();
465  return os;
466  }
467 
468 } // namespace art
469 
470 #endif /* art_Framework_Principal_ProductRetriever_h */
471 
472 // Local Variables:
473 // mode: c++
474 // End:
bool get(SelectorBase const &, Handle< PROD > &result) const
ProductID getProductID(std::string const &instance_name="") const
ModuleContext const & mc_
const std::string instance
std::string const & instance() const noexcept
Definition: InputTag.cc:85
Principal const & principal_
BranchType const branchType_
InputTag const & inputTag() const
Definition: ProductToken.h:94
std::string const & process() const noexcept
Definition: InputTag.cc:91
T const * product() const
Definition: Handle.h:363
ModuleDescription const & md_
std::vector< ProductToken< PROD > > getProductTokens(SelectorBase const &selector=MatchAllSelector{}) const
std::string const & label() const noexcept
Definition: InputTag.cc:79
T const * product() const
Definition: Handle.h:174
Definition: fwd.h:46
std::vector< InputTag > getInputTags(SelectorBase const &selector=MatchAllSelector{}) const
std::size_t getView(std::string const &moduleLabel, std::string const &productInstanceName, std::string const &processName, std::vector< ELEMENT const * > &result) const
ValidHandle< PROD > getValidHandle(InputTag const &tag) const
Handle< PROD > getHandle(SelectorBase const &) const
bool getByLabel(std::string const &label, std::string const &instance, Handle< PROD > &result) const
BranchType
Definition: BranchType.h:20
Definition: MVAAlg.h:12
InputTag const & inputTag() const
Definition: ProductToken.h:61
PROD const & getProduct(InputTag const &tag) const
std::vector< Handle< PROD > > getMany(SelectorBase const &selector=MatchAllSelector{}) const