LArSoft  v09_90_00
Liquid Argon Software toolkit - https://larsoft.org/
createProductLookups.cc
Go to the documentation of this file.
2 // vim: set sw=2:
3 
7 
8 #include <algorithm>
9 #include <string>
10 #include <unordered_map>
11 
12 using namespace art;
13 
14 namespace {
15 
16  struct CheapTag {
17  std::string label;
18  std::string instance;
19  std::string process;
20  };
21 
22  inline bool
23  operator==(CheapTag const& left, CheapTag const& right)
24  {
25  return left.label == right.label && left.instance == right.instance &&
26  left.process == right.process;
27  }
28 
29  class PendingBTLEntry {
30  public:
31  PendingBTLEntry(std::string const& fcn,
32  std::string const& moduleLabel,
33  std::string const& instanceName,
34  std::string const& procName,
35  ProductID const pid)
36  : fcn_{fcn}, ct_{moduleLabel, instanceName, procName}, pid_{pid}
37  {}
38 
39  std::string const&
40  fcn() const noexcept
41  {
42  return fcn_;
43  }
44  CheapTag const&
45  ct() const noexcept
46  {
47  return ct_;
48  }
49  std::string const&
50  process() const noexcept
51  {
52  return ct_.process;
53  }
54  ProductID
55  pid() const
56  {
57  return pid_;
58  }
59 
60  private:
61  std::string fcn_;
62  CheapTag ct_;
63  ProductID pid_;
64  };
65 }
66 
69 {
70  // Computing the product lookups does not rely on any ROOT facilities.
71  ProductLookup_t result;
72  std::vector<PendingBTLEntry> pendingEntries;
73  std::unordered_map<ProductID, CheapTag, ProductID::Hash> insertedABVs;
74  for (auto const& [pid, pd] : descriptions) {
75  auto const& prodFCN = pd.friendlyClassName();
76  auto const& procName = pd.processName();
77  result[prodFCN][procName].emplace_back(pid);
78 
79  // Additional work only for Assns lookup
80  auto const& moduleLabel = pd.moduleLabel();
81  auto const& instanceName = pd.productInstanceName();
82  auto const& className = pd.producedClassName();
83 
84  if (!is_assns(className))
85  continue;
86 
87  auto const baseName = name_of_assns_base(className);
88  if (!baseName.empty()) {
89  // We're an Assns<A, B, D>, with a base Assns<A, B>.
90  pendingEntries.emplace_back(art::friendlyname::friendlyName(baseName),
91  moduleLabel,
92  instanceName,
93  procName,
94  pid);
95  } else {
96  // Add our pid to the list of real Assns<A, B, void>
97  // products already registered.
98  insertedABVs.emplace(pid, CheapTag{moduleLabel, instanceName, procName});
99  }
100  }
101 
102  auto const iend = insertedABVs.cend();
103  // Preserve useful ordering, only inserting if we don't already have
104  // a *real* Assns<A, B, void> for that module label / instance name
105  // combination.
106  std::for_each(
107  pendingEntries.cbegin(),
108  pendingEntries.cend(),
109  [&result, &insertedABVs, iend](auto const& pe) {
110  auto& pids = result[pe.fcn()][pe.process()];
111  if (pids.empty() ||
112  !std::any_of(pids.cbegin(),
113  pids.cend(),
114  [&insertedABVs, &iend, &pe](ProductID const pid) {
115  auto i = insertedABVs.find(pid);
116  return i != iend && pe.ct() == i->second;
117  })) {
118  pids.emplace_back(pe.pid());
119  }
120  });
121 
122  return result;
123 }
bool operator==(Provenance const &a, Provenance const &b) noexcept
Definition: Provenance.cc:141
constexpr auto const & right(const_AssnsIter< L, R, D, Dir > const &a, const_AssnsIter< L, R, D, Dir > const &b)
Definition: AssnsIter.h:102
const std::string instance
string name_of_assns_base(string assns_type_name)
Definition: TypeID.cc:188
ProductLookup_t createProductLookups(ProductDescriptionsByID const &descriptions)
std::string friendlyName(std::string const &iFullName)
constexpr auto const & left(const_AssnsIter< L, R, D, Dir > const &a, const_AssnsIter< L, R, D, Dir > const &b)
Definition: AssnsIter.h:94
Definition: MVAAlg.h:12
std::map< ProductID, BranchDescription > ProductDescriptionsByID
std::map< std::string, ProcessLookup > ProductLookup_t
Definition: type_aliases.h:23
bool is_assns(std::string const &type_name)
Definition: TypeID.h:66