Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2021-02-14 13:33:10

0001 #ifndef PhysicsTools_PatUtils_ShiftedParticleProducerT_h
0002 #define PhysicsTools_PatUtils_ShiftedParticleProducerT_h
0003 
0004 /** \class ShiftedParticleProducerT
0005  *
0006  * Vary energy of electrons/muons/tau-jets by +/- 1 standard deviation,
0007  * in order to estimate resulting uncertainty on MET
0008  *
0009  * NOTE: energy scale uncertainties need to be specified in python config
0010  *
0011  * \author Christian Veelken, LLR
0012  *
0013  *
0014  *
0015  */
0016 
0017 #include "FWCore/Framework/interface/stream/EDProducer.h"
0018 #include "FWCore/Framework/interface/Event.h"
0019 #include "FWCore/Framework/interface/EventSetup.h"
0020 #include "FWCore/ParameterSet/interface/ParameterSet.h"
0021 #include "FWCore/Utilities/interface/InputTag.h"
0022 #include "FWCore/Utilities/interface/isFinite.h"
0023 
0024 #include "CommonTools/Utils/interface/StringCutObjectSelector.h"
0025 #include "DataFormats/Candidate/interface/Candidate.h"
0026 
0027 #include <string>
0028 #include <vector>
0029 
0030 template <typename T>
0031 class ShiftedParticleProducerT : public edm::stream::EDProducer<> {
0032   typedef std::vector<T> ParticleCollection;
0033 
0034 public:
0035   explicit ShiftedParticleProducerT(const edm::ParameterSet& cfg)
0036       : moduleLabel_(cfg.getParameter<std::string>("@module_label")) {
0037     srcToken_ = consumes<ParticleCollection>(cfg.getParameter<edm::InputTag>("src"));
0038 
0039     shiftBy_ = cfg.getParameter<double>("shiftBy");
0040 
0041     if (cfg.exists("binning")) {
0042       typedef std::vector<edm::ParameterSet> vParameterSet;
0043       vParameterSet cfgBinning = cfg.getParameter<vParameterSet>("binning");
0044       for (vParameterSet::const_iterator cfgBinningEntry = cfgBinning.begin(); cfgBinningEntry != cfgBinning.end();
0045            ++cfgBinningEntry) {
0046         binning_.push_back(new binningEntryType(*cfgBinningEntry));
0047       }
0048     } else {
0049       double uncertainty = cfg.getParameter<double>("uncertainty");
0050       binning_.push_back(new binningEntryType(uncertainty));
0051     }
0052 
0053     produces<ParticleCollection>();
0054   }
0055   ~ShiftedParticleProducerT() override {
0056     for (typename std::vector<binningEntryType*>::const_iterator it = binning_.begin(); it != binning_.end(); ++it) {
0057       delete (*it);
0058     }
0059   }
0060 
0061 private:
0062   void produce(edm::Event& evt, const edm::EventSetup& es) override {
0063     edm::Handle<ParticleCollection> originalParticles;
0064     evt.getByToken(srcToken_, originalParticles);
0065 
0066     auto shiftedParticles = std::make_unique<ParticleCollection>();
0067 
0068     for (typename ParticleCollection::const_iterator originalParticle = originalParticles->begin();
0069          originalParticle != originalParticles->end();
0070          ++originalParticle) {
0071       double uncertainty = 0.;
0072       for (typename std::vector<binningEntryType*>::iterator binningEntry = binning_.begin();
0073            binningEntry != binning_.end();
0074            ++binningEntry) {
0075         if ((!(*binningEntry)->binSelection_) || (*(*binningEntry)->binSelection_)(*originalParticle)) {
0076           uncertainty = (*binningEntry)->binUncertainty_;
0077           break;
0078         }
0079       }
0080 
0081       double shift = shiftBy_ * uncertainty;
0082 
0083       reco::Candidate::LorentzVector shiftedParticleP4 = originalParticle->p4();
0084       //leave 0*nan = 0
0085       if (!(edm::isNotFinite(shift) && shiftedParticleP4.mag2() == 0))
0086         shiftedParticleP4 *= (1. + shift);
0087 
0088       T shiftedParticle(*originalParticle);
0089       shiftedParticle.setP4(shiftedParticleP4);
0090 
0091       shiftedParticles->push_back(shiftedParticle);
0092     }
0093 
0094     evt.put(std::move(shiftedParticles));
0095   }
0096 
0097   std::string moduleLabel_;
0098 
0099   edm::EDGetTokenT<ParticleCollection> srcToken_;
0100 
0101   struct binningEntryType {
0102     binningEntryType(double uncertainty) : binSelection_(nullptr), binUncertainty_(uncertainty) {}
0103     binningEntryType(const edm::ParameterSet& cfg)
0104         : binSelection_(new StringCutObjectSelector<T>(cfg.getParameter<std::string>("binSelection"))),
0105           binUncertainty_(cfg.getParameter<double>("binUncertainty")) {}
0106     ~binningEntryType() { delete binSelection_; }
0107     StringCutObjectSelector<T>* binSelection_;
0108     double binUncertainty_;
0109   };
0110   std::vector<binningEntryType*> binning_;
0111 
0112   double shiftBy_;  // set to +1.0/-1.0 for up/down variation of energy scale
0113 };
0114 
0115 #endif