All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
CanvasUtils.h
Go to the documentation of this file.
1 /**
2  * @file icarusalg/Utilities/CanvasUtils.h
3  * @brief Helper functions based on _art_/canvas.
4  * @author Gianluca Petrillo (petrillo@slac.stanford.edu)
5  * @date January 13, 2022
6  *
7  * This library is header only.
8  */
9 
10 #ifndef ICARUSALG_UTILITIES_CANVASUTILS_H
11 #define ICARUSALG_UTILITIES_CANVASUTILS_H
12 
13 // framework libraries
14 #include "canvas/Persistency/Common/Ptr.h"
15 #include "canvas/Persistency/Provenance/BranchDescription.h"
16 #include "canvas/Persistency/Provenance/ProductID.h"
17 #include "canvas/Utilities/Exception.h"
18 
19 // C++ standard libraries
20 #include <type_traits> // std::enable_if_t
21 
22 
23 namespace util {
24 
25  //----------------------------------------------------------------------------
26  /**
27  * @brief Reads and returns the input tag of the producer of `productID`.
28  * @tparam Event type of event to read data from (`art::Event` interface)
29  * @param event event to read data products from
30  * @param productID reference data product
31  * @return the input tag of the producer of `productID`
32  * @throw art::Exception (error code: `art::errors::ProductNotFound`) if no
33  * input tag could be found
34  *
35  * This utility facilitates the traversal of associations.
36  * Assuming that a pointer to a data product element is available, we may need
37  * to read another data product from the same producer (e.g. from a pointer to
38  * a `recob::Track` from a collection, we want to learn the associations of
39  * that track to `recob::Hit`, assuming that the same module that produced the
40  * tracks also produced their associations to hit).
41  * This is trivial if the input tag of the data product element is known, but
42  * it's not if that data product is instead known only by a
43  * pointer/association.
44  * In that case, this function discovers the needed input tag. Example:
45  * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
46  * auto const& assns
47  * = event.getProduct<std::vector<recob::Hit>>(inputTagOf(trackPtr.id()));
48  * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
49  * where `trackPtr` is a `art::Ptr<recob::Track>` that may come for example
50  * from a `recob::PFParticle`/`recob::Track` association.
51  */
52  template <typename Event>
53  art::InputTag inputTagOf(Event const& event, art::ProductID const& productID);
54 
55 
56  /**
57  * @brief Reads and returns the input tag of the product with the specified
58  * `handle`.
59  * @tparam Event type of event to read data from (`art::Event` interface)
60  * @tparam Handle type of handle
61  * @param event event to read data products from
62  * @param handle data product handle
63  * @return the input tag of the producer of data product at `handle`
64  * @throw art::Exception (error code: `art::errors::ProductNotFound`) if no
65  * input tag could be found
66  * @see `inputTag(Event const&, art::ProductID const&)`
67  *
68  * This utility is a wrapper of the version working on product ID.
69  */
70  template <typename Event, typename Handle>
72  std::is_void_v<std::void_t<typename Handle::HandleTag>>,
73  art::InputTag
74  >
75  inputTagOf(Event const& event, Handle const& handle)
76  { return inputTagOf(event, handle.id()); }
77 
78 
79  /**
80  * @brief Reads and returns the input tag of the product `ptr` points to.
81  * @tparam Event type of event to read data from (`art::Event` interface)
82  * @tparam T type of the datum pointed by the pointer
83  * @param event event to read data products from
84  * @param ptr _art_ pointer to the data product element
85  * @return the input tag of the producer of data product of `ptr`
86  * @throw art::Exception (error code: `art::errors::ProductNotFound`) if no
87  * input tag could be found
88  * @see `inputTag(Event const&, art::ProductID const&)`
89  *
90  * This utility is a wrapper of the version working on product ID.
91  */
92  template <typename Event, typename T>
93  art::InputTag inputTagOf(Event const& event, art::Ptr<T> const& ptr)
94  { return inputTagOf(event, ptr.id()); }
95 
96 
97  //----------------------------------------------------------------------------
98 
99 
100 } // namespace util
101 
102 
103 //------------------------------------------------------------------------------
104 //--- template implementation
105 //------------------------------------------------------------------------------
106 template <typename Event>
107 art::InputTag util::inputTagOf
108  (Event const& event, art::ProductID const& productID)
109 {
110 
111  cet::exempt_ptr<art::BranchDescription const> metaDescr
112  = event.getProductDescription(productID);
113  if (metaDescr) return metaDescr->inputTag();
114 
115  throw art::Exception(art::errors::ProductNotFound)
116  << "Branch (and input tag) not found for product ID " << productID;
117 
118 } // util::inputTagOf()
119 
120 
121 //------------------------------------------------------------------------------
122 
123 
124 #endif // ICARUSALG_UTILITIES_CANVASUTILS_H
typename std::enable_if< B, T >::type enable_if_t
Definition: json.hpp:2191
art::InputTag inputTagOf(Event const &event, art::ProductID const &productID)
Reads and returns the input tag of the producer of productID.
Definition: CanvasUtils.h:108