File indexing completed on 2024-04-06 12:24:04
0001 #ifndef PhysicsTools_PatUtils_ShiftedParticleProducerT_h
0002 #define PhysicsTools_PatUtils_ShiftedParticleProducerT_h
0003
0004
0005
0006
0007
0008
0009
0010
0011
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
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_;
0113 };
0114
0115 #endif