LArSoft  v06_85_00
Liquid Argon Software toolkit - http://larsoft.org/
Consumer.h
Go to the documentation of this file.
1 #ifndef art_Framework_Principal_Consumer_h
2 #define art_Framework_Principal_Consumer_h
3 
4 //============================================================================
5 // Consumer is the base class for all module types that retrieve
6 // products. See below for guidance as to which interface should be
7 // called for a given context.
8 //
9 // N.B. All 'consumes*' or 'mayConsume*' calls should be done in a
10 // module's constructor, before processing any beginJob
11 // callbacks.
12 //
13 // Unconditional retrieval of products
14 // -----------------------------------
15 //
16 // For products that are always intended to be retrieved for a given
17 // module execution, the 'consumes' family of calls should be invoked
18 // in a user's module constructor (e.g.):
19 //
20 // consumes<int>(input_tag); // => ProductToken<int>
21 // consumesMany<int>(); // => void
22 // consumesView<int>(input_tag); // => ViewToken<int>
23 //
24 // Making such calls tells the framework that the particular module in
25 // question will make the following product retrievals (e.g.):
26 //
27 // e.getValidHandle<int>(input_tag);
28 // e.getManyByType<int>();
29 // art::View<int> v;
30 // e.getView(input_tag, v);
31 //
32 // The returned type of the consumes calls are shown above. To
33 // eventually facilitate faster product lookup, the returned tokens
34 // can be supplied by the user (e.g.):
35 //
36 // ProductToken<int> intToken_; // data member of module class
37 // e.getValidHandle(intToken_); // => ValidHandle<int>
38 //
39 // ViewToken<int> viewToken_; // data member of module class
40 // std::vector<int const*> v;
41 // e.getView(viewToken_, v);
42 //
43 // The consumesMany function template does not return a token.
44 //
45 // Conditional retrieval of products
46 // ---------------------------------
47 //
48 // If there are situations in which a product *may* be retrieved
49 // (e.g. within an 'if' block), then the *mayConsume* interface should
50 // be considered instead of the consumes interface:
51 //
52 // mayConsume<int>(input_tag); // => ProductToken<int>
53 // mayConsumeMany<int>(); // => void
54 // mayConsumeView<int>(); // => ViewToken<int>
55 //
56 // The return types of the functions are the same as their 'consumes'
57 // partners for unconditional product retrieving. However, how the
58 // tokens are used by the framework may be different than how they are
59 // used in the 'consumes' case.
60 
61 // Retrieving products in non-module contexts
62 // ------------------------------------------
63 //
64 // There are cases where products are retrieved in non-module
65 // contexts. Although such product retrieval is not forbidden, it is
66 // not a generally recommended usage pattern. The 'consumes'
67 // interface is, therefore, not supported in non-module contexts.
68 //============================================================================
69 
76 #include "cetlib/exempt_ptr.h"
77 
78 namespace fhicl {
79  class ParameterSet;
80 }
81 
82 namespace art {
83 
84  class DataViewImpl;
85  class ModuleDescription;
86 
87  class Consumer {
88  struct InvalidTag {
89  };
90 
91  public:
92  explicit Consumer() = default;
93 
94  static cet::exempt_ptr<Consumer> non_module_context();
95 
96  template <typename T, BranchType = InEvent>
97  ProductToken<T> consumes(InputTag const&);
98 
99  template <typename T, BranchType = InEvent>
100  void consumesMany();
101 
102  template <typename Element, BranchType = InEvent>
103  ViewToken<Element> consumesView(InputTag const&);
104 
105  // mayConsume variants, which should be used whenever product
106  // retrievals do not always occur whenever the user is presented
107  // with a transactional object.
108  template <typename T, BranchType = InEvent>
109  ProductToken<T> mayConsume(InputTag const&);
110 
111  template <typename T, BranchType = InEvent>
112  void mayConsumeMany();
113 
114  template <typename Element, BranchType = InEvent>
115  ViewToken<Element> mayConsumeView(InputTag const&);
116 
117  protected:
118  friend class DataViewImpl;
119  void validateConsumedProduct(BranchType const bt, ProductInfo const& pi);
120 
121  // After the modules are constructed, their ModuleDescription
122  // values are assigned. We receive the values of that assignment.
123  void setModuleDescription(ModuleDescription const& md);
124 
125  // Once all of the 'consumes(Many)' calls have been made for this
126  // recorder, the consumables are sorted, and the configuration is
127  // retrieved to specify the desired behavior in the case of a
128  // missing consumes clause.
129  void prepareForJob(fhicl::ParameterSet const& pset);
130  void showMissingConsumes() const;
131 
132  private:
134  explicit Consumer(InvalidTag) : moduleContext_{false} {}
135 
136  bool moduleContext_{true};
137  bool requireConsumes_{false};
138  ConsumableProducts consumables_{};
139  ConsumableProductSets missingConsumes_{};
140  cet::exempt_ptr<ModuleDescription const> moduleDescription_{nullptr};
141  };
142 }
143 
144 //===========================================================================
145 template <typename T, art::BranchType BT>
148 {
149  if (!moduleContext_)
150  return ProductToken<T>::invalid();
151 
152  consumables_[BT].emplace_back(ConsumableType::Product,
153  TypeID{typeid(T)},
154  it.label(),
155  it.instance(),
156  it.process());
157  return ProductToken<T>{it};
158 }
159 
160 template <typename T, art::BranchType BT>
161 void
163 {
164  if (!moduleContext_)
165  return;
166 
167  consumables_[BT].emplace_back(ConsumableType::Many, TypeID{typeid(T)});
168 }
169 
170 template <typename T, art::BranchType BT>
173 {
174  if (!moduleContext_)
175  return ViewToken<T>::invalid();
176 
177  consumables_[BT].emplace_back(ConsumableType::ViewElement,
178  TypeID{typeid(T)},
179  it.label(),
180  it.instance(),
181  it.process());
182  return ViewToken<T>{it};
183 }
184 
185 //=======================================================================
186 // mayConsume variants
187 
188 template <typename T, art::BranchType BT>
191 {
192  if (!moduleContext_)
193  return ProductToken<T>::invalid();
194 
195  consumables_[BT].emplace_back(ConsumableType::Product,
196  TypeID{typeid(T)},
197  it.label(),
198  it.instance(),
199  it.process());
200  return ProductToken<T>{it};
201 }
202 
203 template <typename T, art::BranchType BT>
204 void
206 {
207  if (!moduleContext_)
208  return;
209 
210  consumables_[BT].emplace_back(ConsumableType::Many, TypeID{typeid(T)});
211 }
212 
213 template <typename T, art::BranchType BT>
216 {
217  if (!moduleContext_)
218  return ViewToken<T>::invalid();
219 
220  consumables_[BT].emplace_back(ConsumableType::ViewElement,
221  TypeID{typeid(T)},
222  it.label(),
223  it.instance(),
224  it.process());
225  return ViewToken<T>{it};
226 }
227 
228 #endif /* art_Framework_Principal_Consumer_h */
229 
230 // Local Variables:
231 // mode: c++
232 // End:
std::array< ConsumableProductVectorPerBranch, NumBranchTypes > ConsumableProducts
Definition: ProductInfo.h:55
ViewToken< Element > consumesView(InputTag const &)
Consumer(InvalidTag)
Definition: Consumer.h:134
std::string const & process() const noexcept
Definition: InputTag.h:67
void mayConsumeMany()
Definition: Consumer.h:205
parameter set interface
std::string const & instance() const noexcept
Definition: InputTag.h:60
ProductToken< T > mayConsume(InputTag const &)
void consumesMany()
Definition: Consumer.h:162
constexpr T pi()
Returns the constant pi (up to 35 decimal digits of precision)
BranchType
Definition: BranchType.h:18
HLT enums.
std::array< ConsumableProductSetPerBranch, NumBranchTypes > ConsumableProductSets
Definition: ProductInfo.h:57
ProductToken< T > consumes(InputTag const &)
std::string const & label() const noexcept
Definition: InputTag.h:55
ViewToken< Element > mayConsumeView(InputTag const &)