Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2022-06-10 01:53:54

0001 #include "DataFormats/L1TCorrelator/interface/TkElectron.h"
0002 #include "DataFormats/L1TCorrelator/interface/TkElectronFwd.h"
0003 #include "DataFormats/L1Trigger/interface/EGamma.h"
0004 #include "DataFormats/L1TCorrelator/interface/TkEm.h"
0005 #include "DataFormats/L1TCorrelator/interface/TkEmFwd.h"
0006 
0007 #include "FWCore/Framework/interface/global/EDProducer.h"
0008 #include "FWCore/Framework/interface/Event.h"
0009 #include "FWCore/ParameterSet/interface/ParameterSet.h"
0010 #include "FWCore/Utilities/interface/transform.h"
0011 #include "FWCore/Utilities/interface/InputTag.h"
0012 #include <vector>
0013 #include <iostream>
0014 
0015 class L1TEGMultiMerger : public edm::global::EDProducer<> {
0016 public:
0017   explicit L1TEGMultiMerger(const edm::ParameterSet&);
0018   ~L1TEGMultiMerger() override;
0019 
0020 private:
0021   void produce(edm::StreamID, edm::Event&, const edm::EventSetup&) const override;
0022 
0023   struct RefRemapper {
0024     BXVector<edm::Ref<BXVector<l1t::EGamma>>> oldRefs;
0025     std::map<edm::Ref<BXVector<l1t::EGamma>>, edm::Ref<BXVector<l1t::EGamma>>> old2newRefMap;
0026   };
0027 
0028   template <class T>
0029   class InstanceMerger {
0030   public:
0031     InstanceMerger(L1TEGMultiMerger* prod, const edm::ParameterSet& conf)
0032         : instanceLabel_(conf.getParameter<std::string>("instance")) {
0033       for (const auto& producer_tag : conf.getParameter<std::vector<edm::InputTag>>("pfProducers")) {
0034         tokens_.push_back(
0035             prod->consumes<T>(edm::InputTag(producer_tag.label(), producer_tag.instance(), producer_tag.process())));
0036       }
0037       // FIXME: move this outside
0038       prod->produces<T>(instanceLabel_);
0039     }
0040 
0041     void produce(edm::Event& iEvent, RefRemapper& refRemapper) const {
0042       edm::Handle<T> handle;
0043       auto out = std::make_unique<T>();
0044       for (const auto& token : tokens_) {
0045         iEvent.getByToken(token, handle);
0046         populate(out, handle, refRemapper);
0047       }
0048       remapRefs(iEvent, out, refRemapper);
0049       iEvent.put(std::move(out), instanceLabel_);
0050     }
0051 
0052   private:
0053     template <class TT>
0054     void remapRefs(edm::Event& iEvent, std::unique_ptr<TT>& out, RefRemapper& refRemapper) const {
0055       for (auto& egobj : *out) {
0056         auto newref = refRemapper.old2newRefMap.find(egobj.EGRef());
0057         if (newref != refRemapper.old2newRefMap.end()) {
0058           egobj.setEGRef(newref->second);
0059         }
0060       }
0061     }
0062 
0063     void remapRefs(edm::Event& iEvent, std::unique_ptr<BXVector<l1t::EGamma>>& out, RefRemapper& refRemapper) const {
0064       edm::RefProd<BXVector<l1t::EGamma>> ref_egs = iEvent.getRefBeforePut<BXVector<l1t::EGamma>>(instanceLabel_);
0065       edm::Ref<BXVector<l1t::EGamma>>::key_type idx = 0;
0066       for (std::size_t ix = 0; ix < out->size(); ix++) {
0067         refRemapper.old2newRefMap[refRemapper.oldRefs[ix]] = edm::Ref<BXVector<l1t::EGamma>>(ref_egs, idx++);
0068       }
0069     }
0070 
0071     template <class TT>
0072     void populate(std::unique_ptr<TT>& out, const edm::Handle<TT>& in, RefRemapper& refRemapper) const {
0073       out->insert(out->end(), in->begin(), in->end());
0074     }
0075 
0076     void populate(std::unique_ptr<BXVector<l1t::EGamma>>& out,
0077                   const edm::Handle<BXVector<l1t::EGamma>>& in,
0078                   RefRemapper& refRemapper) const {
0079       edm::Ref<BXVector<l1t::EGamma>>::key_type idx = 0;
0080       for (int bx = in->getFirstBX(); bx <= in->getLastBX(); bx++) {
0081         for (auto egee_itr = in->begin(bx); egee_itr != in->end(bx); egee_itr++) {
0082           out->push_back(bx, *egee_itr);
0083           // this to ensure that the old ref and the new object have the same index in the BXVector collection so that we can still match them
0084           // no matter which BX we will insert next
0085           refRemapper.oldRefs.push_back(bx, edm::Ref<BXVector<l1t::EGamma>>(in, idx++));
0086         }
0087       }
0088     }
0089 
0090     std::vector<edm::EDGetTokenT<T>> tokens_;
0091     std::string instanceLabel_;
0092   };
0093 
0094   std::vector<InstanceMerger<l1t::TkElectronCollection>> tkEleMerger;
0095   std::vector<InstanceMerger<l1t::TkEmCollection>> tkEmMerger;
0096   std::vector<InstanceMerger<BXVector<l1t::EGamma>>> tkEGMerger;
0097 };
0098 
0099 L1TEGMultiMerger::L1TEGMultiMerger(const edm::ParameterSet& conf) {
0100   for (const auto& config : conf.getParameter<std::vector<edm::ParameterSet>>("tkEgs")) {
0101     tkEGMerger.push_back(InstanceMerger<BXVector<l1t::EGamma>>(this, config));
0102   }
0103   for (const auto& config : conf.getParameter<std::vector<edm::ParameterSet>>("tkElectrons")) {
0104     tkEleMerger.push_back(InstanceMerger<l1t::TkElectronCollection>(this, config));
0105   }
0106   for (const auto& config : conf.getParameter<std::vector<edm::ParameterSet>>("tkEms")) {
0107     tkEmMerger.push_back(InstanceMerger<l1t::TkEmCollection>(this, config));
0108   }
0109 }
0110 
0111 L1TEGMultiMerger::~L1TEGMultiMerger() {}
0112 
0113 void L1TEGMultiMerger::produce(edm::StreamID, edm::Event& iEvent, const edm::EventSetup&) const {
0114   RefRemapper refmapper;
0115   for (const auto& egMerger : tkEGMerger)
0116     egMerger.produce(iEvent, refmapper);
0117   for (const auto& eleMerger : tkEleMerger)
0118     eleMerger.produce(iEvent, refmapper);
0119   for (const auto& emMerger : tkEmMerger)
0120     emMerger.produce(iEvent, refmapper);
0121 }
0122 
0123 #include "FWCore/Framework/interface/MakerMacros.h"
0124 DEFINE_FWK_MODULE(L1TEGMultiMerger);