Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2022-04-08 00:35:15

0001 
0002 /*----------------------------------------------------------------------
0003 
0004 Toy EDProducers of Ints for testing purposes only.
0005 
0006 ----------------------------------------------------------------------*/
0007 
0008 #include "DataFormats/Common/interface/Handle.h"
0009 #include "DataFormats/Common/interface/TriggerResults.h"
0010 #include "DataFormats/TestObjects/interface/ToyProducts.h"
0011 //
0012 #include "FWCore/Framework/interface/EDProducer.h"
0013 #include "FWCore/Framework/interface/stream/EDProducer.h"
0014 #include "FWCore/Framework/interface/global/EDProducer.h"
0015 #include "FWCore/Framework/interface/limited/EDProducer.h"
0016 #include "FWCore/Framework/interface/one/EDProducer.h"
0017 #include "FWCore/Framework/interface/Event.h"
0018 #include "FWCore/Framework/interface/MakerMacros.h"
0019 #include "FWCore/Framework/interface/ProcessBlock.h"
0020 #include "FWCore/ParameterSet/interface/ConfigurationDescriptions.h"
0021 #include "FWCore/ParameterSet/interface/ParameterSetDescription.h"
0022 #include "FWCore/ParameterSet/interface/ParameterSet.h"
0023 #include "FWCore/Utilities/interface/EDMException.h"
0024 #include "FWCore/Utilities/interface/InputTag.h"
0025 #include "FWCore/Utilities/interface/transform.h"
0026 //
0027 #include <cassert>
0028 #include <string>
0029 #include <vector>
0030 #include <unistd.h>
0031 
0032 namespace edmtest {
0033 
0034   //--------------------------------------------------------------------
0035   //
0036   // Int producers
0037   //
0038   //--------------------------------------------------------------------
0039 
0040   //--------------------------------------------------------------------
0041   //
0042   // throws an exception.
0043   // Announces an IntProduct but does not produce one;
0044   // every call to FailingProducer::produce throws a cms exception
0045   //
0046   class FailingProducer : public edm::global::EDProducer<> {
0047   public:
0048     explicit FailingProducer(edm::ParameterSet const& /*p*/) { produces<IntProduct>(); }
0049     void produce(edm::StreamID, edm::Event& e, edm::EventSetup const& c) const override;
0050   };
0051 
0052   void FailingProducer::produce(edm::StreamID, edm::Event&, edm::EventSetup const&) const {
0053     // We throw an edm exception with a configurable action.
0054     throw edm::Exception(edm::errors::NotFound) << "Intentional 'NotFound' exception for testing purposes\n";
0055   }
0056   //--------------------------------------------------------------------
0057   //
0058   // throws an exception.
0059   // Announces an IntProduct but does not produce one;
0060   // every call to FailingInLumiProducer::produce throws a cms exception
0061   //
0062   class FailingInLumiProducer : public edm::global::EDProducer<edm::BeginLuminosityBlockProducer> {
0063   public:
0064     explicit FailingInLumiProducer(edm::ParameterSet const& /*p*/) {
0065       produces<IntProduct, edm::Transition::BeginLuminosityBlock>();
0066     }
0067     void produce(edm::StreamID, edm::Event& e, edm::EventSetup const& c) const override;
0068 
0069     void globalBeginLuminosityBlockProduce(edm::LuminosityBlock&, edm::EventSetup const&) const override;
0070   };
0071 
0072   void FailingInLumiProducer::produce(edm::StreamID, edm::Event&, edm::EventSetup const&) const {}
0073   void FailingInLumiProducer::globalBeginLuminosityBlockProduce(edm::LuminosityBlock&, edm::EventSetup const&) const {
0074     // We throw an edm exception with a configurable action.
0075     throw edm::Exception(edm::errors::NotFound) << "Intentional 'NotFound' exception for testing purposes\n";
0076   }
0077 
0078   //--------------------------------------------------------------------
0079   //
0080   // throws an exception.
0081   // Announces an IntProduct but does not produce one;
0082   // every call to FailingProducer::produce throws a cms exception
0083   //
0084   class FailingInRunProducer : public edm::global::EDProducer<edm::BeginRunProducer> {
0085   public:
0086     explicit FailingInRunProducer(edm::ParameterSet const& /*p*/) { produces<IntProduct, edm::Transition::BeginRun>(); }
0087     void produce(edm::StreamID, edm::Event& e, edm::EventSetup const& c) const override;
0088 
0089     void globalBeginRunProduce(edm::Run&, edm::EventSetup const&) const override;
0090   };
0091 
0092   void FailingInRunProducer::produce(edm::StreamID, edm::Event&, edm::EventSetup const&) const {}
0093   void FailingInRunProducer::globalBeginRunProduce(edm::Run&, edm::EventSetup const&) const {
0094     // We throw an edm exception with a configurable action.
0095     throw edm::Exception(edm::errors::NotFound) << "Intentional 'NotFound' exception for testing purposes\n";
0096   }
0097 
0098   //--------------------------------------------------------------------
0099   //
0100   // Announces an IntProduct but does not produce one;
0101   // every call to NonProducer::produce does nothing.
0102   //
0103   class NonProducer : public edm::global::EDProducer<> {
0104   public:
0105     explicit NonProducer(edm::ParameterSet const& /*p*/) { produces<IntProduct>(); }
0106     void produce(edm::StreamID, edm::Event& e, edm::EventSetup const& c) const override;
0107   };
0108 
0109   void NonProducer::produce(edm::StreamID, edm::Event&, edm::EventSetup const&) const {}
0110 
0111   //--------------------------------------------------------------------
0112   //
0113   // Produces an IntProduct instance.
0114   //
0115   // NOTE: this really should be a global::EDProducer<> but for testing we use stream
0116   class IntProducer : public edm::stream::EDProducer<> {
0117   public:
0118     explicit IntProducer(edm::ParameterSet const& p)
0119         : token_{produces<IntProduct>()}, value_(p.getParameter<int>("ivalue")) {}
0120     void produce(edm::Event& e, edm::EventSetup const& c) override;
0121 
0122     static void fillDescriptions(edm::ConfigurationDescriptions& descriptions) {
0123       edm::ParameterSetDescription desc;
0124       desc.add<int>("ivalue");
0125       descriptions.addDefault(desc);
0126     }
0127 
0128   private:
0129     edm::EDPutTokenT<IntProduct> token_;
0130     int value_;
0131   };
0132 
0133   void IntProducer::produce(edm::Event& e, edm::EventSetup const&) {
0134     // EventSetup is not used.
0135     e.emplace(token_, value_);
0136   }
0137 
0138   //--------------------------------------------------------------------
0139   //
0140   // Produces an IntProduct instance.
0141   //
0142   class IntLegacyProducer : public edm::EDProducer {
0143   public:
0144     explicit IntLegacyProducer(edm::ParameterSet const& p) : value_(p.getParameter<int>("ivalue")) {
0145       produces<IntProduct>();
0146     }
0147     explicit IntLegacyProducer(int i) : value_(i) { produces<IntProduct>(); }
0148     void produce(edm::Event& e, edm::EventSetup const& c) override;
0149 
0150   private:
0151     int value_;
0152   };
0153 
0154   void IntLegacyProducer::produce(edm::Event& e, edm::EventSetup const&) {
0155     // EventSetup is not used.
0156     e.put(std::make_unique<IntProduct>(value_));
0157   }
0158 
0159   //--------------------------------------------------------------------
0160   //
0161   // Produces an IntProduct instance.
0162   //
0163   //
0164   class BusyWaitIntProducer : public edm::global::EDProducer<> {
0165   public:
0166     explicit BusyWaitIntProducer(edm::ParameterSet const& p)
0167         : token_{produces<IntProduct>()},
0168           value_(p.getParameter<int>("ivalue")),
0169           iterations_(p.getParameter<unsigned int>("iterations")),
0170           pi_(std::acos(-1)),
0171           lumiNumberToThrow_(p.getParameter<unsigned int>("lumiNumberToThrow")) {}
0172 
0173     void produce(edm::StreamID, edm::Event& e, edm::EventSetup const& c) const override;
0174 
0175     static void fillDescriptions(edm::ConfigurationDescriptions& descriptions);
0176 
0177   private:
0178     const edm::EDPutTokenT<IntProduct> token_;
0179     const int value_;
0180     const unsigned int iterations_;
0181     const double pi_;
0182     const unsigned int lumiNumberToThrow_;
0183   };
0184 
0185   void BusyWaitIntProducer::produce(edm::StreamID, edm::Event& e, edm::EventSetup const&) const {
0186     double sum = 0.;
0187     const double stepSize = pi_ / iterations_;
0188     for (unsigned int i = 0; i < iterations_; ++i) {
0189       sum += stepSize * cos(i * stepSize);
0190     }
0191 
0192     e.emplace(token_, value_ + sum);
0193 
0194     if (e.luminosityBlock() == lumiNumberToThrow_) {
0195       throw cms::Exception("Test");
0196     }
0197   }
0198 
0199   void BusyWaitIntProducer::fillDescriptions(edm::ConfigurationDescriptions& descriptions) {
0200     edm::ParameterSetDescription desc;
0201     desc.add<int>("ivalue");
0202     desc.add<unsigned int>("iterations");
0203     desc.add<unsigned int>("lumiNumberToThrow", 0);
0204     descriptions.addDefault(desc);
0205   }
0206 
0207   //--------------------------------------------------------------------
0208   class BusyWaitIntLimitedProducer : public edm::limited::EDProducer<> {
0209   public:
0210     explicit BusyWaitIntLimitedProducer(edm::ParameterSet const& p)
0211         : edm::limited::EDProducerBase(p),
0212           edm::limited::EDProducer<>(p),
0213           token_{produces<IntProduct>()},
0214           value_(p.getParameter<int>("ivalue")),
0215           iterations_(p.getParameter<unsigned int>("iterations")),
0216           pi_(std::acos(-1)) {}
0217 
0218     void produce(edm::StreamID, edm::Event& e, edm::EventSetup const& c) const override;
0219 
0220   private:
0221     const edm::EDPutTokenT<IntProduct> token_;
0222     const int value_;
0223     const unsigned int iterations_;
0224     const double pi_;
0225     mutable std::atomic<unsigned int> reentrancy_{0};
0226   };
0227 
0228   void BusyWaitIntLimitedProducer::produce(edm::StreamID, edm::Event& e, edm::EventSetup const&) const {
0229     auto v = ++reentrancy_;
0230     if (v > concurrencyLimit()) {
0231       --reentrancy_;
0232       throw cms::Exception("NotLimited", "produce called to many times concurrently.");
0233     }
0234 
0235     double sum = 0.;
0236     const double stepSize = pi_ / iterations_;
0237     for (unsigned int i = 0; i < iterations_; ++i) {
0238       sum += stepSize * cos(i * stepSize);
0239     }
0240 
0241     e.emplace(token_, value_ + sum);
0242     --reentrancy_;
0243   }
0244 
0245   //--------------------------------------------------------------------
0246   class BusyWaitIntLegacyProducer : public edm::EDProducer {
0247   public:
0248     explicit BusyWaitIntLegacyProducer(edm::ParameterSet const& p)
0249         : value_(p.getParameter<int>("ivalue")),
0250           iterations_(p.getParameter<unsigned int>("iterations")),
0251           pi_(std::acos(-1)) {
0252       produces<IntProduct>();
0253     }
0254 
0255     void produce(edm::Event& e, edm::EventSetup const& c) override;
0256 
0257   private:
0258     const int value_;
0259     const unsigned int iterations_;
0260     const double pi_;
0261   };
0262 
0263   void BusyWaitIntLegacyProducer::produce(edm::Event& e, edm::EventSetup const&) {
0264     double sum = 0.;
0265     const double stepSize = pi_ / iterations_;
0266     for (unsigned int i = 0; i < iterations_; ++i) {
0267       sum += stepSize * cos(i * stepSize);
0268     }
0269 
0270     e.put(std::make_unique<IntProduct>(value_ + sum));
0271   }
0272 
0273   //--------------------------------------------------------------------
0274 
0275   class ConsumingIntProducer : public edm::stream::EDProducer<> {
0276   public:
0277     explicit ConsumingIntProducer(edm::ParameterSet const& p)
0278         : token_{produces<IntProduct>()}, value_(p.getParameter<int>("ivalue")) {
0279       // not used, only exists to test PathAndConsumesOfModules
0280       consumes<edm::TriggerResults>(edm::InputTag("TriggerResults"));
0281       consumesMany<edm::TriggerResults>();
0282     }
0283     void produce(edm::Event& e, edm::EventSetup const& c) override;
0284 
0285   private:
0286     const edm::EDPutTokenT<IntProduct> token_;
0287     const int value_;
0288   };
0289 
0290   void ConsumingIntProducer::produce(edm::Event& e, edm::EventSetup const&) { e.emplace(token_, value_); }
0291 
0292   //--------------------------------------------------------------------
0293   //
0294   // Produces an IntProduct instance whose value is the event number,
0295   // rather than the value of a configured parameter.
0296   //
0297   class EventNumberIntProducer : public edm::global::EDProducer<> {
0298   public:
0299     explicit EventNumberIntProducer(edm::ParameterSet const&) : token_{produces<UInt64Product>()} {}
0300     void produce(edm::StreamID, edm::Event& e, edm::EventSetup const& c) const override;
0301 
0302   private:
0303     const edm::EDPutTokenT<UInt64Product> token_;
0304   };
0305 
0306   void EventNumberIntProducer::produce(edm::StreamID, edm::Event& e, edm::EventSetup const&) const {
0307     // EventSetup is not used.
0308     e.emplace(token_, e.id().event());
0309   }
0310 
0311   //--------------------------------------------------------------------
0312   //
0313   // Produces a TransientIntProduct instance.
0314   //
0315   class TransientIntProducer : public edm::global::EDProducer<> {
0316   public:
0317     explicit TransientIntProducer(edm::ParameterSet const& p)
0318         : token_{produces<TransientIntProduct>()}, value_(p.getParameter<int>("ivalue")) {}
0319     void produce(edm::StreamID, edm::Event& e, edm::EventSetup const& c) const override;
0320 
0321   private:
0322     const edm::EDPutTokenT<TransientIntProduct> token_;
0323     const int value_;
0324   };
0325 
0326   void TransientIntProducer::produce(edm::StreamID, edm::Event& e, edm::EventSetup const&) const {
0327     // EventSetup is not used.
0328     e.emplace(token_, value_);
0329   }
0330 
0331   //--------------------------------------------------------------------
0332   //
0333   // Produces a IntProduct instance from a TransientIntProduct
0334   //
0335   class IntProducerFromTransient : public edm::global::EDProducer<> {
0336   public:
0337     explicit IntProducerFromTransient(edm::ParameterSet const&)
0338         : putToken_{produces<IntProduct>()}, getToken_{consumes(edm::InputTag{"TransientThing"})} {}
0339     void produce(edm::StreamID, edm::Event& e, edm::EventSetup const& c) const override;
0340 
0341   private:
0342     const edm::EDPutTokenT<IntProduct> putToken_;
0343     const edm::EDGetTokenT<TransientIntProduct> getToken_;
0344   };
0345 
0346   void IntProducerFromTransient::produce(edm::StreamID, edm::Event& e, edm::EventSetup const&) const {
0347     // EventSetup is not used.
0348     auto result = e.getHandle(getToken_);
0349     assert(result);
0350     e.emplace(putToken_, result.product()->value);
0351   }
0352 
0353   //--------------------------------------------------------------------
0354   //
0355   // Produces an Int16_tProduct instance.
0356   //
0357   class Int16_tProducer : public edm::global::EDProducer<> {
0358   public:
0359     explicit Int16_tProducer(edm::ParameterSet const& p)
0360         : token_{produces<Int16_tProduct>()}, value_(p.getParameter<int>("ivalue")) {}
0361     void produce(edm::StreamID, edm::Event& e, edm::EventSetup const& c) const override;
0362 
0363   private:
0364     const edm::EDPutTokenT<Int16_tProduct> token_;
0365     const int16_t value_;
0366   };
0367 
0368   void Int16_tProducer::produce(edm::StreamID, edm::Event& e, edm::EventSetup const&) const {
0369     // EventSetup is not used.
0370     e.emplace(token_, value_);
0371   }
0372 
0373   //
0374   // Produces an IntProduct instance, using an IntProduct as input.
0375   //
0376 
0377   class AddIntsProducer : public edm::global::EDProducer<> {
0378   public:
0379     explicit AddIntsProducer(edm::ParameterSet const& p)
0380         : putToken_{produces<IntProduct>()},
0381           otherPutToken_{produces<IntProduct>("other")},
0382           onlyGetOnEvent_(p.getUntrackedParameter<unsigned int>("onlyGetOnEvent")) {
0383       auto const& labels = p.getParameter<std::vector<edm::InputTag>>("labels");
0384       for (auto const& label : labels) {
0385         tokens_.emplace_back(consumes(label));
0386       }
0387     }
0388     void produce(edm::StreamID, edm::Event& e, edm::EventSetup const& c) const override;
0389 
0390     static void fillDescriptions(edm::ConfigurationDescriptions& descriptions) {
0391       edm::ParameterSetDescription desc;
0392       desc.addUntracked<unsigned int>("onlyGetOnEvent", 0u);
0393       desc.add<std::vector<edm::InputTag>>("labels");
0394       descriptions.addDefault(desc);
0395     }
0396 
0397   private:
0398     std::vector<edm::EDGetTokenT<IntProduct>> tokens_;
0399     const edm::EDPutTokenT<IntProduct> putToken_;
0400     const edm::EDPutTokenT<IntProduct> otherPutToken_;
0401     unsigned int onlyGetOnEvent_;
0402   };
0403 
0404   void AddIntsProducer::produce(edm::StreamID, edm::Event& e, edm::EventSetup const&) const {
0405     // EventSetup is not used.
0406     int value = 0;
0407 
0408     if (onlyGetOnEvent_ == 0u || e.eventAuxiliary().event() == onlyGetOnEvent_) {
0409       for (auto const& token : tokens_) {
0410         value += e.get(token).value;
0411       }
0412     }
0413     e.emplace(putToken_, value);
0414     e.emplace(otherPutToken_, value);
0415   }
0416 
0417   //
0418   // Produces an IntProduct instance, using many IntProducts as input.
0419   //
0420 
0421   class AddAllIntsProducer : public edm::global::EDProducer<> {
0422   public:
0423     explicit AddAllIntsProducer(edm::ParameterSet const& p) : putToken_{produces()} { consumesMany<IntProduct>(); }
0424     void produce(edm::StreamID, edm::Event& e, edm::EventSetup const& c) const override;
0425 
0426     static void fillDescriptions(edm::ConfigurationDescriptions& descriptions) {
0427       edm::ParameterSetDescription desc;
0428       descriptions.addDefault(desc);
0429     }
0430 
0431   private:
0432     const edm::EDPutTokenT<int> putToken_;
0433   };
0434 
0435   void AddAllIntsProducer::produce(edm::StreamID, edm::Event& e, edm::EventSetup const&) const {
0436     std::vector<edm::Handle<IntProduct>> ints;
0437     e.getManyByType(ints);
0438 
0439     int value = 0;
0440     for (auto const& i : ints) {
0441       value += i->value;
0442     }
0443 
0444     e.emplace(putToken_, value);
0445   }
0446 
0447   //
0448   // Produces multiple IntProduct products
0449   //
0450 
0451   class ManyIntProducer : public edm::global::EDProducer<> {
0452   public:
0453     explicit ManyIntProducer(edm::ParameterSet const& p)
0454         : tokenValues_{vector_transform(
0455               p.getParameter<std::vector<edm::ParameterSet>>("values"),
0456               [this](edm::ParameterSet const& pset) {
0457                 auto const& branchAlias = pset.getParameter<std::string>("branchAlias");
0458                 if (not branchAlias.empty()) {
0459                   return TokenValue{
0460                       produces<IntProduct>(pset.getParameter<std::string>("instance")).setBranchAlias(branchAlias),
0461                       pset.getParameter<int>("value")};
0462                 }
0463                 return TokenValue{produces<IntProduct>(pset.getParameter<std::string>("instance")),
0464                                   pset.getParameter<int>("value")};
0465               })},
0466           throw_{p.getUntrackedParameter<bool>("throw")} {
0467       tokenValues_.push_back(TokenValue{produces<IntProduct>(), p.getParameter<int>("ivalue")});
0468     }
0469 
0470     static void fillDescriptions(edm::ConfigurationDescriptions& descriptions) {
0471       edm::ParameterSetDescription desc;
0472       desc.add<int>("ivalue");
0473       desc.addUntracked<bool>("throw", false);
0474 
0475       {
0476         edm::ParameterSetDescription pset;
0477         pset.add<std::string>("instance");
0478         pset.add<int>("value");
0479         pset.add<std::string>("branchAlias", "");
0480         desc.addVPSet("values", pset, std::vector<edm::ParameterSet>{});
0481       }
0482 
0483       descriptions.addDefault(desc);
0484     }
0485 
0486     void produce(edm::StreamID, edm::Event& e, edm::EventSetup const& c) const override;
0487 
0488   private:
0489     struct TokenValue {
0490       edm::EDPutTokenT<IntProduct> token;
0491       int value;
0492     };
0493     std::vector<TokenValue> tokenValues_;
0494     bool throw_;
0495   };
0496 
0497   void ManyIntProducer::produce(edm::StreamID, edm::Event& e, edm::EventSetup const&) const {
0498     if (throw_) {
0499       throw edm::Exception(edm::errors::NotFound) << "Intentional 'NotFound' exception for testing purposes\n";
0500     }
0501 
0502     // EventSetup is not used.
0503     for (auto const& tv : tokenValues_) {
0504       e.emplace(tv.token, tv.value);
0505     }
0506   }
0507 
0508   //
0509   // Produces multiple IntProduct products based on other products
0510   //
0511 
0512   class ManyIntWhenRegisteredProducer : public edm::global::EDProducer<> {
0513   public:
0514     explicit ManyIntWhenRegisteredProducer(edm::ParameterSet const& p)
0515         : sourceLabel_(p.getParameter<std::string>("src")) {
0516       callWhenNewProductsRegistered([=](edm::BranchDescription const& iBranch) {
0517         if (iBranch.moduleLabel() == sourceLabel_) {
0518           if (iBranch.branchType() != edm::InEvent) {
0519             throw edm::Exception(edm::errors::UnimplementedFeature)
0520                 << "ManyIntWhenRegisteredProducer supports only event branches";
0521           }
0522 
0523           this->tokens_.push_back(
0524               Tokens{this->consumes<IntProduct>(
0525                          edm::InputTag{iBranch.moduleLabel(), iBranch.productInstanceName(), iBranch.processName()}),
0526                      this->produces<IntProduct>(iBranch.productInstanceName())});
0527         }
0528       });
0529     }
0530 
0531     static void fillDescriptions(edm::ConfigurationDescriptions& descriptions) {
0532       edm::ParameterSetDescription desc;
0533       desc.add<std::string>("src");
0534       descriptions.addDefault(desc);
0535     }
0536 
0537     void produce(edm::StreamID, edm::Event& e, edm::EventSetup const& c) const override;
0538 
0539   private:
0540     struct Tokens {
0541       edm::EDGetTokenT<IntProduct> get;
0542       edm::EDPutTokenT<IntProduct> put;
0543     };
0544 
0545     std::string sourceLabel_;
0546     std::vector<Tokens> tokens_;
0547   };
0548 
0549   void ManyIntWhenRegisteredProducer::produce(edm::StreamID, edm::Event& e, edm::EventSetup const&) const {
0550     for (auto const& toks : tokens_) {
0551       e.emplace(toks.put, e.get(toks.get));
0552     }
0553   };
0554 
0555   //--------------------------------------------------------------------
0556 
0557   class NonEventIntProducer : public edm::global::EDProducer<edm::Accumulator,
0558                                                              edm::BeginRunProducer,
0559                                                              edm::BeginLuminosityBlockProducer,
0560                                                              edm::EndLuminosityBlockProducer,
0561                                                              edm::EndRunProducer,
0562                                                              edm::BeginProcessBlockProducer,
0563                                                              edm::EndProcessBlockProducer,
0564                                                              edm::InputProcessBlockCache<>> {
0565   public:
0566     explicit NonEventIntProducer(edm::ParameterSet const& p)
0567         : bpbToken_{produces<IntProduct, edm::Transition::BeginProcessBlock>("beginProcessBlock")},
0568           brToken_{produces<IntProduct, edm::Transition::BeginRun>("beginRun")},
0569           blToken_{produces<IntProduct, edm::Transition::BeginLuminosityBlock>("beginLumi")},
0570           elToken_{produces<IntProduct, edm::Transition::EndLuminosityBlock>("endLumi")},
0571           erToken_{produces<IntProduct, edm::Transition::EndRun>("endRun")},
0572           epbToken_{produces<IntProduct, edm::Transition::EndProcessBlock>("endProcessBlock")},
0573           value_(p.getParameter<int>("ivalue")),
0574           sleepTime_(p.getParameter<unsigned int>("sleepTime")),
0575           bpbExpect_{p.getUntrackedParameter<int>("expectBeginProcessBlock")},
0576           brExpect_{p.getUntrackedParameter<int>("expectBeginRun")},
0577           blExpect_{p.getUntrackedParameter<int>("expectBeginLuminosityBlock")},
0578           elExpect_{p.getUntrackedParameter<int>("expectEndLuminosityBlock")},
0579           erExpect_{p.getUntrackedParameter<int>("expectEndRun")},
0580           epbExpect_{p.getUntrackedParameter<int>("expectEndProcessBlock")},
0581           aipbExpect_{p.getUntrackedParameter<int>("expectAccessInputProcessBlock")} {
0582       {
0583         auto tag = p.getParameter<edm::InputTag>("consumesBeginProcessBlock");
0584         if (not tag.label().empty()) {
0585           bpbGet_ = consumes<edm::InProcess>(tag);
0586         }
0587       }
0588       {
0589         auto tag = p.getParameter<edm::InputTag>("consumesBeginRun");
0590         if (not tag.label().empty()) {
0591           brGet_ = consumes<edm::InRun>(tag);
0592         }
0593       }
0594       {
0595         auto tag = p.getParameter<edm::InputTag>("consumesBeginLuminosityBlock");
0596         if (not tag.label().empty()) {
0597           blGet_ = consumes<edm::InLumi>(tag);
0598         }
0599       }
0600       {
0601         auto tag = p.getParameter<edm::InputTag>("consumesEndLuminosityBlock");
0602         if (not tag.label().empty()) {
0603           elGet_ = consumes<edm::InLumi>(tag);
0604         }
0605       }
0606       {
0607         auto tag = p.getParameter<edm::InputTag>("consumesEndRun");
0608         if (not tag.label().empty()) {
0609           erGet_ = consumes<edm::InRun>(tag);
0610         }
0611       }
0612       {
0613         auto tag = p.getParameter<edm::InputTag>("consumesEndProcessBlock");
0614         if (not tag.label().empty()) {
0615           epbGet_ = consumes<edm::InProcess>(tag);
0616         }
0617       }
0618       {
0619         auto tag = p.getParameter<edm::InputTag>("consumesAccessInputProcessBlock");
0620         if (not tag.label().empty()) {
0621           aipbGet_ = consumes<edm::InProcess>(tag);
0622         }
0623       }
0624     }
0625     void accumulate(edm::StreamID iID, edm::Event const& e, edm::EventSetup const& c) const override;
0626     void beginProcessBlockProduce(edm::ProcessBlock&) override;
0627     void endProcessBlockProduce(edm::ProcessBlock&) override;
0628     void globalBeginRunProduce(edm::Run& e, edm::EventSetup const&) const override;
0629     void globalEndRunProduce(edm::Run& e, edm::EventSetup const&) const override;
0630     void globalBeginLuminosityBlockProduce(edm::LuminosityBlock& e, edm::EventSetup const&) const override;
0631     void globalEndLuminosityBlockProduce(edm::LuminosityBlock& e, edm::EventSetup const&) const override;
0632     void accessInputProcessBlock(edm::ProcessBlock const&) override;
0633 
0634     static void fillDescriptions(edm::ConfigurationDescriptions& conf) {
0635       edm::ParameterSetDescription desc;
0636       desc.add<int>("ivalue", 0);
0637       desc.add<unsigned int>("sleepTime", 0);
0638       desc.add<edm::InputTag>("consumesBeginProcessBlock", {});
0639       desc.addUntracked<int>("expectBeginProcessBlock", 0);
0640       desc.add<edm::InputTag>("consumesEndProcessBlock", {});
0641       desc.addUntracked<int>("expectEndProcessBlock", 0);
0642       desc.add<edm::InputTag>("consumesAccessInputProcessBlock", {});
0643       desc.addUntracked<int>("expectAccessInputProcessBlock", 0);
0644       desc.add<edm::InputTag>("consumesBeginRun", {});
0645       desc.addUntracked<int>("expectBeginRun", 0);
0646       desc.add<edm::InputTag>("consumesEndRun", {});
0647       desc.addUntracked<int>("expectEndRun", 0);
0648       desc.add<edm::InputTag>("consumesBeginLuminosityBlock", {});
0649       desc.addUntracked<int>("expectBeginLuminosityBlock", 0);
0650       desc.add<edm::InputTag>("consumesEndLuminosityBlock", {});
0651       desc.addUntracked<int>("expectEndLuminosityBlock", 0);
0652 
0653       conf.addDefault(desc);
0654     }
0655 
0656   private:
0657     void check(IntProduct, int) const;
0658     const edm::EDPutTokenT<IntProduct> bpbToken_;
0659     const edm::EDPutTokenT<IntProduct> brToken_;
0660     const edm::EDPutTokenT<IntProduct> blToken_;
0661     const edm::EDPutTokenT<IntProduct> elToken_;
0662     const edm::EDPutTokenT<IntProduct> erToken_;
0663     const edm::EDPutTokenT<IntProduct> epbToken_;
0664     const int value_;
0665     const unsigned int sleepTime_;
0666     edm::EDGetTokenT<IntProduct> bpbGet_;
0667     edm::EDGetTokenT<IntProduct> brGet_;
0668     edm::EDGetTokenT<IntProduct> blGet_;
0669     edm::EDGetTokenT<IntProduct> elGet_;
0670     edm::EDGetTokenT<IntProduct> erGet_;
0671     edm::EDGetTokenT<IntProduct> epbGet_;
0672     edm::EDGetTokenT<IntProduct> aipbGet_;
0673     const int bpbExpect_;
0674     const int brExpect_;
0675     const int blExpect_;
0676     const int elExpect_;
0677     const int erExpect_;
0678     const int epbExpect_;
0679     const int aipbExpect_;
0680   };
0681 
0682   void NonEventIntProducer::accumulate(edm::StreamID iID, edm::Event const& e, edm::EventSetup const&) const {}
0683   void NonEventIntProducer::beginProcessBlockProduce(edm::ProcessBlock& processBlock) {
0684     if (not bpbGet_.isUninitialized()) {
0685       check(processBlock.get(bpbGet_), bpbExpect_);
0686     }
0687     if (sleepTime_ > 0) {
0688       // These sleeps are here to force modules to run concurrently
0689       // in multi-threaded processes. Otherwise, the modules are so
0690       // fast it is hard to tell whether a module finishes before the
0691       // the Framework starts the next module.
0692       usleep(sleepTime_);
0693     }
0694     processBlock.emplace(bpbToken_, value_);
0695   }
0696   void NonEventIntProducer::endProcessBlockProduce(edm::ProcessBlock& processBlock) {
0697     if (not epbGet_.isUninitialized()) {
0698       check(processBlock.get(epbGet_), epbExpect_);
0699     }
0700     if (sleepTime_ > 0) {
0701       usleep(sleepTime_);
0702     }
0703     processBlock.emplace(epbToken_, value_);
0704   }
0705   void NonEventIntProducer::accessInputProcessBlock(edm::ProcessBlock const& processBlock) {
0706     if (not aipbGet_.isUninitialized()) {
0707       check(processBlock.get(aipbGet_), aipbExpect_);
0708     }
0709     if (sleepTime_ > 0) {
0710       usleep(sleepTime_);
0711     }
0712   }
0713   void NonEventIntProducer::globalBeginRunProduce(edm::Run& r, edm::EventSetup const&) const {
0714     if (not brGet_.isUninitialized()) {
0715       check(r.get(brGet_), brExpect_);
0716     }
0717     if (sleepTime_ > 0) {
0718       usleep(sleepTime_);
0719     }
0720     r.emplace(brToken_, value_);
0721   }
0722   void NonEventIntProducer::globalEndRunProduce(edm::Run& r, edm::EventSetup const&) const {
0723     if (not erGet_.isUninitialized()) {
0724       check(r.get(erGet_), erExpect_);
0725     }
0726     if (sleepTime_ > 0) {
0727       usleep(sleepTime_);
0728     }
0729     r.emplace(erToken_, value_);
0730   }
0731   void NonEventIntProducer::globalBeginLuminosityBlockProduce(edm::LuminosityBlock& l, edm::EventSetup const&) const {
0732     if (not blGet_.isUninitialized()) {
0733       check(l.get(blGet_), blExpect_);
0734     }
0735     if (sleepTime_ > 0) {
0736       usleep(sleepTime_);
0737     }
0738     l.emplace(blToken_, value_);
0739   }
0740   void NonEventIntProducer::globalEndLuminosityBlockProduce(edm::LuminosityBlock& l, edm::EventSetup const&) const {
0741     if (not elGet_.isUninitialized()) {
0742       check(l.get(elGet_), elExpect_);
0743     }
0744     if (sleepTime_ > 0) {
0745       usleep(sleepTime_);
0746     }
0747     l.emplace(elToken_, value_);
0748   }
0749   void NonEventIntProducer::check(IntProduct iProd, int iExpect) const {
0750     if (iExpect != iProd.value) {
0751       throw cms::Exception("BadValue") << "expected " << iExpect << " but got " << iProd.value;
0752     }
0753   }
0754 
0755   //--------------------------------------------------------------------
0756   //
0757   // Produces an IntProduct in ProcessBlock at beginProcessBlock
0758   //
0759   class IntProducerBeginProcessBlock : public edm::global::EDProducer<edm::BeginProcessBlockProducer> {
0760   public:
0761     explicit IntProducerBeginProcessBlock(edm::ParameterSet const& p)
0762         : token_{produces<IntProduct, edm::Transition::BeginProcessBlock>()}, value_(p.getParameter<int>("ivalue")) {}
0763     void produce(edm::StreamID, edm::Event&, edm::EventSetup const&) const override {}
0764     void beginProcessBlockProduce(edm::ProcessBlock&) override;
0765 
0766   private:
0767     edm::EDPutTokenT<IntProduct> token_;
0768     int value_;
0769   };
0770 
0771   void IntProducerBeginProcessBlock::beginProcessBlockProduce(edm::ProcessBlock& processBlock) {
0772     processBlock.emplace(token_, value_);
0773   }
0774 
0775   //--------------------------------------------------------------------
0776   //
0777   // Produces an IntProduct in ProcessBlock at endProcessBlock
0778   //
0779   class IntProducerEndProcessBlock : public edm::global::EDProducer<edm::EndProcessBlockProducer> {
0780   public:
0781     explicit IntProducerEndProcessBlock(edm::ParameterSet const& p)
0782         : token_{produces<IntProduct, edm::Transition::EndProcessBlock>()},
0783           token2_{produces<IntProduct, edm::Transition::EndProcessBlock>("two")},
0784           token3_{produces<IntProduct, edm::Transition::EndProcessBlock>("three")},
0785           token4_{produces<IntProduct, edm::Transition::EndProcessBlock>("four")},
0786           value_(p.getParameter<int>("ivalue")) {}
0787     void produce(edm::StreamID, edm::Event&, edm::EventSetup const&) const override {}
0788     void endProcessBlockProduce(edm::ProcessBlock&) override;
0789 
0790   private:
0791     edm::EDPutTokenT<IntProduct> token_;
0792     edm::EDPutToken token2_;
0793     edm::EDPutTokenT<IntProduct> token3_;
0794     edm::EDPutToken token4_;
0795     int value_;
0796   };
0797 
0798   void IntProducerEndProcessBlock::endProcessBlockProduce(edm::ProcessBlock& processBlock) {
0799     processBlock.emplace(token_, value_);
0800     processBlock.emplace<IntProduct>(token2_, value_ + 2);
0801     processBlock.put(token3_, std::make_unique<IntProduct>(value_ + 3));
0802     processBlock.put(token4_, std::make_unique<IntProduct>(value_ + 4));
0803   }
0804 
0805   //--------------------------------------------------------------------
0806   //
0807   // Produces an TransientIntProduct in ProcessBlock at endProcessBlock
0808   //
0809   class TransientIntProducerEndProcessBlock : public edm::global::EDProducer<edm::EndProcessBlockProducer> {
0810   public:
0811     explicit TransientIntProducerEndProcessBlock(edm::ParameterSet const& p)
0812         : token_{produces<TransientIntProduct, edm::Transition::EndProcessBlock>()},
0813           value_(p.getParameter<int>("ivalue")) {}
0814     void produce(edm::StreamID, edm::Event&, edm::EventSetup const&) const override {}
0815     void endProcessBlockProduce(edm::ProcessBlock&) override;
0816 
0817   private:
0818     edm::EDPutTokenT<TransientIntProduct> token_;
0819     int value_;
0820   };
0821 
0822   void TransientIntProducerEndProcessBlock::endProcessBlockProduce(edm::ProcessBlock& processBlock) {
0823     processBlock.emplace(token_, value_);
0824   }
0825 
0826   //--------------------------------------------------------------------
0827   //
0828   // Produces an IntProduct instance, the module must get run, otherwise an exception is thrown
0829   class MustRunIntProducer : public edm::global::EDProducer<> {
0830   public:
0831     explicit MustRunIntProducer(edm::ParameterSet const& p)
0832         : moduleLabel_{p.getParameter<std::string>("@module_label")},
0833           token_{produces<IntProduct>()},
0834           value_(p.getParameter<int>("ivalue")),
0835           produce_{p.getParameter<bool>("produce")},
0836           mustRunEvent_{p.getParameter<bool>("mustRunEvent")} {}
0837     ~MustRunIntProducer() {
0838       if (not wasRunEndJob_) {
0839         throw cms::Exception("NotRun") << "This module (" << moduleLabel_
0840                                        << ") should have run for endJob transition, but it did not";
0841       }
0842     }
0843     static void fillDescriptions(edm::ConfigurationDescriptions& descriptions) {
0844       edm::ParameterSetDescription desc;
0845       desc.add<int>("ivalue");
0846       desc.add<bool>("produce", true);
0847       desc.add<bool>("mustRunEvent", true)
0848           ->setComment(
0849               "If set to false, the endJob() is still required to be called to check that the module was not deleted "
0850               "early on");
0851       descriptions.addDefault(desc);
0852     }
0853     void produce(edm::StreamID, edm::Event& e, edm::EventSetup const& c) const override {
0854       wasRunEvent_ = true;
0855       if (produce_) {
0856         e.emplace(token_, value_);
0857       }
0858     }
0859     void endJob() override {
0860       wasRunEndJob_ = true;
0861       if (mustRunEvent_ and not wasRunEvent_) {
0862         throw cms::Exception("NotRun") << "This module should have run for event transitions, but it did not";
0863       }
0864     }
0865 
0866   private:
0867     const std::string moduleLabel_;
0868     const edm::EDPutTokenT<IntProduct> token_;
0869     const int value_;
0870     const bool produce_;
0871     const bool mustRunEvent_;
0872     mutable std::atomic<bool> wasRunEndJob_ = false;
0873     mutable std::atomic<bool> wasRunEvent_ = false;
0874   };
0875 }  // namespace edmtest
0876 
0877 using edmtest::AddAllIntsProducer;
0878 using edmtest::AddIntsProducer;
0879 using edmtest::BusyWaitIntLegacyProducer;
0880 using edmtest::BusyWaitIntLimitedProducer;
0881 using edmtest::BusyWaitIntProducer;
0882 using edmtest::ConsumingIntProducer;
0883 using edmtest::EventNumberIntProducer;
0884 using edmtest::FailingProducer;
0885 using edmtest::Int16_tProducer;
0886 using edmtest::IntLegacyProducer;
0887 using edmtest::IntProducer;
0888 using edmtest::IntProducerBeginProcessBlock;
0889 using edmtest::IntProducerEndProcessBlock;
0890 using edmtest::IntProducerFromTransient;
0891 using edmtest::ManyIntProducer;
0892 using edmtest::ManyIntWhenRegisteredProducer;
0893 using edmtest::NonEventIntProducer;
0894 using edmtest::NonProducer;
0895 using edmtest::TransientIntProducer;
0896 using edmtest::TransientIntProducerEndProcessBlock;
0897 DEFINE_FWK_MODULE(FailingProducer);
0898 DEFINE_FWK_MODULE(edmtest::FailingInLumiProducer);
0899 DEFINE_FWK_MODULE(edmtest::FailingInRunProducer);
0900 DEFINE_FWK_MODULE(NonProducer);
0901 DEFINE_FWK_MODULE(IntProducer);
0902 DEFINE_FWK_MODULE(IntLegacyProducer);
0903 DEFINE_FWK_MODULE(BusyWaitIntProducer);
0904 DEFINE_FWK_MODULE(BusyWaitIntLimitedProducer);
0905 DEFINE_FWK_MODULE(BusyWaitIntLegacyProducer);
0906 DEFINE_FWK_MODULE(ConsumingIntProducer);
0907 DEFINE_FWK_MODULE(EventNumberIntProducer);
0908 DEFINE_FWK_MODULE(TransientIntProducer);
0909 DEFINE_FWK_MODULE(IntProducerFromTransient);
0910 DEFINE_FWK_MODULE(Int16_tProducer);
0911 DEFINE_FWK_MODULE(AddIntsProducer);
0912 DEFINE_FWK_MODULE(AddAllIntsProducer);
0913 DEFINE_FWK_MODULE(ManyIntProducer);
0914 DEFINE_FWK_MODULE(ManyIntWhenRegisteredProducer);
0915 DEFINE_FWK_MODULE(NonEventIntProducer);
0916 DEFINE_FWK_MODULE(IntProducerBeginProcessBlock);
0917 DEFINE_FWK_MODULE(IntProducerEndProcessBlock);
0918 DEFINE_FWK_MODULE(TransientIntProducerEndProcessBlock);
0919 DEFINE_FWK_MODULE(edmtest::MustRunIntProducer);