CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
EGExtraInfoModifierFromDB.cc
Go to the documentation of this file.
6 
9 
14 
17 
19 
20 #include <vdt/vdtMath.h>
21 
22 namespace {
23  const edm::InputTag empty_tag;
24 }
25 
26 #include <unordered_map>
27 
29 public:
32  typedef std::pair<edm::InputTag, ValMapFloatToken> ValMapFloatTagTokenPair;
33  typedef std::pair<edm::InputTag, ValMapIntToken> ValMapIntTagTokenPair;
34 
35  struct electron_config {
38  std::unordered_map<std::string, ValMapFloatTagTokenPair> tag_float_token_map;
39  std::unordered_map<std::string, ValMapIntTagTokenPair> tag_int_token_map;
40 
41  std::vector<std::string> condnames_mean_50ns;
42  std::vector<std::string> condnames_sigma_50ns;
43  std::vector<std::string> condnames_mean_25ns;
44  std::vector<std::string> condnames_sigma_25ns;
47  };
48 
49  struct photon_config {
52  std::unordered_map<std::string, ValMapFloatTagTokenPair> tag_float_token_map;
53  std::unordered_map<std::string, ValMapIntTagTokenPair> tag_int_token_map;
54 
55  std::vector<std::string> condnames_mean_50ns;
56  std::vector<std::string> condnames_sigma_50ns;
57  std::vector<std::string> condnames_mean_25ns;
58  std::vector<std::string> condnames_sigma_25ns;
59  };
60 
63 
64  void setEvent(const edm::Event&) override final;
65  void setEventContent(const edm::EventSetup&) override final;
66  void setConsumes(edm::ConsumesCollector&) override final;
67 
68  void modifyObject(reco::GsfElectron&) const override final;
69  void modifyObject(reco::Photon&) const override final;
70 
71  // just calls reco versions
72  void modifyObject(pat::Electron&) const override final;
73  void modifyObject(pat::Photon&) const override final;
74 
75 private:
78  std::unordered_map<unsigned,edm::Ptr<reco::GsfElectron> > eles_by_oop; // indexed by original object ptr
79  std::unordered_map<unsigned,edm::Handle<edm::ValueMap<float> > > ele_vmaps;
80  std::unordered_map<unsigned,edm::Handle<edm::ValueMap<int> > > ele_int_vmaps;
81  std::unordered_map<unsigned,edm::Ptr<reco::Photon> > phos_by_oop;
82  std::unordered_map<unsigned,edm::Handle<edm::ValueMap<float> > > pho_vmaps;
83  std::unordered_map<unsigned,edm::Handle<edm::ValueMap<int> > > pho_int_vmaps;
84 
88  edm::EDGetTokenT<unsigned int> bunchSpacingToken_;
89  float rhoValue_;
91  edm::EDGetTokenT<double> rhoToken_;
92  int nVtx_;
94  edm::EDGetTokenT<reco::VertexCollection> vtxToken_;
96 
98 
104 };
105 
108  "EGExtraInfoModifierFromDB");
109 
110 EGExtraInfoModifierFromDB::EGExtraInfoModifierFromDB(const edm::ParameterSet& conf) :
112 
113  bunchspacing_ = 450;
114  autoDetectBunchSpacing_ = conf.getParameter<bool>("autoDetectBunchSpacing");
115 
116  rhoTag_ = conf.getParameter<edm::InputTag>("rhoCollection");
117  vtxTag_ = conf.getParameter<edm::InputTag>("vertexCollection");
118 
119  if (autoDetectBunchSpacing_) {
120  bunchspacingTag_ = conf.getParameter<edm::InputTag>("bunchSpacingTag");
121  } else {
122  bunchspacing_ = conf.getParameter<int>("manualBunchSpacing");
123  }
124 
125  constexpr char electronSrc[] = "electronSrc";
126  constexpr char photonSrc[] = "photonSrc";
127 
128  if(conf.exists("electron_config")) {
129  const edm::ParameterSet& electrons = conf.getParameter<edm::ParameterSet>("electron_config");
130  if( electrons.exists(electronSrc) )
131  e_conf.electron_src = electrons.getParameter<edm::InputTag>(electronSrc);
132 
133  std::vector<std::string> intValueMaps;
134  if ( electrons.existsAs<std::vector<std::string> >("intValueMaps"))
135  intValueMaps = electrons.getParameter<std::vector<std::string> >("intValueMaps");
136 
137  const std::vector<std::string> parameters = electrons.getParameterNames();
138  for( const std::string& name : parameters ) {
139  if( std::string(electronSrc) == name )
140  continue;
141  if( electrons.existsAs<edm::InputTag>(name)) {
142  for (auto vmp : intValueMaps) {
143  if (name == vmp) {
145  break;
146  }
147  }
149  }
150  }
151 
152  e_conf.condnames_mean_50ns = electrons.getParameter<std::vector<std::string> >("regressionKey_50ns");
153  e_conf.condnames_sigma_50ns = electrons.getParameter<std::vector<std::string> >("uncertaintyKey_50ns");
154  e_conf.condnames_mean_25ns = electrons.getParameter<std::vector<std::string> >("regressionKey_25ns");
155  e_conf.condnames_sigma_25ns = electrons.getParameter<std::vector<std::string> >("uncertaintyKey_25ns");
156  e_conf.condnames_weight_50ns = electrons.getParameter<std::string>("combinationKey_50ns");
157  e_conf.condnames_weight_25ns = electrons.getParameter<std::string>("combinationKey_25ns");
158  }
159 
160  if( conf.exists("photon_config") ) {
161  const edm::ParameterSet& photons = conf.getParameter<edm::ParameterSet>("photon_config");
162 
163  if( photons.exists(photonSrc) )
164  ph_conf.photon_src = photons.getParameter<edm::InputTag>(photonSrc);
165 
166  std::vector<std::string> intValueMaps;
167  if ( photons.existsAs<std::vector<std::string> >("intValueMaps"))
168  intValueMaps = photons.getParameter<std::vector<std::string> >("intValueMaps");
169 
170  const std::vector<std::string> parameters = photons.getParameterNames();
171  for( const std::string& name : parameters ) {
172  if( std::string(photonSrc) == name )
173  continue;
174  if( photons.existsAs<edm::InputTag>(name)) {
175  for (auto vmp : intValueMaps) {
176  if (name == vmp) {
178  break;
179  }
180  }
182  }
183  }
184 
185  ph_conf.condnames_mean_50ns = photons.getParameter<std::vector<std::string>>("regressionKey_50ns");
186  ph_conf.condnames_sigma_50ns = photons.getParameter<std::vector<std::string>>("uncertaintyKey_50ns");
187  ph_conf.condnames_mean_25ns = photons.getParameter<std::vector<std::string>>("regressionKey_25ns");
188  ph_conf.condnames_sigma_25ns = photons.getParameter<std::vector<std::string>>("uncertaintyKey_25ns");
189  }
190 }
191 
192 namespace {
193  template<typename T>
194  inline void get_product(const edm::Event& evt,
196  std::unordered_map<unsigned, edm::Handle<edm::ValueMap<T> > >& map) {
197  evt.getByToken(tok,map[tok.index()]);
198  }
199 }
200 
202  eles_by_oop.clear();
203  phos_by_oop.clear();
204  ele_vmaps.clear();
205  ele_int_vmaps.clear();
206  pho_vmaps.clear();
207  pho_int_vmaps.clear();
208 
212 
213  for( unsigned i = 0; i < eles->size(); ++i ) {
214  edm::Ptr<pat::Electron> ptr = eles->ptrAt(i);
215  eles_by_oop[ptr->originalObjectRef().key()] = ptr;
216  }
217  }
218 
219  for (std::unordered_map<std::string, ValMapFloatTagTokenPair>::iterator imap = e_conf.tag_float_token_map.begin();
220  imap != e_conf.tag_float_token_map.end();
221  imap++) {
222  get_product(evt, imap->second.second, ele_vmaps);
223  }
224 
225  for (std::unordered_map<std::string, ValMapIntTagTokenPair>::iterator imap = e_conf.tag_int_token_map.begin();
226  imap != e_conf.tag_int_token_map.end();
227  imap++) {
228  get_product(evt, imap->second.second, ele_int_vmaps);
229  }
230 
234 
235  for( unsigned i = 0; i < phos->size(); ++i ) {
236  edm::Ptr<pat::Photon> ptr = phos->ptrAt(i);
237  phos_by_oop[ptr->originalObjectRef().key()] = ptr;
238  }
239  }
240 
241 
242  for (std::unordered_map<std::string, ValMapFloatTagTokenPair>::iterator imap = ph_conf.tag_float_token_map.begin();
243  imap != ph_conf.tag_float_token_map.end();
244  imap++) {
245  get_product(evt, imap->second.second, pho_vmaps);
246  }
247 
248  for (std::unordered_map<std::string, ValMapIntTagTokenPair>::iterator imap = ph_conf.tag_int_token_map.begin();
249  imap != ph_conf.tag_int_token_map.end();
250  imap++) {
251  get_product(evt, imap->second.second, pho_int_vmaps);
252  }
253 
255  edm::Handle<unsigned int> bunchSpacingH;
256  evt.getByToken(bunchSpacingToken_,bunchSpacingH);
257  bunchspacing_ = *bunchSpacingH;
258  }
259 
260  edm::Handle<double> rhoH;
261  evt.getByToken(rhoToken_, rhoH);
262  rhoValue_ = *rhoH;
263 
264  evt.getByToken(vtxToken_, vtxH_);
265  nVtx_ = vtxH_->size();
266 }
267 
269 
270  iSetup_ = &evs;
271 
272  edm::ESHandle<GBRForestD> forestDEH;
273  edm::ESHandle<GBRForest> forestEH;
274 
275  const std::vector<std::string> ph_condnames_mean = (bunchspacing_ == 25) ? ph_conf.condnames_mean_25ns : ph_conf.condnames_mean_50ns;
276  const std::vector<std::string> ph_condnames_sigma = (bunchspacing_ == 25) ? ph_conf.condnames_sigma_25ns : ph_conf.condnames_sigma_50ns;
277 
278  unsigned int ncor = ph_condnames_mean.size();
279  for (unsigned int icor=0; icor<ncor; ++icor) {
280  evs.get<GBRDWrapperRcd>().get(ph_condnames_mean[icor], forestDEH);
281  ph_forestH_mean_.push_back(forestDEH.product());
282  evs.get<GBRDWrapperRcd>().get(ph_condnames_sigma[icor], forestDEH);
283  ph_forestH_sigma_.push_back(forestDEH.product());
284  }
285 
286  const std::vector<std::string> e_condnames_mean = (bunchspacing_ == 25) ? e_conf.condnames_mean_25ns : e_conf.condnames_mean_50ns;
287  const std::vector<std::string> e_condnames_sigma = (bunchspacing_ == 25) ? e_conf.condnames_sigma_25ns : e_conf.condnames_sigma_50ns;
288  const std::string ep_condnames_weight = (bunchspacing_ == 25) ? e_conf.condnames_weight_25ns : e_conf.condnames_weight_50ns;
289 
290  unsigned int encor = e_condnames_mean.size();
291  evs.get<GBRWrapperRcd>().get(ep_condnames_weight, forestEH);
292  ep_forestH_weight_ = forestEH.product();
293 
294  for (unsigned int icor=0; icor<encor; ++icor) {
295  evs.get<GBRDWrapperRcd>().get(e_condnames_mean[icor], forestDEH);
296  e_forestH_mean_.push_back(forestDEH.product());
297  evs.get<GBRDWrapperRcd>().get(e_condnames_sigma[icor], forestDEH);
298  e_forestH_sigma_.push_back(forestDEH.product());
299  }
300 }
301 
302 namespace {
303  template<typename T, typename U, typename V>
304  inline void make_consumes(T& tag,U& tok,V& sume) {
305  if(!(empty_tag == tag))
306  tok = sume.template consumes<edm::ValueMap<float> >(tag);
307  }
308 
309  template<typename T, typename U, typename V>
310  inline void make_int_consumes(T& tag,U& tok,V& sume) {
311  if(!(empty_tag == tag))
312  tok = sume.template consumes<edm::ValueMap<int> >(tag);
313  }
314 }
315 
317 
318  rhoToken_ = sumes.consumes<double>(rhoTag_);
320 
322  bunchSpacingToken_ = sumes.consumes<unsigned int>(bunchspacingTag_);
323 
324  //setup electrons
325  if(!(empty_tag == e_conf.electron_src))
327 
328  for ( std::unordered_map<std::string, ValMapFloatTagTokenPair>::iterator imap = e_conf.tag_float_token_map.begin();
329  imap != e_conf.tag_float_token_map.end();
330  imap++) {
331  make_consumes(imap->second.first, imap->second.second, sumes);
332  }
333 
334  for ( std::unordered_map<std::string, ValMapIntTagTokenPair>::iterator imap = e_conf.tag_int_token_map.begin();
335  imap != e_conf.tag_int_token_map.end();
336  imap++) {
337  make_int_consumes(imap->second.first, imap->second.second, sumes);
338  }
339 
340  // setup photons
341  if(!(empty_tag == ph_conf.photon_src))
343 
344  for ( std::unordered_map<std::string, ValMapFloatTagTokenPair>::iterator imap = ph_conf.tag_float_token_map.begin();
345  imap != ph_conf.tag_float_token_map.end();
346  imap++) {
347  make_consumes(imap->second.first, imap->second.second, sumes);
348  }
349 
350  for ( std::unordered_map<std::string, ValMapIntTagTokenPair>::iterator imap = ph_conf.tag_int_token_map.begin();
351  imap != ph_conf.tag_int_token_map.end();
352  imap++) {
353  make_int_consumes(imap->second.first, imap->second.second, sumes);
354  }
355 }
356 
357 namespace {
358  template<typename T, typename U, typename V, typename Z>
359  inline void assignValue(const T& ptr, const U& tok, const V& map, Z& value) {
360  if( !tok.isUninitialized() ) value = map.find(tok.index())->second->get(ptr.id(),ptr.key());
361  }
362 }
363 
365  // regression calculation needs no additional valuemaps
366 
367  const reco::SuperClusterRef& the_sc = ele.superCluster();
368  const edm::Ptr<reco::CaloCluster>& theseed = the_sc->seed();
369  const int numberOfClusters = the_sc->clusters().size();
370  const bool missing_clusters = !the_sc->clusters()[numberOfClusters-1].isAvailable();
371 
372  if( missing_clusters ) return ; // do not apply corrections in case of missing info (slimmed MiniAOD electrons)
373 
374  std::array<float, 33> eval;
375  const double raw_energy = the_sc->rawEnergy();
376  const auto& ess = ele.showerShape();
377 
378  // SET INPUTS
379  eval[0] = nVtx_;
380  eval[1] = raw_energy;
381  eval[2] = the_sc->eta();
382  eval[3] = the_sc->phi();
383  eval[4] = the_sc->etaWidth();
384  eval[5] = the_sc->phiWidth();
385  eval[6] = ess.r9;
386  eval[7] = theseed->energy()/raw_energy;
387  eval[8] = ess.eMax/raw_energy;
388  eval[9] = ess.e2nd/raw_energy;
389  eval[10] = (ess.eLeft + ess.eRight != 0.f ? (ess.eLeft-ess.eRight)/(ess.eLeft+ess.eRight) : 0.f);
390  eval[11] = (ess.eTop + ess.eBottom != 0.f ? (ess.eTop-ess.eBottom)/(ess.eTop+ess.eBottom) : 0.f);
391  eval[12] = ess.sigmaIetaIeta;
392  eval[13] = ess.sigmaIetaIphi;
393  eval[14] = ess.sigmaIphiIphi;
394  eval[15] = std::max(0,numberOfClusters-1);
395 
396  // calculate sub-cluster variables
397  std::vector<float> clusterRawEnergy;
398  clusterRawEnergy.resize(std::max(3, numberOfClusters), 0);
399  std::vector<float> clusterDEtaToSeed;
400  clusterDEtaToSeed.resize(std::max(3, numberOfClusters), 0);
401  std::vector<float> clusterDPhiToSeed;
402  clusterDPhiToSeed.resize(std::max(3, numberOfClusters), 0);
403  float clusterMaxDR = 999.;
404  float clusterMaxDRDPhi = 999.;
405  float clusterMaxDRDEta = 999.;
406  float clusterMaxDRRawEnergy = 0.;
407 
408  size_t iclus = 0;
409  float maxDR = 0;
411  // loop over all clusters that aren't the seed
412  auto clusend = the_sc->clustersEnd();
413  for( auto clus = the_sc->clustersBegin(); clus != clusend; ++clus ) {
414  pclus = *clus;
415 
416  if(theseed == pclus )
417  continue;
418  clusterRawEnergy[iclus] = pclus->energy();
419  clusterDPhiToSeed[iclus] = reco::deltaPhi(pclus->phi(),theseed->phi());
420  clusterDEtaToSeed[iclus] = pclus->eta() - theseed->eta();
421 
422  // find cluster with max dR
423  const auto the_dr = reco::deltaR(*pclus, *theseed);
424  if(the_dr > maxDR) {
425  maxDR = the_dr;
426  clusterMaxDR = maxDR;
427  clusterMaxDRDPhi = clusterDPhiToSeed[iclus];
428  clusterMaxDRDEta = clusterDEtaToSeed[iclus];
429  clusterMaxDRRawEnergy = clusterRawEnergy[iclus];
430  }
431  ++iclus;
432  }
433 
434  eval[16] = clusterMaxDR;
435  eval[17] = clusterMaxDRDPhi;
436  eval[18] = clusterMaxDRDEta;
437  eval[19] = clusterMaxDRRawEnergy/raw_energy;
438  eval[20] = clusterRawEnergy[0]/raw_energy;
439  eval[21] = clusterRawEnergy[1]/raw_energy;
440  eval[22] = clusterRawEnergy[2]/raw_energy;
441  eval[23] = clusterDPhiToSeed[0];
442  eval[24] = clusterDPhiToSeed[1];
443  eval[25] = clusterDPhiToSeed[2];
444  eval[26] = clusterDEtaToSeed[0];
445  eval[27] = clusterDEtaToSeed[1];
446  eval[28] = clusterDEtaToSeed[2];
447 
448  // calculate coordinate variables
449  const bool iseb = ele.isEB();
450  float dummy;
451  int iPhi;
452  int iEta;
453  float cryPhi;
454  float cryEta;
455  EcalClusterLocal _ecalLocal;
456  if (ele.isEB())
457  _ecalLocal.localCoordsEB(*theseed, *iSetup_, cryEta, cryPhi, iEta, iPhi, dummy, dummy);
458  else
459  _ecalLocal.localCoordsEE(*theseed, *iSetup_, cryEta, cryPhi, iEta, iPhi, dummy, dummy);
460 
461  if (iseb) {
462  eval[29] = cryEta;
463  eval[30] = cryPhi;
464  eval[31] = iEta;
465  eval[32] = iPhi;
466  } else {
467  eval[29] = the_sc->preshowerEnergy()/the_sc->rawEnergy();
468  }
469 
470  //magic numbers for MINUIT-like transformation of BDT output onto limited range
471  //(These should be stored inside the conditions object in the future as well)
472  constexpr double meanlimlow = 0.2;
473  constexpr double meanlimhigh = 2.0;
474  constexpr double meanoffset = meanlimlow + 0.5*(meanlimhigh-meanlimlow);
475  constexpr double meanscale = 0.5*(meanlimhigh-meanlimlow);
476 
477  constexpr double sigmalimlow = 0.0002;
478  constexpr double sigmalimhigh = 0.5;
479  constexpr double sigmaoffset = sigmalimlow + 0.5*(sigmalimhigh-sigmalimlow);
480  constexpr double sigmascale = 0.5*(sigmalimhigh-sigmalimlow);
481 
482  int coridx = 0;
483  if (!iseb)
484  coridx = 1;
485 
486  //these are the actual BDT responses
487  double rawmean = e_forestH_mean_[coridx]->GetResponse(eval.data());
488  double rawsigma = e_forestH_sigma_[coridx]->GetResponse(eval.data());
489 
490  //apply transformation to limited output range (matching the training)
491  double mean = meanoffset + meanscale*vdt::fast_sin(rawmean);
492  double sigma = sigmaoffset + sigmascale*vdt::fast_sin(rawsigma);
493 
494  //regression target is ln(Etrue/Eraw)
495  //so corrected energy is ecor=exp(mean)*e, uncertainty is exp(mean)*eraw*sigma=ecor*sigma
496  double ecor = mean*(eval[1]);
497  if (!iseb)
498  ecor = mean*(eval[1]+the_sc->preshowerEnergy());
499  const double sigmacor = sigma*ecor;
500 
501  ele.setCorrectedEcalEnergy(ecor);
502  ele.setCorrectedEcalEnergyError(sigmacor);
503 
504  // E-p combination
505  //std::array<float, 11> eval_ep;
506  float eval_ep[11];
507 
508  const float ep = ele.trackMomentumAtVtx().R();
509  const float tot_energy = the_sc->rawEnergy()+the_sc->preshowerEnergy();
510  const float momentumError = ele.trackMomentumError();
511  const float trkMomentumRelError = ele.trackMomentumError()/ep;
512  const float eOverP = tot_energy*mean/ep;
513  eval_ep[0] = tot_energy*mean;
514  eval_ep[1] = sigma/mean;
515  eval_ep[2] = ep;
516  eval_ep[3] = trkMomentumRelError;
517  eval_ep[4] = sigma/mean/trkMomentumRelError;
518  eval_ep[5] = tot_energy*mean/ep;
519  eval_ep[6] = tot_energy*mean/ep*sqrt(sigma/mean*sigma/mean+trkMomentumRelError*trkMomentumRelError);
520  eval_ep[7] = ele.ecalDriven();
521  eval_ep[8] = ele.trackerDrivenSeed();
522  eval_ep[9] = int(ele.classification());//eleClass;
523  eval_ep[10] = iseb;
524 
525  // CODE FOR FUTURE SEMI_PARAMETRIC
526  //double rawweight = ep_forestH_mean_[coridx]->GetResponse(eval_ep.data());
528  //double weight = meanoffset + meanscale*vdt::fast_sin(rawweight);
530 
531  // CODE FOR STANDARD BDT
532  double weight = 0.;
533  if ( eOverP > 0.025 &&
534  std::abs(ep-ecor) < 15.*std::sqrt( momentumError*momentumError + sigmacor*sigmacor ) ) {
535  // protection against crazy track measurement
536  weight = ep_forestH_weight_->GetResponse(eval_ep);
537  if(weight>1.)
538  weight = 1.;
539  else if(weight<0.)
540  weight = 0.;
541  }
542 
543  double combinedMomentum = weight*ele.trackMomentumAtVtx().R() + (1.-weight)*ecor;
544  double combinedMomentumError = sqrt(weight*weight*ele.trackMomentumError()*ele.trackMomentumError() + (1.-weight)*(1.-weight)*sigmacor*sigmacor);
545 
546  math::XYZTLorentzVector oldMomentum = ele.p4();
547  math::XYZTLorentzVector newMomentum = math::XYZTLorentzVector(oldMomentum.x()*combinedMomentum/oldMomentum.t(),
548  oldMomentum.y()*combinedMomentum/oldMomentum.t(),
549  oldMomentum.z()*combinedMomentum/oldMomentum.t(),
550  combinedMomentum);
551 
552  //ele.correctEcalEnergy(combinedMomentum, combinedMomentumError);
553  ele.correctMomentum(newMomentum, ele.trackMomentumError(), combinedMomentumError);
554 }
555 
557  modifyObject(static_cast<reco::GsfElectron&>(ele));
558 }
559 
561  // regression calculation needs no additional valuemaps
562 
563  std::array<float, 31> eval;
564  const reco::SuperClusterRef& the_sc = pho.superCluster();
565  const edm::Ptr<reco::CaloCluster>& theseed = the_sc->seed();
566 
567  const int numberOfClusters = the_sc->clusters().size();
568  const bool missing_clusters = !the_sc->clusters()[numberOfClusters-1].isAvailable();
569 
570  if( missing_clusters ) return ; // do not apply corrections in case of missing info (slimmed MiniAOD electrons)
571 
572  const double raw_energy = the_sc->rawEnergy();
573  const auto& ess = pho.showerShapeVariables();
574 
575  // SET INPUTS
576  eval[0] = raw_energy;
577  eval[1] = pho.r9();
578  eval[2] = the_sc->etaWidth();
579  eval[3] = the_sc->phiWidth();
580  eval[4] = std::max(0,numberOfClusters - 1);
581  eval[5] = pho.hadronicOverEm();
582  eval[6] = rhoValue_;
583  eval[7] = nVtx_;
584  eval[8] = theseed->eta()-the_sc->position().Eta();
585  eval[9] = reco::deltaPhi(theseed->phi(),the_sc->position().Phi());
586  eval[10] = theseed->energy()/raw_energy;
587  eval[11] = ess.e3x3/ess.e5x5;
588  eval[12] = ess.sigmaIetaIeta;
589  eval[13] = ess.sigmaIphiIphi;
590  eval[14] = ess.sigmaIetaIphi/(ess.sigmaIphiIphi*ess.sigmaIetaIeta);
591  eval[15] = ess.maxEnergyXtal/ess.e5x5;
592  eval[16] = ess.e2nd/ess.e5x5;
593  eval[17] = ess.eTop/ess.e5x5;
594  eval[18] = ess.eBottom/ess.e5x5;
595  eval[19] = ess.eLeft/ess.e5x5;
596  eval[20] = ess.eRight/ess.e5x5;
597  eval[21] = ess.e2x5Max/ess.e5x5;
598  eval[22] = ess.e2x5Left/ess.e5x5;
599  eval[23] = ess.e2x5Right/ess.e5x5;
600  eval[24] = ess.e2x5Top/ess.e5x5;
601  eval[25] = ess.e2x5Bottom/ess.e5x5;
602 
603  const bool iseb = pho.isEB();
604  if (iseb) {
605  EBDetId ebseedid(theseed->seed());
606  eval[26] = pho.e5x5()/theseed->energy();
607  eval[27] = ebseedid.ieta();
608  eval[28] = ebseedid.iphi();
609  } else {
610  EEDetId eeseedid(theseed->seed());
611  eval[26] = the_sc->preshowerEnergy()/raw_energy;
612  eval[27] = the_sc->preshowerEnergyPlane1()/raw_energy;
613  eval[28] = the_sc->preshowerEnergyPlane2()/raw_energy;
614  eval[29] = eeseedid.ix();
615  eval[30] = eeseedid.iy();
616  }
617 
618  //magic numbers for MINUIT-like transformation of BDT output onto limited range
619  //(These should be stored inside the conditions object in the future as well)
620  const double meanlimlow = 0.2;
621  const double meanlimhigh = 2.0;
622  const double meanoffset = meanlimlow + 0.5*(meanlimhigh-meanlimlow);
623  const double meanscale = 0.5*(meanlimhigh-meanlimlow);
624 
625  const double sigmalimlow = 0.0002;
626  const double sigmalimhigh = 0.5;
627  const double sigmaoffset = sigmalimlow + 0.5*(sigmalimhigh-sigmalimlow);
628  const double sigmascale = 0.5*(sigmalimhigh-sigmalimlow);
629 
630  int coridx = 0;
631  if (!iseb)
632  coridx = 1;
633 
634  //these are the actual BDT responses
635  double rawmean = ph_forestH_mean_[coridx]->GetResponse(eval.data());
636  double rawsigma = ph_forestH_sigma_[coridx]->GetResponse(eval.data());
637  //apply transformation to limited output range (matching the training)
638  double mean = meanoffset + meanscale*vdt::fast_sin(rawmean);
639  double sigma = sigmaoffset + sigmascale*vdt::fast_sin(rawsigma);
640 
641  //regression target is ln(Etrue/Eraw)
642  //so corrected energy is ecor=exp(mean)*e, uncertainty is exp(mean)*eraw*sigma=ecor*sigma
643  double ecor = mean*eval[0];
644  if (!iseb)
645  ecor = mean*(eval[0]+the_sc->preshowerEnergy());
646 
647  double sigmacor = sigma*ecor;
648  pho.setCorrectedEnergy(reco::Photon::P4type::regression2, ecor, sigmacor, true);
649 }
650 
652  modifyObject(static_cast<reco::Photon&>(pho));
653 }
const double Z[kNumberCalorimeter]
double GetResponse(const float *vector) const
Definition: GBRForest.h:59
const ShowerShape & showerShape() const
Definition: GsfElectron.h:429
EDGetTokenT< ProductType > consumes(edm::InputTag const &tag)
bool isAvailable() const
Definition: Ref.h:576
T getParameter(std::string const &) const
int i
Definition: DBlmapReader.cc:9
Analysis-level Photon class.
Definition: Photon.h:47
dictionary parameters
Definition: Parameters.py:2
float trackMomentumError() const
Definition: GsfElectron.h:773
bool existsAs(std::string const &parameterName, bool trackiness=true) const
checks if a parameter exists as a given type
Definition: ParameterSet.h:186
std::unordered_map< std::string, ValMapIntTagTokenPair > tag_int_token_map
const LorentzVector & p4(P4Kind kind) const
Definition: GsfElectron.cc:223
reco::SuperClusterRef superCluster() const
Ref to SuperCluster.
key_type key() const
Definition: Ptr.h:186
void setCorrectedEnergy(P4type type, float E, float dE, bool toCand=true)
float e5x5() const
Definition: Photon.h:221
bool getByToken(EDGetToken token, Handle< PROD > &result) const
Definition: Event.h:464
std::unordered_map< std::string, ValMapIntTagTokenPair > tag_int_token_map
std::unordered_map< unsigned, edm::Ptr< reco::Photon > > phos_by_oop
void correctMomentum(const LorentzVector &p4, float trackMomentumError, float p4Error)
Definition: GsfElectron.h:795
math::XYZVectorF trackMomentumAtVtx() const
Definition: GsfElectron.h:289
std::unordered_map< std::string, ValMapFloatTagTokenPair > tag_float_token_map
bool exists(std::string const &parameterName) const
checks if a parameter exists
std::vector< const GBRForestD * > ph_forestH_sigma_
std::vector< Vertex > VertexCollection
collection of Vertex objects
Definition: VertexFwd.h:9
double deltaR(const T1 &t1, const T2 &t2)
Definition: deltaR.h:48
std::unordered_map< std::string, ValMapFloatTagTokenPair > tag_float_token_map
std::unordered_map< unsigned, edm::Handle< edm::ValueMap< int > > > pho_int_vmaps
#define constexpr
bool isEB() const
Definition: GsfElectron.h:350
return((rh^lh)&mask)
U second(std::pair< T, U > const &p)
XYZTLorentzVectorD XYZTLorentzVector
Lorentz vector with cylindrical internal representation using pseudorapidity.
Definition: LorentzVector.h:29
std::unordered_map< unsigned, edm::Handle< edm::ValueMap< float > > > pho_vmaps
void setCorrectedEcalEnergyError(float newEnergyError)
Definition: GsfElectron.cc:177
const std::string & name() const
void setConsumes(edm::ConsumesCollector &) overridefinal
std::pair< edm::InputTag, ValMapFloatToken > ValMapFloatTagTokenPair
T sqrt(T t)
Definition: SSEVec.h:48
virtual SuperClusterRef superCluster() const
reference to a SuperCluster
Definition: GsfElectron.h:182
std::unordered_map< unsigned, edm::Ptr< reco::GsfElectron > > eles_by_oop
Abs< T >::type abs(const T &t)
Definition: Abs.h:22
#define private
Definition: FWEveView.cc:22
float hadronicOverEm() const
the total hadronic over electromagnetic fraction
Definition: Photon.h:203
std::vector< std::string > getParameterNames() const
std::unordered_map< unsigned, edm::Handle< edm::ValueMap< float > > > ele_vmaps
edm::EDGetTokenT< edm::ValueMap< int > > ValMapIntToken
std::vector< const GBRForestD * > ph_forestH_mean_
tuple conf
Definition: dbtoconf.py:185
void setEvent(const edm::Event &) overridefinal
double deltaPhi(double phi1, double phi2)
Definition: deltaPhi.h:12
edm::EDGetTokenT< edm::View< pat::Photon > > tok_photon_src
std::pair< edm::InputTag, ValMapIntToken > ValMapIntTagTokenPair
Classification classification() const
Definition: GsfElectron.h:694
const T & get() const
Definition: EventSetup.h:56
T const * product() const
Definition: ESHandle.h:86
edm::EDGetTokenT< unsigned int > bunchSpacingToken_
edm::EDGetTokenT< edm::ValueMap< float > > ValMapFloatToken
Analysis-level electron class.
Definition: Electron.h:52
edm::Handle< reco::VertexCollection > vtxH_
string const
Definition: compareJSON.py:14
std::vector< const GBRForestD * > e_forestH_mean_
void setEventContent(const edm::EventSetup &) overridefinal
void localCoordsEB(const reco::CaloCluster &bclus, const edm::EventSetup &es, float &etacry, float &phicry, int &ieta, int &iphi, float &thetatilt, float &phitilt) const
bool isEB() const
Definition: Photon.h:120
void setCorrectedEcalEnergy(float newEnergy)
Definition: GsfElectron.cc:180
void modifyObject(reco::GsfElectron &) const overridefinal
edm::EDGetTokenT< reco::VertexCollection > vtxToken_
float r9() const
Definition: Photon.h:227
bool trackerDrivenSeed() const
Definition: GsfElectron.h:187
bool isUninitialized() const
Definition: EDGetToken.h:73
std::unordered_map< unsigned, edm::Handle< edm::ValueMap< int > > > ele_int_vmaps
#define DEFINE_EDM_PLUGIN(factory, type, name)
int weight
Definition: histoStyle.py:50
void localCoordsEE(const reco::CaloCluster &bclus, const edm::EventSetup &es, float &xcry, float &ycry, int &ix, int &iy, float &thetatilt, float &phitilt) const
long double T
const ShowerShape & showerShapeVariables() const
Definition: Photon.h:196
bool ecalDriven() const
Definition: GsfElectron.cc:172
std::vector< const GBRForestD * > e_forestH_sigma_
edm::EDGetTokenT< double > rhoToken_
EGExtraInfoModifierFromDB(const edm::ParameterSet &conf)
edm::EDGetTokenT< edm::View< pat::Electron > > tok_electron_src