Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2021-02-14 12:49:59

0001 /// Take:
0002 //    - a PF candidate collection (which uses the old muons)
0003 //    - a map from the old muons to the new muons (in which some muons have been un-tagged and so are no longer PF muons)
0004 //      format: edm::Association<std::vector<reco::Muon>>
0005 //  Produce:
0006 //    - a new PFCandidate collection using the new muons, and in which the muons that have been un-tagged are removed
0007 //    - a second PFCandidate collection with just those discarded muons
0008 //    - a ValueMap<reco::PFCandidateRef> that maps the old to the new, and vice-versa
0009 
0010 #include "FWCore/Framework/interface/Frameworkfwd.h"
0011 #include "FWCore/Framework/interface/global/EDProducer.h"
0012 #include "FWCore/ParameterSet/interface/ParameterSet.h"
0013 
0014 #include "FWCore/Framework/interface/Event.h"
0015 
0016 #include "DataFormats/MuonReco/interface/Muon.h"
0017 #include "DataFormats/ParticleFlowCandidate/interface/PFCandidateFwd.h"
0018 #include "DataFormats/ParticleFlowCandidate/interface/PFCandidate.h"
0019 
0020 #include "DataFormats/Common/interface/View.h"
0021 #include "DataFormats/Common/interface/Association.h"
0022 #include <iostream>
0023 
0024 class PFCandidateMuonUntagger : public edm::global::EDProducer<> {
0025 public:
0026   PFCandidateMuonUntagger(const edm::ParameterSet &);
0027   ~PFCandidateMuonUntagger() override{};
0028 
0029   void produce(edm::StreamID iID, edm::Event &, const edm::EventSetup &) const override;
0030 
0031 private:
0032   edm::EDGetTokenT<std::vector<reco::PFCandidate>> pfcandidates_;
0033   edm::EDGetTokenT<edm::Association<std::vector<reco::Muon>>> oldToNewMuons_;
0034 
0035   template <typename H1>
0036   void writeValueMap(edm::Event &out, const H1 &from, const std::vector<int> values, const std::string &name) {
0037     typedef edm::ValueMap<int> IntMap;
0038     std::unique_ptr<IntMap> intmap(new IntMap());
0039     typename IntMap::Filler filler(*intmap);
0040     filler.insert(from, values.begin(), values.end());
0041     filler.fill();
0042     out.put(std::move(intmap), name);
0043   }
0044 };
0045 
0046 PFCandidateMuonUntagger::PFCandidateMuonUntagger(const edm::ParameterSet &iConfig)
0047     : pfcandidates_(consumes<std::vector<reco::PFCandidate>>(iConfig.getParameter<edm::InputTag>("pfcandidates"))),
0048       oldToNewMuons_(
0049           consumes<edm::Association<std::vector<reco::Muon>>>(iConfig.getParameter<edm::InputTag>("oldToNewMuons"))) {
0050   produces<std::vector<reco::PFCandidate>>();
0051   produces<std::vector<reco::PFCandidate>>("discarded");
0052   produces<edm::ValueMap<reco::PFCandidateRef>>();
0053 }
0054 
0055 void PFCandidateMuonUntagger::produce(edm::StreamID iID, edm::Event &iEvent, const edm::EventSetup &) const {
0056   edm::Handle<edm::Association<std::vector<reco::Muon>>> oldToNewMuons;
0057   iEvent.getByToken(oldToNewMuons_, oldToNewMuons);
0058 
0059   edm::Handle<std::vector<reco::PFCandidate>> pfcandidates;
0060   iEvent.getByToken(pfcandidates_, pfcandidates);
0061 
0062   int n = pfcandidates->size();
0063   std::unique_ptr<std::vector<reco::PFCandidate>> copy(new std::vector<reco::PFCandidate>());
0064   std::unique_ptr<std::vector<reco::PFCandidate>> discarded(new std::vector<reco::PFCandidate>());
0065   copy->reserve(n);
0066   std::vector<int> oldToNew(n), newToOld, badToOld;
0067   newToOld.reserve(n);
0068 
0069   int i = -1;
0070   for (const reco::PFCandidate &pf : *pfcandidates) {
0071     ++i;
0072     if (pf.muonRef().isNonnull()) {
0073       reco::MuonRef newRef = (*oldToNewMuons)[pf.muonRef()];
0074       if (abs(pf.pdgId()) == 13 && !newRef->isPFMuon()) {  // was untagging
0075         discarded->push_back(pf);
0076         oldToNew[i] = (-discarded->size());
0077         badToOld.push_back(i);
0078         discarded->back().setMuonRef(newRef);
0079       } else {
0080         copy->push_back(pf);
0081         oldToNew[i] = (copy->size());
0082         newToOld.push_back(i);
0083         copy->back().setMuonRef(newRef);
0084       }
0085     } else {
0086       copy->push_back(pf);
0087       oldToNew[i] = (copy->size());
0088       newToOld.push_back(i);
0089     }
0090   }
0091 
0092   // Now we put things in the event
0093   edm::OrphanHandle<std::vector<reco::PFCandidate>> newpf = iEvent.put(std::move(copy));
0094   edm::OrphanHandle<std::vector<reco::PFCandidate>> badpf = iEvent.put(std::move(discarded), "discarded");
0095 
0096   std::unique_ptr<edm::ValueMap<reco::PFCandidateRef>> pf2pf(new edm::ValueMap<reco::PFCandidateRef>());
0097   edm::ValueMap<reco::PFCandidateRef>::Filler filler(*pf2pf);
0098   std::vector<reco::PFCandidateRef> refs;
0099   refs.reserve(n);
0100   // old to new
0101   for (i = 0; i < n; ++i) {
0102     if (oldToNew[i] > 0) {
0103       refs.push_back(reco::PFCandidateRef(newpf, oldToNew[i] - 1));
0104     } else {
0105       refs.push_back(reco::PFCandidateRef(badpf, -oldToNew[i] - 1));
0106     }
0107   }
0108   filler.insert(pfcandidates, refs.begin(), refs.end());
0109   // new good to old
0110   refs.clear();
0111   for (int i : newToOld) {
0112     refs.push_back(reco::PFCandidateRef(pfcandidates, i));
0113   }
0114   filler.insert(newpf, refs.begin(), refs.end());
0115   // new bad to old
0116   refs.clear();
0117   for (int i : badToOld) {
0118     refs.push_back(reco::PFCandidateRef(pfcandidates, i));
0119   }
0120   filler.insert(badpf, refs.begin(), refs.end());
0121   // done
0122   filler.fill();
0123   iEvent.put(std::move(pf2pf));
0124 }
0125 #include "FWCore/Framework/interface/MakerMacros.h"
0126 DEFINE_FWK_MODULE(PFCandidateMuonUntagger);