Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2021-02-14 14:29:57

0001 #include "FWCore/Framework/interface/ConsumesCollector.h"
0002 #include "FWCore/Framework/interface/Event.h"
0003 #include "FWCore/Framework/interface/ProducesCollector.h"
0004 #include "FWCore/MessageLogger/interface/MessageLogger.h"
0005 #include "FWCore/ParameterSet/interface/ParameterSet.h"
0006 #include "SimGeneral/MixingModule/interface/PileUpEventPrincipal.h"
0007 
0008 #include "DataFormats/Common/interface/Handle.h"
0009 #include "SimDataFormats/CaloAnalysis/interface/CaloParticle.h"
0010 #include "SimDataFormats/CaloAnalysis/interface/CaloParticleFwd.h"
0011 #include "SimDataFormats/CaloAnalysis/interface/SimCluster.h"
0012 #include "SimDataFormats/CaloAnalysis/interface/SimClusterFwd.h"
0013 
0014 #include "SimGeneral/PreMixingModule/interface/PreMixingWorker.h"
0015 #include "SimGeneral/PreMixingModule/interface/PreMixingWorkerFactory.h"
0016 
0017 class PreMixingCaloParticleWorker : public PreMixingWorker {
0018 public:
0019   PreMixingCaloParticleWorker(const edm::ParameterSet &ps, edm::ProducesCollector, edm::ConsumesCollector &&iC);
0020   ~PreMixingCaloParticleWorker() override = default;
0021 
0022   void initializeEvent(edm::Event const &iEvent, edm::EventSetup const &iSetup) override;
0023   void addSignals(edm::Event const &iEvent, edm::EventSetup const &iSetup) override;
0024   void addPileups(PileUpEventPrincipal const &pep, edm::EventSetup const &iSetup) override;
0025   void put(edm::Event &iEvent,
0026            edm::EventSetup const &iSetup,
0027            std::vector<PileupSummaryInfo> const &ps,
0028            int bunchSpacing) override;
0029 
0030 private:
0031   using EnergyMap = std::vector<std::pair<unsigned, float>>;
0032 
0033   void add(const SimClusterCollection &clusters, const CaloParticleCollection &particles, const EnergyMap &energyMap);
0034 
0035   edm::EDGetTokenT<SimClusterCollection> sigClusterToken_;
0036   edm::EDGetTokenT<CaloParticleCollection> sigParticleToken_;
0037   edm::EDGetTokenT<EnergyMap> sigEnergyToken_;
0038 
0039   edm::InputTag particlePileInputTag_;
0040   std::string particleCollectionDM_;
0041 
0042   std::unordered_map<unsigned, float> totalEnergy_;
0043 
0044   std::unique_ptr<SimClusterCollection> newClusters_;
0045   std::unique_ptr<CaloParticleCollection> newParticles_;
0046   SimClusterRefProd clusterRef_;
0047 };
0048 
0049 PreMixingCaloParticleWorker::PreMixingCaloParticleWorker(const edm::ParameterSet &ps,
0050                                                          edm::ProducesCollector producesCollector,
0051                                                          edm::ConsumesCollector &&iC)
0052     : sigClusterToken_(iC.consumes<SimClusterCollection>(ps.getParameter<edm::InputTag>("labelSig"))),
0053       sigParticleToken_(iC.consumes<CaloParticleCollection>(ps.getParameter<edm::InputTag>("labelSig"))),
0054       sigEnergyToken_(iC.consumes<EnergyMap>(ps.getParameter<edm::InputTag>("labelSig"))),
0055       particlePileInputTag_(ps.getParameter<edm::InputTag>("pileInputTag")),
0056       particleCollectionDM_(ps.getParameter<std::string>("collectionDM")) {
0057   producesCollector.produces<SimClusterCollection>(particleCollectionDM_);
0058   producesCollector.produces<CaloParticleCollection>(particleCollectionDM_);
0059 }
0060 
0061 void PreMixingCaloParticleWorker::initializeEvent(edm::Event const &iEvent, edm::EventSetup const &iSetup) {
0062   newClusters_ = std::make_unique<SimClusterCollection>();
0063   newParticles_ = std::make_unique<CaloParticleCollection>();
0064 
0065   // need RefProds in order to re-key the CaloParticle->SimCluster refs
0066   // TODO: try to remove const_cast, requires making Event non-const in
0067   // BMixingModule::initializeEvent
0068   clusterRef_ = const_cast<edm::Event &>(iEvent).getRefBeforePut<SimClusterCollection>(particleCollectionDM_);
0069 }
0070 
0071 void PreMixingCaloParticleWorker::addSignals(edm::Event const &iEvent, edm::EventSetup const &iSetup) {
0072   edm::Handle<SimClusterCollection> clusters;
0073   iEvent.getByToken(sigClusterToken_, clusters);
0074 
0075   edm::Handle<CaloParticleCollection> particles;
0076   iEvent.getByToken(sigParticleToken_, particles);
0077 
0078   edm::Handle<EnergyMap> energy;
0079   iEvent.getByToken(sigEnergyToken_, energy);
0080 
0081   if (clusters.isValid() && particles.isValid() && energy.isValid()) {
0082     add(*clusters, *particles, *energy);
0083   }
0084 }
0085 
0086 void PreMixingCaloParticleWorker::addPileups(PileUpEventPrincipal const &pep, edm::EventSetup const &iSetup) {
0087   edm::Handle<SimClusterCollection> clusters;
0088   pep.getByLabel(particlePileInputTag_, clusters);
0089 
0090   edm::Handle<CaloParticleCollection> particles;
0091   pep.getByLabel(particlePileInputTag_, particles);
0092 
0093   edm::Handle<EnergyMap> energy;
0094   pep.getByLabel(particlePileInputTag_, energy);
0095 
0096   if (clusters.isValid() && particles.isValid() && energy.isValid()) {
0097     add(*clusters, *particles, *energy);
0098   }
0099 }
0100 
0101 void PreMixingCaloParticleWorker::add(const SimClusterCollection &clusters,
0102                                       const CaloParticleCollection &particles,
0103                                       const EnergyMap &energy) {
0104   const size_t startingIndex = newClusters_->size();
0105 
0106   // Copy SimClusters
0107   newClusters_->reserve(newClusters_->size() + clusters.size());
0108   std::copy(clusters.begin(), clusters.end(), std::back_inserter(*newClusters_));
0109 
0110   // Copy CaloParticles
0111   newParticles_->reserve(newParticles_->size() + particles.size());
0112   for (const auto &p : particles) {
0113     newParticles_->push_back(p);
0114     auto &particle = newParticles_->back();
0115 
0116     // re-key the refs to SimClusters
0117     particle.clearSimClusters();
0118     for (const auto &ref : p.simClusters()) {
0119       particle.addSimCluster(SimClusterRef(clusterRef_, startingIndex + ref.index()));
0120     }
0121   }
0122 
0123   // Add energies
0124   for (const auto &elem : energy) {
0125     totalEnergy_[elem.first] += elem.second;
0126   }
0127 }
0128 
0129 void PreMixingCaloParticleWorker::put(edm::Event &iEvent,
0130                                       edm::EventSetup const &iSetup,
0131                                       std::vector<PileupSummaryInfo> const &ps,
0132                                       int bunchSpacing) {
0133   for (auto &sc : *newClusters_) {
0134     auto hitsAndEnergies = sc.hits_and_fractions();
0135     sc.clearHitsAndFractions();
0136     for (auto &hAndE : hitsAndEnergies) {
0137       const float totalenergy = totalEnergy_[hAndE.first];
0138       float fraction = 0.;
0139       if (totalenergy > 0)
0140         fraction = hAndE.second / totalenergy;
0141       else
0142         edm::LogWarning("PreMixingParticleWorker")
0143             << "TotalSimEnergy for hit " << hAndE.first << " is 0! The fraction for this hit cannot be computed.";
0144       sc.addRecHitAndFraction(hAndE.first, fraction);
0145     }
0146   }
0147 
0148   // clear memory
0149   std::unordered_map<unsigned, float>{}.swap(totalEnergy_);
0150 
0151   iEvent.put(std::move(newClusters_), particleCollectionDM_);
0152   iEvent.put(std::move(newParticles_), particleCollectionDM_);
0153 }
0154 
0155 DEFINE_PREMIXING_WORKER(PreMixingCaloParticleWorker);