CMS 3D CMS Logo

ThinningTestAnalyzer.cc
Go to the documentation of this file.
12 #include "DataFormats/TestObjects/interface/Thing.h"
13 #include "DataFormats/TestObjects/interface/ThingCollection.h"
14 #include "DataFormats/TestObjects/interface/TrackOfThings.h"
16 
17 #include <vector>
18 
19 namespace edmtest {
20 
22  public:
24 
25  static void fillDescriptions(edm::ConfigurationDescriptions& descriptions);
26 
27  void analyze(edm::StreamID, edm::Event const& e, edm::EventSetup const& c) const override;
28 
29  private:
31  std::tuple<edm::Handle<ThingCollection>, edm::RefProd<ThingCollection>> getThinned(edm::Event const& event) const;
34 
35  template <typename RefT>
36  void testRefToParent(RefT const& ref,
37  std::string_view refName,
38  int const expectedValue,
39  int const eventOffset) const;
40 
41  template <typename RefT>
42  void testRefToThinned(RefT const& ref,
43  std::string_view refName,
44  int const expectedValue,
45  int const eventOffset,
46  edm::ProductID const thinnedCollectionID) const;
47 
48  void testVectors(TrackOfThings const& track,
49  edm::RefProd<ThingCollection> const& thinnedRefProd,
51  int const eventOffset) const;
52 
53  void incrementExpectedValue(std::vector<int>::const_iterator& iter) const;
54 
59 
61  std::vector<int> expectedParentContent_;
65  std::vector<int> expectedThinnedContent_;
66  std::vector<unsigned int> expectedIndexesIntoParent_;
68  std::vector<int> expectedValues_;
72  };
73 
75  parentToken_ = consumes<ThingCollection>(pset.getParameter<edm::InputTag>("parentTag"));
76  thinnedToken_ = mayConsume<ThingCollection>(pset.getParameter<edm::InputTag>("thinnedTag"));
77  associationToken_ = mayConsume<edm::ThinnedAssociation>(pset.getParameter<edm::InputTag>("associationTag"));
78  trackToken_ = consumes<TrackOfThingsCollection>(pset.getParameter<edm::InputTag>("trackTag"));
79  parentWasDropped_ = pset.getParameter<bool>("parentWasDropped");
80  if (!parentWasDropped_) {
81  expectedParentContent_ = pset.getParameter<std::vector<int>>("expectedParentContent");
82  }
83  thinnedWasDropped_ = pset.getParameter<bool>("thinnedWasDropped");
84  thinnedIsAlias_ = pset.getParameter<bool>("thinnedIsAlias");
85  if (!thinnedWasDropped_) {
86  expectedThinnedContent_ = pset.getParameter<std::vector<int>>("expectedThinnedContent");
87  }
88  refToParentIsAvailable_ = pset.getParameter<bool>("refToParentIsAvailable");
89  associationShouldBeDropped_ = pset.getParameter<bool>("associationShouldBeDropped");
91  expectedIndexesIntoParent_ = pset.getParameter<std::vector<unsigned int>>("expectedIndexesIntoParent");
92  }
93  expectedValues_ = pset.getParameter<std::vector<int>>("expectedValues");
94 
95  auto slimmedFactor = [](int count, int factor) {
96  int ret = 1;
97  for (int i = 0; i < count; ++i) {
98  ret *= factor;
99  }
100  return ret;
101  };
102  int const slimmedValueFactor = pset.getParameter<int>("slimmedValueFactor");
103  parentSlimmedValueFactor_ = slimmedFactor(pset.getParameter<int>("parentSlimmedCount"), slimmedValueFactor);
104  thinnedSlimmedValueFactor_ = slimmedFactor(pset.getParameter<int>("thinnedSlimmedCount"), slimmedValueFactor);
105  refSlimmedValueFactor_ = slimmedFactor(pset.getParameter<int>("refSlimmedCount"), slimmedValueFactor);
106  }
107 
110  desc.add<edm::InputTag>("parentTag");
111  desc.add<edm::InputTag>("thinnedTag");
112  desc.add<edm::InputTag>("associationTag");
113  desc.add<edm::InputTag>("trackTag");
114  desc.add<bool>("parentWasDropped", false);
115  desc.add<bool>("thinnedWasDropped", false);
116  desc.add<bool>("thinnedIsAlias", false);
117  desc.add<bool>("refToParentIsAvailable", true)
118  ->setComment(
119  "If Ref-to-parent is generally available. With thinnedRefFrom it may happen that the Ref-to-parent is not "
120  "available, but the Ref-to-thinned is. In such case this parameter should be set to 'False', and the "
121  "'expectedValues' should be set to correspond the values via Ref-to-thinned.");
122  std::vector<int> defaultV;
123  std::vector<unsigned int> defaultVU;
124  desc.add<std::vector<int>>("expectedParentContent", defaultV);
125  desc.add<std::vector<int>>("expectedThinnedContent", defaultV);
126  desc.add<std::vector<unsigned int>>("expectedIndexesIntoParent", defaultVU);
127  desc.add<bool>("associationShouldBeDropped", false);
128  desc.add<std::vector<int>>("expectedValues");
129  desc.add<int>("parentSlimmedCount", 0);
130  desc.add<int>("thinnedSlimmedCount", 0);
131  desc.add<int>("refSlimmedCount", 0);
132  desc.add<int>("slimmedValueFactor", 10);
133  descriptions.addDefault(desc);
134  }
135 
137  auto parentCollection = getParent(event);
138  auto [thinnedCollection, thinnedRefProd] = getThinned(event);
139  auto associationCollection = getAssociation(event);
141 
143  if (associationCollection->parentCollectionID() != parentCollection.id()) {
144  throw cms::Exception("TestFailure") << "analyze parent ProductID is not correct";
145  }
146  }
147 
149  if (associationCollection->thinnedCollectionID() != thinnedCollection.id()) {
150  throw cms::Exception("TestFailure") << "analyze thinned ProductID is not correct";
151  }
152  }
153 
154  int const eventOffset = static_cast<int>(event.eventAuxiliary().event() * 100 + 100);
155 
156  std::vector<int>::const_iterator expectedValue = expectedValues_.begin();
157  for (auto const& track : *trackCollection) {
158  testRefToParent(track.ref1, "ref1", *expectedValue, eventOffset);
159  if (not thinnedWasDropped_) {
160  testRefToThinned(edm::thinnedRefFrom(track.ref1, thinnedRefProd, event.productGetter()),
161  "ref1",
162  *expectedValue,
163  eventOffset,
164  thinnedCollection.id());
165  }
166  testRefToParent(track.refToBase1, "refToBase1", *expectedValue, eventOffset);
167  incrementExpectedValue(expectedValue);
168 
169  testRefToParent(track.ref2, "ref2", *expectedValue, eventOffset);
170  if (not thinnedWasDropped_) {
171  testRefToThinned(edm::thinnedRefFrom(track.ref2, thinnedRefProd, event.productGetter()),
172  "ref2",
173  *expectedValue,
174  eventOffset,
175  thinnedCollection.id());
176  }
177  incrementExpectedValue(expectedValue);
178 
179  testRefToParent(track.ptr1, "ptr1", *expectedValue, eventOffset);
180  incrementExpectedValue(expectedValue);
181 
182  testRefToParent(track.ptr2, "ptr2", *expectedValue, eventOffset);
183  incrementExpectedValue(expectedValue);
184 
185  testVectors(track, thinnedRefProd, event.productGetter(), eventOffset);
186  }
187  }
188 
190  auto parentCollection = event.getHandle(parentToken_);
191 
192  unsigned int i = 0;
193  if (parentWasDropped_) {
194  if (parentCollection.isValid()) {
195  throw cms::Exception("TestFailure") << "parent collection present, should have been dropped";
196  }
197  } else if (!expectedParentContent_.empty()) {
198  if (parentCollection->size() != expectedParentContent_.size()) {
199  throw cms::Exception("TestFailure") << "parent collection has unexpected size, got " << parentCollection->size()
200  << " expected " << expectedParentContent_.size();
201  }
202  for (auto const& thing : *parentCollection) {
203  // Just some numbers that match the somewhat arbitrary values put in
204  // by the ThingProducer.
205  int expected = static_cast<int>(expectedParentContent_.at(i) + event.eventAuxiliary().event() * 100 + 100) *
207  if (thing.a != expected) {
208  throw cms::Exception("TestFailure")
209  << "parent collection has unexpected content, got " << thing.a << " expected " << expected;
210  }
211  ++i;
212  }
213  }
214 
215  return parentCollection;
216  }
217 
218  std::tuple<edm::Handle<ThingCollection>, edm::RefProd<ThingCollection>> ThinningTestAnalyzer::getThinned(
219  edm::Event const& event) const {
220  auto thinnedCollection = event.getHandle(thinnedToken_);
221 
222  // Check to see the content is what we expect based on what was written
223  // by ThingProducer and TrackOfThingsProducer. The values are somewhat
224  // arbitrary and meaningless.
225  edm::RefProd<ThingCollection> thinnedRefProd;
226  if (thinnedWasDropped_) {
227  if (thinnedCollection.isValid()) {
228  throw cms::Exception("TestFailure") << "thinned collection present, should have been dropped";
229  }
230  } else {
231  thinnedRefProd = edm::RefProd<ThingCollection>{thinnedCollection};
232  unsigned expectedIndex = 0;
233  if (thinnedCollection->size() != expectedThinnedContent_.size()) {
234  throw cms::Exception("TestFailure")
235  << "thinned collection has unexpected size, got " << thinnedCollection->size() << " expected "
236  << expectedThinnedContent_.size();
237  }
238  for (auto const& thing : *thinnedCollection) {
239  const int expected = (expectedThinnedContent_.at(expectedIndex) + event.eventAuxiliary().event() * 100 + 100) *
241  if (thing.a != expected) {
242  throw cms::Exception("TestFailure")
243  << "thinned collection has unexpected content, got " << thing.a << " expected " << expected;
244  }
245  ++expectedIndex;
246  }
247  }
248  return std::tuple(thinnedCollection, thinnedRefProd);
249  }
250 
252  auto associationCollection = event.getHandle(associationToken_);
253  if (associationShouldBeDropped_ && associationCollection.isValid()) {
254  throw cms::Exception("TestFailure") << "association collection should have been dropped but was not";
255  }
257  unsigned int expectedIndex = 0;
258  if (associationCollection->indexesIntoParent().size() != expectedIndexesIntoParent_.size()) {
259  throw cms::Exception("TestFailure") << "association collection has unexpected size";
260  }
261  for (auto const& association : associationCollection->indexesIntoParent()) {
262  if (association != expectedIndexesIntoParent_.at(expectedIndex)) {
263  throw cms::Exception("TestFailure")
264  << "association collection has unexpected content, for index " << expectedIndex << " got " << association
265  << " expected " << expectedIndexesIntoParent_.at(expectedIndex);
266  }
267  ++expectedIndex;
268  }
269  }
270  return associationCollection;
271  }
272 
274  auto trackCollection = event.getHandle(trackToken_);
275  if (trackCollection->size() != 5u) {
276  throw cms::Exception("TestFailure") << "unexpected Track size";
277  }
278  return trackCollection;
279  }
280 
281  template <typename RefT>
283  std::string_view refName,
284  int const expectedValue,
285  int const eventOffset) const {
286  if (not refToParentIsAvailable_ or expectedValue == -1) {
287  if (ref.isAvailable()) {
288  throw cms::Exception("TestFailure")
289  << refName << " is available when it should not be, refers to " << ref.id() << " key " << ref.key();
290  }
291  } else {
292  if (!ref.isAvailable()) {
293  throw cms::Exception("TestFailure") << refName << " is not available when it should be";
294  }
295  // Check twice to test some possible caching problems.
296  const int expected = (expectedValue + eventOffset) * refSlimmedValueFactor_;
297  if (ref->a != expected) {
298  throw cms::Exception("TestFailure")
299  << "Unexpected values from " << refName << ", got " << ref->a << " expected " << expected;
300  }
301  if (ref->a != expected) {
302  throw cms::Exception("TestFailure")
303  << "Unexpected values from " << refName << " (2nd try), got " << ref->a << " expected " << expected;
304  }
305  }
306  }
307 
308  template <typename RefT>
309  void ThinningTestAnalyzer::testRefToThinned(RefT const& refToThinned,
310  std::string_view refName,
311  int const expectedValue,
312  int const eventOffset,
313  edm::ProductID const thinnedCollectionID) const {
314  if (expectedValue == -1) {
315  if (refToThinned.isNonnull()) {
316  throw cms::Exception("TestFailure") << "thinnedRefFrom(" << refName << ") is non-null when it should be null";
317  }
318  if (refToThinned.isAvailable()) {
319  throw cms::Exception("TestFailure") << "thinnedRefFrom(" << refName << ") is available when it should not be";
320  }
321  } else {
322  if (refToThinned.isNull()) {
323  throw cms::Exception("TestFailure") << "thinnedRefFrom(" << refName << ") is null when it should not be";
324  }
325  if (refToThinned.id() != thinnedCollectionID) {
326  throw cms::Exception("TestFailure") << "thinnedRefFrom(" << refName << ").id() " << refToThinned.id()
327  << " differs from expectation " << thinnedCollectionID;
328  }
329  if (not refToThinned.isAvailable()) {
330  throw cms::Exception("TestFailure") << "thinnedRefFrom(" << refName << ") is not available when it should be";
331  }
332  // Check twice to test some possible caching problems.
333  // need to account for slimming because going through an explicit ref-to-slimmed
334  const int expected = (expectedValue + eventOffset) * thinnedSlimmedValueFactor_;
335  if (refToThinned->a != expected) {
336  throw cms::Exception("TestFailure") << "Unexpected values from thinnedRefFrom(" << refName << "), got "
337  << refToThinned->a << " expected " << expected;
338  }
339  if (refToThinned->a != expected) {
340  throw cms::Exception("TestFailure") << "Unexpected values from thinnedRefFrom(" << refName << ") (2nd try) "
341  << refToThinned->a << " expected " << expected;
342  }
343  }
344  }
345 
346  void ThinningTestAnalyzer::testVectors(TrackOfThings const& track,
347  edm::RefProd<ThingCollection> const& thinnedRefProd,
349  int const eventOffset) const {
350  // Test RefVector, PtrVector, and RefToBaseVector
351  unsigned int k = 0;
352  bool allPresent = true;
353  for (auto iExpectedValue : expectedValues_) {
354  if (iExpectedValue != -1) {
355  if (not thinnedWasDropped_) {
356  auto refToThinned = edm::thinnedRefFrom(track.refVector1[k], thinnedRefProd, productGetter);
357  // need to account for slimming because going through an explicit ref-to-slimmed
358  const int expected = (iExpectedValue + eventOffset) * thinnedSlimmedValueFactor_;
359  if (refToThinned->a != expected) {
360  throw cms::Exception("TestFailure") << "unexpected values from thinnedRefFrom(refVector1), got "
361  << refToThinned->a << " expected " << expected;
362  }
363  }
365  const int expected = (iExpectedValue + eventOffset) * refSlimmedValueFactor_;
366  if (track.refVector1[k]->a != expected) {
367  throw cms::Exception("TestFailure")
368  << "unexpected values from refVector1, got " << track.refVector1[k]->a << " expected " << expected;
369  }
370  if (track.ptrVector1[k]->a != expected) {
371  throw cms::Exception("TestFailure") << "unexpected values from ptrVector1";
372  }
373  if (track.refToBaseVector1[k]->a != expected) {
374  throw cms::Exception("TestFailure") << "unexpected values from refToBaseVector1";
375  }
376  }
377  } else {
378  allPresent = false;
379  }
380  ++k;
381  }
382 
383  if (refToParentIsAvailable_ and allPresent) {
384  if (!track.refVector1.isAvailable()) {
385  throw cms::Exception("TestFailure") << "unexpected value (false) from refVector::isAvailable";
386  }
387  if (!track.ptrVector1.isAvailable()) {
388  throw cms::Exception("TestFailure") << "unexpected value (false) from ptrVector::isAvailable";
389  }
390  if (!track.refToBaseVector1.isAvailable()) {
391  throw cms::Exception("TestFailure") << "unexpected value (false) from refToBaseVector::isAvailable";
392  }
393  } else {
394  if (track.refVector1.isAvailable()) {
395  throw cms::Exception("TestFailure") << "unexpected value (true) from refVector::isAvailable";
396  }
397  if (track.ptrVector1.isAvailable()) {
398  throw cms::Exception("TestFailure") << "unexpected value (true) from ptrVector::isAvailable";
399  }
400  if (track.refToBaseVector1.isAvailable()) {
401  throw cms::Exception("TestFailure") << "unexpected value (true) from refToBaseVector::isAvailable";
402  }
403  }
404  k = 0;
405  for (auto iExpectedValue : expectedValues_) {
406  if (refToParentIsAvailable_ and iExpectedValue != -1) {
407  const int expected = (iExpectedValue + eventOffset) * refSlimmedValueFactor_;
408  if (track.refVector1[k]->a != expected) {
409  throw cms::Exception("TestFailure")
410  << "unexpected values from refVector1, got " << track.refVector1[k]->a << " expected " << expected;
411  }
412  if (track.ptrVector1[k]->a != expected) {
413  throw cms::Exception("TestFailure") << "unexpected values from ptrVector1";
414  }
415  if (track.refToBaseVector1[k]->a != expected) {
416  throw cms::Exception("TestFailure") << "unexpected values from refToBaseVector1";
417  }
418  } else {
419  allPresent = false;
420  }
421  ++k;
422  }
423  }
424 
425  void ThinningTestAnalyzer::incrementExpectedValue(std::vector<int>::const_iterator& iter) const {
426  ++iter;
427  if (iter == expectedValues_.end())
428  iter = expectedValues_.begin();
429  }
430 } // namespace edmtest
void analyze(edm::StreamID, edm::Event const &e, edm::EventSetup const &c) const override
ret
prodAgent to be discontinued
edm::EDGetTokenT< ThingCollection > thinnedToken_
std::vector< int > expectedThinnedContent_
edm::Handle< TrackOfThingsCollection > getTrackCollection(edm::Event const &event) const
edm::EDGetTokenT< TrackOfThingsCollection > trackToken_
std::vector< int > expectedParentContent_
edm::EDGetTokenT< ThingCollection > parentToken_
void addDefault(ParameterSetDescription const &psetDescription)
std::tuple< layerClusterToCaloParticle, caloParticleToLayerCluster > association
The Signals That Services Can Subscribe To This is based on ActivityRegistry and is current per Services can connect to the signals distributed by the ActivityRegistry in order to monitor the activity of the application Each possible callback has some defined which we here list in angle e< void, edm::EventID const &, edm::Timestamp const & > We also list in braces which AR_WATCH_USING_METHOD_ is used for those or
Definition: Activities.doc:12
void incrementExpectedValue(std::vector< int >::const_iterator &iter) const
void testVectors(TrackOfThings const &track, edm::RefProd< ThingCollection > const &thinnedRefProd, edm::EDProductGetter const &productGetter, int const eventOffset) const
edm::Handle< ThingCollection > getParent(edm::Event const &event) const
#define DEFINE_FWK_MODULE(type)
Definition: MakerMacros.h:16
edm::Handle< edm::ThinnedAssociation > getAssociation(edm::Event const &event) const
trackCollection
Definition: JetHT_cfg.py:51
Ref< C, T, F > thinnedRefFrom(Ref< C, T, F > const &parent, RefProd< C > const &thinned, edm::EDProductGetter const &prodGetter)
Return a Ref to thinned collection corresponding to an element of the Ref to parent collection...
Definition: RefItemGet.h:129
std::vector< unsigned int > expectedIndexesIntoParent_
void testRefToThinned(RefT const &ref, std::string_view refName, int const expectedValue, int const eventOffset, edm::ProductID const thinnedCollectionID) const
void testRefToParent(RefT const &ref, std::string_view refName, int const expectedValue, int const eventOffset) const
static void fillDescriptions(edm::ConfigurationDescriptions &descriptions)
edm::EDGetTokenT< edm::ThinnedAssociation > associationToken_
ThinningTestAnalyzer(edm::ParameterSet const &pset)
EDProductGetter const * productGetter(std::atomic< void const *> const &iCache)
std::tuple< edm::Handle< ThingCollection >, edm::RefProd< ThingCollection > > getThinned(edm::Event const &event) const
Definition: event.py:1