CMS 3D CMS Logo

ThinningDSVTestAnalyzer.cc
Go to the documentation of this file.
2 
15 #include "DataFormats/TestObjects/interface/Thing.h"
16 #include "DataFormats/TestObjects/interface/TrackOfDSVThings.h"
18 
19 #include <vector>
20 
21 namespace edmtest {
22 
24  public:
26 
27  static void fillDescriptions(edm::ConfigurationDescriptions& descriptions);
28 
29  void analyze(edm::StreamID, edm::Event const& e, edm::EventSetup const& c) const override;
30 
31  private:
32  void incrementExpectedValue(std::vector<int>::const_iterator& iter) const;
33 
38 
39  struct DSContent {
40  unsigned int id;
41  std::vector<int> values;
42  };
43 
45  std::vector<DSContent> expectedParentContent_;
49  std::vector<DSContent> expectedThinnedContent_;
50  std::vector<unsigned int> expectedIndexesIntoParent_;
53  std::vector<int> expectedValues_;
57  };
58 
60  : parentToken_(consumes<edmNew::DetSetVector<Thing>>(pset.getParameter<edm::InputTag>("parentTag"))),
61  thinnedToken_(consumes<edmNew::DetSetVector<Thing>>(pset.getParameter<edm::InputTag>("thinnedTag"))),
62  associationToken_(consumes<edm::ThinnedAssociation>(pset.getParameter<edm::InputTag>("associationTag"))),
63  trackToken_(consumes<TrackOfDSVThingsCollection>(pset.getParameter<edm::InputTag>("trackTag"))),
64  parentWasDropped_(pset.getParameter<bool>("parentWasDropped")),
65  thinnedWasDropped_(pset.getParameter<bool>("thinnedWasDropped")),
66  thinnedIsAlias_(pset.getParameter<bool>("thinnedIsAlias")),
67  refToParentIsAvailable_(pset.getParameter<bool>("refToParentIsAvailable")),
68  associationShouldBeDropped_(pset.getParameter<bool>("associationShouldBeDropped")),
69  expectedNumberOfTracks_(pset.getParameter<unsigned int>("expectedNumberOfTracks")),
70  expectedValues_(pset.getParameter<std::vector<int>>("expectedValues")) {
71  auto makeDSContent = [](edm::ParameterSet const& p) {
72  return DSContent{p.getParameter<unsigned int>("id"), p.getParameter<std::vector<int>>("values")};
73  };
74  if (!parentWasDropped_) {
76  pset.getParameter<std::vector<edm::ParameterSet>>("expectedParentContent"), makeDSContent);
77  }
78  if (!thinnedWasDropped_) {
80  pset.getParameter<std::vector<edm::ParameterSet>>("expectedThinnedContent"), makeDSContent);
81  }
83  expectedIndexesIntoParent_ = pset.getParameter<std::vector<unsigned int>>("expectedIndexesIntoParent");
84  }
85 
86  auto slimmedFactor = [](int count, int factor) {
87  int ret = 1;
88  for (int i = 0; i < count; ++i) {
89  ret *= factor;
90  }
91  return ret;
92  };
93  int const slimmedValueFactor = pset.getParameter<int>("slimmedValueFactor");
94  parentSlimmedValueFactor_ = slimmedFactor(pset.getParameter<int>("parentSlimmedCount"), slimmedValueFactor);
95  thinnedSlimmedValueFactor_ = slimmedFactor(pset.getParameter<int>("thinnedSlimmedCount"), slimmedValueFactor);
96  refSlimmedValueFactor_ = slimmedFactor(pset.getParameter<int>("refSlimmedCount"), slimmedValueFactor);
97  }
98 
101  desc.add<edm::InputTag>("parentTag");
102  desc.add<edm::InputTag>("thinnedTag");
103  desc.add<edm::InputTag>("associationTag");
104  desc.add<edm::InputTag>("trackTag");
105  desc.add<bool>("parentWasDropped", false);
106  desc.add<bool>("thinnedWasDropped", false);
107  desc.add<bool>("thinnedIsAlias", false);
108  desc.add<bool>("refToParentIsAvailable", true)
109  ->setComment(
110  "If Ref-to-parent is generally available. With thinnedRefFrom it may happen that the Ref-to-parent is not "
111  "available, but the Ref-to-thinned is. In such case this parameter should be set to 'False', and the "
112  "'expectedValues' should be set to correspond the values via Ref-to-thinned.");
113  std::vector<int> defaultV;
114  std::vector<unsigned int> defaultVU;
115  std::vector<edm::ParameterSet> defaultVPSet;
116  edm::ParameterSetDescription dsValidator;
117  dsValidator.add<unsigned int>("id");
118  dsValidator.add<std::vector<int>>("values", defaultV);
119  desc.addVPSet("expectedParentContent", dsValidator, defaultVPSet);
120  desc.addVPSet("expectedThinnedContent", dsValidator, defaultVPSet);
121  desc.add<std::vector<unsigned int>>("expectedIndexesIntoParent", defaultVU);
122  desc.add<bool>("associationShouldBeDropped", false);
123  desc.add<unsigned int>("expectedNumberOfTracks", 5);
124  desc.add<std::vector<int>>("expectedValues");
125  desc.add<int>("parentSlimmedCount", 0);
126  desc.add<int>("thinnedSlimmedCount", 0);
127  desc.add<int>("refSlimmedCount", 0);
128  desc.add<int>("slimmedValueFactor", 10);
129  descriptions.addDefault(desc);
130  }
131 
133  auto parentCollection = event.getHandle(parentToken_);
134  auto thinnedCollection = event.getHandle(thinnedToken_);
135  auto associationCollection = event.getHandle(associationToken_);
136  auto trackCollection = event.getHandle(trackToken_);
137 
138  if (parentWasDropped_) {
139  if (parentCollection.isValid()) {
140  throw cms::Exception("TestFailure") << "parent collection present, should have been dropped";
141  }
142  } else if (!expectedParentContent_.empty()) {
143  if (parentCollection->size() != expectedParentContent_.size()) {
144  throw cms::Exception("TestFailure") << "parent collection has unexpected size, got " << parentCollection->size()
145  << " expected " << expectedParentContent_.size();
146  }
147 
148  auto iExpected = expectedParentContent_.begin();
149  for (auto const& detset : *parentCollection) {
150  auto const& expectedContent = *iExpected;
151  ++iExpected;
152 
153  if (detset.id() != expectedContent.id) {
154  throw cms::Exception("TestFailure")
155  << "parent collection detset has unexpected id " << detset.id() << " expected " << expectedContent.id;
156  }
157  if (detset.size() != expectedContent.values.size()) {
158  throw cms::Exception("TestFailure")
159  << "parent collection detset with id " << detset.id() << " has unexpected size, got " << detset.size()
160  << " expected " << expectedContent.values.size();
161  }
162  auto iValue = expectedContent.values.begin();
163  for (auto const& thing : detset) {
164  // Just some numbers that match the somewhat arbitrary values put in
165  // by the ThingProducer.
166  int expected =
167  static_cast<int>(*iValue + (event.eventAuxiliary().event() - 1) * 100) * parentSlimmedValueFactor_;
168  if (thing.a != expected) {
169  throw cms::Exception("TestFailure")
170  << "parent collection has unexpected content for detset with id " << detset.id() << ", got " << thing.a
171  << " expected " << expected << " (element " << std::distance(expectedContent.values.begin(), iValue)
172  << ")";
173  }
174  ++iValue;
175  }
176  }
177  }
178 
179  // Check to see the content is what we expect based on what was written
180  // by ThingProducer and TrackOfThingsProducer. The values are somewhat
181  // arbitrary and meaningless.
183  if (thinnedWasDropped_) {
184  if (thinnedCollection.isValid()) {
185  throw cms::Exception("TestFailure") << "thinned collection present, should have been dropped";
186  }
187  } else {
188  thinnedRefProd = edm::RefProd<edmNew::DetSetVector<Thing>>{thinnedCollection};
189  if (thinnedCollection->size() != expectedThinnedContent_.size()) {
190  throw cms::Exception("TestFailure")
191  << "thinned collection has unexpected size, got " << thinnedCollection->size() << " expected "
192  << expectedThinnedContent_.size();
193  }
194 
195  auto iExpected = expectedThinnedContent_.begin();
196  for (auto const& detset : *thinnedCollection) {
197  auto const& expectedContent = *iExpected;
198  ++iExpected;
199 
200  if (detset.id() != expectedContent.id) {
201  throw cms::Exception("TestFailure")
202  << "thinned collection detset has unexpected id " << detset.id() << " expected " << expectedContent.id;
203  }
204  if (detset.size() != expectedContent.values.size()) {
205  throw cms::Exception("TestFailure")
206  << "thinned collection detset with id " << detset.id() << " has unexpected size, got " << detset.size()
207  << " expected " << expectedContent.values.size();
208  }
209  auto iValue = expectedContent.values.begin();
210  for (auto const& thing : detset) {
211  int expected =
212  static_cast<int>(*iValue + (event.eventAuxiliary().event() - 1) * 100) * thinnedSlimmedValueFactor_;
213  if (thing.a != expected) {
214  throw cms::Exception("TestFailure")
215  << "thinned collection has unexpected content for detset with id " << detset.id() << ", got " << thing.a
216  << " expected " << expected << " (element " << std::distance(expectedContent.values.begin(), iValue)
217  << ")";
218  }
219  ++iValue;
220  }
221  }
222  }
223 
224  if (associationShouldBeDropped_ && associationCollection.isValid()) {
225  throw cms::Exception("TestFailure") << "association collection should have been dropped but was not";
226  }
228  unsigned int expectedIndex = 0;
229  if (associationCollection->indexesIntoParent().size() != expectedIndexesIntoParent_.size()) {
230  throw cms::Exception("TestFailure")
231  << "association collection has unexpected size " << associationCollection->indexesIntoParent().size()
232  << " expected " << expectedIndexesIntoParent_.size();
233  }
234  for (auto const& association : associationCollection->indexesIntoParent()) {
235  if (association != expectedIndexesIntoParent_.at(expectedIndex)) {
236  throw cms::Exception("TestFailure")
237  << "association collection has unexpected content, for index " << expectedIndex << " got " << association
238  << " expected " << expectedIndexesIntoParent_.at(expectedIndex);
239  }
240  ++expectedIndex;
241  }
242  }
243 
245  if (associationCollection->parentCollectionID() != parentCollection.id()) {
246  throw cms::Exception("TestFailure") << "analyze parent ProductID is not correct";
247  }
248  }
249 
251  if (associationCollection->thinnedCollectionID() != thinnedCollection.id()) {
252  throw cms::Exception("TestFailure") << "analyze thinned ProductID is not correct";
253  }
254  }
255 
256  if (trackCollection->size() != expectedNumberOfTracks_) {
257  throw cms::Exception("TestFailure")
258  << "unexpected Track size " << trackCollection->size() << " expected " << expectedNumberOfTracks_;
259  }
260 
261  if (expectedValues_.empty()) {
262  return;
263  }
264 
265  int eventOffset = (static_cast<int>(event.eventAuxiliary().event()) - 1) * 100;
266 
267  std::vector<int>::const_iterator expectedValue = expectedValues_.begin();
268  for (auto const& track : *trackCollection) {
269  if (not refToParentIsAvailable_ or *expectedValue == -1) {
270  if (track.ref1.isAvailable()) {
271  throw cms::Exception("TestFailure") << "ref1 is available when it should not be, refers to "
272  << track.ref1.id() << " key " << track.ref1.key();
273  }
274  } else {
275  if (!track.ref1.isAvailable()) {
276  throw cms::Exception("TestFailure") << "ref1 is not available when it should be";
277  }
278  // Check twice to test some possible caching problems.
279  const int expected = (*expectedValue + eventOffset) * refSlimmedValueFactor_;
280  if (track.ref1->a != expected) {
281  throw cms::Exception("TestFailure")
282  << "Unexpected values from ref1, got " << track.ref1->a << " expected " << expected;
283  }
284  if (track.ref1->a != expected) {
285  throw cms::Exception("TestFailure")
286  << "Unexpected values from ref1 (2nd try), got " << track.ref1->a << " expected " << expected;
287  ;
288  }
289  }
290 
291  if (not thinnedWasDropped_) {
292  auto refToThinned = edm::thinnedRefFrom(track.ref1, thinnedRefProd, event.productGetter());
293  if (*expectedValue == -1) {
294  if (refToThinned.isNonnull()) {
295  throw cms::Exception("TestFailure") << "thinnedRefFrom(ref1) is non-null when it should be null";
296  }
297  if (refToThinned.isAvailable()) {
298  throw cms::Exception("TestFailure") << "thinnedRefFrom(ref1) is available when it should not be";
299  }
300  } else {
301  if (refToThinned.isNull()) {
302  throw cms::Exception("TestFailure") << "thinnedRefFrom(ref1) is null when it should not be";
303  }
304  if (refToThinned.id() != thinnedCollection.id()) {
305  throw cms::Exception("TestFailure") << "thinnedRefFrom(ref).id() " << refToThinned.id()
306  << " differs from expectation " << thinnedCollection.id();
307  }
308  if (not refToThinned.isAvailable()) {
309  throw cms::Exception("TestFailure") << "thinnedRefFrom(ref1) is not available when it should be";
310  }
311  // Check twice to test some possible caching problems.
312  // need to account for slimming because going through an explicit ref-to-slimmed
313  const int expected = (*expectedValue + eventOffset) * thinnedSlimmedValueFactor_;
314  if (refToThinned->a != expected) {
315  throw cms::Exception("TestFailure")
316  << "Unexpected values from thinnedRefFrom(ref1), got " << refToThinned->a << " expected " << expected;
317  }
318  if (refToThinned->a != expected) {
319  throw cms::Exception("TestFailure") << "Unexpected values from thinnedRefFrom(ref1) (2nd try) "
320  << refToThinned->a << " expected " << expected;
321  }
322  }
323  }
324  incrementExpectedValue(expectedValue);
325 
326  if (not refToParentIsAvailable_ or *expectedValue == -1) {
327  if (track.ref2.isAvailable()) {
328  throw cms::Exception("TestFailure") << "ref2 is available when it should not be";
329  }
330  } else {
331  if (!track.ref2.isAvailable()) {
332  throw cms::Exception("TestFailure") << "ref2 is not available when it should be";
333  }
334 
335  const int expected = (*expectedValue + eventOffset) * refSlimmedValueFactor_;
336  if (track.ref2->a != expected) {
337  throw cms::Exception("TestFailure")
338  << "unexpected values from ref2, got " << track.ref2->a << " expected " << expected;
339  }
340  if (track.ref2->a != expected) {
341  throw cms::Exception("TestFailure")
342  << "unexpected values from ref2 (2nd try), got " << track.ref2->a << " expected " << expected;
343  }
344  }
345 
346  if (not thinnedWasDropped_) {
347  auto refToThinned = edm::thinnedRefFrom(track.ref2, thinnedRefProd, event.productGetter());
348  if (*expectedValue == -1) {
349  if (refToThinned.isNonnull()) {
350  throw cms::Exception("TestFailure") << "thinnedRefFrom(ref2) is non-null when it should be null";
351  }
352  if (refToThinned.isAvailable()) {
353  throw cms::Exception("TestFailure") << "thinnedRefFrom(ref2) is available when it should not be";
354  }
355  } else {
356  if (refToThinned.isNull()) {
357  throw cms::Exception("TestFailure") << "thinnedRefFrom(ref2) is null when it should not be";
358  }
359  if (refToThinned.id() != thinnedCollection.id()) {
360  throw cms::Exception("TestFailure") << "thinnedRefFrom(ref2).id() " << refToThinned.id()
361  << " differs from expectation " << thinnedCollection.id();
362  }
363  if (not refToThinned.isAvailable()) {
364  throw cms::Exception("TestFailure") << "thinnedRefFrom(ref2) is not available when it should be";
365  }
366  // Check twice to test some possible caching problems.
367  // need to account for slimming because going through an explicit ref-to-slimmed
368  const int expected = (*expectedValue + eventOffset) * thinnedSlimmedValueFactor_;
369  if (refToThinned->a != expected) {
370  throw cms::Exception("TestFailure")
371  << "Unexpected values from thinnedRefFrom(ref2), got " << refToThinned->a << " expected " << expected;
372  }
373  if (refToThinned->a != expected) {
374  throw cms::Exception("TestFailure") << "Unexpected values from thinnedRefFrom(ref2) (2nd try), got "
375  << refToThinned->a << " expected " << expected;
376  }
377  }
378  }
379 
380  incrementExpectedValue(expectedValue);
381 
382  // Test RefVector
383  unsigned int k = 0;
384  bool allPresent = true;
385  for (auto iExpectedValue : expectedValues_) {
386  if (iExpectedValue != -1) {
387  if (not thinnedWasDropped_) {
388  auto refToThinned = edm::thinnedRefFrom(track.refVector1[k], thinnedRefProd, event.productGetter());
389  // need to account for slimming because going through an explicit ref-to-slimmed
390  const int expected = (iExpectedValue + eventOffset) * thinnedSlimmedValueFactor_;
391  if (refToThinned->a != expected) {
392  throw cms::Exception("TestFailure") << "unexpected values from thinnedRefFrom(refVector1), got "
393  << refToThinned->a << " expected " << expected;
394  }
395  }
397  const int expected = (iExpectedValue + eventOffset) * refSlimmedValueFactor_;
398  if (track.refVector1[k]->a != expected) {
399  throw cms::Exception("TestFailure")
400  << "unexpected values from refVector1, got " << track.refVector1[k]->a << " expected " << expected;
401  }
402  }
403  } else {
404  allPresent = false;
405  }
406  ++k;
407  }
408 
409  if (refToParentIsAvailable_ and allPresent) {
410  if (!track.refVector1.isAvailable()) {
411  throw cms::Exception("TestFailure") << "unexpected value (false) from refVector::isAvailable";
412  }
413  } else {
414  if (track.refVector1.isAvailable()) {
415  throw cms::Exception("TestFailure") << "unexpected value (true) from refVector::isAvailable";
416  }
417  }
418  k = 0;
419  for (auto iExpectedValue : expectedValues_) {
420  if (refToParentIsAvailable_ and iExpectedValue != -1) {
421  const int expected = (iExpectedValue + eventOffset) * refSlimmedValueFactor_;
422  if (track.refVector1[k]->a != expected) {
423  throw cms::Exception("TestFailure")
424  << "unexpected values from refVector1, got " << track.refVector1[k]->a << " expected " << expected;
425  }
426  } else {
427  allPresent = false;
428  }
429  ++k;
430  }
431  }
432  }
433 
434  void ThinningDSVTestAnalyzer::incrementExpectedValue(std::vector<int>::const_iterator& iter) const {
435  ++iter;
436  if (iter == expectedValues_.end())
437  iter = expectedValues_.begin();
438  }
439 } // namespace edmtest
ThinningDSVTestAnalyzer(edm::ParameterSet const &pset)
void incrementExpectedValue(std::vector< int >::const_iterator &iter) const
static void fillDescriptions(edm::ConfigurationDescriptions &descriptions)
ret
prodAgent to be discontinued
edm::EDGetTokenT< edmNew::DetSetVector< Thing > > parentToken_
auto vector_transform(std::vector< InputType > const &input, Function predicate) -> std::vector< typename std::remove_cv< typename std::remove_reference< decltype(predicate(input.front()))>::type >::type >
Definition: transform.h:11
std::tuple< layerClusterToCaloParticle, caloParticleToLayerCluster > association
void analyze(edm::StreamID, edm::Event const &e, edm::EventSetup const &c) const override
void addDefault(ParameterSetDescription const &psetDescription)
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
std::vector< DSContent > expectedThinnedContent_
edm::EDGetTokenT< edmNew::DetSetVector< Thing > > thinnedToken_
edm::EDGetTokenT< edm::ThinnedAssociation > associationToken_
#define DEFINE_FWK_MODULE(type)
Definition: MakerMacros.h:16
ParameterDescriptionBase * add(U const &iLabel, T const &value)
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< DSContent > expectedParentContent_
HLT enums.
edm::EDGetTokenT< TrackOfDSVThingsCollection > trackToken_
std::vector< unsigned int > expectedIndexesIntoParent_
Definition: event.py:1