Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2024-04-06 12:30:37

0001 // File: MixingModule.cc
0002 // Description:  see MixingModule.h
0003 // Author:  Ursula Berthon, LLR Palaiseau, Bill Tanenbaum
0004 //
0005 //--------------------------------------------
0006 
0007 #include <functional>
0008 #include <memory>
0009 
0010 #include "MixingModule.h"
0011 #include "MixingWorker.h"
0012 #include "Adjuster.h"
0013 
0014 #include "CondFormats/RunInfo/interface/MixingModuleConfig.h"
0015 #include "FWCore/MessageLogger/interface/MessageLogger.h"
0016 #include "FWCore/Utilities/interface/EDMException.h"
0017 #include "FWCore/Utilities/interface/Algorithms.h"
0018 #include "FWCore/Framework/interface/ConsumesCollector.h"
0019 #include "FWCore/Framework/interface/ESHandle.h"
0020 #include "FWCore/Framework/interface/EventSetup.h"
0021 #include "FWCore/Framework/interface/ModuleContextSentry.h"
0022 #include "FWCore/Framework/interface/TriggerNamesService.h"
0023 #include "FWCore/ServiceRegistry/interface/InternalContext.h"
0024 #include "FWCore/ServiceRegistry/interface/ModuleCallingContext.h"
0025 #include "FWCore/ServiceRegistry/interface/ParentContext.h"
0026 #include "FWCore/ServiceRegistry/interface/Service.h"
0027 #include "DataFormats/Common/interface/Handle.h"
0028 #include "DataFormats/Provenance/interface/Provenance.h"
0029 #include "DataFormats/Provenance/interface/BranchDescription.h"
0030 #include "SimDataFormats/CrossingFrame/interface/CrossingFramePlaybackInfoExtended.h"
0031 #include "SimDataFormats/CrossingFrame/interface/CrossingFramePlaybackInfoNew.h"
0032 #include "FWCore/Utilities/interface/TypeID.h"
0033 #include "SimGeneral/MixingModule/interface/DigiAccumulatorMixMod.h"
0034 #include "SimGeneral/MixingModule/interface/DigiAccumulatorMixModFactory.h"
0035 #include "SimGeneral/MixingModule/interface/PileUpEventPrincipal.h"
0036 #include "DataFormats/Common/interface/ValueMap.h"
0037 
0038 namespace edm {
0039 
0040   // Constructor
0041   MixingModule::MixingModule(const edm::ParameterSet& ps_mix, MixingCache::Config const* globalConf)
0042       : BMixingModule(ps_mix, globalConf),
0043         inputTagPlayback_(),
0044         mixProdStep2_(ps_mix.getParameter<bool>("mixProdStep2")),
0045         mixProdStep1_(ps_mix.getParameter<bool>("mixProdStep1")),
0046         digiAccumulators_() {
0047     if (!mixProdStep1_ && !mixProdStep2_)
0048       LogInfo("MixingModule") << " The MixingModule was run in the Standard mode.";
0049     if (mixProdStep1_)
0050       LogInfo("MixingModule") << " The MixingModule was run in the Step1 mode. It produces a mixed secondary source.";
0051     if (mixProdStep2_)
0052       LogInfo("MixingModule") << " The MixingModule was run in the Step2 mode. It uses a mixed secondary source.";
0053 
0054     useCurrentProcessOnly_ = false;
0055     if (ps_mix.exists("useCurrentProcessOnly")) {
0056       useCurrentProcessOnly_ = ps_mix.getParameter<bool>("useCurrentProcessOnly");
0057       LogInfo("MixingModule") << " using given Parameter 'useCurrentProcessOnly' =" << useCurrentProcessOnly_;
0058     }
0059     std::string labelPlayback;
0060     if (ps_mix.exists("LabelPlayback")) {
0061       labelPlayback = ps_mix.getParameter<std::string>("LabelPlayback");
0062     }
0063     if (labelPlayback.empty()) {
0064       labelPlayback = ps_mix.getParameter<std::string>("@module_label");
0065     }
0066     if (playback_) {
0067       inputTagPlayback_ = InputTag(labelPlayback, "", edm::InputTag::kSkipCurrentProcess);
0068       consumes<CrossingFramePlaybackInfoNew>(inputTagPlayback_);
0069     }
0070     wrapLongTimes_ = false;
0071     if (ps_mix.exists("WrapLongTimes")) {
0072       wrapLongTimes_ = ps_mix.getParameter<bool>("WrapLongTimes");
0073     }
0074 
0075     skipSignal_ = false;
0076     if (ps_mix.exists("skipSignal")) {
0077       skipSignal_ = ps_mix.getParameter<bool>("skipSignal");
0078     }
0079 
0080     ParameterSet ps = ps_mix.getParameter<ParameterSet>("mixObjects");
0081     std::vector<std::string> names = ps.getParameterNames();
0082     for (std::vector<std::string>::iterator it = names.begin(); it != names.end(); ++it) {
0083       ParameterSet pset = ps.getParameter<ParameterSet>((*it));
0084       if (!pset.exists("type"))
0085         continue;  //to allow replacement by empty pset
0086       std::string object = pset.getParameter<std::string>("type");
0087       std::vector<InputTag> tags = pset.getParameter<std::vector<InputTag> >("input");
0088 
0089       //if (!mixProdStep2_) {
0090 
0091       InputTag tagCF = InputTag();
0092       std::string labelCF = " ";
0093 
0094       if (object == "SimTrack") {
0095         InputTag tag;
0096         if (!tags.empty())
0097           tag = tags[0];
0098         std::string label;
0099 
0100         branchesActivate(TypeID(typeid(std::vector<SimTrack>)).friendlyClassName(), std::string(""), tag, label);
0101         adjustersObjects_.push_back(new Adjuster<std::vector<SimTrack> >(tag, consumesCollector(), wrapLongTimes_));
0102         bool makeCrossingFrame = pset.getUntrackedParameter<bool>("makeCrossingFrame", false);
0103         if (makeCrossingFrame) {
0104           workersObjects_.push_back(new MixingWorker<SimTrack>(
0105               minBunch_, maxBunch_, bunchSpace_, std::string(""), label, labelCF, maxNbSources_, tag, tagCF));
0106           produces<CrossingFrame<SimTrack> >(label);
0107         }
0108         consumes<std::vector<SimTrack> >(tag);
0109 
0110         LogInfo("MixingModule") << "Will mix " << object << "s with InputTag= " << tag.encode() << ", label will be "
0111                                 << label;
0112         //            std::cout <<"Will mix "<<object<<"s with InputTag= "<<tag.encode()<<", label will be "<<label<<std::endl;
0113 
0114       } else if (object == "RecoTrack") {
0115         InputTag tag;
0116         if (!tags.empty())
0117           tag = tags[0];
0118         std::string label;
0119 
0120         branchesActivate(TypeID(typeid(std::vector<reco::Track>)).friendlyClassName(), std::string(""), tag, label);
0121         branchesActivate(
0122             TypeID(typeid(std::vector<reco::TrackExtra>)).friendlyClassName(), std::string(""), tag, label);
0123         branchesActivate(
0124             TypeID(typeid(edm::OwnVector<TrackingRecHit, edm::ClonePolicy<TrackingRecHit> >)).friendlyClassName(),
0125             std::string(""),
0126             tag,
0127             label);
0128         adjustersObjects_.push_back(
0129             new Adjuster<edm::OwnVector<TrackingRecHit> >(tag, consumesCollector(), wrapLongTimes_));
0130         // note: no crossing frame is foreseen to be used for this object type
0131 
0132         LogInfo("MixingModule") << "Will mix " << object << "s with InputTag= " << tag.encode() << ", label will be "
0133                                 << label;
0134         //std::cout <<"Will mix "<<object<<"s with InputTag= "<<tag.encode()<<", label will be "<<label<<std::endl;
0135 
0136       } else if (object == "SimVertex") {
0137         InputTag tag;
0138         if (!tags.empty())
0139           tag = tags[0];
0140         std::string label;
0141 
0142         branchesActivate(TypeID(typeid(std::vector<SimVertex>)).friendlyClassName(), std::string(""), tag, label);
0143         adjustersObjects_.push_back(new Adjuster<std::vector<SimVertex> >(tag, consumesCollector(), wrapLongTimes_));
0144         bool makeCrossingFrame = pset.getUntrackedParameter<bool>("makeCrossingFrame", false);
0145         if (makeCrossingFrame) {
0146           workersObjects_.push_back(new MixingWorker<SimVertex>(
0147               minBunch_, maxBunch_, bunchSpace_, std::string(""), label, labelCF, maxNbSources_, tag, tagCF));
0148           produces<CrossingFrame<SimVertex> >(label);
0149         }
0150         consumes<std::vector<SimVertex> >(tag);
0151 
0152         LogInfo("MixingModule") << "Will mix " << object << "s with InputTag " << tag.encode() << ", label will be "
0153                                 << label;
0154         //            std::cout <<"Will mix "<<object<<"s with InputTag "<<tag.encode()<<", label will be "<<label<<std::endl;
0155 
0156       } else if (object == "HepMCProduct") {
0157         InputTag tag;
0158         if (!tags.empty())
0159           tag = tags[0];
0160         std::string label;
0161 
0162         branchesActivate(TypeID(typeid(HepMCProduct)).friendlyClassName(), std::string(""), tag, label);
0163         bool makeCrossingFrame = pset.getUntrackedParameter<bool>("makeCrossingFrame", false);
0164         if (makeCrossingFrame) {
0165           workersObjects_.push_back(new MixingWorker<HepMCProduct>(
0166               minBunch_, maxBunch_, bunchSpace_, std::string(""), label, labelCF, maxNbSources_, tag, tagCF, tags));
0167           produces<CrossingFrame<HepMCProduct> >(label);
0168         }
0169         consumes<HepMCProduct>(tag);
0170 
0171         LogInfo("MixingModule") << "Will mix " << object << "s with InputTag= " << tag.encode() << ", label will be "
0172                                 << label;
0173         //            std::cout <<"Will mix "<<object<<"s with InputTag= "<<tag.encode()<<", label will be "<<label<<std::endl;
0174         for (size_t i = 1; i < tags.size(); ++i) {
0175           InputTag fallbackTag = tags[i];
0176           std::string fallbackLabel;
0177           branchesActivate(
0178               TypeID(typeid(HepMCProduct)).friendlyClassName(), std::string(""), fallbackTag, fallbackLabel);
0179           mayConsume<HepMCProduct>(fallbackTag);
0180         }
0181 
0182       } else if (object == "PCaloHit") {
0183         std::vector<std::string> subdets = pset.getParameter<std::vector<std::string> >("subdets");
0184         std::vector<std::string> crossingFrames =
0185             pset.getUntrackedParameter<std::vector<std::string> >("crossingFrames", std::vector<std::string>());
0186         sort_all(crossingFrames);
0187         for (unsigned int ii = 0; ii < subdets.size(); ++ii) {
0188           InputTag tag;
0189           if (tags.size() == 1)
0190             tag = tags[0];
0191           else if (tags.size() > 1)
0192             tag = tags[ii];
0193           std::string label;
0194 
0195           branchesActivate(TypeID(typeid(std::vector<PCaloHit>)).friendlyClassName(), subdets[ii], tag, label);
0196           adjustersObjects_.push_back(new Adjuster<std::vector<PCaloHit> >(tag, consumesCollector(), wrapLongTimes_));
0197           if (binary_search_all(crossingFrames, tag.instance())) {
0198             workersObjects_.push_back(new MixingWorker<PCaloHit>(
0199                 minBunch_, maxBunch_, bunchSpace_, subdets[ii], label, labelCF, maxNbSources_, tag, tagCF));
0200             produces<CrossingFrame<PCaloHit> >(label);
0201             consumes<std::vector<PCaloHit> >(tag);
0202           }
0203 
0204           LogInfo("MixingModule") << "Will mix " << object << "s with InputTag= " << tag.encode() << ", label will be "
0205                                   << label;
0206           //              std::cout <<"Will mix "<<object<<"s with InputTag= "<<tag.encode()<<", label will be "<<label<<std::endl;
0207         }
0208 
0209       } else if (object == "PSimHit") {
0210         std::vector<std::string> subdets = pset.getParameter<std::vector<std::string> >("subdets");
0211         std::vector<std::string> crossingFrames =
0212             pset.getUntrackedParameter<std::vector<std::string> >("crossingFrames", std::vector<std::string>());
0213         sort_all(crossingFrames);
0214         std::vector<std::string> pcrossingFrames =
0215             pset.getUntrackedParameter<std::vector<std::string> >("pcrossingFrames", std::vector<std::string>());
0216         sort_all(pcrossingFrames);
0217         for (unsigned int ii = 0; ii < subdets.size(); ++ii) {
0218           InputTag tag;
0219           if (tags.size() == 1)
0220             tag = tags[0];
0221           else if (tags.size() > 1)
0222             tag = tags[ii];
0223           std::string label;
0224 
0225           branchesActivate(TypeID(typeid(std::vector<PSimHit>)).friendlyClassName(), subdets[ii], tag, label);
0226           adjustersObjects_.push_back(new Adjuster<std::vector<PSimHit> >(tag, consumesCollector(), wrapLongTimes_));
0227           if (binary_search_all(crossingFrames, tag.instance())) {
0228             bool makePCrossingFrame = binary_search_all(pcrossingFrames, tag.instance());
0229             workersObjects_.push_back(new MixingWorker<PSimHit>(minBunch_,
0230                                                                 maxBunch_,
0231                                                                 bunchSpace_,
0232                                                                 subdets[ii],
0233                                                                 label,
0234                                                                 labelCF,
0235                                                                 maxNbSources_,
0236                                                                 tag,
0237                                                                 tagCF,
0238                                                                 makePCrossingFrame));
0239             produces<CrossingFrame<PSimHit> >(label);
0240             if (makePCrossingFrame) {
0241               produces<PCrossingFrame<PSimHit> >(label);
0242             }
0243             consumes<std::vector<PSimHit> >(tag);
0244           }
0245 
0246           LogInfo("MixingModule") << "Will mix " << object << "s with InputTag= " << tag.encode() << ", label will be "
0247                                   << label;
0248           //              std::cout <<"Will mix "<<object<<"s with InputTag= "<<tag.encode()<<", label will be "<<label<<std::endl;
0249         }
0250       } else {
0251         LogWarning("MixingModule")
0252             << "You have asked to mix an unknown type of object(" << object
0253             << ").\n If you want to include it in mixing, please contact the authors of the MixingModule!";
0254       }
0255       //} //if for mixProdStep2
0256     }  //while over the mixObjects parameters
0257 
0258     sort_all(wantedBranches_);
0259     for (unsigned int branch = 0; branch < wantedBranches_.size(); ++branch)
0260       LogDebug("MixingModule") << "Will keep branch " << wantedBranches_[branch] << " for mixing ";
0261 
0262     dropUnwantedBranches(wantedBranches_);
0263 
0264     produces<PileupMixingContent>();
0265 
0266     produces<CrossingFramePlaybackInfoNew>();
0267 
0268     edm::ConsumesCollector iC(consumesCollector());
0269     if (globalConf->configFromDB_) {
0270       configToken_ = esConsumes<edm::Transition::BeginLuminosityBlock>();
0271     }
0272     // Create and configure digitizers
0273     createDigiAccumulators(ps_mix, iC);
0274   }
0275 
0276   void MixingModule::createDigiAccumulators(const edm::ParameterSet& mixingPSet, edm::ConsumesCollector& iC) {
0277     ParameterSet const& digiPSet = mixingPSet.getParameterSet("digitizers");
0278     std::vector<std::string> digiNames = digiPSet.getParameterNames();
0279     for (auto const& digiName : digiNames) {
0280       ParameterSet const& pset = digiPSet.getParameterSet(digiName);
0281       if (pset.existsAs<edm::InputTag>("HepMCProductLabel")) {
0282         consumes<HepMCProduct>(pset.getParameter<edm::InputTag>("HepMCProductLabel"));
0283       }
0284       std::unique_ptr<DigiAccumulatorMixMod> accumulator = std::unique_ptr<DigiAccumulatorMixMod>(
0285           DigiAccumulatorMixModFactory::get()->makeDigiAccumulator(pset, producesCollector(), iC));
0286       // Create appropriate DigiAccumulator
0287       if (accumulator.get() != nullptr) {
0288         digiAccumulators_.push_back(accumulator.release());
0289       }
0290     }
0291   }
0292 
0293   void MixingModule::reload(const edm::EventSetup& setup) {
0294     //change the basic parameters.
0295     auto const& config = setup.getData(configToken_);
0296     minBunch_ = config.minBunch();
0297     maxBunch_ = config.maxBunch();
0298     bunchSpace_ = config.bunchSpace();
0299     //propagate to change the workers
0300     for (unsigned int ii = 0; ii < workersObjects_.size(); ++ii) {
0301       workersObjects_[ii]->reload(minBunch_, maxBunch_, bunchSpace_);
0302     }
0303   }
0304 
0305   void MixingModule::branchesActivate(const std::string& friendlyName,
0306                                       const std::string& subdet,
0307                                       InputTag& tag,
0308                                       std::string& label) {
0309     label = tag.label() + tag.instance();
0310     wantedBranches_.push_back(friendlyName + '_' + tag.label() + '_' + tag.instance());
0311 
0312     //if useCurrentProcessOnly, we have to change the input tag
0313     if (useCurrentProcessOnly_) {
0314       const std::string processName = edm::Service<edm::service::TriggerNamesService>()->getProcessName();
0315       tag = InputTag(tag.label(), tag.instance(), processName);
0316     }
0317   }
0318 
0319   void MixingModule::checkSignal(const edm::Event& e) {
0320     if (adjusters_.empty()) {
0321       for (auto const& adjuster : adjustersObjects_) {
0322         if (skipSignal_ or adjuster->checkSignal(e)) {
0323           adjusters_.push_back(adjuster);
0324         }
0325       }
0326     }
0327     if (workers_.empty()) {
0328       for (auto const& worker : workersObjects_) {
0329         if (skipSignal_ or worker->checkSignal(e)) {
0330           workers_.push_back(worker);
0331         }
0332       }
0333     }
0334   }
0335 
0336   void MixingModule::createnewEDProduct() {
0337     //create playback info
0338     playbackInfo_ = new CrossingFramePlaybackInfoNew(minBunch_, maxBunch_, maxNbSources_);
0339     //and CrossingFrames
0340     for (unsigned int ii = 0; ii < workers_.size(); ++ii) {
0341       workers_[ii]->createnewEDProduct();
0342     }
0343   }
0344 
0345   // Virtual destructor needed.
0346   MixingModule::~MixingModule() {
0347     for (auto& worker : workersObjects_) {
0348       delete worker;
0349     }
0350 
0351     for (auto& adjuster : adjustersObjects_) {
0352       delete adjuster;
0353     }
0354 
0355     for (auto& digiAccumulator : digiAccumulators_) {
0356       delete digiAccumulator;
0357     }
0358   }
0359 
0360   void MixingModule::addSignals(const edm::Event& e, const edm::EventSetup& setup) {
0361     if (skipSignal_) {
0362       return;
0363     }
0364 
0365     LogDebug("MixingModule") << "===============> adding signals for " << e.id();
0366 
0367     accumulateEvent(e, setup);
0368     // fill in signal part of CrossingFrame
0369     for (unsigned int ii = 0; ii < workers_.size(); ++ii) {
0370       workers_[ii]->addSignals(e);
0371     }
0372   }
0373 
0374   bool MixingModule::pileAllWorkers(EventPrincipal const& eventPrincipal,
0375                                     ModuleCallingContext const* mcc,
0376                                     int bunchCrossing,
0377                                     int eventId,
0378                                     int& vertexOffset,
0379                                     const edm::EventSetup& setup,
0380                                     StreamID const& streamID) {
0381     InternalContext internalContext(eventPrincipal.id(), mcc);
0382     ParentContext parentContext(&internalContext);
0383     ModuleCallingContext moduleCallingContext(&moduleDescription());
0384     ModuleContextSentry moduleContextSentry(&moduleCallingContext, parentContext);
0385 
0386     setupPileUpEvent(setup);
0387 
0388     for (auto const& adjuster : adjusters_) {
0389       adjuster->doOffset(bunchSpace_, bunchCrossing, eventPrincipal, &moduleCallingContext, eventId, vertexOffset);
0390     }
0391     PileUpEventPrincipal pep(eventPrincipal, &moduleCallingContext, bunchCrossing);
0392 
0393     accumulateEvent(pep, setup, streamID);
0394 
0395     for (auto const& worker : workers_) {
0396       LogDebug("MixingModule") << " merging Event:  id " << eventPrincipal.id();
0397       //      std::cout <<"PILEALLWORKERS merging Event:  id " << eventPrincipal.id() << std::endl;
0398 
0399       worker->addPileups(eventPrincipal, &moduleCallingContext, eventId);
0400     }
0401 
0402     return true;
0403   }
0404 
0405   void MixingModule::doPileUp(edm::Event& e, const edm::EventSetup& setup) {
0406     using namespace std::placeholders;
0407 
0408     // Don't allocate because PileUp will do it for us.
0409     std::vector<edm::SecondaryEventIDAndFileInfo> recordEventID;
0410     std::vector<size_t> sizes;
0411     sizes.reserve(maxNbSources_ * (maxBunch_ + 1 - minBunch_));
0412     size_t playbackCounter = 0U;
0413     edm::Handle<CrossingFramePlaybackInfoNew> playbackInfo_H;
0414     edm::Handle<CrossingFramePlaybackInfoExtended> oldFormatPlaybackInfo_H;
0415     bool oldFormatPlayback = false;
0416     if (playback_) {
0417       bool got = e.getByLabel(inputTagPlayback_, playbackInfo_H);
0418       if (!got) {
0419         bool gotOld = e.getByLabel(inputTagPlayback_, oldFormatPlaybackInfo_H);
0420         if (!gotOld) {
0421           throw cms::Exception("MixingProductNotFound")
0422               << " No "
0423                  "CrossingFramePlaybackInfoNew on the input file, but playback "
0424                  "option set!!!!! Please change the input file if you really want "
0425                  "playback!!!!!!"
0426               << std::endl;
0427         }
0428         oldFormatPlayback = true;
0429       }
0430     }
0431 
0432     // source[0] is "real" pileup.  Check to see that this is what we are doing.
0433 
0434     std::vector<int> PileupList;
0435     PileupList.clear();
0436     TrueNumInteractions_.clear();
0437 
0438     std::shared_ptr<PileUp> source0 = inputSources_[0];
0439 
0440     if ((source0 && source0->doPileUp(0)) && !playback_) {
0441       //    if((!inputSources_[0] || !inputSources_[0]->doPileUp()) && !playback_ )
0442 
0443       // Pre-calculate all pileup distributions before we go fishing for events
0444 
0445       source0->CalculatePileup(minBunch_, maxBunch_, PileupList, TrueNumInteractions_, e.streamID());
0446     }
0447 
0448     // pre-populate Pileup information
0449     // necessary for luminosity-dependent effects during hit accumulation
0450 
0451     std::vector<int> numInteractionList;
0452     std::vector<int> bunchCrossingList;
0453     std::vector<float> TrueInteractionList;
0454     std::vector<edm::EventID> eventInfoList;  // will be empty if we pre-populate, but it's not used in digitizers
0455 
0456     if (!playback_) {
0457       //Makin' a list: Basically, we don't care about the "other" sources at this point.
0458       for (int bunchCrossing = minBunch_; bunchCrossing <= maxBunch_; ++bunchCrossing) {
0459         bunchCrossingList.push_back(bunchCrossing);
0460         if (!inputSources_[0] || !inputSources_[0]->doPileUp(0)) {
0461           numInteractionList.push_back(0);
0462           TrueInteractionList.push_back(0);
0463         } else {
0464           numInteractionList.push_back(PileupList[bunchCrossing - minBunch_]);
0465           TrueInteractionList.push_back((TrueNumInteractions_)[bunchCrossing - minBunch_]);
0466         }
0467       }
0468     } else {  // have to read PU information from playback info
0469       for (int bunchIdx = minBunch_; bunchIdx <= maxBunch_; ++bunchIdx) {
0470         bunchCrossingList.push_back(bunchIdx);
0471         for (size_t readSrcIdx = 0; readSrcIdx < maxNbSources_; ++readSrcIdx) {
0472           if (oldFormatPlayback) {
0473             std::vector<edm::EventID> const& playEventID =
0474                 oldFormatPlaybackInfo_H->getStartEventId(readSrcIdx, bunchIdx);
0475             size_t numberOfEvents = playEventID.size();
0476             if (readSrcIdx == 0) {
0477               PileupList.push_back(numberOfEvents);
0478               TrueNumInteractions_.push_back(numberOfEvents);
0479               numInteractionList.push_back(numberOfEvents);
0480               TrueInteractionList.push_back(numberOfEvents);
0481             }
0482           } else {
0483             size_t numberOfEvents = playbackInfo_H->getNumberOfEvents(bunchIdx, readSrcIdx);
0484             if (readSrcIdx == 0) {
0485               PileupList.push_back(numberOfEvents);
0486               TrueNumInteractions_.push_back(numberOfEvents);
0487               numInteractionList.push_back(numberOfEvents);
0488               TrueInteractionList.push_back(numberOfEvents);
0489             }
0490           }
0491         }
0492       }
0493     }
0494 
0495     for (Accumulators::const_iterator accItr = digiAccumulators_.begin(), accEnd = digiAccumulators_.end();
0496          accItr != accEnd;
0497          ++accItr) {
0498       (*accItr)->StorePileupInformation(
0499           bunchCrossingList, numInteractionList, TrueInteractionList, eventInfoList, bunchSpace_);
0500     }
0501 
0502     //    for (int bunchIdx = minBunch_; bunchIdx <= maxBunch_; ++bunchIdx) {
0503     //  std::cout << " bunch ID, Pileup, True " << bunchIdx << " " << PileupList[bunchIdx-minBunch_] << " " <<  TrueNumInteractions_[bunchIdx-minBunch_] << std::endl;
0504     //}
0505 
0506     for (int bunchIdx = minBunch_; bunchIdx <= maxBunch_; ++bunchIdx) {
0507       for (size_t setBcrIdx = 0; setBcrIdx < workers_.size(); ++setBcrIdx) {
0508         workers_[setBcrIdx]->setBcrOffset();
0509       }
0510       for (Accumulators::const_iterator accItr = digiAccumulators_.begin(), accEnd = digiAccumulators_.end();
0511            accItr != accEnd;
0512            ++accItr) {
0513         (*accItr)->initializeBunchCrossing(e, setup, bunchIdx);
0514       }
0515 
0516       for (size_t readSrcIdx = 0; readSrcIdx < maxNbSources_; ++readSrcIdx) {
0517         std::shared_ptr<PileUp> source = inputSources_[readSrcIdx];  // this looks like we create
0518                                                                      // new PileUp objects for each
0519                                                                      // source for each event?
0520                                                                      // Why?
0521         for (size_t setSrcIdx = 0; setSrcIdx < workers_.size(); ++setSrcIdx) {
0522           workers_[setSrcIdx]->setSourceOffset(readSrcIdx);
0523         }
0524 
0525         if (!source || !source->doPileUp(bunchIdx)) {
0526           sizes.push_back(0U);
0527           if (playback_ && !oldFormatPlayback) {
0528             playbackCounter += playbackInfo_H->getNumberOfEvents(bunchIdx, readSrcIdx);
0529           }
0530           continue;
0531         }
0532 
0533         //        int eventId = 0;
0534         int vertexOffset = 0;
0535 
0536         ModuleCallingContext const* mcc = e.moduleCallingContext();
0537         if (!playback_) {
0538           // non-minbias pileup only gets one event for now. Fix later if desired.
0539           int numberOfEvents = (readSrcIdx == 0 ? PileupList[bunchIdx - minBunch_] : 1);
0540           sizes.push_back(numberOfEvents);
0541           inputSources_[readSrcIdx]->readPileUp(e.id(),
0542                                                 recordEventID,
0543                                                 std::bind(&MixingModule::pileAllWorkers,
0544                                                           std::ref(*this),
0545                                                           _1,
0546                                                           mcc,
0547                                                           bunchIdx,
0548                                                           _2,
0549                                                           vertexOffset,
0550                                                           std::ref(setup),
0551                                                           e.streamID()),
0552                                                 numberOfEvents,
0553                                                 e.streamID());
0554         } else if (oldFormatPlayback) {
0555           std::vector<edm::EventID> const& playEventID = oldFormatPlaybackInfo_H->getStartEventId(readSrcIdx, bunchIdx);
0556           size_t numberOfEvents = playEventID.size();
0557           if (readSrcIdx == 0) {
0558             PileupList.push_back(numberOfEvents);
0559             TrueNumInteractions_.push_back(numberOfEvents);
0560           }
0561           sizes.push_back(numberOfEvents);
0562           std::vector<EventID>::const_iterator begin = playEventID.begin();
0563           std::vector<EventID>::const_iterator end = playEventID.end();
0564           inputSources_[readSrcIdx]->playOldFormatPileUp(begin,
0565                                                          end,
0566                                                          recordEventID,
0567                                                          std::bind(&MixingModule::pileAllWorkers,
0568                                                                    std::ref(*this),
0569                                                                    _1,
0570                                                                    mcc,
0571                                                                    bunchIdx,
0572                                                                    _2,
0573                                                                    vertexOffset,
0574                                                                    std::ref(setup),
0575                                                                    e.streamID()));
0576         } else {
0577           size_t numberOfEvents = playbackInfo_H->getNumberOfEvents(bunchIdx, readSrcIdx);
0578           if (readSrcIdx == 0) {
0579             PileupList.push_back(numberOfEvents);
0580             TrueNumInteractions_.push_back(numberOfEvents);
0581           }
0582           sizes.push_back(numberOfEvents);
0583           std::vector<SecondaryEventIDAndFileInfo>::const_iterator begin = playbackInfo_H->getEventId(playbackCounter);
0584           playbackCounter += numberOfEvents;
0585           std::vector<SecondaryEventIDAndFileInfo>::const_iterator end = playbackInfo_H->getEventId(playbackCounter);
0586           inputSources_[readSrcIdx]->playPileUp(begin,
0587                                                 end,
0588                                                 recordEventID,
0589                                                 std::bind(&MixingModule::pileAllWorkers,
0590                                                           std::ref(*this),
0591                                                           _1,
0592                                                           mcc,
0593                                                           bunchIdx,
0594                                                           _2,
0595                                                           vertexOffset,
0596                                                           std::ref(setup),
0597                                                           e.streamID()));
0598         }
0599       }
0600       for (Accumulators::const_iterator accItr = digiAccumulators_.begin(), accEnd = digiAccumulators_.end();
0601            accItr != accEnd;
0602            ++accItr) {
0603         (*accItr)->finalizeBunchCrossing(e, setup, bunchIdx);
0604       }
0605     }
0606 
0607     // Save playback information
0608     for (auto const item : recordEventID) {
0609       eventInfoList.emplace_back(item.eventID());
0610     }
0611 
0612     // setInfo swaps recordEventID, so recordEventID is useless (empty) after the call.
0613     playbackInfo_->setInfo(recordEventID, sizes);
0614 
0615     // Keep track of pileup accounting...
0616 
0617     std::unique_ptr<PileupMixingContent> PileupMixing_;
0618 
0619     PileupMixing_ = std::make_unique<PileupMixingContent>(
0620         bunchCrossingList, numInteractionList, TrueInteractionList, eventInfoList, bunchSpace_);
0621 
0622     e.put(std::move(PileupMixing_));
0623 
0624     // we have to do the ToF transformation for PSimHits once all pileup has been added
0625     for (unsigned int ii = 0; ii < workers_.size(); ++ii) {
0626       workers_[ii]->setTof();
0627       workers_[ii]->put(e);
0628     }
0629   }
0630 
0631   void MixingModule::put(edm::Event& e, const edm::EventSetup& setup) {
0632     if (playbackInfo_) {
0633       std::unique_ptr<CrossingFramePlaybackInfoNew> pOut(playbackInfo_);
0634       e.put(std::move(pOut));
0635     }
0636   }
0637 
0638   void MixingModule::beginRun(edm::Run const& run, edm::EventSetup const& setup) {
0639     for (Accumulators::const_iterator accItr = digiAccumulators_.begin(), accEnd = digiAccumulators_.end();
0640          accItr != accEnd;
0641          ++accItr) {
0642       (*accItr)->beginRun(run, setup);
0643     }
0644     BMixingModule::beginRun(run, setup);
0645   }
0646 
0647   void MixingModule::endRun(edm::Run const& run, edm::EventSetup const& setup) {
0648     for (Accumulators::const_iterator accItr = digiAccumulators_.begin(), accEnd = digiAccumulators_.end();
0649          accItr != accEnd;
0650          ++accItr) {
0651       (*accItr)->endRun(run, setup);
0652     }
0653     BMixingModule::endRun(run, setup);
0654   }
0655 
0656   void MixingModule::beginLuminosityBlock(edm::LuminosityBlock const& lumi, edm::EventSetup const& setup) {
0657     for (Accumulators::const_iterator accItr = digiAccumulators_.begin(), accEnd = digiAccumulators_.end();
0658          accItr != accEnd;
0659          ++accItr) {
0660       (*accItr)->beginLuminosityBlock(lumi, setup);
0661     }
0662     BMixingModule::beginLuminosityBlock(lumi, setup);
0663   }
0664 
0665   void MixingModule::endLuminosityBlock(edm::LuminosityBlock const& lumi, edm::EventSetup const& setup) {
0666     for (Accumulators::const_iterator accItr = digiAccumulators_.begin(), accEnd = digiAccumulators_.end();
0667          accItr != accEnd;
0668          ++accItr) {
0669       (*accItr)->endLuminosityBlock(lumi, setup);
0670     }
0671     BMixingModule::endLuminosityBlock(lumi, setup);
0672   }
0673 
0674   void MixingModule::initializeEvent(edm::Event const& event, edm::EventSetup const& setup) {
0675     for (Accumulators::const_iterator accItr = digiAccumulators_.begin(), accEnd = digiAccumulators_.end();
0676          accItr != accEnd;
0677          ++accItr) {
0678       (*accItr)->initializeEvent(event, setup);
0679     }
0680   }
0681 
0682   void MixingModule::accumulateEvent(edm::Event const& event, edm::EventSetup const& setup) {
0683     for (Accumulators::const_iterator accItr = digiAccumulators_.begin(), accEnd = digiAccumulators_.end();
0684          accItr != accEnd;
0685          ++accItr) {
0686       (*accItr)->accumulate(event, setup);
0687     }
0688   }
0689 
0690   void MixingModule::accumulateEvent(PileUpEventPrincipal const& event,
0691                                      edm::EventSetup const& setup,
0692                                      edm::StreamID const& streamID) {
0693     for (Accumulators::const_iterator accItr = digiAccumulators_.begin(), accEnd = digiAccumulators_.end();
0694          accItr != accEnd;
0695          ++accItr) {
0696       (*accItr)->accumulate(event, setup, streamID);
0697     }
0698   }
0699 
0700   void MixingModule::finalizeEvent(edm::Event& event, edm::EventSetup const& setup) {
0701     for (Accumulators::const_iterator accItr = digiAccumulators_.begin(), accEnd = digiAccumulators_.end();
0702          accItr != accEnd;
0703          ++accItr) {
0704       (*accItr)->finalizeEvent(event, setup);
0705     }
0706   }
0707 }  // namespace edm