Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2024-04-06 12:24:05

0001 /** \class ShiftedPFCandidateProducerForPFMVAMEt
0002  *
0003  * Vary energy of PFCandidates coinciding in eta-phi with selected electrons/muons/tau-jets/jets
0004  * by electron/muon/tau-jet/jet energy uncertainty.
0005  *
0006  * NOTE: Auxiliary class specific to estimating systematic uncertainty
0007  *       on PFMET reconstructed by MVA-based algorithm
0008  *      (implemented in RecoMET/METPUSubtraction/src/PFMETProducerMVA.cc)
0009  *
0010  * \author Christian Veelken, LLR
0011  *
0012  *
0013  *
0014  */
0015 
0016 #include "DataFormats/Candidate/interface/Candidate.h"
0017 #include "DataFormats/Common/interface/View.h"
0018 #include "DataFormats/Math/interface/deltaR.h"
0019 #include "DataFormats/ParticleFlowCandidate/interface/PFCandidate.h"
0020 #include "DataFormats/ParticleFlowCandidate/interface/PFCandidateFwd.h"
0021 #include "FWCore/Framework/interface/Event.h"
0022 #include "FWCore/Framework/interface/EventSetup.h"
0023 #include "FWCore/Framework/interface/stream/EDProducer.h"
0024 #include "FWCore/ParameterSet/interface/ParameterSet.h"
0025 #include "FWCore/Utilities/interface/InputTag.h"
0026 
0027 #include <string>
0028 #include <vector>
0029 
0030 class ShiftedPFCandidateProducerForPFMVAMEt : public edm::stream::EDProducer<> {
0031 public:
0032   explicit ShiftedPFCandidateProducerForPFMVAMEt(const edm::ParameterSet&);
0033   ~ShiftedPFCandidateProducerForPFMVAMEt() override;
0034 
0035 private:
0036   typedef edm::View<reco::Candidate> CandidateView;
0037 
0038   void produce(edm::Event&, const edm::EventSetup&) override;
0039 
0040   std::string moduleLabel_;
0041 
0042   edm::EDGetTokenT<reco::PFCandidateCollection> srcPFCandidatesToken_;
0043   edm::EDGetTokenT<CandidateView> srcUnshiftedObjectsToken_;
0044   edm::EDGetTokenT<CandidateView> srcShiftedObjectsToken_;
0045 
0046   double dRmatch_PFCandidate_;
0047   double dRmatch_Object_;
0048 
0049   double dR2match_PFCandidate_;
0050   double dR2match_Object_;
0051 
0052   struct objectEntryType {
0053     objectEntryType(const reco::Candidate::LorentzVector& shiftedObjectP4,
0054                     const reco::Candidate::LorentzVector& unshiftedObjectP4,
0055                     double dRmatch)
0056         : shiftedObjectP4_(shiftedObjectP4),
0057           unshiftedObjectP4_(unshiftedObjectP4),
0058           dRmatch_(dRmatch),
0059           isValidMatch_(false) {
0060       if (unshiftedObjectP4.energy() > 0.) {
0061         shift_ = (shiftedObjectP4.energy() / unshiftedObjectP4.energy()) - 1.;
0062         isValidMatch_ = true;
0063       }
0064     }
0065     ~objectEntryType() {}
0066     reco::Candidate::LorentzVector shiftedObjectP4_;
0067     reco::Candidate::LorentzVector unshiftedObjectP4_;
0068     double dRmatch_;
0069     double shift_;
0070     bool isValidMatch_;
0071   };
0072 
0073   std::vector<objectEntryType> objects_;
0074 };
0075 
0076 const double dRDefault = 1000;
0077 
0078 ShiftedPFCandidateProducerForPFMVAMEt::ShiftedPFCandidateProducerForPFMVAMEt(const edm::ParameterSet& cfg)
0079     : moduleLabel_(cfg.getParameter<std::string>("@module_label")),
0080       srcPFCandidatesToken_(consumes<reco::PFCandidateCollection>(cfg.getParameter<edm::InputTag>("srcPFCandidates"))),
0081       srcUnshiftedObjectsToken_(consumes<CandidateView>(cfg.getParameter<edm::InputTag>("srcUnshiftedObjects"))),
0082       srcShiftedObjectsToken_(consumes<CandidateView>(cfg.getParameter<edm::InputTag>("srcShiftedObjects"))) {
0083   dRmatch_PFCandidate_ = cfg.getParameter<double>("dRmatch_PFCandidate");
0084   dRmatch_Object_ = cfg.exists("dRmatch_Object") ? cfg.getParameter<double>("dRmatch_Object") : 0.1;
0085 
0086   dR2match_PFCandidate_ = dRmatch_PFCandidate_ * dRmatch_PFCandidate_;
0087   dR2match_Object_ = dRmatch_Object_ * dRmatch_Object_;
0088 
0089   produces<reco::PFCandidateCollection>();
0090 }
0091 
0092 ShiftedPFCandidateProducerForPFMVAMEt::~ShiftedPFCandidateProducerForPFMVAMEt() {
0093   // nothing to be done yet...
0094 }
0095 
0096 void ShiftedPFCandidateProducerForPFMVAMEt::produce(edm::Event& evt, const edm::EventSetup& es) {
0097   edm::Handle<reco::PFCandidateCollection> originalPFCandidates;
0098   evt.getByToken(srcPFCandidatesToken_, originalPFCandidates);
0099 
0100   edm::Handle<CandidateView> unshiftedObjects;
0101   evt.getByToken(srcUnshiftedObjectsToken_, unshiftedObjects);
0102 
0103   edm::Handle<CandidateView> shiftedObjects;
0104   evt.getByToken(srcShiftedObjectsToken_, shiftedObjects);
0105 
0106   objects_.clear();
0107 
0108   std::vector<bool> match(shiftedObjects->size(), false);
0109   int prevMatch = -1;
0110   int cnt = 0;
0111 
0112   for (CandidateView::const_iterator unshiftedObject = unshiftedObjects->begin();
0113        unshiftedObject != unshiftedObjects->end();
0114        ++unshiftedObject) {
0115     bool isMatched_Object = false;
0116     double dR2bestMatch_Object = dRDefault;
0117     reco::Candidate::LorentzVector shiftedObjectP4_matched;
0118     prevMatch = -1;
0119 
0120     for (CandidateView::const_iterator shiftedObject = shiftedObjects->begin(); shiftedObject != shiftedObjects->end();
0121          ++shiftedObject) {
0122       if (match[cnt])
0123         continue;
0124 
0125       double dR2 = deltaR2(unshiftedObject->p4(), shiftedObject->p4());
0126       if (dR2 < dR2match_Object_ && dR2 < dR2bestMatch_Object) {
0127         shiftedObjectP4_matched = shiftedObject->p4();
0128         isMatched_Object = true;
0129         dR2bestMatch_Object = dR2;
0130 
0131         prevMatch = cnt;
0132       }
0133       cnt++;
0134     }
0135     if (isMatched_Object) {
0136       //Ambiguity removal
0137       match[prevMatch] = true;
0138       objects_.push_back(objectEntryType(shiftedObjectP4_matched, unshiftedObject->p4(), sqrt(dR2bestMatch_Object)));
0139     }
0140   }
0141 
0142   match.assign(objects_.size(), false);
0143 
0144   auto shiftedPFCandidates = std::make_unique<reco::PFCandidateCollection>();
0145 
0146   for (reco::PFCandidateCollection::const_iterator originalPFCandidate = originalPFCandidates->begin();
0147        originalPFCandidate != originalPFCandidates->end();
0148        ++originalPFCandidate) {
0149     double shift = 0.;
0150     bool applyShift = false;
0151     double dR2bestMatch_PFCandidate = dRDefault;
0152     prevMatch = -1;
0153     cnt = 0;
0154 
0155     for (std::vector<objectEntryType>::const_iterator object = objects_.begin(); object != objects_.end(); ++object) {
0156       if (!object->isValidMatch_)
0157         continue;
0158       if (match[cnt])
0159         continue;
0160 
0161       double dR2 = deltaR2(originalPFCandidate->p4(), object->unshiftedObjectP4_);
0162       if (dR2 < dR2match_PFCandidate_ && dR2 < dR2bestMatch_PFCandidate) {
0163         shift = object->shift_;
0164         applyShift = true;
0165         dR2bestMatch_PFCandidate = dR2;
0166 
0167         prevMatch = cnt;
0168       }
0169       cnt++;
0170     }
0171 
0172     reco::Candidate::LorentzVector shiftedPFCandidateP4 = originalPFCandidate->p4();
0173     if (applyShift) {
0174       //Ambiguity removal
0175       match[prevMatch] = true;
0176 
0177       shiftedPFCandidateP4 *= (1. + shift);
0178     }
0179 
0180     reco::PFCandidate shiftedPFCandidate(*originalPFCandidate);
0181     shiftedPFCandidate.setP4(shiftedPFCandidateP4);
0182 
0183     shiftedPFCandidates->push_back(shiftedPFCandidate);
0184   }
0185 
0186   evt.put(std::move(shiftedPFCandidates));
0187 }
0188 
0189 #include "FWCore/Framework/interface/MakerMacros.h"
0190 
0191 DEFINE_FWK_MODULE(ShiftedPFCandidateProducerForPFMVAMEt);