CMS 3D CMS Logo

EGEtScaleSysModifier.cc
Go to the documentation of this file.
5 
6 #include <vdt/vdtMath.h>
7 
8 //in the legacy re-reco we came across an Et scale issue, specifically an inflection at 45 GeV
9 //it is problematic to address in the normal scale and smearing code therefore
10 //this patch modifies the e/gamma object to "patch in" this additional systematic
11 //Questions:
12 //1 ) Why dont we add this to the overall scale systematic?
13 //Well we could but the whole point of this is to get a proper template which can be evolved
14 //correctly. The issue is not that the current systematic doesnt cover this systematic on a
15 //per bin basis, it does, the problem is the sign flips at 45 GeV so its fine if you use
16 //only eles/phos > 45 or <45 GeV but the template cant simultaneously cover the entire spectrum
17 //and you'll get a nasty constrained fit.
18 //And if you care about these sort of things (and you probably should), you shouldnt be using
19 //the overall systematic anyways but its seperate parts
20 //
21 //2 ) Why dont you do it inside the standard class
22 //We could but we're rather hoping to solve this issue more cleanly in the future
23 //but we would hold up the reminiAOD too long to do so so this is just to get something
24 //which should be fine for 90% of analyses in the miniAOD. So this is a temporary fix
25 //which we hope to rip out soon (if you're reading this in 2024 because we're still doing it
26 //this way, all I can say is sorry, we thought it would go away soon! )
27 
28 
30 public:
32  ~EGEtScaleSysModifier() override{}
33 
34  void setEvent(const edm::Event&) final;
35  void setEventContent(const edm::EventSetup&) final;
36 
37  void modifyObject(pat::Electron& ele) const final;
38  void modifyObject(pat::Photon& pho) const final;
39 
40 private:
41  std::pair<float,float> calCombinedMom(reco::GsfElectron& ele,const float scale,
42  const float smear)const;
43  void setEcalEnergy(reco::GsfElectron& ele,const float scale,const float smear)const;
44 
46  public:
48  virtual ~UncertFuncBase(){}
49  virtual float val(const float et)const=0;
50  };
51 
52  //defines two uncertaintes, one Et<X and one Et>Y
53  //for X<Et<Y, it linearly extrapolates betwen the two values
54  class UncertFuncV1 : public UncertFuncBase {
55  public:
57  lowEt_(conf.getParameter<double>("lowEt")),highEt_(conf.getParameter<double>("highEt")),
58  lowEtUncert_(conf.getParameter<double>("lowEtUncert")),
59  highEtUncert_(conf.getParameter<double>("highEtUncert")),
60  dEt_(highEt_-lowEt_),
61  dUncert_(highEtUncert_ - lowEtUncert_)
62  {
63  if(highEt_<=lowEt_) throw cms::Exception("ConfigError") <<" highEt "<<highEt_<<" is not higher than lowEt "<<lowEt_;
64  }
65  ~UncertFuncV1() override{}
66 
67  float val(const float et)const override{
68  if(et<=lowEt_) return lowEtUncert_;
69  else if(et>=highEt_) return highEtUncert_;
70  else{
71  return (et-lowEt_)*dUncert_/dEt_+lowEtUncert_;
72  }
73  }
74  private:
75  float lowEt_;
76  float highEt_;
77  float lowEtUncert_;
79  float dEt_;
80  float dUncert_;
81  };
82 
84  std::unique_ptr<UncertFuncBase> uncertFunc_;
85 };
86 
89  epCombTool_(conf.getParameter<edm::ParameterSet>("epCombConfig"))
90 {
91  const edm::ParameterSet funcPSet = conf.getParameter<edm::ParameterSet>("uncertFunc");
92  const std::string& funcName = funcPSet.getParameter<std::string>("name");
93  if(funcName == "UncertFuncV1"){
94  uncertFunc_ = std::make_unique<UncertFuncV1>(funcPSet);
95  }else{
96  throw cms::Exception("ConfigError") <<"Error constructing EGEtScaleSysModifier, function name "<<funcName<<" not valid";
97  }
98 
99 }
100 
102 {
103 
104 }
105 
107 {
109 }
110 
111 
113 {
114  auto getVal = [](const pat::Electron& ele,EGEnergySysIndex::Index valIndex){
115  return ele.userFloat(EGEnergySysIndex::name(valIndex));
116  };
117  //so ele.energy() may be either pre or post corrections, we have no idea
118  //so we explicity access the pre and post correction ecal energies
119  //we need the pre corrected to properly do the e/p combination
120  //we need the post corrected to get et uncertainty
121  const float ecalEnergyPostCorr = getVal(ele,EGEnergySysIndex::kEcalPostCorr);
122  const float ecalEnergyPreCorr = getVal(ele,EGEnergySysIndex::kEcalPreCorr);
123  const float ecalEnergyErrPreCorr = getVal(ele,EGEnergySysIndex::kEcalErrPreCorr);
124 
125  //the et cut is in terms of ecal et using the track angle and post corr ecal energy
126  const float etUncert = uncertFunc_->val(ele.et()/ele.energy()*ecalEnergyPostCorr);
127  const float smear = getVal(ele,EGEnergySysIndex::kSmearValue);
128  const float corr = getVal(ele,EGEnergySysIndex::kScaleValue);
129 
130  //get the values we have to reset back to
131  const float oldEcalEnergy = ele.ecalEnergy();
132  const float oldEcalEnergyErr = ele.ecalEnergyError();
133  const auto oldP4 = ele.p4();
134  const float oldP4Err = ele.p4Error(reco::GsfElectron::P4_COMBINATION);
135  const float oldTrkMomErr = ele.trackMomentumError();
136 
137  ele.setCorrectedEcalEnergy(ecalEnergyPreCorr);
138  ele.setCorrectedEcalEnergyError(ecalEnergyErrPreCorr);
139 
140  const float energyEtUncertUp = calCombinedMom(ele,corr+etUncert,smear).first;
141  const float energyEtUncertDn = calCombinedMom(ele,corr-etUncert,smear).first;
142 
143  //reset it back to how it was
144  ele.setCorrectedEcalEnergy(oldEcalEnergy);
145  ele.setCorrectedEcalEnergyError(oldEcalEnergyErr);
146  ele.correctMomentum(oldP4,oldTrkMomErr,oldP4Err);
147 
148  ele.addUserFloat("energyScaleEtUp",energyEtUncertUp);
149  ele.addUserFloat("energyScaleEtDown",energyEtUncertDn);
150 
151 }
152 
154 {
155  auto getVal = [](const pat::Photon& pho,EGEnergySysIndex::Index valIndex){
156  return pho.userFloat(EGEnergySysIndex::name(valIndex));
157  };
158  //so pho.energy() may be either pre or post corrections, we have no idea
159  //so we explicity access the pre and post correction ecal energies
160  //post corr for the et value for the systematic, pre corr to apply them
161  const float ecalEnergyPostCorr = getVal(pho,EGEnergySysIndex::kEcalPostCorr);
162  const float ecalEnergyPreCorr = getVal(pho,EGEnergySysIndex::kEcalPreCorr);
163 
164  //the et cut is in terms of post corr ecal energy
165  const float etUncert = uncertFunc_->val(pho.et()/pho.energy()*ecalEnergyPostCorr);
166  const float corr = getVal(pho,EGEnergySysIndex::kScaleValue);
167 
168  const float energyEtUncertUp = ecalEnergyPreCorr*(corr+etUncert);
169  const float energyEtUncertDn = ecalEnergyPreCorr*(corr-etUncert);
170 
171  pho.addUserFloat("energyScaleEtUp",energyEtUncertUp);
172  pho.addUserFloat("energyScaleEtDown",energyEtUncertDn);
173 
174 }
175 
177  const float scale,
178  const float smear)const
179 {
180  const float oldEcalEnergy = ele.ecalEnergy();
181  const float oldEcalEnergyErr = ele.ecalEnergyError();
182  const auto oldP4 = ele.p4();
183  const float oldP4Err = ele.p4Error(reco::GsfElectron::P4_COMBINATION);
184  const float oldTrkMomErr = ele.trackMomentumError();
185 
186  setEcalEnergy(ele,scale,smear);
187  const auto& combinedMomentum = epCombTool_.combine(ele);
188  ele.setCorrectedEcalEnergy(oldEcalEnergy);
189  ele.setCorrectedEcalEnergyError(oldEcalEnergyErr);
190  ele.correctMomentum(oldP4,oldTrkMomErr,oldP4Err);
191 
192 
193  return combinedMomentum;
194 }
195 
197  const float scale,
198  const float smear)const
199 {
200  const float oldEcalEnergy = ele.ecalEnergy();
201  const float oldEcalEnergyErr = ele.ecalEnergyError();
202  ele.setCorrectedEcalEnergy( oldEcalEnergy*scale );
203  ele.setCorrectedEcalEnergyError(std::hypot( oldEcalEnergyErr*scale, oldEcalEnergy*smear*scale ) );
204 }
205 
206 
207 
210  "EGEtScaleSysModifier");
T getParameter(std::string const &) const
Analysis-level Photon class.
Definition: Photon.h:47
virtual float val(const float et) const =0
float trackMomentumError() const
Definition: GsfElectron.h:848
const LorentzVector & p4(P4Kind kind) const
Definition: GsfElectron.cc:228
std::unique_ptr< UncertFuncBase > uncertFunc_
void modifyObject(pat::Electron &ele) const final
static const std::string & name(size_t index)
void correctMomentum(const LorentzVector &p4, float trackMomentumError, float p4Error)
Definition: GsfElectron.h:870
EpCombinationTool epCombTool_
void combine(SimpleElectron &mySimpleElectron) const
float p4Error(P4Kind kind) const
Definition: GsfElectron.cc:240
void addUserFloat(const std::string &label, float data, const bool overwrite=false)
Set user-defined float.
Definition: PATObject.h:813
float userFloat(const std::string &key) const
Definition: PATObject.h:791
std::pair< float, float > calCombinedMom(reco::GsfElectron &ele, const float scale, const float smear) const
int iEvent
Definition: GenABIO.cc:224
void setCorrectedEcalEnergyError(float newEnergyError)
Definition: GsfElectron.cc:179
double et() const final
transverse energy
double energy() const final
energy
UncertFuncV1(const edm::ParameterSet &conf)
void setEventContent(const edm::EventSetup &iSetup)
float ecalEnergyError() const
Definition: GsfElectron.h:861
JetCorrectorParameters corr
Definition: classes.h:5
void setEvent(const edm::Event &) final
Analysis-level electron class.
Definition: Electron.h:52
void setEventContent(const edm::EventSetup &) final
void setEcalEnergy(reco::GsfElectron &ele, const float scale, const float smear) const
et
define resolution functions of each parameter
float ecalEnergy() const
Definition: GsfElectron.h:860
void setCorrectedEcalEnergy(float newEnergy)
Definition: GsfElectron.cc:182
HLT enums.
EGEtScaleSysModifier(const edm::ParameterSet &conf, edm::ConsumesCollector &)
#define DEFINE_EDM_PLUGIN(factory, type, name)
float val(const float et) const override