DataViewImpl.h
Go to the documentation of this file.
1 #ifndef art_Framework_Principal_DataViewImpl_h
2 #define art_Framework_Principal_DataViewImpl_h
3 
4 // ======================================================================
5 //
6 // DataViewImpl - This is the implementation for accessing EDProducts
7 // and inserting new EDproducts.
8 //
9 // Getting Data
10 //
11 // The art::DataViewImpl class provides many 'get*" methods for
12 // getting data it contains.
13 //
14 // The primary method for getting data is to use getByLabel(). The
15 // labels are the label of the module assigned in the configuration
16 // file and the 'product instance label' (which can be omitted in the
17 // case the 'product instance label' is the default value). The C++
18 // type of the product plus the two labels uniquely identify a product
19 // in the DataViewImpl.
20 //
21 // We use an Event in the examples, but a Run or a SubRun can also
22 // hold products.
23 //
24 // art::Handle<AppleCollection> apples;
25 // event.getByLabel("tree", apples);
26 //
27 // art::Handle<FruitCollection> fruits;
28 // event.getByLabel("market", "apples", fruits);
29 //
30 // Putting Data
31 //
32 // auto pApples = std::make_unique<AppleCollection>();
33 // // fill the collection
34 // ...
35 // event.put(std::move(pApples));
36 //
37 // auto pFruits = std::make_unique<FruitCollection>();
38 // // fill the collection
39 // ...
40 // event.put(std::move(pFruits), "apples");
41 //
42 // ======================================================================
43 
62 
63 #include <cassert>
64 #include <memory>
65 #include <ostream>
66 #include <set>
67 #include <string>
68 #include <utility>
69 #include <vector>
70 
71 namespace art {
72  template <typename PROD>
73  std::ostream& operator<<(std::ostream& os, Handle<PROD> const& h);
74 }
75 
77 public:
78  DataViewImpl(DataViewImpl const&) = delete;
79  DataViewImpl& operator=(DataViewImpl const&) = delete;
80 
81  explicit DataViewImpl(Principal const& p,
82  ModuleDescription const& md,
83  BranchType bt,
84  bool recordParents,
85  cet::exempt_ptr<Consumer> consumer);
86 
87  size_t size() const;
88 
89  template <typename PROD>
90  bool get(SelectorBase const&, Handle<PROD>& result) const;
91 
92  template <typename PROD>
93  bool get(ProductID const pid, Handle<PROD>& result) const;
94 
95  template <typename PROD>
96  bool getByLabel(std::string const& label,
97  std::string const& productInstanceName,
98  Handle<PROD>& result) const;
99 
100  template <typename PROD>
101  bool getByLabel(std::string const& label,
102  std::string const& productInstanceName,
103  std::string const& processName,
104  Handle<PROD>& result) const;
105 
106  /// same as above, but using the InputTag class
107  template <typename PROD>
108  PROD const& getByLabel(InputTag const& tag) const;
109 
110  template <typename PROD>
111  bool getByLabel(InputTag const& tag, Handle<PROD>& result) const;
112 
113  template <typename PROD>
114  PROD const* getPointerByLabel(InputTag const& tag) const;
115 
116  template <typename PROD>
117  bool getByToken(ProductToken<PROD> const& token, Handle<PROD>& result) const;
118 
119  template <typename PROD>
120  ValidHandle<PROD> getValidHandle(InputTag const& tag) const;
121 
122  template <typename PROD>
124 
125  template <typename PROD>
126  void getMany(SelectorBase const&, std::vector<Handle<PROD>>& results) const;
127 
128  template <typename PROD>
129  void getManyByType(std::vector<Handle<PROD>>& results) const;
130 
131  // If getView returns true, then result.isValid() is certain to be
132  // true -- but the View may still be empty.
133  template <typename ELEMENT>
134  std::size_t getView(std::string const& moduleLabel,
135  std::string const& productInstanceName,
136  std::vector<ELEMENT const*>& result) const;
137 
138  template <typename ELEMENT>
139  std::size_t getView(InputTag const& tag,
140  std::vector<ELEMENT const*>& result) const;
141 
142  template <typename ELEMENT>
143  std::size_t getView(ViewToken<ELEMENT> const& token,
144  std::vector<ELEMENT const*>& result) const;
145 
146  template <typename ELEMENT>
147  bool getView(std::string const& moduleLabel,
148  std::string const& instanceName,
149  View<ELEMENT>& result) const;
150 
151  template <typename ELEMENT>
152  bool getView(InputTag const& tag, View<ELEMENT>& result) const;
153 
154  template <typename ELEMENT>
155  bool getView(ViewToken<ELEMENT> const& tag, View<ELEMENT>& result) const;
156 
157  template <typename PROD>
158  bool removeCachedProduct(Handle<PROD>& h) const;
159 
160  ProcessHistory const& processHistory() const;
161 
162  struct PMValue {
163 
164  PMValue(std::unique_ptr<EDProduct>&& p,
165  BranchDescription const& b,
166  RangeSet const& r)
167  : prod{std::move(p)}, pd{b}, rs{r}
168  {}
169 
170  std::unique_ptr<EDProduct> prod;
173  };
174 
175  using RetrievedProductIDs = std::vector<ProductID>;
176  using RetrievedProductSet = std::set<ProductID>;
177  using TypeLabelMap = std::map<TypeLabel, PMValue>;
178 
179 protected:
180  void recordAsParent(Provenance const& prov) const;
181 
182  TypeLabelMap&
184  {
185  return putProducts_;
186  }
187  TypeLabelMap const&
188  putProducts() const
189  {
190  return putProducts_;
191  }
192 
193  // Return the map of products that was retrieved via get*. The
194  // retrievedProducts_ member is used to form the sequence of
195  // ProductIDs that serve as the "parents" to any put products.
196  RetrievedProductSet const&
198  {
199  return retrievedProducts_;
200  }
201 
202  // Convert the retrievedProducts_ member to just the sequence of
203  // ProductIDs corresponding to product parents.
205 
206  void checkPutProducts(bool checkProducts,
207  std::set<TypeLabel> const& expectedProducts,
208  TypeLabelMap const& putProducts);
209 
211  TypeID const& type,
212  std::string const& productInstanceName) const;
213 
214  using GroupQueryResultVec = std::vector<GroupQueryResult>;
215 
216 private:
217  void removeNonViewableMatches_(TypeID const& requestedElementType,
219 
220  void ensureUniqueProduct_(std::size_t nFound,
221  TypeID const& typeID,
222  std::string const& moduleLabel,
223  std::string const& productInstanceName,
224  std::string const& processName) const;
225 
226  // The following 'get' functions serve to isolate the DataViewImpl class
227  // from the Principal class.
228  GroupQueryResult get_(WrappedTypeID const& wrapped,
229  SelectorBase const&) const;
230 
231  GroupQueryResult getByProductID_(ProductID const pid) const;
232 
234  std::string const& label,
235  std::string const& productInstanceName,
236  std::string const& processName) const;
237 
239  SelectorBase const& sel) const;
240 
242  std::string const& label,
243  std::string const& productInstanceName,
244  std::string const& processName) const;
245 
246  // If getView returns true, then result.isValid() is certain to be
247  // true -- but the View may still be empty.
248  template <typename ELEMENT>
249  GroupQueryResultVec getView_(std::string const& moduleLabel,
250  std::string const& productInstanceName,
251  std::string const& processName) const;
252 
253  template <typename ELEMENT>
254  void fillView_(GroupQueryResult& bh,
255  std::vector<ELEMENT const*>& result) const;
256 
257  void removeCachedProduct_(ProductID const pid) const;
258 
259  //------------------------------------------------------------
260  // Data members
261  //
262 
263  // putProducts_ is the holding pen for EDProducts inserted into this
264  // DataViewImpl. Pointers in these collections own the products to
265  // which they point.
267 
268  // gotProductIDs_ must be mutable because it records all 'gets',
269  // which do not logically modify the DataViewImpl. gotProductIDs_ is
270  // merely a cache reflecting what has been retrieved from the
271  // Principal class.
273 
274  // Each DataViewImpl must have an associated Principal, used as the
275  // source of all 'gets' and the target of 'puts'.
277 
278  // Each DataViewImpl must have a description of the module executing
279  // the "transaction" which the DataViewImpl represents.
281 
282  // Is this an Event, a SubRun, or a Run.
284 
285  // Should we record the parents for any products that will be put.
286  bool const recordParents_;
287 
288  // The consumer is access to validate that the product being
289  // retrieved has been declared in a user's module c'tor to be a
290  // consumable product..
292 };
293 
294 template <typename PROD>
295 inline std::ostream&
296 art::operator<<(std::ostream& os, Handle<PROD> const& h)
297 {
298  os << h.product() << " " << h.provenance() << " " << h.id();
299  return os;
300 }
301 
302 // Implementation of DataViewImpl member templates. See
303 // DataViewImpl.cc for the implementation of non-template members.
304 
305 template <typename PROD>
306 inline bool
308 {
309  result.clear(); // Is this the correct thing to do if an exception is thrown?
310  // We do *not* track whether consumes was called for a SelectorBase.
311  GroupQueryResult bh = get_(WrappedTypeID::make<PROD>(), sel);
312  convert_handle(bh, result);
313  bool const ok{bh.succeeded() && !result.failedToGet()};
314  if (recordParents_ && ok) {
315  recordAsParent(*result.provenance());
316  }
317  return ok;
318 }
319 
320 template <typename PROD>
321 bool
323 {
324  result.clear(); // Is this the correct thing to do if an exception is thrown?
325  // We do *not* track whether consumes was called for a ProductID.
327  convert_handle(bh, result);
328  bool const ok{bh.succeeded() && !result.failedToGet()};
329  if (recordParents_ && ok) {
330  recordAsParent(*result.provenance());
331  }
332  return ok;
333 }
334 
335 template <typename PROD>
336 inline bool
338 {
339  return getByLabel<PROD>(tag.label(), tag.instance(), tag.process(), result);
340 }
341 
342 template <typename PROD>
343 inline bool
345  std::string const& productInstanceName,
346  Handle<PROD>& result) const
347 {
348  return getByLabel<PROD>(label, productInstanceName, {}, result);
349 }
350 
351 template <typename PROD>
352 inline bool
354  std::string const& productInstanceName,
355  std::string const& processName,
356  Handle<PROD>& result) const
357 {
358  result.clear(); // Is this the correct thing to do if an exception is thrown?
359  auto const wrapped = WrappedTypeID::make<PROD>();
361  wrapped.product_type,
362  label,
363  productInstanceName,
364  processName};
365  consumer_->validateConsumedProduct(branchType_, pinfo);
366  GroupQueryResult bh =
367  getByLabel_(wrapped, label, productInstanceName, processName);
368  convert_handle(bh, result);
369  bool const ok{bh.succeeded() && !result.failedToGet()};
370  if (recordParents_ && ok) {
371  recordAsParent(*result.provenance());
372  }
373  return ok;
374 }
375 
376 template <typename PROD>
377 inline PROD const&
379 {
380  Handle<PROD> h;
381  getByLabel(tag, h);
382  return *h;
383 }
384 
385 template <typename PROD>
386 inline bool
388  Handle<PROD>& result) const
389 {
390  auto const& tag = token.inputTag_;
391  return getByLabel(tag.label(), tag.instance(), tag.process(), result);
392 }
393 
394 template <typename PROD>
395 inline PROD const*
397 {
398  Handle<PROD> h;
399  getByLabel(tag, h);
400  return &(*h);
401 }
402 
403 template <typename PROD>
406 {
407  Handle<PROD> h;
408  getByLabel(tag, h);
409  return ValidHandle<PROD>(&(*h), *h.provenance());
410 }
411 
412 template <typename PROD>
415 {
416  return getValidHandle<PROD>(token.inputTag_);
417 }
418 
419 template <typename PROD>
420 inline void
422  std::vector<Handle<PROD>>& results) const
423 {
424  auto const wrapped = WrappedTypeID::make<PROD>();
425  consumer_->validateConsumedProduct(
426  branchType_,
427  ProductInfo{ProductInfo::ConsumableType::Many, wrapped.product_type});
428 
429  std::vector<Handle<PROD>> products;
430  for (auto const& qr : getMany_(wrapped, sel)) {
432  convert_handle(qr, result);
433  products.push_back(result);
434  }
435  results.swap(products);
436  if (!recordParents_) {
437  return;
438  }
439  for (auto const& h : results) {
440  recordAsParent(*h.provenance());
441  }
442 }
443 
444 template <typename PROD>
445 inline void
447 {
449 }
450 
451 template <typename ELEMENT>
454  std::string const& productInstanceName,
455  std::string const& processName) const
456 {
457  TypeID const typeID{typeid(ELEMENT)};
459  typeID,
460  moduleLabel,
461  productInstanceName,
462  processName};
463  consumer_->validateConsumedProduct(branchType_, pinfo);
464  auto bhv =
465  getMatchingSequenceByLabel_(moduleLabel, productInstanceName, processName);
466  removeNonViewableMatches_(typeID, bhv);
468  bhv.size(), typeID, moduleLabel, productInstanceName, processName);
469  return bhv;
470 } // getView_<>()
471 
472 template <typename ELEMENT>
473 std::size_t
475  std::string const& productInstanceName,
476  std::vector<ELEMENT const*>& result) const
477 {
478  auto bhv = getView_<ELEMENT>(moduleLabel, productInstanceName, {});
479  std::size_t const orig_size = result.size();
480  fillView_(bhv[0], result);
481  return result.size() - orig_size;
482 } // getView<>()
483 
484 template <typename ELEMENT>
485 std::size_t
487  std::vector<ELEMENT const*>& result) const
488 {
489  auto bhv = getView_<ELEMENT>(tag.label(), tag.instance(), tag.process());
490  std::size_t const orig_size = result.size();
491  fillView_(bhv[0], result);
492  return result.size() - orig_size;
493 } // getView<>()
494 
495 template <typename ELEMENT>
496 bool
498  std::string const& productInstanceName,
499  View<ELEMENT>& result) const
500 {
501  auto bhv = getView_<ELEMENT>(moduleLabel, productInstanceName, {});
502  fillView_(bhv[0], result.vals());
503  result.set_innards(bhv[0].result()->productID(),
504  bhv[0].result()->uniqueProduct());
505  return true;
506 }
507 
508 template <typename ELEMENT>
509 bool
511 {
512  auto bhv = getView_<ELEMENT>(tag.label(), tag.instance(), tag.process());
513  fillView_(bhv[0], result.vals());
514  result.set_innards(bhv[0].result()->productID(),
515  bhv[0].result()->uniqueProduct());
516  return true;
517 }
518 
519 template <typename ELEMENT>
520 bool
522  View<ELEMENT>& result) const
523 {
524  return getView(token.inputTag_, result);
525 }
526 
527 // ----------------------------------------------------------------------
528 
529 template <typename ELEMENT>
530 void
532  std::vector<ELEMENT const*>& result) const
533 {
534  std::vector<void const*> erased_ptrs;
535  auto product = bh.result()->uniqueProduct();
536  // The lookups and the checking done in getView_ ensure that the
537  // retrieved product supports the requested view.
538  product->fillView(erased_ptrs);
539  if (recordParents_) {
541  }
542  std::vector<ELEMENT const*> vals;
543  cet::transform_all(erased_ptrs, std::back_inserter(vals), [](auto p) {
544  return static_cast<ELEMENT const*>(p);
545  });
546  result.swap(vals);
547 }
548 
549 template <typename PROD>
550 bool
552 {
553  bool result{false};
554  if (h.isValid() && !h.provenance()->produced()) {
556  h.clear();
557  result = true;
558  }
559  return result;
560 }
561 
562 #endif /* art_Framework_Principal_DataViewImpl_h */
563 
564 // Local Variables:
565 // mode: c++
566 // End:
GroupQueryResultVec getView_(std::string const &moduleLabel, std::string const &productInstanceName, std::string const &processName) const
GroupQueryResultVec getMatchingSequenceByLabel_(std::string const &label, std::string const &productInstanceName, std::string const &processName) const
RetrievedProductIDs retrievedProductIDs() const
std::set< ProductID > RetrievedProductSet
Definition: DataViewImpl.h:176
RetrievedProductSet const & retrievedProducts() const
Definition: DataViewImpl.h:197
Principal const & principal_
Definition: DataViewImpl.h:276
void recordAsParent(Provenance const &prov) const
void ensureUniqueProduct_(std::size_t nFound, TypeID const &typeID, std::string const &moduleLabel, std::string const &productInstanceName, std::string const &processName) const
PROD const * getPointerByLabel(InputTag const &tag) const
Definition: DataViewImpl.h:396
BranchDescription const & pd
Definition: DataViewImpl.h:171
GroupQueryResult get_(WrappedTypeID const &wrapped, SelectorBase const &) const
const char * p
Definition: xmltok.h:285
ProcessHistory const & processHistory() const
bool get(SelectorBase const &, Handle< PROD > &result) const
Definition: DataViewImpl.h:307
BranchType const branchType_
Definition: DataViewImpl.h:283
const char * label
cet::exempt_ptr< Consumer > consumer_
Definition: DataViewImpl.h:291
PMValue(std::unique_ptr< EDProduct > &&p, BranchDescription const &b, RangeSet const &r)
Definition: DataViewImpl.h:164
bool isValid() const
Definition: Handle.h:189
std::size_t getView(std::string const &moduleLabel, std::string const &productInstanceName, std::vector< ELEMENT const * > &result) const
Definition: DataViewImpl.h:474
void getMany(SelectorBase const &, std::vector< Handle< PROD >> &results) const
Definition: DataViewImpl.h:421
std::string const & process() const noexcept
Definition: InputTag.h:67
TypeLabelMap const & putProducts() const
Definition: DataViewImpl.h:188
Provenance const * provenance() const
Definition: Handle.h:203
InputTag inputTag_
Definition: ProductToken.h:87
void removeNonViewableMatches_(TypeID const &requestedElementType, GroupQueryResultVec &results) const
std::map< TypeLabel, PMValue > TypeLabelMap
Definition: DataViewImpl.h:177
std::vector< ProductID > RetrievedProductIDs
Definition: DataViewImpl.h:175
std::string const & instance() const noexcept
Definition: InputTag.h:60
void convert_handle(GroupQueryResult const &, Handle< T > &)
Definition: Handle.h:248
Provenance const * provenance() const
Definition: Handle.h:340
void getManyByType(std::vector< Handle< PROD >> &results) const
Definition: DataViewImpl.h:446
ModuleDescription const & md_
Definition: DataViewImpl.h:280
Definition: fwd.h:47
GroupQueryResult getByProductID_(ProductID const pid) const
auto transform_all(Container &, OutputIt, UnaryOp)
GroupQueryResult getByLabel_(WrappedTypeID const &wrapped, std::string const &label, std::string const &productInstanceName, std::string const &processName) const
InputTag inputTag_
Definition: ProductToken.h:65
std::unique_ptr< EDProduct > prod
Definition: DataViewImpl.h:170
::xsd::cxx::tree::string< char, simple_type > string
Definition: Database.h:154
T product(std::vector< T > dims)
bool getByLabel(std::string const &label, std::string const &productInstanceName, Handle< PROD > &result) const
Definition: DataViewImpl.h:344
std::vector< GroupQueryResult > GroupQueryResultVec
Definition: DataViewImpl.h:214
void clear()
Definition: Handle.h:236
void fillView_(GroupQueryResult &bh, std::vector< ELEMENT const * > &result) const
Definition: DataViewImpl.h:531
void removeCachedProduct_(ProductID const pid) const
RetrievedProductSet retrievedProducts_
Definition: DataViewImpl.h:272
cet::exempt_ptr< Group const > result() const
const hit & b
Definition: hits.cxx:21
BranchType
Definition: BranchType.h:18
void set_innards(ProductID const &id, EDProduct const *p)
Definition: View.h:131
TypeLabelMap & putProducts()
Definition: DataViewImpl.h:183
DataViewImpl & operator=(DataViewImpl const &)=delete
TRandom3 r(0)
Service to store calibration data products (CDP) in the SQLite3 metadatabase of a file...
Definition: FillParentInfo.h:8
BranchDescription const & getProductDescription(TypeID const &type, std::string const &productInstanceName) const
bool removeCachedProduct(Handle< PROD > &h) const
Definition: DataViewImpl.h:551
DataViewImpl(DataViewImpl const &)=delete
ValidHandle< PROD > getValidHandle(InputTag const &tag) const
TypeLabelMap putProducts_
Definition: DataViewImpl.h:266
bool getByToken(ProductToken< PROD > const &token, Handle< PROD > &result) const
Definition: DataViewImpl.h:387
void checkPutProducts(bool checkProducts, std::set< TypeLabel > const &expectedProducts, TypeLabelMap const &putProducts)
::xsd::cxx::tree::token< char, normalized_string > token
Definition: Database.h:156
GroupQueryResultVec getMany_(WrappedTypeID const &wrapped, SelectorBase const &sel) const
ProductID id() const
Definition: Handle.h:210
std::string const & label() const noexcept
Definition: InputTag.h:55
size_t size() const
bool failedToGet() const
Definition: Handle.h:196
collection_type & vals()
Definition: View.h:34
bool const recordParents_
Definition: DataViewImpl.h:286