File indexing completed on 2022-09-29 01:11:55
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040
0041
0042
0043
0044
0045
0046 #ifndef GeneratorInterface_Core_ConcurrentGeneratorFilter_h
0047 #define GeneratorInterface_Core_ConcurrentGeneratorFilter_h
0048
0049 #include <memory>
0050 #include <string>
0051 #include <vector>
0052 #include <atomic>
0053
0054 #include "FWCore/Framework/interface/global/EDFilter.h"
0055 #include "FWCore/Framework/interface/Event.h"
0056 #include "FWCore/Framework/interface/EventSetup.h"
0057 #include "FWCore/Framework/interface/FileBlock.h"
0058 #include "FWCore/Framework/interface/LuminosityBlock.h"
0059 #include "FWCore/Framework/interface/MakerMacros.h"
0060 #include "FWCore/Framework/interface/Run.h"
0061 #include "FWCore/ParameterSet/interface/ParameterSet.h"
0062 #include "FWCore/ServiceRegistry/interface/RandomEngineSentry.h"
0063 #include "FWCore/Utilities/interface/BranchType.h"
0064 #include "FWCore/Utilities/interface/EDMException.h"
0065 #include "FWCore/Utilities/interface/EDGetToken.h"
0066 #include "FWCore/Utilities/interface/TypeID.h"
0067 #include "DataFormats/Provenance/interface/BranchDescription.h"
0068 #include "CLHEP/Random/RandomEngine.h"
0069
0070
0071 #include "SimDataFormats/GeneratorProducts/interface/LHERunInfoProduct.h"
0072 #include "GeneratorInterface/LHEInterface/interface/LHERunInfo.h"
0073
0074
0075 #include "SimDataFormats/GeneratorProducts/interface/LHEEventProduct.h"
0076 #include "GeneratorInterface/LHEInterface/interface/LHEEvent.h"
0077
0078 #include "SimDataFormats/GeneratorProducts/interface/HepMCProduct.h"
0079 #include "SimDataFormats/GeneratorProducts/interface/GenRunInfoProduct.h"
0080 #include "SimDataFormats/GeneratorProducts/interface/GenLumiInfoHeader.h"
0081 #include "SimDataFormats/GeneratorProducts/interface/GenLumiInfoProduct.h"
0082 #include "SimDataFormats/GeneratorProducts/interface/GenEventInfoProduct.h"
0083
0084 namespace edm {
0085 namespace gen {
0086 struct GenRunCache {
0087 mutable std::atomic<GenRunInfoProduct*> product_{nullptr};
0088 ~GenRunCache() { delete product_.load(); }
0089
0090
0091
0092
0093 std::unique_ptr<GenRunInfoProduct> release() const noexcept {
0094 auto retValue = product_.load();
0095 product_.store(nullptr);
0096 return std::unique_ptr<GenRunInfoProduct>(retValue);
0097 }
0098 };
0099 struct GenLumiSummary {
0100 mutable std::unique_ptr<GenLumiInfoProduct> lumiInfo_;
0101 };
0102 template <typename HAD, typename DEC>
0103 struct GenStreamCache {
0104 GenStreamCache(ParameterSet const& iPSet) : hadronizer_{iPSet}, nEventsInLumiBlock_{0} {}
0105 HAD hadronizer_;
0106 std::unique_ptr<DEC> decayer_;
0107 unsigned int nEventsInLumiBlock_;
0108 unsigned long long nStreamEndLumis_{0};
0109 bool initialized_ = false;
0110 };
0111 template <typename HAD, typename DEC>
0112 struct GenLumiCache {
0113 gen::GenStreamCache<HAD, DEC>* useInLumi_{nullptr};
0114 };
0115 }
0116
0117 template <class HAD, class DEC>
0118 class ConcurrentGeneratorFilter : public global::EDFilter<EndRunProducer,
0119 BeginLuminosityBlockProducer,
0120 EndLuminosityBlockProducer,
0121 RunCache<gen::GenRunCache>,
0122 LuminosityBlockCache<gen::GenLumiCache<HAD, DEC>>,
0123 LuminosityBlockSummaryCache<gen::GenLumiSummary>,
0124 StreamCache<gen::GenStreamCache<HAD, DEC>>> {
0125 public:
0126 typedef HAD Hadronizer;
0127 typedef DEC Decayer;
0128
0129
0130 explicit ConcurrentGeneratorFilter(ParameterSet const& ps);
0131
0132 bool filter(StreamID id, Event& e, EventSetup const& es) const override;
0133 std::unique_ptr<gen::GenStreamCache<HAD, DEC>> beginStream(StreamID) const override;
0134 std::shared_ptr<gen::GenRunCache> globalBeginRun(Run const&, EventSetup const&) const override;
0135 std::shared_ptr<gen::GenLumiSummary> globalBeginLuminosityBlockSummary(LuminosityBlock const&,
0136 EventSetup const&) const override;
0137 std::shared_ptr<gen::GenLumiCache<HAD, DEC>> globalBeginLuminosityBlock(LuminosityBlock const&,
0138 EventSetup const&) const override;
0139 void globalBeginLuminosityBlockProduce(LuminosityBlock&, EventSetup const&) const override;
0140 void streamBeginLuminosityBlock(StreamID, LuminosityBlock const&, EventSetup const&) const override;
0141 void streamEndLuminosityBlock(StreamID, LuminosityBlock const&, EventSetup const&) const override;
0142 void streamEndLuminosityBlockSummary(StreamID,
0143 LuminosityBlock const&,
0144 EventSetup const&,
0145 gen::GenLumiSummary*) const override;
0146 void globalEndLuminosityBlock(LuminosityBlock const&, EventSetup const&) const override;
0147 void globalEndLuminosityBlockSummary(LuminosityBlock const&,
0148 EventSetup const&,
0149 gen::GenLumiSummary*) const override;
0150 void globalEndLuminosityBlockProduce(LuminosityBlock&,
0151 EventSetup const&,
0152 gen::GenLumiSummary const*) const override;
0153 void streamEndRun(StreamID, Run const&, EventSetup const&) const override;
0154 void globalEndRun(Run const&, EventSetup const&) const override;
0155 void globalEndRunProduce(Run&, EventSetup const&) const override;
0156
0157 private:
0158 void initLumi(gen::GenStreamCache<HAD, DEC>* cache, LuminosityBlock const& index, EventSetup const& es) const;
0159 ParameterSet config_;
0160 mutable std::atomic<gen::GenStreamCache<HAD, DEC>*> useInLumi_{nullptr};
0161 mutable std::atomic<unsigned long long> greatestNStreamEndLumis_{0};
0162 mutable std::atomic<bool> streamEndRunComplete_{true};
0163
0164
0165 mutable unsigned long long nGlobalBeginRuns_{0};
0166 mutable unsigned long long nInitializedInGlobalLumiAfterNewRun_{0};
0167 };
0168
0169
0170
0171
0172
0173 template <class HAD, class DEC>
0174 ConcurrentGeneratorFilter<HAD, DEC>::ConcurrentGeneratorFilter(ParameterSet const& ps) : config_(ps) {
0175
0176
0177
0178
0179
0180
0181
0182
0183
0184 this->template produces<HepMCProduct>("unsmeared");
0185 this->template produces<GenEventInfoProduct>();
0186 this->template produces<GenLumiInfoHeader, edm::Transition::BeginLuminosityBlock>();
0187 this->template produces<GenLumiInfoProduct, edm::Transition::EndLuminosityBlock>();
0188 this->template produces<GenRunInfoProduct, edm::Transition::EndRun>();
0189 }
0190
0191 template <class HAD, class DEC>
0192 std::unique_ptr<gen::GenStreamCache<HAD, DEC>> ConcurrentGeneratorFilter<HAD, DEC>::beginStream(StreamID) const {
0193 auto cache = std::make_unique<gen::GenStreamCache<HAD, DEC>>(config_);
0194
0195 if (config_.exists("ExternalDecays")) {
0196 ParameterSet ps1 = config_.getParameter<ParameterSet>("ExternalDecays");
0197 cache->decayer_.reset(new Decayer(ps1));
0198 }
0199
0200
0201 gen::GenStreamCache<HAD, DEC>* expected = nullptr;
0202 useInLumi_.compare_exchange_strong(expected, cache.get());
0203
0204 return cache;
0205 }
0206
0207 template <class HAD, class DEC>
0208 std::shared_ptr<gen::GenRunCache> ConcurrentGeneratorFilter<HAD, DEC>::globalBeginRun(Run const&,
0209 EventSetup const&) const {
0210 ++nGlobalBeginRuns_;
0211 return std::make_shared<gen::GenRunCache>();
0212 }
0213
0214 template <class HAD, class DEC>
0215 std::shared_ptr<gen::GenLumiSummary> ConcurrentGeneratorFilter<HAD, DEC>::globalBeginLuminosityBlockSummary(
0216 LuminosityBlock const&, EventSetup const&) const {
0217 return std::make_shared<gen::GenLumiSummary>();
0218 }
0219
0220 template <class HAD, class DEC>
0221 void ConcurrentGeneratorFilter<HAD, DEC>::initLumi(gen::GenStreamCache<HAD, DEC>* cache,
0222 LuminosityBlock const& lumi,
0223 EventSetup const& es) const {
0224 cache->nEventsInLumiBlock_ = 0;
0225
0226
0227 Service<RandomNumberGenerator> rng;
0228 auto enginePtr = rng->cloneEngine(lumi.index());
0229 cache->hadronizer_.setRandomEngine(enginePtr.get());
0230 if (cache->decayer_) {
0231 cache->decayer_->setRandomEngine(enginePtr.get());
0232 }
0233
0234 auto unsetH = [](HAD* h) { h->setRandomEngine(nullptr); };
0235 auto unsetD = [](DEC* d) {
0236 if (d) {
0237 d->setRandomEngine(nullptr);
0238 }
0239 };
0240
0241 std::unique_ptr<HAD, decltype(unsetH)> randomEngineSentry(&cache->hadronizer_, unsetH);
0242 std::unique_ptr<DEC, decltype(unsetD)> randomEngineSentryDecay(cache->decayer_.get(), unsetD);
0243
0244 cache->hadronizer_.randomizeIndex(lumi, enginePtr.get());
0245
0246 if (!cache->hadronizer_.readSettings(0))
0247 throw edm::Exception(errors::Configuration)
0248 << "Failed to read settings for the hadronizer " << cache->hadronizer_.classname() << " \n";
0249
0250 if (cache->decayer_) {
0251 cache->decayer_->init(es);
0252 if (!cache->hadronizer_.declareStableParticles(cache->decayer_->operatesOnParticles()))
0253 throw edm::Exception(errors::Configuration)
0254 << "Failed to declare stable particles in hadronizer " << cache->hadronizer_.classname()
0255 << " for internal parton generation\n";
0256 if (!cache->hadronizer_.declareSpecialSettings(cache->decayer_->specialSettings()))
0257 throw edm::Exception(errors::Configuration)
0258 << "Failed to declare special settings in hadronizer " << cache->hadronizer_.classname() << "\n";
0259 }
0260
0261 if (!cache->hadronizer_.initializeForInternalPartons())
0262 throw edm::Exception(errors::Configuration)
0263 << "Failed to initialize hadronizer " << cache->hadronizer_.classname()
0264 << " for internal parton generation\n";
0265
0266 cache->initialized_ = true;
0267 }
0268
0269 template <class HAD, class DEC>
0270 bool ConcurrentGeneratorFilter<HAD, DEC>::filter(StreamID id, Event& ev, EventSetup const& ) const {
0271 auto cache = this->streamCache(id);
0272 RandomEngineSentry<HAD> randomEngineSentry(&cache->hadronizer_, ev.streamID());
0273 RandomEngineSentry<DEC> randomEngineSentryDecay(cache->decayer_.get(), ev.streamID());
0274
0275 cache->hadronizer_.setEDMEvent(ev);
0276
0277 bool passEvtGenSelector = false;
0278 std::unique_ptr<HepMC::GenEvent> event(nullptr);
0279
0280 while (!passEvtGenSelector) {
0281 event.reset();
0282 cache->hadronizer_.setEDMEvent(ev);
0283
0284 if (!cache->hadronizer_.generatePartonsAndHadronize())
0285 return false;
0286
0287
0288
0289
0290
0291
0292
0293 if (!cache->hadronizer_.decay())
0294 return false;
0295
0296 event = cache->hadronizer_.getGenEvent();
0297 if (!event.get())
0298 return false;
0299
0300
0301
0302
0303 if (cache->decayer_) {
0304 auto t = cache->decayer_->decay(event.get());
0305 if (t != event.get()) {
0306 event.reset(t);
0307 }
0308 }
0309 if (!event.get())
0310 return false;
0311
0312 passEvtGenSelector = cache->hadronizer_.select(event.get());
0313 }
0314
0315
0316
0317
0318
0319
0320 cache->hadronizer_.resetEvent(std::move(event));
0321
0322
0323
0324
0325 if (!cache->hadronizer_.residualDecay())
0326 return false;
0327
0328 cache->hadronizer_.finalizeEvent();
0329
0330 event = cache->hadronizer_.getGenEvent();
0331 if (!event.get())
0332 return false;
0333
0334 event->set_event_number(ev.id().event());
0335
0336
0337
0338
0339 std::unique_ptr<GenEventInfoProduct> genEventInfo(cache->hadronizer_.getGenEventInfo());
0340 if (!genEventInfo.get()) {
0341
0342 genEventInfo = std::make_unique<GenEventInfoProduct>(event.get());
0343 }
0344
0345 ev.put(std::move(genEventInfo));
0346
0347 std::unique_ptr<HepMCProduct> bare_product(new HepMCProduct());
0348 bare_product->addHepMCData(event.release());
0349 ev.put(std::move(bare_product), "unsmeared");
0350 cache->nEventsInLumiBlock_++;
0351 return true;
0352 }
0353
0354 template <class HAD, class DEC>
0355 std::shared_ptr<gen::GenLumiCache<HAD, DEC>> ConcurrentGeneratorFilter<HAD, DEC>::globalBeginLuminosityBlock(
0356 edm::LuminosityBlock const&, edm::EventSetup const&) const {
0357
0358 while (useInLumi_.load() == nullptr) {
0359 }
0360
0361
0362
0363 if (nInitializedInGlobalLumiAfterNewRun_ < nGlobalBeginRuns_) {
0364 while (!streamEndRunComplete_.load()) {
0365 }
0366 nInitializedInGlobalLumiAfterNewRun_ = nGlobalBeginRuns_;
0367 }
0368
0369 auto lumiCache = std::make_shared<gen::GenLumiCache<HAD, DEC>>();
0370 lumiCache->useInLumi_ = useInLumi_.load();
0371 return lumiCache;
0372 }
0373
0374 template <class HAD, class DEC>
0375 void ConcurrentGeneratorFilter<HAD, DEC>::globalBeginLuminosityBlockProduce(LuminosityBlock& lumi,
0376 EventSetup const& es) const {
0377 initLumi(useInLumi_, lumi, es);
0378 std::unique_ptr<GenLumiInfoHeader> genLumiInfoHeader(useInLumi_.load()->hadronizer_.getGenLumiInfoHeader());
0379 lumi.put(std::move(genLumiInfoHeader));
0380 useInLumi_.store(nullptr);
0381 }
0382
0383 template <class HAD, class DEC>
0384 void ConcurrentGeneratorFilter<HAD, DEC>::streamBeginLuminosityBlock(StreamID id,
0385 LuminosityBlock const& lumi,
0386 EventSetup const& es) const {
0387 gen::GenStreamCache<HAD, DEC>* streamCachePtr = this->streamCache(id);
0388 if (this->luminosityBlockCache(lumi.index())->useInLumi_ != streamCachePtr) {
0389 initLumi(streamCachePtr, lumi, es);
0390 }
0391 }
0392
0393 template <class HAD, class DEC>
0394 void ConcurrentGeneratorFilter<HAD, DEC>::streamEndLuminosityBlock(StreamID id,
0395 LuminosityBlock const&,
0396 EventSetup const&) const {
0397 this->streamCache(id)->hadronizer_.cleanLHE();
0398 }
0399
0400 template <class HAD, class DEC>
0401 void ConcurrentGeneratorFilter<HAD, DEC>::streamEndLuminosityBlockSummary(StreamID id,
0402 LuminosityBlock const&,
0403 EventSetup const&,
0404 gen::GenLumiSummary* iSummary) const {
0405 auto cache = this->streamCache(id);
0406 cache->hadronizer_.statistics();
0407 if (cache->decayer_)
0408 cache->decayer_->statistics();
0409
0410 GenRunInfoProduct genRunInfo = GenRunInfoProduct(cache->hadronizer_.getGenRunInfo());
0411 std::vector<GenLumiInfoProduct::ProcessInfo> GenLumiProcess;
0412 const GenRunInfoProduct::XSec& xsec = genRunInfo.internalXSec();
0413 GenLumiInfoProduct::ProcessInfo temp;
0414 unsigned int nEvtInLumiBlock_ = cache->nEventsInLumiBlock_;
0415 temp.setProcess(0);
0416 temp.setLheXSec(xsec.value(), xsec.error());
0417 temp.setNPassPos(nEvtInLumiBlock_);
0418 temp.setNPassNeg(0);
0419 temp.setNTotalPos(nEvtInLumiBlock_);
0420 temp.setNTotalNeg(0);
0421 temp.setTried(nEvtInLumiBlock_, nEvtInLumiBlock_, nEvtInLumiBlock_);
0422 temp.setSelected(nEvtInLumiBlock_, nEvtInLumiBlock_, nEvtInLumiBlock_);
0423 temp.setKilled(nEvtInLumiBlock_, nEvtInLumiBlock_, nEvtInLumiBlock_);
0424 temp.setAccepted(0, -1, -1);
0425 temp.setAcceptedBr(0, -1, -1);
0426 GenLumiProcess.push_back(temp);
0427
0428 GenLumiInfoProduct genLumiInfo;
0429 genLumiInfo.setHEPIDWTUP(-1);
0430 genLumiInfo.setProcessInfo(GenLumiProcess);
0431
0432 if (iSummary->lumiInfo_) {
0433 iSummary->lumiInfo_->mergeProduct(genLumiInfo);
0434 } else {
0435 iSummary->lumiInfo_ = std::make_unique<GenLumiInfoProduct>(std::move(genLumiInfo));
0436 }
0437
0438 cache->nEventsInLumiBlock_ = 0;
0439
0440
0441
0442
0443 gen::GenStreamCache<HAD, DEC>* streamCachePtr = this->streamCache(id);
0444 unsigned long long expected = streamCachePtr->nStreamEndLumis_;
0445 ++streamCachePtr->nStreamEndLumis_;
0446 if (greatestNStreamEndLumis_.compare_exchange_strong(expected, streamCachePtr->nStreamEndLumis_)) {
0447 streamEndRunComplete_ = false;
0448 useInLumi_ = streamCachePtr;
0449 }
0450 }
0451
0452 template <class HAD, class DEC>
0453 void ConcurrentGeneratorFilter<HAD, DEC>::globalEndLuminosityBlock(edm::LuminosityBlock const&,
0454 edm::EventSetup const&) const {}
0455
0456 template <class HAD, class DEC>
0457 void ConcurrentGeneratorFilter<HAD, DEC>::globalEndLuminosityBlockSummary(LuminosityBlock const&,
0458 EventSetup const&,
0459 gen::GenLumiSummary*) const {}
0460
0461 template <class HAD, class DEC>
0462 void ConcurrentGeneratorFilter<HAD, DEC>::globalEndLuminosityBlockProduce(LuminosityBlock& lumi,
0463 EventSetup const&,
0464 gen::GenLumiSummary const* iSummary) const {
0465 lumi.put(std::move(iSummary->lumiInfo_));
0466 }
0467
0468 template <class HAD, class DEC>
0469 void ConcurrentGeneratorFilter<HAD, DEC>::streamEndRun(StreamID id, Run const& run, EventSetup const&) const {
0470 auto rCache = this->runCache(run.index());
0471 auto cache = this->streamCache(id);
0472
0473
0474
0475
0476
0477
0478 if (cache->initialized_) {
0479 cache->hadronizer_.statistics();
0480 if (cache->decayer_)
0481 cache->decayer_->statistics();
0482 }
0483 GenRunInfoProduct& genRunInfo = cache->hadronizer_.getGenRunInfo();
0484 GenRunInfoProduct* expect = nullptr;
0485
0486 std::unique_ptr<GenRunInfoProduct> griproduct(new GenRunInfoProduct(genRunInfo));
0487
0488 if (rCache->product_.compare_exchange_strong(expect, griproduct.get())) {
0489 griproduct.release();
0490 }
0491 if (cache == useInLumi_.load()) {
0492 streamEndRunComplete_ = true;
0493 }
0494 }
0495
0496 template <class HAD, class DEC>
0497 void ConcurrentGeneratorFilter<HAD, DEC>::globalEndRun(Run const&, EventSetup const&) const {}
0498
0499 template <class HAD, class DEC>
0500 void ConcurrentGeneratorFilter<HAD, DEC>::globalEndRunProduce(Run& run, EventSetup const&) const {
0501 run.put(this->runCache(run.index())->release());
0502 }
0503
0504 }
0505
0506 #endif