MixOp.h
Go to the documentation of this file.
1 #ifndef art_Framework_IO_ProductMix_MixOp_h
2 #define art_Framework_IO_ProductMix_MixOp_h
3 
4 // Template encapsulating all the attributes and functionality of a
5 // product mixing operation.
6 
17 #include "canvas/Persistency/Provenance/Compatibility/BranchIDList.h"
21 #include "cetlib/exempt_ptr.h"
22 
23 #include <algorithm>
24 #include <functional>
25 
26 namespace art {
27  template <typename PROD, typename OPROD>
28  class MixOp;
29 }
30 
31 template <typename PROD, typename OPROD>
32 class art::MixOp : public art::MixOpBase {
33 public:
34  template <typename FUNC>
35  MixOp(InputTag const& inputTag,
37  FUNC mixFunc,
38  bool outputProduct,
39  bool compactMissingProducts,
40  BranchType bt);
41 
42  InputTag const& inputTag() const override;
43 
44  TypeID const& inputType() const override;
45 
46  std::string const& outputInstanceLabel() const override;
47 
48  void mixAndPut(Event& e, PtrRemapper const& remap) const override;
49 
50  void initializeBranchInfo(RootBranchInfoList const& rbiList) override;
51 
52  ProductID incomingProductID() const override;
53 
54  ProductID outgoingProductID() const override;
55 
56  void readFromFile(
57  EntryNumberSequence const& seq,
58  cet::exempt_ptr<BranchIDLists const> branchIDLists) override;
59 
60  BranchType branchType() const override;
61 
62 private:
63  using SpecProdList = std::vector<std::shared_ptr<Wrapper<PROD>>>;
64 
73  bool const outputProduct_;
76 };
77 
78 template <typename PROD, typename OPROD>
79 template <typename FUNC>
82  FUNC mixFunc,
83  bool const outputProduct,
84  bool const compactMissingProducts,
85  BranchType const bt)
86  : inputTag_{inputTag}
87  , inputType_{typeid(PROD)}
89  , mixFunc_{mixFunc}
92  , outputProduct_{outputProduct}
93  , compactMissingProducts_{compactMissingProducts}
94  , branchType_{bt}
95 {}
96 
97 template <typename PROD, typename OPROD>
98 art::InputTag const&
100 {
101  return inputTag_;
102 }
103 
104 template <typename PROD, typename OPROD>
105 art::TypeID const&
107 {
108  return inputType_;
109 }
110 
111 template <typename PROD, typename OPROD>
112 std::string const&
114 {
115  return outputInstanceLabel_;
116 }
117 
118 template <typename PROD, typename OPROD>
119 void
121 {
122  auto rProd = std::make_unique<OPROD>();
123  std::vector<PROD const*> inConverted;
124  inConverted.reserve(inProducts_.size());
125  try {
126  auto const endIter = cend(inProducts_);
127  for (auto i = cbegin(inProducts_); i != endIter; ++i) {
128  auto const prod = (*i)->product();
129  if (prod || !compactMissingProducts_) {
130  inConverted.emplace_back(prod);
131  }
132  }
133  }
134  catch (std::bad_cast const&) {
136  << "Unable to obtain correctly-typed product from wrapper.\n";
137  }
138  if (mixFunc_(inConverted, *rProd, remap)) {
139  if (!outputProduct_) {
141  << "Returned true (output product to be put in event) from a mix "
142  "function\n"
143  << "declared with outputProduct=false.\n";
144  }
145  if (outputInstanceLabel_.empty()) {
146  e.put(std::move(rProd));
147  } else {
148  e.put(std::move(rProd), outputInstanceLabel_);
149  }
150  } // False means don't want this in the event.
151 }
152 
153 template <typename PROD, typename OPROD>
154 void
156  RootBranchInfoList const& branchInfo_List)
157 {
158  if (!branchInfo_List.findBranchInfo(inputType_, inputTag_, branchInfo_)) {
160  << "Unable to find requested product " << inputTag_ << " of type "
161  << inputType_.friendlyClassName() << " in secondary input stream.\n";
162  }
163  // Check dictionaries for input product, not output product: let
164  // output modules take care of that.
165  std::vector<TypeID> const types{TypeID{typeid(PROD)}};
167 }
168 
169 template <typename PROD, typename OPROD>
172 {
173  return ProductID{branchInfo_.branchName()};
174 }
175 
176 template <typename PROD, typename OPROD>
179 {
181  if (outputProduct_) {
182  TypeID const outputType{typeid(OPROD)};
183  BranchKey const key{outputType.friendlyClassName(),
184  moduleLabel_,
186  processName_,
187  art::InEvent}; // Outgoing product must be InEvent.
188  auto I = ProductMetaData::instance().productList().find(key);
189  if (I == ProductMetaData::instance().productList().end()) {
191  << "MixOp unable to find branch id for a product ("
192  << outputType.className() << ") that should have been registered!\n";
193  }
194  result = I->second.productID();
195  }
196  return result;
197 }
198 
199 template <typename PROD, typename OPROD>
200 void
202  EntryNumberSequence const& seq,
204 {
205  inProducts_.clear();
206  inProducts_.reserve(seq.size());
207  if (branchInfo_.branch() == nullptr) {
208  throw Exception(errors::LogicError) << "Branch not initialized for read.\n";
209  }
210  configureStreamers(branchIDLists);
211 
212  // Assume the sequence is ordered per
213  // MixHelper::generateEventSequence.
214  auto const b = seq.cbegin(), e = seq.cend();
215  for (auto i = b; i != e; ++i) {
216  auto fit = std::find(b, i, *i);
217  if (fit == i) { // Need new product.
218  inProducts_.emplace_back(new Wrapper<PROD>);
219  Wrapper<PROD>* wp = inProducts_.back().get();
220  branchInfo_.branch()->SetAddress(&wp);
221  branchInfo_.branch()->GetEntry(*i);
222  branchInfo_.branch()->ResetAddress();
223  } else { // Already have one: find and use.
224  auto pit = cbegin(inProducts_);
225  std::advance(pit, std::distance(b, fit));
226  inProducts_.emplace_back(*pit);
227  }
228  }
229 }
230 
231 template <typename PROD, typename OPROD>
232 inline art::BranchType
234 {
235  return branchType_;
236 }
237 
238 #endif /* art_Framework_IO_ProductMix_MixOp_h */
239 
240 // Local Variables:
241 // mode: c++
242 // End:
TypeID const & inputType() const override
Definition: MixOp.h:106
MixFunc< PROD, OPROD > const mixFunc_
Definition: MixOp.h:68
void mixAndPut(Event &e, PtrRemapper const &remap) const override
Definition: MixOp.h:120
BranchType const branchType_
Definition: MixOp.h:75
std::string friendlyClassName() const
bool findBranchInfo(InputTag const &tag, RootBranchInfo &rbInfo) const
std::string const & branchName() const
void configureStreamers(cet::exempt_ptr< BranchIDLists const > branchIDLists)
ProductID incomingProductID() const override
Definition: MixOp.h:171
std::string const moduleLabel_
Definition: MixOp.h:71
std::vector< std::shared_ptr< Wrapper< PROD >>> SpecProdList
Definition: MixOp.h:63
InputTag const & inputTag() const override
Definition: MixOp.h:99
unsigned distance(const T &t1, const T &t2)
MixOp(InputTag const &inputTag, std::string const &outputInstanceLabel, FUNC mixFunc, bool outputProduct, bool compactMissingProducts, BranchType bt)
Definition: MixOp.h:80
std::string const outputInstanceLabel_
Definition: MixOp.h:67
ProductID put(std::unique_ptr< PROD > &&product)
Definition: Event.h:102
BranchType branchType() const override
Definition: MixOp.h:233
ProductID outgoingProductID() const override
Definition: MixOp.h:178
static ProductMetaData const & instance()
bool const outputProduct_
Definition: MixOp.h:73
InputTag const inputTag_
Definition: MixOp.h:65
std::function< bool(std::vector< PROD const * > const &, OPROD &, PtrRemapper const &)> MixFunc
Definition: MixTypes.h:17
SpecProdList inProducts_
Definition: MixOp.h:69
void initializeBranchInfo(RootBranchInfoList const &rbiList) override
Definition: MixOp.h:155
std::vector< FileIndex::EntryNumber_t > EntryNumberSequence
Definition: MixTypes.h:23
bool const compactMissingProducts_
Definition: MixOp.h:74
T prod(const std::vector< T > &v)
Definition: prod.hpp:17
std::string const processName_
Definition: MixOp.h:70
TypeID const inputType_
Definition: MixOp.h:66
cet::coded_exception< errors::ErrorCodes, ExceptionDetail::translate > Exception
Definition: Exception.h:66
RootBranchInfo branchInfo_
Definition: MixOp.h:72
ProductList const & productList() const
void readFromFile(EntryNumberSequence const &seq, cet::exempt_ptr< BranchIDLists const > branchIDLists) override
Definition: MixOp.h:201
const hit & b
Definition: hits.cxx:21
TBranch const * branch() const
void checkForMissingDictionaries(std::vector< TypeID > const &types) noexcept( false)
BranchType
Definition: BranchType.h:18
Service to store calibration data products (CDP) in the SQLite3 metadatabase of a file...
Definition: FillParentInfo.h:8
std::string const & outputInstanceLabel() const override
Definition: MixOp.h:113
Float_t e
Definition: plot.C:35
enum BeamMode string