SimpleDerivedAnalyzer_module.cc
Go to the documentation of this file.
1 // ======================================================================
2 //
3 // SimpleDerivedAnalyzer
4 //
5 // ======================================================================
6 
14 #include "cetlib_except/exception.h"
15 #include "fhiclcpp/ParameterSet.h"
16 
17 #include <iostream>
18 #include <memory>
19 #include <string>
20 #include <vector>
21 
22 namespace arttest {
24 }
25 
27 
28 template <typename T>
29 void
31 {
32  assert(v.vals().size() > 0);
33 }
34 
35 // dummy is a type we can be sure is not used in any collections in
36 // the Event; no dictionary exists for it.
37 struct dummy {
38 };
39 
40 //--------------------------------------------------------------------
41 //
42 // Produces a SimpleProduct product instance.
43 //
45 public:
46  using SimpleDerivedProduct = std::vector<SimpleDerived>;
47 
48  struct Config {
49  fhicl::Atom<std::string> input_label{fhicl::Name{"input_label"}};
50  fhicl::Atom<std::string> input_label2{fhicl::Name{"input_label2"}};
52  };
54  explicit SimpleDerivedAnalyzer(Parameters const& p);
55 
56 private:
57  void analyze(art::Event const& e) override;
58 
59  void test_getView(art::Event const& e) const;
60  void test_getViewReturnFalse(art::Event const& e) const;
61  void test_getViewThrowing(art::Event const& e) const;
62 
63  void test_PtrVector(art::Event const& e) const;
64 
65  static constexpr std::size_t
67  {
68  return 16;
69  }
70 
71  template <typename DATA_TYPE>
72  void test_PtrVector(art::PtrVector<DATA_TYPE> const& v,
73  art::EventNumber_t event_num,
74  std::size_t nElements = expectedSize()) const;
75 
78  std::size_t const nvalues_;
81  // The following tokens can be initialized from the above members.
82  art::ViewToken<Simple> const simpleToken_{
83  consumesView<Simple>(tagWithInstance_)};
84  art::ViewToken<Simple> const simpleCurrentToken_{
85  consumesView<Simple>(tagForCurrentProcess_)};
86  art::ViewToken<SimpleDerived> const simpleDerivedToken_{
87  consumesView<SimpleDerived>(tagWithInstance_)};
88  art::ViewToken<SimpleDerived> const simpleDerivedCurrentToken_{
89  consumesView<SimpleDerived>(tagForCurrentProcess_)};
90 }; // SimpleDerivedAnalyzer
91 
93  : art::EDAnalyzer{p}
94  , tagWithInstance_{p().input_label(), "derived"}
95  , tagForCurrentProcess_{p().input_label(), "derived", "DEVEL"}
96  , nvalues_{p().nvalues()}
97  , ptrVectorToken_{consumes<art::PtrVector<SimpleDerived>>(
98  art::InputTag{p().input_label2()})}
99  , dummyToken_{consumesView<dummy>(art::InputTag{p().input_label()})}
100 {}
101 
102 void
104 {
105  test_getView(e);
106  // TODO: uncomment this when getView is modified to return false
107  // upon not finding the right label.
108  // test_getViewReturnFalse(e);
110  test_PtrVector(e);
113  assert(v.isValid());
115 
118  assert(vB.isValid());
120 }
121 
122 template <class T>
123 void
124 verify_elements(std::vector<T> const& ptrs,
125  std::size_t sz,
126  art::EventNumber_t event_num,
127  std::size_t /*nvalues*/)
128 {
129  for (std::size_t k = 0; k != sz; ++k) {
130  assert((unsigned)ptrs[k]->key == sz - k + event_num);
131  double expect = 1.5 * k + 100.0;
132  assert(ptrs[k]->value == expect);
133  assert(ptrs[k]->dummy() == 16.25);
134  }
135 }
136 
137 template <typename T>
138 void
140  art::ViewToken<T> const& token,
141  art::ViewToken<T> const& tokenForCurrentProcess,
142  std::size_t const nvalues)
143 {
144  auto const event_num = e.id().event();
145  std::vector<T const*> ptrs;
146  auto sz = e.getView(token, ptrs);
147  assert(sz == nvalues);
148  verify_elements(ptrs, sz, event_num, nvalues);
149  ptrs.clear();
150  sz = e.getView(tokenForCurrentProcess, ptrs);
151  assert(sz == nvalues);
152  verify_elements(ptrs, sz, event_num, nvalues);
153  art::View<T> v;
154  assert(e.getView(token, v));
155  assert(v.vals().size() == nvalues);
156  verify_elements(v.vals(), v.vals().size(), event_num, nvalues);
157  art::View<T> v2;
158  assert(e.getView(tokenForCurrentProcess, v2));
159  assert(v2.vals().size() == nvalues);
160  verify_elements(v2.vals(), v2.vals().size(), event_num, nvalues);
161  // Fill a PtrVector from the view... after zeroing the first
162  // element.
163  v.vals().front() = 0; // zero out the first pointer...
164  art::PtrVector<T> pvec;
165  v.fill(pvec);
166  for (std::size_t i = 0, sz = pvec.size(); i != sz; ++i) {
167  assert(*pvec[i] == *v.vals()[i + 1]);
168  }
169 }
170 
171 void
173 {
174  // Make sure we can get views into products that are present.
177 } // test_getView()
178 
179 void
181 {
182  std::vector<int const*> ints;
183  try {
184  assert(e.getView("nothing with this illegal label", ints) == false);
185  }
186  catch (std::exception& e) {
187  std::cerr << e.what() << '\n';
188  assert("Unexpected exception thrown" == 0);
189  }
190  catch (...) {
191  assert("Unexpected exception thrown" == 0);
192  }
193 }
194 
195 void
197 {
198  // Make sure attempts to get views into products that are not there
199  // fail correctly.
200  std::vector<dummy const*> dummies;
201  try {
202  e.getView(dummyToken_, dummies);
203  assert("Failed to throw required exception" == 0);
204  }
205  catch (art::Exception& e) {
206  assert(e.categoryCode() == art::errors::ProductNotFound);
207  }
208  catch (...) {
209  assert("Wrong exception thrown" == 0);
210  }
211 }
212 
213 void
215 {
216  auto const event_num = e.id().event();
218  using base_product_t = art::PtrVector<arttest::Simple>;
219 
220  // Read the data.
221  auto const& d = *e.getValidHandle(ptrVectorToken_);
222  auto const sz = d.size();
223  if (sz != expectedSize()) {
224  throw cet::exception("SizeMismatch")
225  << "Expected a PtrVector of size " << expectedSize()
226  << " but the obtained size is " << sz << '\n';
227  }
228  // Test the data
229  test_PtrVector(d, event_num);
230  // Construct from PtrVector<U>
231  {
232  base_product_t s{d};
233  test_PtrVector(s, event_num);
234  product_t p{s};
235  test_PtrVector(p, event_num);
236  }
237  // Construct from initializer list.
238  {
239  auto i(d.cbegin());
240  auto il = {*(i++), *i};
241  base_product_t s{il};
242  test_PtrVector(s, event_num, 2);
243  product_t p({s.front(), s.back()});
244  test_PtrVector(p, event_num, 2);
245  }
246  // Operator= from PtrVector<U>.
247  {
248  base_product_t s;
249  s = d;
250  test_PtrVector(s, event_num);
251  product_t p;
252  p = s;
253  test_PtrVector(p, event_num);
254  }
255  // Operator= from initializer list.
256  {
257  auto i(d.cbegin());
258  base_product_t s;
259  s = {*(i++), *i};
260  test_PtrVector(s, event_num, 2);
261  product_t p;
262  p = {s.front(), s.back()};
263  test_PtrVector(p, event_num, 2);
264  }
265  // Assign from Ptr<U>.
266  {
267  base_product_t s{d};
268  s.assign(1, d.front());
269  test_PtrVector(s, event_num, 1);
270  product_t p{s};
271  p.assign(1, s.front());
272  test_PtrVector(p, event_num, 1);
273  }
274  // Assign from iterators.
275  {
276  base_product_t s{d};
277  s.assign(d.cbegin(), d.cend());
278  test_PtrVector(s, event_num);
279  product_t p{s};
280  p.assign(s.cbegin(), s.cend());
281  test_PtrVector(p, event_num);
282  }
283  // Assign from initializer list.
284  {
285  auto i(d.cbegin());
286  base_product_t s{d};
287  s.assign({*(i++), *i});
288  test_PtrVector(s, event_num, 2);
289  product_t p{s};
290  p.assign({s.front(), s.back()});
291  test_PtrVector(p, event_num, 2);
292  }
293  // Push back.
294  {
295  base_product_t s;
296  s.push_back(d.front());
297  test_PtrVector(s, event_num, 1);
298  product_t p;
299  p.push_back(s.front());
300  test_PtrVector(p, event_num, 1);
301  }
302  // Insert from Ptr<U>.
303  {
304  base_product_t s({d[1]});
305  s.insert(s.begin(), d.front());
306  test_PtrVector(s, event_num, 2);
307  base_product_t p({s.back()});
308  p.insert(p.begin(), s.front());
309  test_PtrVector(p, event_num, 2);
310  }
311  // Insert from iterators.
312  {
313  base_product_t s;
314  s.insert(s.begin(), d.cbegin(), d.cend());
315  test_PtrVector(s, event_num);
316  product_t p;
317  p.insert(p.begin(), s.cbegin(), s.cend());
318  test_PtrVector(p, event_num);
319  }
320  // Erase.
321  {
322  base_product_t s{d};
323  s.erase(s.end() - 1);
324  test_PtrVector(s, event_num, expectedSize() - 1);
325  s.erase(s.begin() + 1, s.end());
326  test_PtrVector(s, event_num, 1);
327  }
328 }
329 
330 template <typename DATA_TYPE>
331 void
333  art::EventNumber_t const event_num,
334  std::size_t const nElements) const
335 {
336  auto const sz(v.size());
337  if (sz != nElements) {
338  throw cet::exception("SizeMismatch")
339  << "Expected size " << nElements << " but got " << sz << ".\n";
340  }
341  auto const b = v.cbegin();
342  auto const e = v.cbegin() + nElements;
343  for (auto i = b; i != e; ++i) {
344  std::size_t const k = i - b;
345  if (static_cast<std::size_t>((*i)->key) != expectedSize() - k + event_num) {
346  throw cet::exception("KeyMismatch")
347  << "At position " << k << " expected key "
348  << expectedSize() - k + event_num << " but obtained " << (*i)->key
349  << ".\n";
350  }
351  assert(*i == *i); // Check operator ==.
352  if (k == 0 && sz > 1) {
353  assert(*i != *(i + 1)); // Check operator !=.
354  assert(*(i) < *(i + 1)); // Check operator <.
355  }
356 
357  double const expect{1.5 * k + 100.0};
358  if ((*i)->value != expect) {
359  throw cet::exception("ValueMismatch")
360  << "At position " << k << " expected value " << expect
361  << " but obtained " << (*i)->value << ".\n";
362  }
363  if ((*i)->dummy() != 16.25) {
364  throw cet::exception("ValueMismatch")
365  << "At position " << k << " expected dummy value " << 16.25
366  << " but obtained " << (*i)->dummy() << ".\n";
367  }
368  }
369 } // test_PtrVector()
370 
def analyze(root, level, gtrees, gbranches, doprint)
Definition: rootstat.py:67
void test_view(art::Event const &e, art::ViewToken< T > const &token, art::ViewToken< T > const &tokenForCurrentProcess, std::size_t const nvalues)
art::ViewToken< SimpleDerived > const simpleDerivedToken_
void test_PtrVector(art::Event const &e) const
void analyze(art::Event const &e) override
void check_for_conversion(art::View< T > const &v)
void fill(PtrVector< T > &pv) const
Definition: View.h:158
art::ViewToken< SimpleDerived > const simpleDerivedCurrentToken_
std::vector< SimpleDerived > SimpleDerivedProduct
const double e
void verify_elements(std::vector< T > const &ptrs, std::size_t sz, art::EventNumber_t event_num, std::size_t)
#define DEFINE_ART_MODULE(klass)
Definition: ModuleMacros.h:68
art::ViewToken< Simple > const simpleCurrentToken_
ValidHandle< PROD > getValidHandle(InputTag const &tag) const
Definition: DataViewImpl.h:480
void test_getViewThrowing(art::Event const &e) const
Definition: fwd.h:43
const_iterator cbegin() const
Definition: PtrVector.h:279
auto vals() -> auto &
Definition: View.h:76
static constexpr std::size_t expectedSize()
size_type size() const
Definition: PtrVector.h:308
art::ProductToken< art::PtrVector< SimpleDerived > > const ptrVectorToken_
p
Definition: test.py:228
cet::coded_exception< errors::ErrorCodes, ExceptionDetail::translate > Exception
Definition: Exception.h:66
auto isValid() const
Definition: View.h:60
art::ViewToken< dummy > const dummyToken_
IDNumber_t< Level::Event > EventNumber_t
Definition: IDNumber.h:118
cet::LibraryManager dummy("noplugin")
art::ViewToken< Simple > const simpleToken_
EventNumber_t event() const
Definition: EventID.h:117
std::size_t getView(std::string const &moduleLabel, std::string const &productInstanceName, std::string const &processName, std::vector< ELEMENT const * > &result) const
Definition: DataViewImpl.h:525
static const double s
Definition: Units.h:99
EventID id() const
Definition: Event.cc:37
cet::coded_exception< error, detail::translate > exception
Definition: exception.h:33
void test_getViewReturnFalse(art::Event const &e) const
void test_getView(art::Event const &e) const