File indexing completed on 2024-09-22 22:37:09
0001 #include "FWCore/Framework/interface/global/EDAnalyzer.h"
0002
0003 #include "FWCore/Framework/interface/Event.h"
0004 #include "FWCore/Framework/interface/EventSetup.h"
0005 #include "FWCore/ParameterSet/interface/ParameterSet.h"
0006 #include "FWCore/Utilities/interface/EDGetToken.h"
0007 #include "FWCore/Utilities/interface/Exception.h"
0008 #include "FWCore/Utilities/interface/InputTag.h"
0009 #include "FWCore/Utilities/interface/transform.h"
0010 #include "FWCore/Framework/interface/MakerMacros.h"
0011 #include "FWCore/ParameterSet/interface/ConfigurationDescriptions.h"
0012 #include "FWCore/ParameterSet/interface/ParameterSetDescription.h"
0013 #include "DataFormats/Common/interface/DetSetVectorNew.h"
0014 #include "DataFormats/Common/interface/ThinnedAssociation.h"
0015 #include "DataFormats/TestObjects/interface/Thing.h"
0016 #include "DataFormats/TestObjects/interface/TrackOfDSVThings.h"
0017 #include "DataFormats/Provenance/interface/ProductID.h"
0018
0019 #include <vector>
0020
0021 namespace edmtest {
0022
0023 class ThinningDSVTestAnalyzer : public edm::global::EDAnalyzer<> {
0024 public:
0025 explicit ThinningDSVTestAnalyzer(edm::ParameterSet const& pset);
0026
0027 static void fillDescriptions(edm::ConfigurationDescriptions& descriptions);
0028
0029 void analyze(edm::StreamID, edm::Event const& e, edm::EventSetup const& c) const override;
0030
0031 private:
0032 void incrementExpectedValue(std::vector<int>::const_iterator& iter) const;
0033
0034 edm::EDGetTokenT<edmNew::DetSetVector<Thing>> parentToken_;
0035 edm::EDGetTokenT<edmNew::DetSetVector<Thing>> thinnedToken_;
0036 edm::EDGetTokenT<edm::ThinnedAssociation> associationToken_;
0037 edm::EDGetTokenT<TrackOfDSVThingsCollection> trackToken_;
0038
0039 struct DSContent {
0040 unsigned int id;
0041 std::vector<int> values;
0042 };
0043
0044 bool parentWasDropped_;
0045 std::vector<DSContent> expectedParentContent_;
0046 bool thinnedWasDropped_;
0047 bool thinnedIsAlias_;
0048 bool refToParentIsAvailable_;
0049 std::vector<DSContent> expectedThinnedContent_;
0050 std::vector<unsigned int> expectedIndexesIntoParent_;
0051 bool associationShouldBeDropped_;
0052 unsigned int expectedNumberOfTracks_;
0053 std::vector<int> expectedValues_;
0054 int parentSlimmedValueFactor_;
0055 int thinnedSlimmedValueFactor_;
0056 int refSlimmedValueFactor_;
0057 };
0058
0059 ThinningDSVTestAnalyzer::ThinningDSVTestAnalyzer(edm::ParameterSet const& pset)
0060 : parentToken_(consumes<edmNew::DetSetVector<Thing>>(pset.getParameter<edm::InputTag>("parentTag"))),
0061 thinnedToken_(consumes<edmNew::DetSetVector<Thing>>(pset.getParameter<edm::InputTag>("thinnedTag"))),
0062 associationToken_(consumes<edm::ThinnedAssociation>(pset.getParameter<edm::InputTag>("associationTag"))),
0063 trackToken_(consumes<TrackOfDSVThingsCollection>(pset.getParameter<edm::InputTag>("trackTag"))),
0064 parentWasDropped_(pset.getParameter<bool>("parentWasDropped")),
0065 thinnedWasDropped_(pset.getParameter<bool>("thinnedWasDropped")),
0066 thinnedIsAlias_(pset.getParameter<bool>("thinnedIsAlias")),
0067 refToParentIsAvailable_(pset.getParameter<bool>("refToParentIsAvailable")),
0068 associationShouldBeDropped_(pset.getParameter<bool>("associationShouldBeDropped")),
0069 expectedNumberOfTracks_(pset.getParameter<unsigned int>("expectedNumberOfTracks")),
0070 expectedValues_(pset.getParameter<std::vector<int>>("expectedValues")) {
0071 auto makeDSContent = [](edm::ParameterSet const& p) {
0072 return DSContent{p.getParameter<unsigned int>("id"), p.getParameter<std::vector<int>>("values")};
0073 };
0074 if (!parentWasDropped_) {
0075 expectedParentContent_ = edm::vector_transform(
0076 pset.getParameter<std::vector<edm::ParameterSet>>("expectedParentContent"), makeDSContent);
0077 }
0078 if (!thinnedWasDropped_) {
0079 expectedThinnedContent_ = edm::vector_transform(
0080 pset.getParameter<std::vector<edm::ParameterSet>>("expectedThinnedContent"), makeDSContent);
0081 }
0082 if (!associationShouldBeDropped_) {
0083 expectedIndexesIntoParent_ = pset.getParameter<std::vector<unsigned int>>("expectedIndexesIntoParent");
0084 }
0085
0086 auto slimmedFactor = [](int count, int factor) {
0087 int ret = 1;
0088 for (int i = 0; i < count; ++i) {
0089 ret *= factor;
0090 }
0091 return ret;
0092 };
0093 int const slimmedValueFactor = pset.getParameter<int>("slimmedValueFactor");
0094 parentSlimmedValueFactor_ = slimmedFactor(pset.getParameter<int>("parentSlimmedCount"), slimmedValueFactor);
0095 thinnedSlimmedValueFactor_ = slimmedFactor(pset.getParameter<int>("thinnedSlimmedCount"), slimmedValueFactor);
0096 refSlimmedValueFactor_ = slimmedFactor(pset.getParameter<int>("refSlimmedCount"), slimmedValueFactor);
0097 }
0098
0099 void ThinningDSVTestAnalyzer::fillDescriptions(edm::ConfigurationDescriptions& descriptions) {
0100 edm::ParameterSetDescription desc;
0101 desc.add<edm::InputTag>("parentTag");
0102 desc.add<edm::InputTag>("thinnedTag");
0103 desc.add<edm::InputTag>("associationTag");
0104 desc.add<edm::InputTag>("trackTag");
0105 desc.add<bool>("parentWasDropped", false);
0106 desc.add<bool>("thinnedWasDropped", false);
0107 desc.add<bool>("thinnedIsAlias", false);
0108 desc.add<bool>("refToParentIsAvailable", true)
0109 ->setComment(
0110 "If Ref-to-parent is generally available. With thinnedRefFrom it may happen that the Ref-to-parent is not "
0111 "available, but the Ref-to-thinned is. In such case this parameter should be set to 'False', and the "
0112 "'expectedValues' should be set to correspond the values via Ref-to-thinned.");
0113 std::vector<int> defaultV;
0114 std::vector<unsigned int> defaultVU;
0115 std::vector<edm::ParameterSet> defaultVPSet;
0116 edm::ParameterSetDescription dsValidator;
0117 dsValidator.add<unsigned int>("id");
0118 dsValidator.add<std::vector<int>>("values", defaultV);
0119 desc.addVPSet("expectedParentContent", dsValidator, defaultVPSet);
0120 desc.addVPSet("expectedThinnedContent", dsValidator, defaultVPSet);
0121 desc.add<std::vector<unsigned int>>("expectedIndexesIntoParent", defaultVU);
0122 desc.add<bool>("associationShouldBeDropped", false);
0123 desc.add<unsigned int>("expectedNumberOfTracks", 5);
0124 desc.add<std::vector<int>>("expectedValues");
0125 desc.add<int>("parentSlimmedCount", 0);
0126 desc.add<int>("thinnedSlimmedCount", 0);
0127 desc.add<int>("refSlimmedCount", 0);
0128 desc.add<int>("slimmedValueFactor", 10);
0129 descriptions.addDefault(desc);
0130 }
0131
0132 void ThinningDSVTestAnalyzer::analyze(edm::StreamID, edm::Event const& event, edm::EventSetup const&) const {
0133 auto parentCollection = event.getHandle(parentToken_);
0134 auto thinnedCollection = event.getHandle(thinnedToken_);
0135 auto associationCollection = event.getHandle(associationToken_);
0136 auto trackCollection = event.getHandle(trackToken_);
0137
0138 if (parentWasDropped_) {
0139 if (parentCollection.isValid()) {
0140 throw cms::Exception("TestFailure") << "parent collection present, should have been dropped";
0141 }
0142 } else if (!expectedParentContent_.empty()) {
0143 if (parentCollection->size() != expectedParentContent_.size()) {
0144 throw cms::Exception("TestFailure") << "parent collection has unexpected size, got " << parentCollection->size()
0145 << " expected " << expectedParentContent_.size();
0146 }
0147
0148 auto iExpected = expectedParentContent_.begin();
0149 for (auto const& detset : *parentCollection) {
0150 auto const& expectedContent = *iExpected;
0151 ++iExpected;
0152
0153 if (detset.id() != expectedContent.id) {
0154 throw cms::Exception("TestFailure")
0155 << "parent collection detset has unexpected id " << detset.id() << " expected " << expectedContent.id;
0156 }
0157 if (detset.size() != expectedContent.values.size()) {
0158 throw cms::Exception("TestFailure")
0159 << "parent collection detset with id " << detset.id() << " has unexpected size, got " << detset.size()
0160 << " expected " << expectedContent.values.size();
0161 }
0162 auto iValue = expectedContent.values.begin();
0163 for (auto const& thing : detset) {
0164
0165
0166 int expected =
0167 static_cast<int>(*iValue + (event.eventAuxiliary().event() - 1) * 100) * parentSlimmedValueFactor_;
0168 if (thing.a != expected) {
0169 throw cms::Exception("TestFailure")
0170 << "parent collection has unexpected content for detset with id " << detset.id() << ", got " << thing.a
0171 << " expected " << expected << " (element " << std::distance(expectedContent.values.begin(), iValue)
0172 << ")";
0173 }
0174 ++iValue;
0175 }
0176 }
0177 }
0178
0179
0180
0181
0182 edm::RefProd<edmNew::DetSetVector<Thing>> thinnedRefProd;
0183 if (thinnedWasDropped_) {
0184 if (thinnedCollection.isValid()) {
0185 throw cms::Exception("TestFailure") << "thinned collection present, should have been dropped";
0186 }
0187 } else {
0188 thinnedRefProd = edm::RefProd<edmNew::DetSetVector<Thing>>{thinnedCollection};
0189 if (thinnedCollection->size() != expectedThinnedContent_.size()) {
0190 throw cms::Exception("TestFailure")
0191 << "thinned collection has unexpected size, got " << thinnedCollection->size() << " expected "
0192 << expectedThinnedContent_.size();
0193 }
0194
0195 auto iExpected = expectedThinnedContent_.begin();
0196 for (auto const& detset : *thinnedCollection) {
0197 auto const& expectedContent = *iExpected;
0198 ++iExpected;
0199
0200 if (detset.id() != expectedContent.id) {
0201 throw cms::Exception("TestFailure")
0202 << "thinned collection detset has unexpected id " << detset.id() << " expected " << expectedContent.id;
0203 }
0204 if (detset.size() != expectedContent.values.size()) {
0205 throw cms::Exception("TestFailure")
0206 << "thinned collection detset with id " << detset.id() << " has unexpected size, got " << detset.size()
0207 << " expected " << expectedContent.values.size();
0208 }
0209 auto iValue = expectedContent.values.begin();
0210 for (auto const& thing : detset) {
0211 int expected =
0212 static_cast<int>(*iValue + (event.eventAuxiliary().event() - 1) * 100) * thinnedSlimmedValueFactor_;
0213 if (thing.a != expected) {
0214 throw cms::Exception("TestFailure")
0215 << "thinned collection has unexpected content for detset with id " << detset.id() << ", got " << thing.a
0216 << " expected " << expected << " (element " << std::distance(expectedContent.values.begin(), iValue)
0217 << ")";
0218 }
0219 ++iValue;
0220 }
0221 }
0222 }
0223
0224 if (associationShouldBeDropped_ && associationCollection.isValid()) {
0225 throw cms::Exception("TestFailure") << "association collection should have been dropped but was not";
0226 }
0227 if (!associationShouldBeDropped_) {
0228 unsigned int expectedIndex = 0;
0229 if (associationCollection->indexesIntoParent().size() != expectedIndexesIntoParent_.size()) {
0230 throw cms::Exception("TestFailure")
0231 << "association collection has unexpected size " << associationCollection->indexesIntoParent().size()
0232 << " expected " << expectedIndexesIntoParent_.size();
0233 }
0234 for (auto const& association : associationCollection->indexesIntoParent()) {
0235 if (association != expectedIndexesIntoParent_.at(expectedIndex)) {
0236 throw cms::Exception("TestFailure")
0237 << "association collection has unexpected content, for index " << expectedIndex << " got " << association
0238 << " expected " << expectedIndexesIntoParent_.at(expectedIndex);
0239 }
0240 ++expectedIndex;
0241 }
0242 }
0243
0244 if (!parentWasDropped_ && !associationShouldBeDropped_) {
0245 if (associationCollection->parentCollectionID() != parentCollection.id()) {
0246 throw cms::Exception("TestFailure") << "analyze parent ProductID is not correct";
0247 }
0248 }
0249
0250 if (!thinnedWasDropped_ && !associationShouldBeDropped_) {
0251 if (associationCollection->thinnedCollectionID() != thinnedCollection.id()) {
0252 throw cms::Exception("TestFailure") << "analyze thinned ProductID is not correct";
0253 }
0254 }
0255
0256 if (trackCollection->size() != expectedNumberOfTracks_) {
0257 throw cms::Exception("TestFailure")
0258 << "unexpected Track size " << trackCollection->size() << " expected " << expectedNumberOfTracks_;
0259 }
0260
0261 if (expectedValues_.empty()) {
0262 return;
0263 }
0264
0265 int eventOffset = (static_cast<int>(event.eventAuxiliary().event()) - 1) * 100;
0266
0267 std::vector<int>::const_iterator expectedValue = expectedValues_.begin();
0268 for (auto const& track : *trackCollection) {
0269 if (not refToParentIsAvailable_ or *expectedValue == -1) {
0270 if (track.ref1.isAvailable()) {
0271 throw cms::Exception("TestFailure") << "ref1 is available when it should not be, refers to "
0272 << track.ref1.id() << " key " << track.ref1.key();
0273 }
0274 } else {
0275 if (!track.ref1.isAvailable()) {
0276 throw cms::Exception("TestFailure") << "ref1 is not available when it should be";
0277 }
0278
0279 const int expected = (*expectedValue + eventOffset) * refSlimmedValueFactor_;
0280 if (track.ref1->a != expected) {
0281 throw cms::Exception("TestFailure")
0282 << "Unexpected values from ref1, got " << track.ref1->a << " expected " << expected;
0283 }
0284 if (track.ref1->a != expected) {
0285 throw cms::Exception("TestFailure")
0286 << "Unexpected values from ref1 (2nd try), got " << track.ref1->a << " expected " << expected;
0287 ;
0288 }
0289 }
0290
0291 if (not thinnedWasDropped_) {
0292 auto refToThinned = edm::thinnedRefFrom(track.ref1, thinnedRefProd, event.productGetter());
0293 if (*expectedValue == -1) {
0294 if (refToThinned.isNonnull()) {
0295 throw cms::Exception("TestFailure") << "thinnedRefFrom(ref1) is non-null when it should be null";
0296 }
0297 if (refToThinned.isAvailable()) {
0298 throw cms::Exception("TestFailure") << "thinnedRefFrom(ref1) is available when it should not be";
0299 }
0300 } else {
0301 if (refToThinned.isNull()) {
0302 throw cms::Exception("TestFailure") << "thinnedRefFrom(ref1) is null when it should not be";
0303 }
0304 if (refToThinned.id() != thinnedCollection.id()) {
0305 throw cms::Exception("TestFailure") << "thinnedRefFrom(ref).id() " << refToThinned.id()
0306 << " differs from expectation " << thinnedCollection.id();
0307 }
0308 if (not refToThinned.isAvailable()) {
0309 throw cms::Exception("TestFailure") << "thinnedRefFrom(ref1) is not available when it should be";
0310 }
0311
0312
0313 const int expected = (*expectedValue + eventOffset) * thinnedSlimmedValueFactor_;
0314 if (refToThinned->a != expected) {
0315 throw cms::Exception("TestFailure")
0316 << "Unexpected values from thinnedRefFrom(ref1), got " << refToThinned->a << " expected " << expected;
0317 }
0318 if (refToThinned->a != expected) {
0319 throw cms::Exception("TestFailure") << "Unexpected values from thinnedRefFrom(ref1) (2nd try) "
0320 << refToThinned->a << " expected " << expected;
0321 }
0322 }
0323 }
0324 incrementExpectedValue(expectedValue);
0325
0326 if (not refToParentIsAvailable_ or *expectedValue == -1) {
0327 if (track.ref2.isAvailable()) {
0328 throw cms::Exception("TestFailure") << "ref2 is available when it should not be";
0329 }
0330 } else {
0331 if (!track.ref2.isAvailable()) {
0332 throw cms::Exception("TestFailure") << "ref2 is not available when it should be";
0333 }
0334
0335 const int expected = (*expectedValue + eventOffset) * refSlimmedValueFactor_;
0336 if (track.ref2->a != expected) {
0337 throw cms::Exception("TestFailure")
0338 << "unexpected values from ref2, got " << track.ref2->a << " expected " << expected;
0339 }
0340 if (track.ref2->a != expected) {
0341 throw cms::Exception("TestFailure")
0342 << "unexpected values from ref2 (2nd try), got " << track.ref2->a << " expected " << expected;
0343 }
0344 }
0345
0346 if (not thinnedWasDropped_) {
0347 auto refToThinned = edm::thinnedRefFrom(track.ref2, thinnedRefProd, event.productGetter());
0348 if (*expectedValue == -1) {
0349 if (refToThinned.isNonnull()) {
0350 throw cms::Exception("TestFailure") << "thinnedRefFrom(ref2) is non-null when it should be null";
0351 }
0352 if (refToThinned.isAvailable()) {
0353 throw cms::Exception("TestFailure") << "thinnedRefFrom(ref2) is available when it should not be";
0354 }
0355 } else {
0356 if (refToThinned.isNull()) {
0357 throw cms::Exception("TestFailure") << "thinnedRefFrom(ref2) is null when it should not be";
0358 }
0359 if (refToThinned.id() != thinnedCollection.id()) {
0360 throw cms::Exception("TestFailure") << "thinnedRefFrom(ref2).id() " << refToThinned.id()
0361 << " differs from expectation " << thinnedCollection.id();
0362 }
0363 if (not refToThinned.isAvailable()) {
0364 throw cms::Exception("TestFailure") << "thinnedRefFrom(ref2) is not available when it should be";
0365 }
0366
0367
0368 const int expected = (*expectedValue + eventOffset) * thinnedSlimmedValueFactor_;
0369 if (refToThinned->a != expected) {
0370 throw cms::Exception("TestFailure")
0371 << "Unexpected values from thinnedRefFrom(ref2), got " << refToThinned->a << " expected " << expected;
0372 }
0373 if (refToThinned->a != expected) {
0374 throw cms::Exception("TestFailure") << "Unexpected values from thinnedRefFrom(ref2) (2nd try), got "
0375 << refToThinned->a << " expected " << expected;
0376 }
0377 }
0378 }
0379
0380 incrementExpectedValue(expectedValue);
0381
0382
0383 unsigned int k = 0;
0384 bool allPresent = true;
0385 for (auto iExpectedValue : expectedValues_) {
0386 if (iExpectedValue != -1) {
0387 if (not thinnedWasDropped_) {
0388 auto refToThinned = edm::thinnedRefFrom(track.refVector1[k], thinnedRefProd, event.productGetter());
0389
0390 const int expected = (iExpectedValue + eventOffset) * thinnedSlimmedValueFactor_;
0391 if (refToThinned->a != expected) {
0392 throw cms::Exception("TestFailure") << "unexpected values from thinnedRefFrom(refVector1), got "
0393 << refToThinned->a << " expected " << expected;
0394 }
0395 }
0396 if (refToParentIsAvailable_) {
0397 const int expected = (iExpectedValue + eventOffset) * refSlimmedValueFactor_;
0398 if (track.refVector1[k]->a != expected) {
0399 throw cms::Exception("TestFailure")
0400 << "unexpected values from refVector1, got " << track.refVector1[k]->a << " expected " << expected;
0401 }
0402 }
0403 } else {
0404 allPresent = false;
0405 }
0406 ++k;
0407 }
0408
0409 if (refToParentIsAvailable_ and allPresent) {
0410 if (!track.refVector1.isAvailable()) {
0411 throw cms::Exception("TestFailure") << "unexpected value (false) from refVector::isAvailable";
0412 }
0413 } else {
0414 if (track.refVector1.isAvailable()) {
0415 throw cms::Exception("TestFailure") << "unexpected value (true) from refVector::isAvailable";
0416 }
0417 }
0418 }
0419 }
0420
0421 void ThinningDSVTestAnalyzer::incrementExpectedValue(std::vector<int>::const_iterator& iter) const {
0422 ++iter;
0423 if (iter == expectedValues_.end())
0424 iter = expectedValues_.begin();
0425 }
0426 }
0427 using edmtest::ThinningDSVTestAnalyzer;
0428 DEFINE_FWK_MODULE(ThinningDSVTestAnalyzer);