Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2025-01-21 01:39:47

0001 
0002 // This test module will try to get IntProducts in Events,
0003 // Lumis, Runs and ProcessBlocks. The number of IntProducts
0004 // and their InputTags (label, instance, process) must be configured.
0005 
0006 // One can also configure an expected value for the sum of
0007 // all the values in the IntProducts that are found.  Note
0008 // that an IntProduct is just a test product that simply
0009 // contains a single integer.
0010 
0011 // If the expected products are not found or some other
0012 // unexpected behavior occurs, an exception will be thrown.
0013 
0014 #include "DataFormats/Common/interface/Handle.h"
0015 #include "DataFormats/Provenance/interface/Provenance.h"
0016 #include "DataFormats/TestObjects/interface/ToyProducts.h"
0017 #include "FWCore/Framework/interface/CacheHandle.h"
0018 #include "FWCore/Framework/interface/one/EDAnalyzer.h"
0019 #include "FWCore/Framework/interface/Event.h"
0020 #include "FWCore/Framework/interface/getProducerParameterSet.h"
0021 #include "FWCore/Framework/interface/GetterOfProducts.h"
0022 #include "FWCore/Framework/interface/LuminosityBlock.h"
0023 #include "FWCore/Framework/interface/MakerMacros.h"
0024 #include "FWCore/Framework/interface/moduleAbilities.h"
0025 #include "FWCore/Framework/interface/ProcessBlock.h"
0026 #include "FWCore/Framework/interface/ProcessMatch.h"
0027 #include "FWCore/Framework/interface/Run.h"
0028 #include "FWCore/ParameterSet/interface/ParameterSet.h"
0029 #include "FWCore/Utilities/interface/BranchType.h"
0030 #include "FWCore/Utilities/interface/Exception.h"
0031 #include "FWCore/Utilities/interface/InputTag.h"
0032 #include "FWCore/Utilities/interface/EDGetToken.h"
0033 
0034 #include <functional>
0035 #include <iostream>
0036 #include <memory>
0037 #include <tuple>
0038 #include <vector>
0039 
0040 namespace edmtest {
0041 
0042   class TestFindProduct : public edm::one::EDAnalyzer<edm::one::WatchRuns,
0043                                                       edm::one::WatchLuminosityBlocks,
0044                                                       edm::WatchProcessBlock,
0045                                                       edm::InputProcessBlockCache<int, long long int>> {
0046   public:
0047     explicit TestFindProduct(edm::ParameterSet const& pset);
0048     ~TestFindProduct() override;
0049 
0050     void analyze(edm::Event const& e, edm::EventSetup const& es) override;
0051     void beginLuminosityBlock(edm::LuminosityBlock const&, edm::EventSetup const&) override;
0052     void endLuminosityBlock(edm::LuminosityBlock const&, edm::EventSetup const&) override;
0053     void beginRun(edm::Run const&, edm::EventSetup const&) override;
0054     void endRun(edm::Run const&, edm::EventSetup const&) override;
0055     void beginProcessBlock(edm::ProcessBlock const&) override;
0056     void accessInputProcessBlock(edm::ProcessBlock const&) override;
0057     void endProcessBlock(edm::ProcessBlock const&) override;
0058     void endJob() override;
0059 
0060     static void fillDescriptions(edm::ConfigurationDescriptions& iDesc);
0061 
0062   private:
0063     std::vector<edm::InputTag> inputTags_;
0064     int expectedSum_;
0065     int expectedCache_;
0066     int sum_;
0067     std::vector<edm::InputTag> inputTagsNotFound_;
0068     bool getByTokenFirst_;
0069     std::vector<edm::InputTag> inputTagsView_;
0070     bool runProducerParameterCheck_;
0071     bool testGetterOfProducts_;
0072 
0073     std::vector<edm::InputTag> inputTagsUInt64_;
0074     std::vector<edm::InputTag> inputTagsEndLumi_;
0075     std::vector<edm::InputTag> inputTagsEndRun_;
0076     std::vector<edm::InputTag> inputTagsBeginProcessBlock_;
0077     std::vector<edm::InputTag> inputTagsInputProcessBlock_;
0078     std::vector<edm::InputTag> inputTagsEndProcessBlock_;
0079     std::vector<edm::InputTag> inputTagsEndProcessBlock2_;
0080     std::vector<edm::InputTag> inputTagsEndProcessBlock3_;
0081     std::vector<edm::InputTag> inputTagsEndProcessBlock4_;
0082 
0083     std::vector<edm::EDGetTokenT<IntProduct>> tokens_;
0084     std::vector<edm::EDGetTokenT<IntProduct>> tokensNotFound_;
0085     std::vector<edm::EDGetTokenT<edm::View<int>>> tokensView_;
0086     std::vector<edm::EDGetTokenT<UInt64Product>> tokensUInt64_;
0087     std::vector<edm::EDGetTokenT<IntProduct>> tokensEndLumi_;
0088     std::vector<edm::EDGetTokenT<IntProduct>> tokensEndRun_;
0089     std::vector<edm::EDGetTokenT<IntProduct>> tokensBeginProcessBlock_;
0090     std::vector<edm::EDGetTokenT<IntProduct>> tokensInputProcessBlock_;
0091     std::vector<edm::EDGetTokenT<IntProduct>> tokensEndProcessBlock_;
0092     std::vector<edm::EDGetToken> tokensEndProcessBlock2_;
0093     std::vector<edm::EDGetTokenT<IntProduct>> tokensEndProcessBlock3_;
0094     std::vector<edm::EDGetTokenT<IntProduct>> tokensEndProcessBlock4_;
0095 
0096     edm::GetterOfProducts<IntProduct> getterOfProducts_;
0097 
0098   };  // class TestFindProduct
0099 
0100   //--------------------------------------------------------------------
0101   //
0102   // Implementation details
0103 
0104   TestFindProduct::TestFindProduct(edm::ParameterSet const& pset)
0105       : inputTags_(pset.getUntrackedParameter<std::vector<edm::InputTag>>("inputTags")),
0106         expectedSum_(pset.getUntrackedParameter<int>("expectedSum", 0)),
0107         expectedCache_(pset.getUntrackedParameter<int>("expectedCache", 0)),
0108         sum_(0),
0109         inputTagsNotFound_(),
0110         getByTokenFirst_(pset.getUntrackedParameter<bool>("getByTokenFirst", false)),
0111         inputTagsView_(),
0112         runProducerParameterCheck_(pset.getUntrackedParameter<bool>("runProducerParameterCheck", false)),
0113         testGetterOfProducts_(pset.getUntrackedParameter<bool>("testGetterOfProducts", false)),
0114         getterOfProducts_(edm::ProcessMatch("*"), this, edm::InProcess) {
0115     if (testGetterOfProducts_) {
0116       callWhenNewProductsRegistered(getterOfProducts_);
0117     }
0118     std::vector<edm::InputTag> emptyTagVector;
0119     inputTagsNotFound_ = pset.getUntrackedParameter<std::vector<edm::InputTag>>("inputTagsNotFound", emptyTagVector);
0120     inputTagsView_ = pset.getUntrackedParameter<std::vector<edm::InputTag>>("inputTagsView", emptyTagVector);
0121     inputTagsUInt64_ = pset.getUntrackedParameter<std::vector<edm::InputTag>>("inputTagsUInt64", emptyTagVector);
0122     inputTagsEndLumi_ = pset.getUntrackedParameter<std::vector<edm::InputTag>>("inputTagsEndLumi", emptyTagVector);
0123     inputTagsEndRun_ = pset.getUntrackedParameter<std::vector<edm::InputTag>>("inputTagsEndRun", emptyTagVector);
0124     inputTagsBeginProcessBlock_ =
0125         pset.getUntrackedParameter<std::vector<edm::InputTag>>("inputTagsBeginProcessBlock", emptyTagVector);
0126     inputTagsInputProcessBlock_ =
0127         pset.getUntrackedParameter<std::vector<edm::InputTag>>("inputTagsInputProcessBlock", emptyTagVector);
0128     inputTagsEndProcessBlock_ =
0129         pset.getUntrackedParameter<std::vector<edm::InputTag>>("inputTagsEndProcessBlock", emptyTagVector);
0130     inputTagsEndProcessBlock2_ =
0131         pset.getUntrackedParameter<std::vector<edm::InputTag>>("inputTagsEndProcessBlock2", emptyTagVector);
0132     inputTagsEndProcessBlock3_ =
0133         pset.getUntrackedParameter<std::vector<edm::InputTag>>("inputTagsEndProcessBlock3", emptyTagVector);
0134     inputTagsEndProcessBlock4_ =
0135         pset.getUntrackedParameter<std::vector<edm::InputTag>>("inputTagsEndProcessBlock4", emptyTagVector);
0136 
0137     for (auto const& tag : inputTags_) {
0138       tokens_.push_back(consumes<IntProduct>(tag));
0139     }
0140     for (auto const& tag : inputTagsNotFound_) {
0141       tokensNotFound_.push_back(consumes<IntProduct>(tag));
0142     }
0143     for (auto const& tag : inputTagsView_) {
0144       tokensView_.push_back(consumes<edm::View<int>>(tag));
0145     }
0146     for (auto const& tag : inputTagsUInt64_) {
0147       tokensUInt64_.push_back(consumes<UInt64Product>(tag));
0148     }
0149     for (auto const& tag : inputTagsEndLumi_) {
0150       tokensEndLumi_.push_back(consumes<IntProduct, edm::InLumi>(tag));
0151     }
0152     for (auto const& tag : inputTagsEndRun_) {
0153       tokensEndRun_.push_back(consumes<IntProduct, edm::InRun>(tag));
0154     }
0155     for (auto const& tag : inputTagsBeginProcessBlock_) {
0156       tokensBeginProcessBlock_.push_back(consumes<IntProduct, edm::InProcess>(tag));
0157     }
0158     for (auto const& tag : inputTagsInputProcessBlock_) {
0159       tokensInputProcessBlock_.push_back(consumes<IntProduct, edm::InProcess>(tag));
0160     }
0161     for (auto const& tag : inputTagsEndProcessBlock_) {
0162       tokensEndProcessBlock_.push_back(consumes<IntProduct, edm::InProcess>(tag));
0163     }
0164     for (auto const& tag : inputTagsEndProcessBlock2_) {
0165       tokensEndProcessBlock2_.push_back(consumes<IntProduct, edm::InProcess>(tag));
0166     }
0167     for (auto const& tag : inputTagsEndProcessBlock3_) {
0168       tokensEndProcessBlock3_.push_back(consumes<IntProduct, edm::InProcess>(tag));
0169     }
0170     for (auto const& tag : inputTagsEndProcessBlock4_) {
0171       tokensEndProcessBlock4_.push_back(consumes<IntProduct, edm::InProcess>(tag));
0172     }
0173 
0174     if (!tokensInputProcessBlock_.empty()) {
0175       registerProcessBlockCacheFiller<int>(
0176           tokensInputProcessBlock_[0],
0177           [this](edm::ProcessBlock const& processBlock, std::shared_ptr<int> const& previousCache) {
0178             auto returnValue = std::make_shared<int>(0);
0179             for (auto const& token : tokensInputProcessBlock_) {
0180               *returnValue += processBlock.get(token).value;
0181             }
0182             return returnValue;
0183           });
0184       registerProcessBlockCacheFiller<1>(
0185           tokensInputProcessBlock_[0],
0186           [this](edm::ProcessBlock const& processBlock, std::shared_ptr<long long int> const& previousCache) {
0187             auto returnValue = std::make_shared<long long int>(0);
0188             for (auto const& token : tokensInputProcessBlock_) {
0189               *returnValue += processBlock.get(token).value;
0190             }
0191             return returnValue;
0192           });
0193     }
0194   }
0195 
0196   void TestFindProduct::fillDescriptions(edm::ConfigurationDescriptions& iDesc) {
0197     iDesc.setComment("Tests state of IntProduct, UInt64Product, and/or View<int> data products in the job.");
0198     edm::ParameterSetDescription ps;
0199 
0200     const std::vector<edm::InputTag> emptyTagVector;
0201 
0202     ps.addUntracked<std::vector<edm::InputTag>>("inputTags", emptyTagVector)
0203         ->setComment("Get these IntProduct data products");
0204     ps.addUntracked<int>("expectedSum", 0)
0205         ->setComment("The sum of all values from data products obtained from entire job.");
0206     ps.addUntracked<int>("expectedCache", 0)->setComment("Check value of ProcessBlock caches.");
0207     ps.addUntracked<bool>("getByTokenFirst", false)->setComment("Call getByToken before calling getByLabel");
0208     ps.addUntracked<bool>("runProducerParameterCheck", false);
0209     ps.addUntracked<bool>("testGetterOfProducts", false);
0210     ps.addUntracked<std::vector<edm::InputTag>>("inputTagsNotFound", emptyTagVector)
0211         ->setComment("Data products which should be missing from the job.");
0212     ps.addUntracked<std::vector<edm::InputTag>>("inputTagsView", emptyTagVector)
0213         ->setComment("Data products to get via View<int>.");
0214     ps.addUntracked<std::vector<edm::InputTag>>("inputTagsUInt64", emptyTagVector)
0215         ->setComment("Get these UInt64Product data products.");
0216     ps.addUntracked<std::vector<edm::InputTag>>("inputTagsEndLumi", emptyTagVector);
0217     ps.addUntracked<std::vector<edm::InputTag>>("inputTagsEndRun", emptyTagVector);
0218     ps.addUntracked<std::vector<edm::InputTag>>("inputTagsBeginProcessBlock", emptyTagVector);
0219     ps.addUntracked<std::vector<edm::InputTag>>("inputTagsInputProcessBlock", emptyTagVector);
0220     ps.addUntracked<std::vector<edm::InputTag>>("inputTagsEndProcessBlock", emptyTagVector);
0221     ps.addUntracked<std::vector<edm::InputTag>>("inputTagsEndProcessBlock2", emptyTagVector);
0222     ps.addUntracked<std::vector<edm::InputTag>>("inputTagsEndProcessBlock3", emptyTagVector);
0223     ps.addUntracked<std::vector<edm::InputTag>>("inputTagsEndProcessBlock4", emptyTagVector);
0224 
0225     iDesc.addDefault(ps);
0226   }
0227 
0228   TestFindProduct::~TestFindProduct() {}
0229 
0230   void TestFindProduct::analyze(edm::Event const& event, edm::EventSetup const&) {
0231     edm::Handle<IntProduct> h;
0232     edm::Handle<IntProduct> hToken;
0233     edm::Handle<edm::View<int>> hView;
0234     edm::Handle<edm::View<int>> hViewToken;
0235 
0236     std::vector<edm::EDGetTokenT<IntProduct>>::const_iterator iToken = tokens_.begin();
0237     for (std::vector<edm::InputTag>::const_iterator iter = inputTags_.begin(), iEnd = inputTags_.end(); iter != iEnd;
0238          ++iter, ++iToken) {
0239       if (getByTokenFirst_) {
0240         event.getByToken(*iToken, hToken);
0241         *hToken;
0242       }
0243 
0244       event.getByLabel(*iter, h);
0245       sum_ += h->value;
0246 
0247       event.getByToken(*iToken, hToken);
0248       if (h->value != hToken->value) {
0249         throw cms::Exception("TestFail")
0250             << "TestFindProduct::analyze getByLabel and getByToken return inconsistent results";
0251       }
0252 
0253       if (runProducerParameterCheck_) {
0254         edm::ParameterSet const* producerPset =
0255             edm::getProducerParameterSet(*hToken.provenance(), event.processHistory());
0256         int par = producerPset->getParameter<int>("ivalue");
0257         // These expected values are just from knowing the values in the
0258         // configuration files for this test.
0259         int expectedParameterValue = 3;
0260         if (!iter->process().empty()) {
0261           if (event.run() == 1) {
0262             expectedParameterValue = 1;
0263           } else {
0264             expectedParameterValue = 2;
0265           }
0266         }
0267         if (par != expectedParameterValue) {
0268           throw cms::Exception("TestFail") << "TestFindProduct::analyze unexpected value from producer parameter set";
0269         }
0270       }
0271     }
0272     iToken = tokensNotFound_.begin();
0273     for (std::vector<edm::InputTag>::const_iterator iter = inputTagsNotFound_.begin(), iEnd = inputTagsNotFound_.end();
0274          iter != iEnd;
0275          ++iter, ++iToken) {
0276       event.getByLabel(*iter, h);
0277       if (h.isValid()) {
0278         throw cms::Exception("TestFail")
0279             << "TestFindProduct::analyze: getByLabel found a product that should not be found "
0280             << h.provenance()->moduleLabel();
0281       }
0282 
0283       event.getByToken(*iToken, hToken);
0284       if (hToken.isValid()) {
0285         throw cms::Exception("TestFail")
0286             << "TestFindProduct::analyze: getByToken found a product that should not be found "
0287             << hToken.provenance()->moduleLabel();
0288       }
0289     }
0290     std::vector<edm::EDGetTokenT<edm::View<int>>>::const_iterator iTokenView = tokensView_.begin();
0291     for (std::vector<edm::InputTag>::const_iterator iter = inputTagsView_.begin(), iEnd = inputTagsView_.end();
0292          iter != iEnd;
0293          ++iter, ++iTokenView) {
0294       if (getByTokenFirst_) {
0295         event.getByToken(*iTokenView, hViewToken);
0296         *hViewToken;
0297       }
0298 
0299       event.getByLabel(*iter, hView);
0300       sum_ += hView->at(0);
0301 
0302       event.getByToken(*iTokenView, hViewToken);
0303       if (hView->at(0) != hViewToken->at(0)) {
0304         throw cms::Exception("TestFail")
0305             << "TestFindProduct::analyze getByLabel and getByToken return inconsistent results";
0306       }
0307     }
0308 
0309     // Get these also and add them into the sum
0310     edm::Handle<UInt64Product> h64;
0311     for (auto const& token : tokensUInt64_) {
0312       event.getByToken(token, h64);
0313       sum_ += h64->value;
0314     }
0315 
0316     if (expectedCache_ != 0) {
0317       std::tuple<edm::CacheHandle<int>, edm::CacheHandle<long long int>> valueTuple = processBlockCaches(event);
0318       {
0319         edm::CacheHandle<int> value = std::get<0>(valueTuple);
0320         if (*value != expectedCache_) {
0321           throw cms::Exception("TestFail") << "TestFindProduct::analyze 0 ProcessBlock cache has unexpected value "
0322                                            << *value << " expected = " << expectedCache_;
0323         }
0324       }
0325       {
0326         edm::CacheHandle<long long int> value = std::get<1>(valueTuple);
0327         if (*value != expectedCache_) {
0328           throw cms::Exception("TestFail") << "TestFindProduct::analyze 1 ProcessBlock cache has unexpected value "
0329                                            << *value << " expected = " << expectedCache_;
0330         }
0331       }
0332     }
0333   }
0334 
0335   void TestFindProduct::beginLuminosityBlock(edm::LuminosityBlock const&, edm::EventSetup const&) {}
0336 
0337   void TestFindProduct::endLuminosityBlock(edm::LuminosityBlock const& lb, edm::EventSetup const&) {
0338     // Get these also and add them into the sum
0339     edm::Handle<IntProduct> h;
0340     for (auto const& token : tokensEndLumi_) {
0341       lb.getByToken(token, h);
0342       sum_ += h->value;
0343     }
0344   }
0345 
0346   void TestFindProduct::beginRun(edm::Run const&, edm::EventSetup const&) {}
0347 
0348   void TestFindProduct::endRun(edm::Run const& run, edm::EventSetup const&) {
0349     // Get these also and add them into the sum
0350     edm::Handle<IntProduct> h;
0351     for (auto const& token : tokensEndRun_) {
0352       run.getByToken(token, h);
0353       sum_ += h->value;
0354     }
0355   }
0356 
0357   void TestFindProduct::beginProcessBlock(edm::ProcessBlock const& processBlock) {
0358     for (auto const& token : tokensBeginProcessBlock_) {
0359       sum_ += processBlock.get(token).value;
0360     }
0361     if (testGetterOfProducts_) {
0362       std::vector<edm::Handle<IntProduct>> handles;
0363       getterOfProducts_.fillHandles(processBlock, handles);
0364       for (auto const& intHandle : handles) {
0365         sum_ += intHandle->value;
0366       }
0367     }
0368   }
0369 
0370   void TestFindProduct::accessInputProcessBlock(edm::ProcessBlock const& processBlock) {
0371     for (auto const& token : tokensInputProcessBlock_) {
0372       int value = processBlock.get(token).value;
0373       sum_ += value;
0374     }
0375   }
0376 
0377   void TestFindProduct::endProcessBlock(edm::ProcessBlock const& processBlock) {
0378     std::vector<int> values;
0379     for (auto const& token : tokensEndProcessBlock_) {
0380       int value = processBlock.get(token).value;
0381       values.push_back(value);
0382       sum_ += value;
0383     }
0384     edm::Handle<IntProduct> h;
0385     unsigned int i = 0;
0386     for (auto val : values) {
0387       if (i < tokensEndProcessBlock2_.size()) {
0388         processBlock.getByToken(tokensEndProcessBlock2_[i], h);
0389         if (h->value != val + 2) {
0390           throw cms::Exception("TestFail") << "TestFindProduct::endProcessBlock 2, received unexpected value";
0391         }
0392       }
0393       if (i < tokensEndProcessBlock3_.size()) {
0394         processBlock.getByToken(tokensEndProcessBlock3_[i], h);
0395         if (h->value != val + 3) {
0396           throw cms::Exception("TestFail") << "TestFindProduct::endProcessBlock 3, received unexpected value";
0397         }
0398       }
0399       if (i < tokensEndProcessBlock4_.size()) {
0400         h = processBlock.getHandle(tokensEndProcessBlock4_[i]);
0401         if (h->value != val + 4) {
0402           throw cms::Exception("TestFail") << "TestFindProduct::endProcessBlock 4, received unexpected value";
0403         }
0404       }
0405       ++i;
0406     }
0407     if (testGetterOfProducts_) {
0408       std::vector<edm::Handle<IntProduct>> handles;
0409       getterOfProducts_.fillHandles(processBlock, handles);
0410       for (auto const& intHandle : handles) {
0411         sum_ += intHandle->value;
0412       }
0413     }
0414   }
0415 
0416   void TestFindProduct::endJob() {
0417     std::cout << "TestFindProduct sum = " << sum_ << std::endl;
0418     if (expectedSum_ != 0 && sum_ != expectedSum_) {
0419       throw cms::Exception("TestFail")
0420           << "TestFindProduct::endJob - Sum of test object values does not equal expected value";
0421     }
0422   }
0423 
0424 }  // namespace edmtest
0425 
0426 using edmtest::TestFindProduct;
0427 DEFINE_FWK_MODULE(TestFindProduct);