LArSoft  v09_90_00
Liquid Argon Software toolkit - https://larsoft.org/
ProductInserter.cc
Go to the documentation of this file.
2 // vim: set sw=2 expandtab :
3 
14 #include "cetlib/HorizontalRule.h"
15 #include "cetlib/exempt_ptr.h"
16 #include "cetlib_except/exception.h"
18 #include "fhiclcpp/fwd.h"
19 #include "range/v3/view.hpp"
20 
21 #include <algorithm>
22 #include <map>
23 #include <memory>
24 #include <ostream>
25 #include <set>
26 #include <string>
27 #include <utility>
28 #include <vector>
29 
30 using namespace cet;
31 using namespace std;
32 
33 namespace art {
34 
35  ProductInserter::~ProductInserter() = default;
36 
37  ProductInserter::ProductInserter(BranchType const bt,
38  Principal& principal,
39  ModuleContext const& mc)
40  : branchType_{bt}, principal_{&principal}, md_{&mc.moduleDescription()}
41  {}
42 
43  void
45  bool const checkProducts,
46  map<TypeLabel, BranchDescription> const* expectedProducts,
47  std::vector<ProductID> retrievedPIDs)
48  {
49  assert(branchType_ == InEvent);
50  std::lock_guard lock{*mutex_};
51  if (checkProducts) {
52  vector<string> missing;
53  for (auto const& [typeLabel, bd] : *expectedProducts) {
54  if (putProducts_.find(typeLabel) != putProducts_.cend()) {
55  continue;
56  }
57  ostringstream desc;
58  desc << bd;
59  missing.emplace_back(desc.str());
60  }
61  if (!missing.empty()) {
62  ostringstream errmsg;
63  HorizontalRule rule{25};
64  errmsg << "The following products have been declared with 'produces',\n"
65  << "but they have not been placed onto the event:\n"
66  << rule('=') << '\n';
67  for (auto const& desc : missing) {
68  errmsg << desc << rule('=') << '\n';
69  }
70  throw Exception{errors::LogicError, "ProductInserter::checkPutProducts"}
71  << errmsg.str();
72  }
73  }
74 
75  for (auto&& [product, pd, rs] : putProducts_ | ::ranges::views::values) {
76  auto pp = make_unique<ProductProvenance const>(
77  pd.productID(), productstatus::present(), retrievedPIDs);
78  principal_->put(pd,
79  std::move(pp),
80  std::move(product),
81  make_unique<RangeSet>(RangeSet::invalid()));
82  }
83  putProducts_.clear();
84  }
85 
86  void
88  {
89  std::lock_guard lock{*mutex_};
90  for (auto&& [product, pd, range_set] :
92  auto pp = make_unique<ProductProvenance const>(pd.productID(),
95  make_unique<RangeSet>(std::move(range_set)) :
96  make_unique<RangeSet>(RangeSet::invalid());
97  principal_->put(pd, std::move(pp), std::move(product), std::move(rs));
98  }
99  putProducts_.clear();
100  }
101 
102  BranchDescription const&
104  TypeID const& type,
105  string const& instance,
106  bool const alwaysEnableLookupOfProducedProducts /*= false*/) const
107  {
108  std::lock_guard lock{*mutex_};
109  auto const product_name = canonicalProductName(type.friendlyClassName(),
110  md_->moduleLabel(),
111  instance,
112  md_->processName());
113  ProductID const pid{product_name};
115  pid, alwaysEnableLookupOfProducedProducts);
116  if (!bd || (bd->producedClassName() != type.className())) {
117  // Either we did not find the product, or the product we
118  // did find does not match (which can happen with Assns
119  // since Assns(A,B) and Assns(B,A) have the same ProductID
120  // but not the same class name.
122  "ProductInserter::getProductDescription_: error while "
123  "trying to retrieve product description:\n")
124  << "No product is registered for\n"
125  << " process name: '" << md_->processName() << "'\n"
126  << " module label: '" << md_->moduleLabel() << "'\n"
127  << " product class name: '" << type.className() << "'\n"
128  << " product friendly class name: '" << type.friendlyClassName()
129  << "'\n"
130  << " product instance name: '" << instance << "'\n"
131  << " branch type: '" << branchType_ << "'\n";
132  }
133  // The description object is owned by either the source or the
134  // event processor, whose lifetimes exceed that of the
135  // ProductInserter object. It is therefore safe to dereference.
136  return *bd;
137  }
138 
139  EDProductGetter const*
141  {
142  return principal_->productGetter(id);
143  }
144 
145  Provenance
147  {
148  return principal_->provenance(id);
149  }
150 
151 } // namespace art
std::string friendlyClassName() const
Definition: TypeID.cc:61
std::string const & moduleLabel() const
EDProductGetter const * productGetter_(ProductID id) const
const std::string instance
STL namespace.
std::string const & processName() const
cet::exempt_ptr< BranchDescription const > getProductDescription(ProductID const pid, bool const alwaysEnableLookupOfProducedProducts=false) const
Definition: Principal.cc:779
EDProductGetter const * productGetter(ProductID id) const
Definition: Principal.cc:177
decltype(auto) values(Coll &&coll)
Range-for loop helper iterating across the values of the specified collection.
void put(BranchDescription const &, std::unique_ptr< ProductProvenance const > &&, std::unique_ptr< EDProduct > &&, std::unique_ptr< RangeSet > &&)
Definition: Principal.cc:713
std::string className() const
Definition: TypeID.cc:48
std::string canonicalProductName(std::string const &friendlyClassName, std::string const &moduleLabel, std::string const &productInstanceName, std::string const &processName)
cet::coded_exception< errors::ErrorCodes, ExceptionDetail::translate > Exception
Definition: Exception.h:66
BranchDescription const & getProductDescription_(TypeID const &type, std::string const &instance, bool const alwaysEnableLookupOfProducedProducts=false) const
std::map< TypeLabel, PMValue > putProducts_
std::unique_ptr< std::recursive_mutex > mutex_
static RangeSet invalid()
Definition: RangeSet.cc:45
BranchType
Definition: BranchType.h:20
Definition: MVAAlg.h:12
constexpr bool range_sets_supported(BranchType const bt)
constexpr ProductStatus present() noexcept
Definition: ProductStatus.h:10
Provenance provenance_(ProductID id) const
ModuleDescription const * md_
Provenance provenance(ProductID id) const
Definition: Principal.cc:189