LArSoft  v09_90_00
Liquid Argon Software toolkit - https://larsoft.org/
ProductRetriever.cc
Go to the documentation of this file.
2 // vim: set sw=2 expandtab :
3 
17 #include "cetlib/HorizontalRule.h"
18 #include "cetlib/exempt_ptr.h"
19 #include "cetlib_except/exception.h"
21 #include "fhiclcpp/fwd.h"
22 
23 #include <memory>
24 #include <string>
25 #include <utility>
26 #include <vector>
27 
28 using namespace std::string_literals;
29 
30 namespace art {
31 
32  ProductRetriever::~ProductRetriever() = default;
33 
34  ProductRetriever::ProductRetriever(BranchType const bt,
35  Principal const& principal,
36  ModuleContext const& mc,
37  bool const recordParents)
38  : branchType_{bt}
39  , principal_{principal}
40  , mc_{mc}
41  , md_{mc.moduleDescription()}
42  , recordParents_{recordParents}
43  {}
44 
45  EDProductGetter const*
47  {
48  std::lock_guard lock{mutex_};
49  return principal_.productGetter(pid);
50  }
51 
52  std::optional<fhicl::ParameterSet const>
53  ProductRetriever::getProcessParameterSet(std::string const& processName) const
54  {
55  std::lock_guard lock{mutex_};
56  auto const config =
58  if (!config) {
59  return std::nullopt;
60  }
61 
62  if (fhicl::ParameterSet ps;
63  fhicl::ParameterSetRegistry::get(config->parameterSetID(), ps)) {
64  return std::make_optional(std::move(ps));
65  }
66  return std::nullopt;
67  }
68 
69  std::vector<ProductID>
71  {
72  std::lock_guard lock{mutex_};
73  return std::vector<ProductID>(begin(retrievedProducts_),
75  }
76 
77  std::optional<Provenance const>
79  {
80  auto gqr = principal_.getByProductID(pid);
81  if (gqr.failed()) {
82  return std::nullopt;
83  }
84 
85  auto group = gqr.result();
86  if (!group->productProvenance()) {
87  // This can happen if someone tries to access the provenance
88  // before the product has been produced.
89  return std::nullopt;
90  }
91  return std::make_optional<Provenance const>(group);
92  }
93 
94  cet::exempt_ptr<BranchDescription const>
96  {
98  }
99 
100  void
101  ProductRetriever::recordAsParent_(cet::exempt_ptr<Group const> grp) const
102  {
103  if (grp->productDescription().transient()) {
104  // If the product retrieved is transient, don't use its
105  // ProductID; use the ProductID's of its parents.
106  auto const& parents = grp->productProvenance()->parentage().parents();
107  retrievedProducts_.insert(cbegin(parents), cend(parents));
108  } else {
109  retrievedProducts_.insert(grp->productDescription().productID());
110  }
111  }
112 
113  cet::exempt_ptr<Group const>
115  std::string const& moduleLabel,
116  std::string const& productInstanceName,
117  ProcessTag const& processTag) const
118  {
119  // Check that the consumesView<ELEMENT, BT>(InputTag),
120  // or the mayConsumeView<ELEMENT, BT>(InputTag)
121  // is actually present.
123  branchType_,
124  md_,
126  typeID,
127  moduleLabel,
128  productInstanceName,
129  processTag});
130  // Fetch the specified data products, which must be containers.
131  auto const groups = principal_.getMatchingSequence(
132  mc_,
133  Selector{ModuleLabelSelector{moduleLabel} &&
134  ProductInstanceNameSelector{productInstanceName} &&
135  ProcessNameSelector{processTag.name()}},
136  processTag);
137  auto qrs = resolve_products(groups, TypeID{});
138  // Remove any containers that do not allow upcasting of their
139  // elements to the desired element type.
140  auto new_end =
141  remove_if(qrs.begin(), qrs.end(), [&typeID](auto const& gqr) {
142  auto const group = gqr.result();
143  assert(group->productDescription().supportsView());
144  return !detail::upcastAllowed(*group->uniqueProduct()->typeInfo(),
145  typeID.typeInfo());
146  });
147  qrs.erase(new_end, qrs.end());
148  // Throw if there is not one and only one container to return.
149  if (qrs.size() != 1) {
151  e << "getView: Found "
152  << (qrs.empty() ? "no products" : "more than one product")
153  << " matching all criteria\n"
154  << "Looking for sequence of type: " << typeID << '\n'
155  << "Looking for module label: " << moduleLabel << '\n'
156  << "Looking for productInstanceName: " << productInstanceName << '\n';
157  if (!processTag.name().empty()) {
158  e << "Looking for processName: " << processTag.name() << '\n';
159  }
160  throw e;
161  }
162  // And return the single result.
163  return qrs[0].result();
164  }
165 
166  ProductID
168  std::string const& instance /* = "" */) const
169  {
170  std::lock_guard lock{mutex_};
171  auto const& product_name = canonicalProductName(
173  ProductID const pid{product_name};
174  auto desc = principal_.getProductDescription(pid);
175  if (!desc) {
177  "ProductRetriever::getProductID: error while trying to "
178  "retrieve product description:\n")
179  << "No product is registered for\n"
180  << " process name: '" << md_.processName() << "'\n"
181  << " module label: '" << md_.moduleLabel() << "'\n"
182  << " product friendly class name: '" << type.friendlyClassName()
183  << "'\n"
184  << " product instance name: '" << instance << "'\n"
185  << " branch type: '" << branchType_ << "'\n";
186  }
187  // The description object is owned by either the source or the
188  // event processor, whose lifetimes exceed that of the
189  // ProductRetriever object. It is therefore safe to dereference.
190  return desc->productID();
191  }
192 
193  std::vector<InputTag>
195  SelectorBase const& selector) const
196  {
197  ProcessTag const processTag{"", md_.processName()};
198  return principal_.getInputTags(mc_, wrapped, selector, processTag);
199  }
200 
203  InputTag const& tag) const
204  {
205  std::lock_guard lock{mutex_};
206  ProcessTag const processTag{tag.process(), md_.processName()};
208  wrapped.product_type,
209  tag.label(),
210  tag.instance(),
211  processTag};
214  mc_, wrapped, tag.label(), tag.instance(), processTag);
215  bool const ok = qr.succeeded() && !qr.failed();
216  if (recordParents_ && ok) {
217  recordAsParent_(qr.result());
218  }
219  return qr;
220  }
221 
224  SelectorBase const& sel) const
225  {
226  std::lock_guard lock{mutex_};
227  // We do *not* track whether consumes was called for a SelectorBase.
228  ProcessTag const processTag{"", md_.processName()};
229  auto qr = principal_.getBySelector(mc_, wrapped, sel, processTag);
230  bool const ok = qr.succeeded() && !qr.failed();
231  if (recordParents_ && ok) {
232  recordAsParent_(qr.result());
233  }
234  return qr;
235  }
236 
239  {
240  std::lock_guard lock{mutex_};
241  auto qr = principal_.getByProductID(pid);
242  bool const ok = qr.succeeded() && !qr.failed();
243  if (recordParents_ && ok) {
244  recordAsParent_(qr.result());
245  }
246  return qr;
247  }
248 
249  std::vector<GroupQueryResult>
251  SelectorBase const& sel) const
252  {
253  std::lock_guard lock{mutex_};
255  branchType_,
256  md_,
258  ProcessTag const processTag{"", md_.processName()};
259  auto qrs = principal_.getMany(mc_, wrapped, sel, processTag);
260  for (auto const& qr : qrs) {
261  if (recordParents_) {
262  recordAsParent_(qr.result());
263  }
264  }
265  return qrs;
266  }
267 } // namespace art
void recordAsParent_(cet::exempt_ptr< Group const > grp) const
decltype(auto) constexpr cend(T &&obj)
ADL-aware version of std::cend.
Definition: StdUtils.h:93
static ConsumesInfo * instance()
Definition: ConsumesInfo.cc:27
std::vector< InputTag > getInputTags(ModuleContext const &mc, WrappedTypeID const &wrapped, SelectorBase const &, ProcessTag const &) const
Definition: Principal.cc:520
std::string friendlyClassName() const
Definition: TypeID.cc:61
std::string const & moduleLabel() const
std::optional< fhicl::ParameterSet const > getProcessParameterSet(std::string const &process) const
static collection_type const & get() noexcept
ModuleContext const & mc_
const std::string instance
std::string const & instance() const noexcept
Definition: InputTag.cc:85
Principal const & principal_
BranchType const branchType_
std::string const & process() const noexcept
Definition: InputTag.cc:91
std::set< ProductID > retrievedProducts_
GroupQueryResult getByLabel_(WrappedTypeID const &wrapped, InputTag const &tag) const
std::string const & processName() const
ModuleDescription const & md_
decltype(auto) constexpr end(T &&obj)
ADL-aware version of std::end.
Definition: StdUtils.h:77
GroupQueryResult getBySelector(ModuleContext const &mc, WrappedTypeID const &wrapped, SelectorBase const &, ProcessTag const &) const
Definition: Principal.cc:488
std::string const & label() const noexcept
Definition: InputTag.cc:79
ProductID getProductID_(TypeID const &typeID, std::string const &instance) const
EDProductGetter const * productGetter(ProductID const pid) const
GroupQueryResult getBySelector_(WrappedTypeID const &wrapped, SelectorBase const &selector) 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
GroupQueryResult getByProductID_(ProductID productID) const
std::recursive_mutex mutex_
std::string canonicalProductName(std::string const &friendlyClassName, std::string const &moduleLabel, std::string const &productInstanceName, std::string const &processName)
std::vector< cet::exempt_ptr< Group > > getMatchingSequence(ModuleContext const &, SelectorBase const &, ProcessTag const &) const
Definition: Principal.cc:550
void validateConsumedProduct(BranchType const, ModuleDescription const &, ProductInfo const &productInfo)
ProcessHistory const & processHistory() const
Definition: Principal.cc:247
cet::exempt_ptr< Group > result() const
cet::coded_exception< errors::ErrorCodes, ExceptionDetail::translate > Exception
Definition: Exception.h:66
std::optional< ProcessConfiguration > getConfigurationForProcess(std::string const &name) const
auto const & name() const
Definition: ProcessTag.h:23
std::vector< InputTag > getInputTags_(WrappedTypeID const &wrapped, SelectorBase const &selector) const
cet::exempt_ptr< BranchDescription const > getProductDescription(ProductID) const
BranchType
Definition: BranchType.h:20
std::vector< GroupQueryResult > getMany(ModuleContext const &mc, WrappedTypeID const &wrapped, SelectorBase const &, ProcessTag const &) const
Definition: Principal.cc:534
decltype(auto) constexpr cbegin(T &&obj)
ADL-aware version of std::cbegin.
Definition: StdUtils.h:85
std::vector< ProductID > retrievedPIDs() const
Definition: MVAAlg.h:12
bool upcastAllowed(std::type_info const &tiFrom, std::type_info const &tiTo)
cet::exempt_ptr< Group const > getContainerForView_(TypeID const &, std::string const &moduleLabel, std::string const &productInstanceName, ProcessTag const &processTag) const
decltype(auto) constexpr begin(T &&obj)
ADL-aware version of std::begin.
Definition: StdUtils.h:69
GroupQueryResult getByLabel(ModuleContext const &mc, WrappedTypeID const &wrapped, std::string const &label, std::string const &productInstanceName, ProcessTag const &processTag) const
Definition: Principal.cc:506
GroupQueryResult getByProductID(ProductID const pid) const
Definition: Principal.cc:839
Float_t e
Definition: plot.C:35
std::vector< GroupQueryResult > getMany_(WrappedTypeID const &wrapped, SelectorBase const &sel) const
std::type_info const & typeInfo() const
Definition: TypeID.cc:36
std::optional< Provenance const > getProductProvenance(ProductID) const
std::vector< GroupQueryResult > resolve_products(std::vector< cet::exempt_ptr< art::Group >> const &groups, art::TypeID const &wrapped_type)
Definition: Group.cc:428