Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2021-09-02 03:46:12

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     for (auto const& adjuster : adjusters_) {
0387       adjuster->doOffset(bunchSpace_, bunchCrossing, eventPrincipal, &moduleCallingContext, eventId, vertexOffset);
0388     }
0389     PileUpEventPrincipal pep(eventPrincipal, &moduleCallingContext, bunchCrossing);
0390 
0391     accumulateEvent(pep, setup, streamID);
0392 
0393     for (auto const& worker : workers_) {
0394       LogDebug("MixingModule") << " merging Event:  id " << eventPrincipal.id();
0395       //      std::cout <<"PILEALLWORKERS merging Event:  id " << eventPrincipal.id() << std::endl;
0396 
0397       worker->addPileups(eventPrincipal, &moduleCallingContext, eventId);
0398     }
0399 
0400     return true;
0401   }
0402 
0403   void MixingModule::doPileUp(edm::Event& e, const edm::EventSetup& setup) {
0404     using namespace std::placeholders;
0405 
0406     // Don't allocate because PileUp will do it for us.
0407     std::vector<edm::SecondaryEventIDAndFileInfo> recordEventID;
0408     std::vector<size_t> sizes;
0409     sizes.reserve(maxNbSources_ * (maxBunch_ + 1 - minBunch_));
0410     size_t playbackCounter = 0U;
0411     edm::Handle<CrossingFramePlaybackInfoNew> playbackInfo_H;
0412     edm::Handle<CrossingFramePlaybackInfoExtended> oldFormatPlaybackInfo_H;
0413     bool oldFormatPlayback = false;
0414     if (playback_) {
0415       bool got = e.getByLabel(inputTagPlayback_, playbackInfo_H);
0416       if (!got) {
0417         bool gotOld = e.getByLabel(inputTagPlayback_, oldFormatPlaybackInfo_H);
0418         if (!gotOld) {
0419           throw cms::Exception("MixingProductNotFound")
0420               << " No "
0421                  "CrossingFramePlaybackInfoNew on the input file, but playback "
0422                  "option set!!!!! Please change the input file if you really want "
0423                  "playback!!!!!!"
0424               << std::endl;
0425         }
0426         oldFormatPlayback = true;
0427       }
0428     }
0429 
0430     // source[0] is "real" pileup.  Check to see that this is what we are doing.
0431 
0432     std::vector<int> PileupList;
0433     PileupList.clear();
0434     TrueNumInteractions_.clear();
0435 
0436     std::shared_ptr<PileUp> source0 = inputSources_[0];
0437 
0438     if ((source0 && source0->doPileUp(0)) && !playback_) {
0439       //    if((!inputSources_[0] || !inputSources_[0]->doPileUp()) && !playback_ )
0440 
0441       // Pre-calculate all pileup distributions before we go fishing for events
0442 
0443       source0->CalculatePileup(minBunch_, maxBunch_, PileupList, TrueNumInteractions_, e.streamID());
0444     }
0445 
0446     // pre-populate Pileup information
0447     // necessary for luminosity-dependent effects during hit accumulation
0448 
0449     std::vector<int> numInteractionList;
0450     std::vector<int> bunchCrossingList;
0451     std::vector<float> TrueInteractionList;
0452     std::vector<edm::EventID> eventInfoList;  // will be empty if we pre-populate, but it's not used in digitizers
0453 
0454     if (!playback_) {
0455       //Makin' a list: Basically, we don't care about the "other" sources at this point.
0456       for (int bunchCrossing = minBunch_; bunchCrossing <= maxBunch_; ++bunchCrossing) {
0457         bunchCrossingList.push_back(bunchCrossing);
0458         if (!inputSources_[0] || !inputSources_[0]->doPileUp(0)) {
0459           numInteractionList.push_back(0);
0460           TrueInteractionList.push_back(0);
0461         } else {
0462           numInteractionList.push_back(PileupList[bunchCrossing - minBunch_]);
0463           TrueInteractionList.push_back((TrueNumInteractions_)[bunchCrossing - minBunch_]);
0464         }
0465       }
0466     } else {  // have to read PU information from playback info
0467       for (int bunchIdx = minBunch_; bunchIdx <= maxBunch_; ++bunchIdx) {
0468         bunchCrossingList.push_back(bunchIdx);
0469         for (size_t readSrcIdx = 0; readSrcIdx < maxNbSources_; ++readSrcIdx) {
0470           if (oldFormatPlayback) {
0471             std::vector<edm::EventID> const& playEventID =
0472                 oldFormatPlaybackInfo_H->getStartEventId(readSrcIdx, bunchIdx);
0473             size_t numberOfEvents = playEventID.size();
0474             if (readSrcIdx == 0) {
0475               PileupList.push_back(numberOfEvents);
0476               TrueNumInteractions_.push_back(numberOfEvents);
0477               numInteractionList.push_back(numberOfEvents);
0478               TrueInteractionList.push_back(numberOfEvents);
0479             }
0480           } else {
0481             size_t numberOfEvents = playbackInfo_H->getNumberOfEvents(bunchIdx, readSrcIdx);
0482             if (readSrcIdx == 0) {
0483               PileupList.push_back(numberOfEvents);
0484               TrueNumInteractions_.push_back(numberOfEvents);
0485               numInteractionList.push_back(numberOfEvents);
0486               TrueInteractionList.push_back(numberOfEvents);
0487             }
0488           }
0489         }
0490       }
0491     }
0492 
0493     for (Accumulators::const_iterator accItr = digiAccumulators_.begin(), accEnd = digiAccumulators_.end();
0494          accItr != accEnd;
0495          ++accItr) {
0496       (*accItr)->StorePileupInformation(
0497           bunchCrossingList, numInteractionList, TrueInteractionList, eventInfoList, bunchSpace_);
0498     }
0499 
0500     //    for (int bunchIdx = minBunch_; bunchIdx <= maxBunch_; ++bunchIdx) {
0501     //  std::cout << " bunch ID, Pileup, True " << bunchIdx << " " << PileupList[bunchIdx-minBunch_] << " " <<  TrueNumInteractions_[bunchIdx-minBunch_] << std::endl;
0502     //}
0503 
0504     for (int bunchIdx = minBunch_; bunchIdx <= maxBunch_; ++bunchIdx) {
0505       for (size_t setBcrIdx = 0; setBcrIdx < workers_.size(); ++setBcrIdx) {
0506         workers_[setBcrIdx]->setBcrOffset();
0507       }
0508       for (Accumulators::const_iterator accItr = digiAccumulators_.begin(), accEnd = digiAccumulators_.end();
0509            accItr != accEnd;
0510            ++accItr) {
0511         (*accItr)->initializeBunchCrossing(e, setup, bunchIdx);
0512       }
0513 
0514       for (size_t readSrcIdx = 0; readSrcIdx < maxNbSources_; ++readSrcIdx) {
0515         std::shared_ptr<PileUp> source = inputSources_[readSrcIdx];  // this looks like we create
0516                                                                      // new PileUp objects for each
0517                                                                      // source for each event?
0518                                                                      // Why?
0519         for (size_t setSrcIdx = 0; setSrcIdx < workers_.size(); ++setSrcIdx) {
0520           workers_[setSrcIdx]->setSourceOffset(readSrcIdx);
0521         }
0522 
0523         if (!source || !source->doPileUp(bunchIdx)) {
0524           sizes.push_back(0U);
0525           if (playback_ && !oldFormatPlayback) {
0526             playbackCounter += playbackInfo_H->getNumberOfEvents(bunchIdx, readSrcIdx);
0527           }
0528           continue;
0529         }
0530 
0531         //        int eventId = 0;
0532         int vertexOffset = 0;
0533 
0534         ModuleCallingContext const* mcc = e.moduleCallingContext();
0535         if (!playback_) {
0536           // non-minbias pileup only gets one event for now. Fix later if desired.
0537           int numberOfEvents = (readSrcIdx == 0 ? PileupList[bunchIdx - minBunch_] : 1);
0538           sizes.push_back(numberOfEvents);
0539           inputSources_[readSrcIdx]->readPileUp(e.id(),
0540                                                 recordEventID,
0541                                                 std::bind(&MixingModule::pileAllWorkers,
0542                                                           std::ref(*this),
0543                                                           _1,
0544                                                           mcc,
0545                                                           bunchIdx,
0546                                                           _2,
0547                                                           vertexOffset,
0548                                                           std::ref(setup),
0549                                                           e.streamID()),
0550                                                 numberOfEvents,
0551                                                 e.streamID());
0552         } else if (oldFormatPlayback) {
0553           std::vector<edm::EventID> const& playEventID = oldFormatPlaybackInfo_H->getStartEventId(readSrcIdx, bunchIdx);
0554           size_t numberOfEvents = playEventID.size();
0555           if (readSrcIdx == 0) {
0556             PileupList.push_back(numberOfEvents);
0557             TrueNumInteractions_.push_back(numberOfEvents);
0558           }
0559           sizes.push_back(numberOfEvents);
0560           std::vector<EventID>::const_iterator begin = playEventID.begin();
0561           std::vector<EventID>::const_iterator end = playEventID.end();
0562           inputSources_[readSrcIdx]->playOldFormatPileUp(begin,
0563                                                          end,
0564                                                          recordEventID,
0565                                                          std::bind(&MixingModule::pileAllWorkers,
0566                                                                    std::ref(*this),
0567                                                                    _1,
0568                                                                    mcc,
0569                                                                    bunchIdx,
0570                                                                    _2,
0571                                                                    vertexOffset,
0572                                                                    std::ref(setup),
0573                                                                    e.streamID()));
0574         } else {
0575           size_t numberOfEvents = playbackInfo_H->getNumberOfEvents(bunchIdx, readSrcIdx);
0576           if (readSrcIdx == 0) {
0577             PileupList.push_back(numberOfEvents);
0578             TrueNumInteractions_.push_back(numberOfEvents);
0579           }
0580           sizes.push_back(numberOfEvents);
0581           std::vector<SecondaryEventIDAndFileInfo>::const_iterator begin = playbackInfo_H->getEventId(playbackCounter);
0582           playbackCounter += numberOfEvents;
0583           std::vector<SecondaryEventIDAndFileInfo>::const_iterator end = playbackInfo_H->getEventId(playbackCounter);
0584           inputSources_[readSrcIdx]->playPileUp(begin,
0585                                                 end,
0586                                                 recordEventID,
0587                                                 std::bind(&MixingModule::pileAllWorkers,
0588                                                           std::ref(*this),
0589                                                           _1,
0590                                                           mcc,
0591                                                           bunchIdx,
0592                                                           _2,
0593                                                           vertexOffset,
0594                                                           std::ref(setup),
0595                                                           e.streamID()));
0596         }
0597       }
0598       for (Accumulators::const_iterator accItr = digiAccumulators_.begin(), accEnd = digiAccumulators_.end();
0599            accItr != accEnd;
0600            ++accItr) {
0601         (*accItr)->finalizeBunchCrossing(e, setup, bunchIdx);
0602       }
0603     }
0604 
0605     // Save playback information
0606     for (auto const item : recordEventID) {
0607       eventInfoList.emplace_back(item.eventID());
0608     }
0609 
0610     // setInfo swaps recordEventID, so recordEventID is useless (empty) after the call.
0611     playbackInfo_->setInfo(recordEventID, sizes);
0612 
0613     // Keep track of pileup accounting...
0614 
0615     std::unique_ptr<PileupMixingContent> PileupMixing_;
0616 
0617     PileupMixing_ = std::make_unique<PileupMixingContent>(
0618         bunchCrossingList, numInteractionList, TrueInteractionList, eventInfoList, bunchSpace_);
0619 
0620     e.put(std::move(PileupMixing_));
0621 
0622     // we have to do the ToF transformation for PSimHits once all pileup has been added
0623     for (unsigned int ii = 0; ii < workers_.size(); ++ii) {
0624       workers_[ii]->setTof();
0625       workers_[ii]->put(e);
0626     }
0627   }
0628 
0629   void MixingModule::put(edm::Event& e, const edm::EventSetup& setup) {
0630     if (playbackInfo_) {
0631       std::unique_ptr<CrossingFramePlaybackInfoNew> pOut(playbackInfo_);
0632       e.put(std::move(pOut));
0633     }
0634   }
0635 
0636   void MixingModule::beginRun(edm::Run const& run, edm::EventSetup const& setup) {
0637     for (Accumulators::const_iterator accItr = digiAccumulators_.begin(), accEnd = digiAccumulators_.end();
0638          accItr != accEnd;
0639          ++accItr) {
0640       (*accItr)->beginRun(run, setup);
0641     }
0642     BMixingModule::beginRun(run, setup);
0643   }
0644 
0645   void MixingModule::endRun(edm::Run const& run, edm::EventSetup const& setup) {
0646     for (Accumulators::const_iterator accItr = digiAccumulators_.begin(), accEnd = digiAccumulators_.end();
0647          accItr != accEnd;
0648          ++accItr) {
0649       (*accItr)->endRun(run, setup);
0650     }
0651     BMixingModule::endRun(run, setup);
0652   }
0653 
0654   void MixingModule::beginLuminosityBlock(edm::LuminosityBlock const& lumi, edm::EventSetup const& setup) {
0655     for (Accumulators::const_iterator accItr = digiAccumulators_.begin(), accEnd = digiAccumulators_.end();
0656          accItr != accEnd;
0657          ++accItr) {
0658       (*accItr)->beginLuminosityBlock(lumi, setup);
0659     }
0660     BMixingModule::beginLuminosityBlock(lumi, setup);
0661   }
0662 
0663   void MixingModule::endLuminosityBlock(edm::LuminosityBlock const& lumi, edm::EventSetup const& setup) {
0664     for (Accumulators::const_iterator accItr = digiAccumulators_.begin(), accEnd = digiAccumulators_.end();
0665          accItr != accEnd;
0666          ++accItr) {
0667       (*accItr)->endLuminosityBlock(lumi, setup);
0668     }
0669     BMixingModule::endLuminosityBlock(lumi, setup);
0670   }
0671 
0672   void MixingModule::initializeEvent(edm::Event const& event, edm::EventSetup const& setup) {
0673     for (Accumulators::const_iterator accItr = digiAccumulators_.begin(), accEnd = digiAccumulators_.end();
0674          accItr != accEnd;
0675          ++accItr) {
0676       (*accItr)->initializeEvent(event, setup);
0677     }
0678   }
0679 
0680   void MixingModule::accumulateEvent(edm::Event const& event, edm::EventSetup const& setup) {
0681     for (Accumulators::const_iterator accItr = digiAccumulators_.begin(), accEnd = digiAccumulators_.end();
0682          accItr != accEnd;
0683          ++accItr) {
0684       (*accItr)->accumulate(event, setup);
0685     }
0686   }
0687 
0688   void MixingModule::accumulateEvent(PileUpEventPrincipal const& event,
0689                                      edm::EventSetup const& setup,
0690                                      edm::StreamID const& streamID) {
0691     for (Accumulators::const_iterator accItr = digiAccumulators_.begin(), accEnd = digiAccumulators_.end();
0692          accItr != accEnd;
0693          ++accItr) {
0694       (*accItr)->accumulate(event, setup, streamID);
0695     }
0696   }
0697 
0698   void MixingModule::finalizeEvent(edm::Event& event, edm::EventSetup const& setup) {
0699     for (Accumulators::const_iterator accItr = digiAccumulators_.begin(), accEnd = digiAccumulators_.end();
0700          accItr != accEnd;
0701          ++accItr) {
0702       (*accItr)->finalizeEvent(event, setup);
0703     }
0704   }
0705 }  // namespace edm