CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
GsfElectronAlgo.cc
Go to the documentation of this file.
29 
30 #include <Math/Point3D.h>
31 #include <memory>
32 
33 #include <algorithm>
34 #include <sstream>
35 
36 using namespace edm;
37 using namespace reco;
38 
40  // soft electron MVA
42  sconfig.vweightsfiles = conf.getParameter<std::vector<std::string>>("SoftElecMVAFilesString");
43  sElectronMVAEstimator = std::make_unique<SoftElectronMVAEstimator>(sconfig);
44  // isolated electron MVA
46  iconfig.vweightsfiles = conf.getParameter<std::vector<std::string>>("ElecMVAFilesString");
47  iElectronMVAEstimator = std::make_unique<ElectronMVAEstimator>(iconfig);
48 
49  // Here we will have to load the DNN PFID if present in the config
51  const auto& pset_dnn = conf.getParameter<edm::ParameterSet>("EleDNNPFid");
52  const bool dnnEnabled = pset_dnn.getParameter<bool>("enabled");
53  if (dnnEnabled) {
54  dconfig.inputTensorName = pset_dnn.getParameter<std::string>("inputTensorName");
55  dconfig.outputTensorName = pset_dnn.getParameter<std::string>("outputTensorName");
56  dconfig.modelsFiles = pset_dnn.getParameter<std::vector<std::string>>("modelsFiles");
57  dconfig.scalersFiles = pset_dnn.getParameter<std::vector<std::string>>("scalersFiles");
58  dconfig.outputDim = pset_dnn.getParameter<uint>("outputDim");
59  const auto useEBModelInGap = pset_dnn.getParameter<bool>("useEBModelInGap");
60  iElectronDNNEstimator = std::make_unique<ElectronDNNEstimator>(dconfig, useEBModelInGap);
61  }
62 }
63 
64 //===================================================================
65 // GsfElectronAlgo::EventData
66 //===================================================================
67 
69  // utilities
70  void retreiveOriginalTrackCollections(const reco::TrackRef&, const reco::GsfTrackRef&);
71 
72  // general
73  edm::Event const* event;
75 
76  // input collections
84 
85  // isolation helpers
90 
95 
98 
99  bool originalCtfTrackCollectionRetreived = false;
100  bool originalGsfTrackCollectionRetreived = false;
101 
102  //PFCluster Isolation handles
104  std::vector<edm::Handle<reco::PFClusterCollection>> hcalClustersHandle;
105 };
106 
107 //===================================================================
108 // GsfElectronAlgo::ElectronData
109 //===================================================================
110 
112  // Refs to subproducts
119 
120  // constructors
122 
123  // utilities
124  void computeCharge(int& charge, reco::GsfElectron::ChargeInfo& info);
125  reco::CaloClusterPtr getEleBasicCluster(MultiTrajectoryStateTransform const&);
126  bool calculateTSOS(MultiTrajectoryStateTransform const&, GsfConstraintAtVertex const&);
127  void calculateMode();
128  reco::Candidate::LorentzVector calculateMomentum();
129 
130  // TSOS
138 
139  // mode
140  GlobalVector innMom, seedMom, eleMom, sclMom, vtxMom, outMom;
141  GlobalPoint innPos, seedPos, elePos, sclPos, vtxPos, outPos;
143 };
144 
146  const reco::GsfTrackRef& gsfTrack) {
147  if ((!originalCtfTrackCollectionRetreived) && (ctfTrack.isNonnull())) {
148  event->get(ctfTrack.id(), originalCtfTracks);
149  originalCtfTrackCollectionRetreived = true;
150  }
151  if ((!originalGsfTrackCollectionRetreived) && (gsfTrack.isNonnull())) {
152  event->get(gsfTrack.id(), originalGsfTracks);
153  originalGsfTrackCollectionRetreived = true;
154  }
155 }
156 
158  : coreRef(core),
159  gsfTrackRef(coreRef->gsfTrack()),
160  superClusterRef(coreRef->superCluster()),
161  ctfTrackRef(coreRef->ctfTrack()),
162  shFracInnerHits(coreRef->ctfGsfOverlap()),
163  beamSpot(bs) {}
164 
166  // determine charge from SC
167  GlobalPoint orig, scpos;
168  ele_convert(beamSpot.position(), orig);
169  ele_convert(superClusterRef->position(), scpos);
170  GlobalVector scvect(scpos - orig);
171  GlobalPoint inntkpos = innTSOS.globalPosition();
172  GlobalVector inntkvect = GlobalVector(inntkpos - orig);
173  float dPhiInnEle = normalizedPhi(scvect.barePhi() - inntkvect.barePhi());
174  if (dPhiInnEle > 0)
175  info.scPixCharge = -1;
176  else
177  info.scPixCharge = 1;
178 
179  // flags
180  int chargeGsf = gsfTrackRef->charge();
181  info.isGsfScPixConsistent = ((chargeGsf * info.scPixCharge) > 0);
182  info.isGsfCtfConsistent = (ctfTrackRef.isNonnull() && ((chargeGsf * ctfTrackRef->charge()) > 0));
184 
185  // default charge
186  if (info.isGsfScPixConsistent || ctfTrackRef.isNull()) {
187  charge = info.scPixCharge;
188  } else {
189  charge = ctfTrackRef->charge();
190  }
191 }
192 
194  CaloClusterPtr eleRef;
195  TrajectoryStateOnSurface tempTSOS;
196  TrajectoryStateOnSurface outTSOS = mtsTransform.outerStateOnSurface(*gsfTrackRef);
197  float dphimin = 1.e30;
198  for (auto const& bc : superClusterRef->clusters()) {
199  GlobalPoint posclu(bc->position().x(), bc->position().y(), bc->position().z());
200  tempTSOS = mtsTransform.extrapolatedState(outTSOS, posclu);
201  if (!tempTSOS.isValid())
202  tempTSOS = outTSOS;
203  GlobalPoint extrap = tempTSOS.globalPosition();
204  float dphi = EleRelPointPair(posclu, extrap, beamSpot.position()).dPhi();
205  if (std::abs(dphi) < dphimin) {
206  dphimin = std::abs(dphi);
207  eleRef = bc;
208  eleTSOS = tempTSOS;
209  }
210  }
211  return eleRef;
212 }
213 
215  GsfConstraintAtVertex const& constraintAtVtx) {
216  //at innermost point
217  innTSOS = mtsTransform.innerStateOnSurface(*gsfTrackRef);
218  if (!innTSOS.isValid())
219  return false;
220 
221  //at vertex
222  // innermost state propagation to the beam spot position
223  GlobalPoint bsPos;
224  ele_convert(beamSpot.position(), bsPos);
225  vtxTSOS = mtsTransform.extrapolatedState(innTSOS, bsPos);
226  if (!vtxTSOS.isValid())
227  vtxTSOS = innTSOS;
228 
229  //at seed
230  outTSOS = mtsTransform.outerStateOnSurface(*gsfTrackRef);
231  if (!outTSOS.isValid())
232  return false;
233 
234  // TrajectoryStateOnSurface seedTSOS
235  seedTSOS = mtsTransform.extrapolatedState(outTSOS,
236  GlobalPoint(superClusterRef->seed()->position().x(),
237  superClusterRef->seed()->position().y(),
238  superClusterRef->seed()->position().z()));
239  if (!seedTSOS.isValid())
240  seedTSOS = outTSOS;
241 
242  // at scl
243  sclTSOS = mtsTransform.extrapolatedState(
244  innTSOS, GlobalPoint(superClusterRef->x(), superClusterRef->y(), superClusterRef->z()));
245  if (!sclTSOS.isValid())
246  sclTSOS = outTSOS;
247 
248  // constrained momentum
249  constrainedVtxTSOS = constraintAtVtx.constrainAtBeamSpot(*gsfTrackRef, beamSpot);
250 
251  return true;
252 }
253 
267  multiTrajectoryStateMode::momentumFromModeCartesian(constrainedVtxTSOS, vtxMomWithConstraint);
268 }
269 
271  double scale = superClusterRef->energy() / vtxMom.mag();
273  vtxMom.x() * scale, vtxMom.y() * scale, vtxMom.z() * scale, superClusterRef->energy());
274 }
275 
277  EventData const& eventData) const {
279 
280  const reco::CaloCluster& seedCluster = *(theClus->seed());
281  DetId seedXtalId = seedCluster.seed();
282  int detector = seedXtalId.subdetId();
283  const EcalRecHitCollection* ecalRecHits = nullptr;
284  if (detector == EcalBarrel)
285  ecalRecHits = eventData.barrelRecHits.product();
286  else
287  ecalRecHits = eventData.endcapRecHits.product();
288 
289  int nSaturatedXtals = 0;
290  bool isSeedSaturated = false;
291  for (auto&& hitFractionPair : theClus->hitsAndFractions()) {
292  auto&& ecalRecHit = ecalRecHits->find(hitFractionPair.first);
293  if (ecalRecHit == ecalRecHits->end())
294  continue;
295  if (ecalRecHit->checkFlag(EcalRecHit::Flags::kSaturated)) {
296  nSaturatedXtals++;
297  if (seedXtalId == ecalRecHit->detid())
298  isSeedSaturated = true;
299  }
300  }
301  si.nSaturatedXtals = nSaturatedXtals;
302  si.isSeedSaturated = isSeedSaturated;
303 
304  return si;
305 }
306 
307 template <bool full5x5>
309  ElectronHcalHelper const& hcalHelperCone,
310  ElectronHcalHelper const& hcalHelperBc,
311  EventData const& eventData,
312  CaloTopology const& topology,
313  CaloGeometry const& geometry,
314  EcalPFRecHitThresholds const& thresholds) const {
315  using ClusterTools = EcalClusterToolsT<full5x5>;
316  reco::GsfElectron::ShowerShape showerShape;
317 
318  const reco::CaloCluster& seedCluster = *(theClus->seed());
319  // temporary, till CaloCluster->seed() is made available
320  DetId seedXtalId = seedCluster.hitsAndFractions()[0].first;
321  int detector = seedXtalId.subdetId();
322 
323  const EcalRecHitCollection* recHits = nullptr;
324  std::vector<int> recHitFlagsToBeExcluded;
325  std::vector<int> recHitSeverityToBeExcluded;
326  if (detector == EcalBarrel) {
327  recHits = eventData.barrelRecHits.product();
328  recHitFlagsToBeExcluded = cfg_.recHits.recHitFlagsToBeExcludedBarrel;
329  recHitSeverityToBeExcluded = cfg_.recHits.recHitSeverityToBeExcludedBarrel;
330  } else {
331  recHits = eventData.endcapRecHits.product();
332  recHitFlagsToBeExcluded = cfg_.recHits.recHitFlagsToBeExcludedEndcaps;
333  recHitSeverityToBeExcluded = cfg_.recHits.recHitSeverityToBeExcludedEndcaps;
334  }
335 
336  const auto& covariances = ClusterTools::covariances(seedCluster, recHits, &topology, &geometry);
337 
338  // do noise-cleaning for full5x5, by passing per crystal PF recHit thresholds and mult values
339  // mult values for EB and EE were obtained by dedicated studies
340  const auto& localCovariances = full5x5 ? ClusterTools::localCovariances(seedCluster,
341  recHits,
342  &topology,
344  &thresholds,
347  : ClusterTools::localCovariances(seedCluster, recHits, &topology);
348 
349  showerShape.sigmaEtaEta = sqrt(covariances[0]);
350  showerShape.sigmaIetaIeta = sqrt(localCovariances[0]);
351  if (!edm::isNotFinite(localCovariances[2]))
352  showerShape.sigmaIphiIphi = sqrt(localCovariances[2]);
353  showerShape.e1x5 = ClusterTools::e1x5(seedCluster, recHits, &topology);
354  showerShape.e2x5Max = ClusterTools::e2x5Max(seedCluster, recHits, &topology);
355  showerShape.e5x5 = ClusterTools::e5x5(seedCluster, recHits, &topology);
356  showerShape.r9 = ClusterTools::e3x3(seedCluster, recHits, &topology) / theClus->rawEnergy();
357 
358  const float scale = full5x5 ? showerShape.e5x5 : theClus->energy();
359 
360  for (uint id = 0; id < showerShape.hcalOverEcal.size(); ++id) {
361  showerShape.hcalOverEcal[id] = hcalHelperCone.hcalESum(*theClus, id + 1) / scale;
362  showerShape.hcalOverEcalBc[id] = hcalHelperBc.hcalESum(*theClus, id + 1) / scale;
363  }
364  showerShape.invalidHcal = !hcalHelperBc.hasActiveHcal(*theClus);
365  showerShape.hcalTowersBehindClusters = hcalHelperBc.hcalTowersBehindClusters(*theClus);
366  showerShape.pre7DepthHcal = false;
367 
368  // extra shower shapes
369  const float see_by_spp = showerShape.sigmaIetaIeta * showerShape.sigmaIphiIphi;
370  if (see_by_spp > 0) {
371  showerShape.sigmaIetaIphi = localCovariances[1] / see_by_spp;
372  } else if (localCovariances[1] > 0) {
373  showerShape.sigmaIetaIphi = 1.f;
374  } else {
375  showerShape.sigmaIetaIphi = -1.f;
376  }
377  showerShape.eMax = ClusterTools::eMax(seedCluster, recHits);
378  showerShape.e2nd = ClusterTools::e2nd(seedCluster, recHits);
379  showerShape.eTop = ClusterTools::eTop(seedCluster, recHits, &topology);
380  showerShape.eLeft = ClusterTools::eLeft(seedCluster, recHits, &topology);
381  showerShape.eRight = ClusterTools::eRight(seedCluster, recHits, &topology);
382  showerShape.eBottom = ClusterTools::eBottom(seedCluster, recHits, &topology);
383 
384  showerShape.e2x5Left = ClusterTools::e2x5Left(seedCluster, recHits, &topology);
385  showerShape.e2x5Right = ClusterTools::e2x5Right(seedCluster, recHits, &topology);
386  showerShape.e2x5Top = ClusterTools::e2x5Top(seedCluster, recHits, &topology);
387  showerShape.e2x5Bottom = ClusterTools::e2x5Bottom(seedCluster, recHits, &topology);
388 
389  return showerShape;
390 }
391 
392 //===================================================================
393 // GsfElectronAlgo
394 //===================================================================
395 
397  const StrategyConfiguration& strategy,
398  const CutsConfiguration& cuts,
399  const ElectronHcalHelper::Configuration& hcalCone,
400  const ElectronHcalHelper::Configuration& hcalBc,
401  const IsolationConfiguration& iso,
402  const PFClusterIsolationConfiguration& pfiso,
404  std::unique_ptr<EcalClusterFunctionBaseClass>&& crackCorrectionFunction,
406  const edm::ParameterSet& tkIsol03,
407  const edm::ParameterSet& tkIsol04,
408  const edm::ParameterSet& tkIsolHEEP03,
409  const edm::ParameterSet& tkIsolHEEP04,
411  : cfg_{input, strategy, cuts, iso, pfiso, recHits},
412  tkIsol03CalcCfg_(tkIsol03),
413  tkIsol04CalcCfg_(tkIsol04),
414  tkIsolHEEP03CalcCfg_(tkIsolHEEP03),
415  tkIsolHEEP04CalcCfg_(tkIsolHEEP04),
416  magneticFieldToken_{cc.esConsumes()},
417  caloGeometryToken_{cc.esConsumes()},
418  caloTopologyToken_{cc.esConsumes()},
419  trackerGeometryToken_{cc.esConsumes()},
420  ecalSeveretyLevelAlgoToken_{cc.esConsumes()},
421  ecalPFRechitThresholdsToken_{cc.esConsumes()},
422  hcalHelperCone_{hcalCone, std::move(cc)},
423  hcalHelperBc_{hcalBc, std::move(cc)},
424  crackCorrectionFunction_{std::forward<std::unique_ptr<EcalClusterFunctionBaseClass>>(crackCorrectionFunction)},
425  regHelper_{reg, cfg_.strategy.useEcalRegression, cfg_.strategy.useCombinationRegression, cc}
426 
427 {
429  ecalisoAlgo_ = std::make_unique<ElectronEcalPFClusterIsolation>(pfiso.ecaldrMax,
430  pfiso.ecaldrVetoBarrel,
431  pfiso.ecaldrVetoEndcap,
432  pfiso.ecaletaStripBarrel,
433  pfiso.ecaletaStripEndcap,
434  pfiso.ecalenergyBarrel,
435  pfiso.ecalenergyEndcap);
436  hcalisoAlgo_ = std::make_unique<ElectronHcalPFClusterIsolation>(pfiso.hcaldrMax,
437  pfiso.hcaldrVetoBarrel,
438  pfiso.hcaldrVetoEndcap,
439  pfiso.hcaletaStripBarrel,
440  pfiso.hcaletaStripEndcap,
441  pfiso.hcalenergyBarrel,
442  pfiso.hcalenergyEndcap,
443  pfiso.hcaluseEt);
444 }
445 
449 
451  crackCorrectionFunction_->init(es);
452  }
453 }
454 
456  CaloGeometry const& caloGeometry,
457  EcalSeverityLevelAlgo const& ecalSeveretyLevelAlgo) {
458  auto const& hbheRecHits = event.get(cfg_.tokens.hbheRecHitsTag);
459 
460  // Isolation algos
461  float egHcalIsoConeSizeOutSmall = 0.3, egHcalIsoConeSizeOutLarge = 0.4;
462  float egHcalIsoConeSizeIn = cfg_.iso.intRadiusHcal, egHcalIsoPtMin = cfg_.iso.etMinHcal;
463 
464  float egIsoConeSizeOutSmall = 0.3, egIsoConeSizeOutLarge = 0.4, egIsoJurassicWidth = cfg_.iso.jurassicWidth;
465  float egIsoPtMinBarrel = cfg_.iso.etMinBarrel, egIsoEMinBarrel = cfg_.iso.eMinBarrel,
466  egIsoConeSizeInBarrel = cfg_.iso.intRadiusEcalBarrel;
467  float egIsoPtMinEndcap = cfg_.iso.etMinEndcaps, egIsoEMinEndcap = cfg_.iso.eMinEndcaps,
468  egIsoConeSizeInEndcap = cfg_.iso.intRadiusEcalEndcaps;
469 
470  auto barrelRecHits = event.getHandle(cfg_.tokens.barrelRecHitCollection);
471  auto endcapRecHits = event.getHandle(cfg_.tokens.endcapRecHitCollection);
472 
474  std::vector<edm::Handle<reco::PFClusterCollection>> hcalPFClusters;
476  ecalPFClusters = event.getHandle(cfg_.tokens.pfClusterProducer);
477  hcalPFClusters.push_back(event.getHandle(cfg_.tokens.pfClusterProducerHCAL));
478  if (cfg_.pfiso.useHF) {
479  hcalPFClusters.push_back(event.getHandle(cfg_.tokens.pfClusterProducerHFEM));
480  hcalPFClusters.push_back(event.getHandle(cfg_.tokens.pfClusterProducerHFHAD));
481  }
482  }
483 
484  auto ctfTracks = event.getHandle(cfg_.tokens.ctfTracks);
485 
486  EventData eventData{
487  .event = &event,
488  .beamspot = &event.get(cfg_.tokens.beamSpotTag),
489  .coreElectrons = event.getHandle(cfg_.tokens.gsfElectronCores),
490  .barrelRecHits = barrelRecHits,
491  .endcapRecHits = endcapRecHits,
492  .currentCtfTracks = ctfTracks,
493  .seeds = event.getHandle(cfg_.tokens.seedsTag),
494  .vertices = event.getHandle(cfg_.tokens.vtxCollectionTag),
495  .conversions = cfg_.strategy.fillConvVtxFitProb ? event.getHandle(cfg_.tokens.conversions)
497 
498  .hadIsolation03 = EgammaHcalIsolation(
500  egHcalIsoConeSizeOutSmall,
502  egHcalIsoConeSizeIn,
503  EgammaHcalIsolation::arrayHB{{0., 0., 0., 0.}},
504  EgammaHcalIsolation::arrayHB{{egHcalIsoPtMin, egHcalIsoPtMin, egHcalIsoPtMin, egHcalIsoPtMin}},
506  EgammaHcalIsolation::arrayHE{{0., 0., 0., 0., 0., 0., 0.}},
507  EgammaHcalIsolation::arrayHE{{egHcalIsoPtMin,
508  egHcalIsoPtMin,
509  egHcalIsoPtMin,
510  egHcalIsoPtMin,
511  egHcalIsoPtMin,
512  egHcalIsoPtMin,
513  egHcalIsoPtMin}},
515  hbheRecHits,
516  caloGeometry,
521  .hadIsolation04 = EgammaHcalIsolation(
523  egHcalIsoConeSizeOutLarge,
525  egHcalIsoConeSizeIn,
526  EgammaHcalIsolation::arrayHB{{0., 0., 0., 0.}},
527  EgammaHcalIsolation::arrayHB{{egHcalIsoPtMin, egHcalIsoPtMin, egHcalIsoPtMin, egHcalIsoPtMin}},
529  EgammaHcalIsolation::arrayHE{{0., 0., 0., 0., 0., 0., 0.}},
530  EgammaHcalIsolation::arrayHE{{egHcalIsoPtMin,
531  egHcalIsoPtMin,
532  egHcalIsoPtMin,
533  egHcalIsoPtMin,
534  egHcalIsoPtMin,
535  egHcalIsoPtMin,
536  egHcalIsoPtMin}},
538  hbheRecHits,
539  caloGeometry,
544  .hadIsolation03Bc = EgammaHcalIsolation(
546  egHcalIsoConeSizeOutSmall,
548  0.,
549  EgammaHcalIsolation::arrayHB{{0., 0., 0., 0.}},
550  EgammaHcalIsolation::arrayHB{{egHcalIsoPtMin, egHcalIsoPtMin, egHcalIsoPtMin, egHcalIsoPtMin}},
552  EgammaHcalIsolation::arrayHE{{0., 0., 0., 0., 0., 0., 0.}},
553  EgammaHcalIsolation::arrayHE{{egHcalIsoPtMin,
554  egHcalIsoPtMin,
555  egHcalIsoPtMin,
556  egHcalIsoPtMin,
557  egHcalIsoPtMin,
558  egHcalIsoPtMin,
559  egHcalIsoPtMin}},
561  hbheRecHits,
562  caloGeometry,
567  .hadIsolation04Bc = EgammaHcalIsolation(
569  egHcalIsoConeSizeOutLarge,
571  0.,
572  EgammaHcalIsolation::arrayHB{{0., 0., 0., 0.}},
573  EgammaHcalIsolation::arrayHB{{egHcalIsoPtMin, egHcalIsoPtMin, egHcalIsoPtMin, egHcalIsoPtMin}},
575  EgammaHcalIsolation::arrayHE{{0., 0., 0., 0., 0., 0., 0.}},
576  EgammaHcalIsolation::arrayHE{{egHcalIsoPtMin,
577  egHcalIsoPtMin,
578  egHcalIsoPtMin,
579  egHcalIsoPtMin,
580  egHcalIsoPtMin,
581  egHcalIsoPtMin,
582  egHcalIsoPtMin}},
584  hbheRecHits,
585  caloGeometry,
590 
591  .ecalBarrelIsol03 = EgammaRecHitIsolation(egIsoConeSizeOutSmall,
592  egIsoConeSizeInBarrel,
593  egIsoJurassicWidth,
594  egIsoPtMinBarrel,
595  egIsoEMinBarrel,
596  &caloGeometry,
597  *barrelRecHits,
598  &ecalSeveretyLevelAlgo,
599  DetId::Ecal),
600  .ecalBarrelIsol04 = EgammaRecHitIsolation(egIsoConeSizeOutLarge,
601  egIsoConeSizeInBarrel,
602  egIsoJurassicWidth,
603  egIsoPtMinBarrel,
604  egIsoEMinBarrel,
605  &caloGeometry,
606  *barrelRecHits,
607  &ecalSeveretyLevelAlgo,
608  DetId::Ecal),
609  .ecalEndcapIsol03 = EgammaRecHitIsolation(egIsoConeSizeOutSmall,
610  egIsoConeSizeInEndcap,
611  egIsoJurassicWidth,
612  egIsoPtMinEndcap,
613  egIsoEMinEndcap,
614  &caloGeometry,
615  *endcapRecHits,
616  &ecalSeveretyLevelAlgo,
617  DetId::Ecal),
618  .ecalEndcapIsol04 = EgammaRecHitIsolation(egIsoConeSizeOutLarge,
619  egIsoConeSizeInEndcap,
620  egIsoJurassicWidth,
621  egIsoPtMinEndcap,
622  egIsoEMinEndcap,
623  &caloGeometry,
624  *endcapRecHits,
625  &ecalSeveretyLevelAlgo,
626  DetId::Ecal),
627  .tkIsol03Calc = EleTkIsolFromCands(tkIsol03CalcCfg_, *ctfTracks),
628  .tkIsol04Calc = EleTkIsolFromCands(tkIsol04CalcCfg_, *ctfTracks),
629  .tkIsolHEEP03Calc = EleTkIsolFromCands(tkIsolHEEP03CalcCfg_, *ctfTracks),
630  .tkIsolHEEP04Calc = EleTkIsolFromCands(tkIsolHEEP04CalcCfg_, *ctfTracks),
631  .originalCtfTracks = {},
632  .originalGsfTracks = {},
633 
634  .ecalClustersHandle = ecalPFClusters,
635  .hcalClustersHandle = hcalPFClusters
636 
637  };
638 
639  eventData.ecalBarrelIsol03.setUseNumCrystals(cfg_.iso.useNumCrystals);
640  eventData.ecalBarrelIsol03.setVetoClustered(cfg_.iso.vetoClustered);
641  eventData.ecalBarrelIsol03.doSeverityChecks(eventData.barrelRecHits.product(),
643  eventData.ecalBarrelIsol03.doFlagChecks(cfg_.recHits.recHitFlagsToBeExcludedBarrel);
644  eventData.ecalBarrelIsol04.setUseNumCrystals(cfg_.iso.useNumCrystals);
645  eventData.ecalBarrelIsol04.setVetoClustered(cfg_.iso.vetoClustered);
646  eventData.ecalBarrelIsol04.doSeverityChecks(eventData.barrelRecHits.product(),
648  eventData.ecalBarrelIsol04.doFlagChecks(cfg_.recHits.recHitFlagsToBeExcludedBarrel);
649  eventData.ecalEndcapIsol03.setUseNumCrystals(cfg_.iso.useNumCrystals);
650  eventData.ecalEndcapIsol03.setVetoClustered(cfg_.iso.vetoClustered);
651  eventData.ecalEndcapIsol03.doSeverityChecks(eventData.endcapRecHits.product(),
653  eventData.ecalEndcapIsol03.doFlagChecks(cfg_.recHits.recHitFlagsToBeExcludedEndcaps);
654  eventData.ecalEndcapIsol04.setUseNumCrystals(cfg_.iso.useNumCrystals);
655  eventData.ecalEndcapIsol04.setVetoClustered(cfg_.iso.vetoClustered);
656  eventData.ecalEndcapIsol04.doSeverityChecks(eventData.endcapRecHits.product(),
658  eventData.ecalEndcapIsol04.doFlagChecks(cfg_.recHits.recHitFlagsToBeExcludedEndcaps);
659 
660  return eventData;
661 }
662 
664  edm::EventSetup const& eventSetup,
667 
668  auto const& magneticField = eventSetup.getData(magneticFieldToken_);
669  auto const& caloGeometry = eventSetup.getData(caloGeometryToken_);
670  auto const& caloTopology = eventSetup.getData(caloTopologyToken_);
671  auto const& trackerGeometry = eventSetup.getData(trackerGeometryToken_);
672  auto const& ecalSeveretyLevelAlgo = eventSetup.getData(ecalSeveretyLevelAlgoToken_);
673  auto const& thresholds = eventSetup.getData(ecalPFRechitThresholdsToken_);
674 
675  // prepare access to hcal data
676  hcalHelperCone_.beginEvent(event, eventSetup);
677  hcalHelperBc_.beginEvent(event, eventSetup);
678 
679  checkSetup(eventSetup);
680  auto eventData = beginEvent(event, caloGeometry, ecalSeveretyLevelAlgo);
681  double magneticFieldInTesla = magneticField.inTesla(GlobalPoint(0., 0., 0.)).z();
682 
683  MultiTrajectoryStateTransform mtsTransform(&trackerGeometry, &magneticField);
684  GsfConstraintAtVertex constraintAtVtx(&trackerGeometry, &magneticField);
685 
686  std::optional<egamma::conv::TrackTable> ctfTrackTable = std::nullopt;
687  std::optional<egamma::conv::TrackTable> gsfTrackTable = std::nullopt;
688 
689  const GsfElectronCoreCollection* coreCollection = eventData.coreElectrons.product();
690  for (unsigned int i = 0; i < coreCollection->size(); ++i) {
691  // check there is no existing electron with this core
692  const GsfElectronCoreRef coreRef = edm::Ref<GsfElectronCoreCollection>(eventData.coreElectrons, i);
693 
694  // check there is a super-cluster
695  if (coreRef->superCluster().isNull())
696  continue;
697 
698  // prepare internal structure for electron specific data
699  ElectronData electronData(coreRef, *eventData.beamspot);
700 
701  // calculate and check Trajectory StatesOnSurface....
702  if (!electronData.calculateTSOS(mtsTransform, constraintAtVtx))
703  continue;
704 
705  eventData.retreiveOriginalTrackCollections(electronData.ctfTrackRef, electronData.coreRef->gsfTrack());
706 
707  if (!eventData.originalCtfTracks.isValid()) {
708  eventData.originalCtfTracks = eventData.currentCtfTracks;
709  }
710 
711  if (ctfTrackTable == std::nullopt) {
712  ctfTrackTable = egamma::conv::TrackTable(*eventData.originalCtfTracks);
713  }
714  if (gsfTrackTable == std::nullopt) {
715  gsfTrackTable = egamma::conv::TrackTable(*eventData.originalGsfTracks);
716  }
717 
718  createElectron(electrons,
719  electronData,
720  eventData,
721  caloTopology,
722  caloGeometry,
723  mtsTransform,
724  magneticFieldInTesla,
725  hoc,
726  ctfTrackTable.value(),
727  gsfTrackTable.value(),
728  thresholds);
729 
730  } // loop over tracks
731  return electrons;
732 }
733 
735  // default value
736  ele.setPassCutBasedPreselection(false);
737 
738  // kind of seeding
739  bool eg = ele.core()->ecalDrivenSeed();
740  bool pf = ele.core()->trackerDrivenSeed() && !ele.core()->ecalDrivenSeed();
741  if (eg && pf) {
742  throw cms::Exception("GsfElectronAlgo|BothEcalAndPureTrackerDriven")
743  << "An electron cannot be both egamma and purely pflow";
744  }
745  if ((!eg) && (!pf)) {
746  throw cms::Exception("GsfElectronAlgo|NeitherEcalNorPureTrackerDriven")
747  << "An electron cannot be neither egamma nor purely pflow";
748  }
749 
750  CutsConfiguration const& cfg = cfg_.cuts;
751 
752  // Et cut
753  double etaValue = EleRelPoint(ele.superCluster()->position(), bs.position()).eta();
754  double etValue = ele.superCluster()->energy() / cosh(etaValue);
755  LogTrace("GsfElectronAlgo") << "Et : " << etValue;
756  if (ele.isEB() && (etValue < cfg.minSCEtBarrel))
757  return;
758  if (ele.isEE() && (etValue < cfg.minSCEtEndcaps))
759  return;
760  LogTrace("GsfElectronAlgo") << "Et criteria are satisfied";
761 
762  // E/p cut
763  double eopValue = ele.eSuperClusterOverP();
764  LogTrace("GsfElectronAlgo") << "E/p : " << eopValue;
765  if (ele.isEB() && (eopValue > cfg.maxEOverPBarrel))
766  return;
767  if (ele.isEE() && (eopValue > cfg.maxEOverPEndcaps))
768  return;
769  if (ele.isEB() && (eopValue < cfg.minEOverPBarrel))
770  return;
771  if (ele.isEE() && (eopValue < cfg.minEOverPEndcaps))
772  return;
773  LogTrace("GsfElectronAlgo") << "E/p criteria are satisfied";
774 
775  // HoE cuts
776  LogTrace("GsfElectronAlgo") << "HoE : " << ele.hcalOverEcal();
777  double hoeCone = ele.hcalOverEcal();
778  double hoeBc = ele.hcalOverEcalBc();
779  const reco::CaloCluster& seedCluster = *(ele.superCluster()->seed());
780  int detector = seedCluster.hitsAndFractions()[0].first.subdetId();
781  bool HoEveto = false;
782  double scle = ele.superCluster()->energy();
783 
784  if (detector == EcalBarrel)
785  HoEveto = hoeCone * scle < cfg.maxHBarrelCone || hoeBc * scle < cfg.maxHBarrelBc ||
786  hoeCone < cfg.maxHOverEBarrelCone || hoeBc < cfg.maxHOverEBarrelBc;
787  else if (detector == EcalEndcap)
788  HoEveto = hoeCone * scle < cfg.maxHEndcapsCone || hoeBc * scle < cfg.maxHEndcapsBc ||
789  hoeCone < cfg.maxHOverEEndcapsCone || hoeBc < cfg.maxHOverEEndcapsBc;
790 
791  if (!HoEveto)
792  return;
793  LogTrace("GsfElectronAlgo") << "H/E criteria are satisfied";
794 
795  // delta eta criteria
796  double deta = ele.deltaEtaSuperClusterTrackAtVtx();
797  LogTrace("GsfElectronAlgo") << "delta eta : " << deta;
798  if (ele.isEB() && (std::abs(deta) > cfg.maxDeltaEtaBarrel))
799  return;
800  if (ele.isEE() && (std::abs(deta) > cfg.maxDeltaEtaEndcaps))
801  return;
802  LogTrace("GsfElectronAlgo") << "Delta eta criteria are satisfied";
803 
804  // delta phi criteria
805  double dphi = ele.deltaPhiSuperClusterTrackAtVtx();
806  LogTrace("GsfElectronAlgo") << "delta phi : " << dphi;
807  if (ele.isEB() && (std::abs(dphi) > cfg.maxDeltaPhiBarrel))
808  return;
809  if (ele.isEE() && (std::abs(dphi) > cfg.maxDeltaPhiEndcaps))
810  return;
811  LogTrace("GsfElectronAlgo") << "Delta phi criteria are satisfied";
812 
813  // sigma ieta ieta
814  LogTrace("GsfElectronAlgo") << "sigma ieta ieta : " << ele.sigmaIetaIeta();
815  if (ele.isEB() && (ele.sigmaIetaIeta() > cfg.maxSigmaIetaIetaBarrel))
816  return;
817  if (ele.isEE() && (ele.sigmaIetaIeta() > cfg.maxSigmaIetaIetaEndcaps))
818  return;
819  LogTrace("GsfElectronAlgo") << "Sigma ieta ieta criteria are satisfied";
820 
821  // fiducial
822  if (!ele.isEB() && cfg.isBarrel)
823  return;
824  if (!ele.isEE() && cfg.isEndcaps)
825  return;
826  if (cfg.isFiducial &&
827  (ele.isEBEEGap() || ele.isEBEtaGap() || ele.isEBPhiGap() || ele.isEERingGap() || ele.isEEDeeGap()))
828  return;
829  LogTrace("GsfElectronAlgo") << "Fiducial flags criteria are satisfied";
830 
831  // seed in TEC
832  edm::RefToBase<TrajectorySeed> seed = ele.gsfTrack()->extra()->seedRef();
833  ElectronSeedRef elseed = seed.castTo<ElectronSeedRef>();
834  if (eg && !cfg_.cuts.seedFromTEC) {
835  if (elseed.isNull()) {
836  throw cms::Exception("GsfElectronAlgo|NotElectronSeed") << "The GsfTrack seed is not an ElectronSeed ?!";
837  } else {
838  if (elseed->subDet(1) == 6)
839  return;
840  }
841  }
842 
843  // transverse impact parameter
844  if (std::abs(ele.gsfTrack()->dxy(bs.position())) > cfg.maxTIP)
845  return;
846  LogTrace("GsfElectronAlgo") << "TIP criterion is satisfied";
847 
848  LogTrace("GsfElectronAlgo") << "All cut based criteria are satisfied";
849  ele.setPassCutBasedPreselection(true);
850 }
851 
853  ElectronData& electronData,
854  EventData& eventData,
855  CaloTopology const& topology,
856  CaloGeometry const& geometry,
857  MultiTrajectoryStateTransform const& mtsTransform,
858  double magneticFieldInTesla,
863  // charge ID
864  int eleCharge;
865  GsfElectron::ChargeInfo eleChargeInfo;
866  electronData.computeCharge(eleCharge, eleChargeInfo);
867 
868  // electron basic cluster
869  CaloClusterPtr elbcRef = electronData.getEleBasicCluster(mtsTransform);
870 
871  // Seed cluster
872  const reco::CaloCluster& seedCluster = *(electronData.superClusterRef->seed());
873 
874  // seed Xtal
875  // temporary, till CaloCluster->seed() is made available
876  DetId seedXtalId = seedCluster.hitsAndFractions()[0].first;
877 
878  electronData.calculateMode();
879 
880  //====================================================
881  // Candidate attributes
882  //====================================================
883 
884  Candidate::LorentzVector momentum = electronData.calculateMomentum();
885 
886  //====================================================
887  // Track-Cluster Matching
888  //====================================================
889 
891  tcMatching.electronCluster = elbcRef;
892  tcMatching.eSuperClusterOverP =
893  (electronData.vtxMom.mag() > 0) ? (electronData.superClusterRef->energy() / electronData.vtxMom.mag()) : (-1.);
894  tcMatching.eSeedClusterOverP =
895  (electronData.vtxMom.mag() > 0.) ? (seedCluster.energy() / electronData.vtxMom.mag()) : (-1);
896  tcMatching.eSeedClusterOverPout =
897  (electronData.seedMom.mag() > 0.) ? (seedCluster.energy() / electronData.seedMom.mag()) : (-1.);
898  tcMatching.eEleClusterOverPout =
899  (electronData.eleMom.mag() > 0.) ? (elbcRef->energy() / electronData.eleMom.mag()) : (-1.);
900 
901  EleRelPointPair scAtVtx(
902  electronData.superClusterRef->position(), electronData.sclPos, eventData.beamspot->position());
903  tcMatching.deltaEtaSuperClusterAtVtx = scAtVtx.dEta();
904  tcMatching.deltaPhiSuperClusterAtVtx = scAtVtx.dPhi();
905 
906  EleRelPointPair seedAtCalo(seedCluster.position(), electronData.seedPos, eventData.beamspot->position());
907  tcMatching.deltaEtaSeedClusterAtCalo = seedAtCalo.dEta();
908  tcMatching.deltaPhiSeedClusterAtCalo = seedAtCalo.dPhi();
909 
910  EleRelPointPair ecAtCalo(elbcRef->position(), electronData.elePos, eventData.beamspot->position());
911  tcMatching.deltaEtaEleClusterAtCalo = ecAtCalo.dEta();
912  tcMatching.deltaPhiEleClusterAtCalo = ecAtCalo.dPhi();
913 
914  //=======================================================
915  // Track extrapolations
916  //=======================================================
917 
919  ele_convert(electronData.vtxPos, tkExtra.positionAtVtx);
920  ele_convert(electronData.sclPos, tkExtra.positionAtCalo);
921  ele_convert(electronData.vtxMom, tkExtra.momentumAtVtx);
922  ele_convert(electronData.sclMom, tkExtra.momentumAtCalo);
923  ele_convert(electronData.seedMom, tkExtra.momentumOut);
924  ele_convert(electronData.eleMom, tkExtra.momentumAtEleClus);
926 
927  //=======================================================
928  // Closest Ctf Track
929  //=======================================================
930 
932  ctfInfo.ctfTrack = electronData.ctfTrackRef;
933  ctfInfo.shFracInnerHits = electronData.shFracInnerHits;
934 
935  //====================================================
936  // FiducialFlags, using nextToBoundary definition of gaps
937  //====================================================
938 
939  reco::GsfElectron::FiducialFlags fiducialFlags;
940  int region = seedXtalId.det();
941  int detector = seedXtalId.subdetId();
942  double feta = std::abs(electronData.superClusterRef->position().eta());
943  if (detector == EcalBarrel) {
944  fiducialFlags.isEB = true;
945  EBDetId ebdetid(seedXtalId);
946  if (EBDetId::isNextToEtaBoundary(ebdetid)) {
947  if (ebdetid.ietaAbs() == 85) {
948  fiducialFlags.isEBEEGap = true;
949  } else {
950  fiducialFlags.isEBEtaGap = true;
951  }
952  }
953  if (EBDetId::isNextToPhiBoundary(ebdetid)) {
954  fiducialFlags.isEBPhiGap = true;
955  }
956  } else if (detector == EcalEndcap) {
957  fiducialFlags.isEE = true;
958  EEDetId eedetid(seedXtalId);
959  if (EEDetId::isNextToRingBoundary(eedetid)) {
960  if (std::abs(feta) < 2.) {
961  fiducialFlags.isEBEEGap = true;
962  } else {
963  fiducialFlags.isEERingGap = true;
964  }
965  }
966  if (EEDetId::isNextToDBoundary(eedetid)) {
967  fiducialFlags.isEEDeeGap = true;
968  }
969  } else if (EcalTools::isHGCalDet((DetId::Detector)region)) {
970  fiducialFlags.isEE = true;
971  //HGCalDetId eeDetid(seedXtalId);
972  // fill in fiducial information when we know how to use it...
973  } else {
974  throw cms::Exception("GsfElectronAlgo|UnknownXtalRegion")
975  << "createElectron(): do not know if it is a barrel or endcap seed cluster !!!!";
976  }
977 
978  //====================================================
979  // SaturationInfo
980  //====================================================
981 
982  auto saturationInfo = calculateSaturationInfo(electronData.superClusterRef, eventData);
983 
984  //====================================================
985  // ShowerShape
986  //====================================================
987 
988  reco::GsfElectron::ShowerShape showerShape;
989  reco::GsfElectron::ShowerShape full5x5_showerShape;
990  if (!EcalTools::isHGCalDet((DetId::Detector)region)) {
991  showerShape = calculateShowerShape<false>(
992  electronData.superClusterRef, hcalHelperCone_, hcalHelperBc_, eventData, topology, geometry, thresholds);
993  full5x5_showerShape = calculateShowerShape<true>(
994  electronData.superClusterRef, hcalHelperCone_, hcalHelperBc_, eventData, topology, geometry, thresholds);
995  }
996 
997  //====================================================
998  // ConversionRejection
999  //====================================================
1000 
1002  if (!ctfTracks.isValid()) {
1003  ctfTracks = eventData.currentCtfTracks;
1004  }
1005 
1006  {
1007  //get the references to the gsf and ctf tracks that are made
1008  //by the electron
1009  const reco::TrackRef el_ctftrack = electronData.coreRef->ctfTrack();
1010  const reco::GsfTrackRef& el_gsftrack = electronData.coreRef->gsfTrack();
1011 
1012  //protect against the wrong collection being passed to the function
1013  if (el_ctftrack.isNonnull() && el_ctftrack.id() != ctfTracks.id())
1014  throw cms::Exception("ConversionFinderError")
1015  << "ProductID of ctf track collection does not match ProductID of electron's CTF track! \n";
1016  if (el_gsftrack.isNonnull() && el_gsftrack.id() != eventData.originalGsfTracks.id())
1017  throw cms::Exception("ConversionFinderError")
1018  << "ProductID of gsf track collection does not match ProductID of electron's GSF track! \n";
1019  }
1020 
1021  // values of conversionInfo.flag
1022  // -9999 : Partner track was not found
1023  // 0 : Partner track found in the CTF collection using
1024  // 1 : Partner track found in the CTF collection using
1025  // 2 : Partner track found in the GSF collection using
1026  // 3 : Partner track found in the GSF collection using the electron's GSF track
1027  auto conversionInfo = egamma::conv::findConversion(*electronData.coreRef, ctfTable, gsfTable, magneticFieldInTesla);
1028 
1030  conversionVars.flags = conversionInfo.flag;
1031  conversionVars.dist = conversionInfo.dist;
1032  conversionVars.dcot = conversionInfo.dcot;
1033  conversionVars.radius = conversionInfo.radiusOfConversion;
1035  //this is an intentionally bugged version which ignores the GsfTrack
1036  //this is a bug which was introduced in reduced e/gamma where the GsfTrack gets
1037  //relinked to a new collection which means it can no longer match the conversion
1038  //as it matches based on product/id
1039  //we keep this defination for the MVAs
1040  const auto matchedConv = ConversionTools::matchedConversion(
1041  electronData.coreRef->ctfTrack(), *eventData.conversions, eventData.beamspot->position(), 2.0, 1e-6, 0);
1042  conversionVars.vtxFitProb = ConversionTools::getVtxFitProb(matchedConv);
1043  }
1044  if (conversionInfo.conversionPartnerCtfTkIdx) {
1045  conversionVars.partner = TrackBaseRef(reco::TrackRef(ctfTracks, conversionInfo.conversionPartnerCtfTkIdx.value()));
1046  } else if (conversionInfo.conversionPartnerGsfTkIdx) {
1047  conversionVars.partner =
1048  TrackBaseRef(reco::GsfTrackRef(eventData.originalGsfTracks, conversionInfo.conversionPartnerGsfTkIdx.value()));
1049  }
1050 
1051  //====================================================
1052  // Go !
1053  //====================================================
1054 
1055  electrons.emplace_back(eleCharge,
1056  eleChargeInfo,
1057  electronData.coreRef,
1058  tcMatching,
1059  tkExtra,
1060  ctfInfo,
1061  fiducialFlags,
1062  showerShape,
1063  full5x5_showerShape,
1064  conversionVars,
1065  saturationInfo);
1066  auto& ele = electrons.back();
1067  // Will be overwritten later in the case of the regression
1068  ele.setCorrectedEcalEnergyError(egamma::ecalClusterEnergyUncertaintyElectronSpecific(*(ele.superCluster())));
1069  ele.setP4(GsfElectron::P4_FROM_SUPER_CLUSTER, momentum, 0, true);
1070  ele.setMass(0.0);
1071 
1072  //====================================================
1073  // brems fractions
1074  //====================================================
1075 
1076  if (electronData.innMom.mag() > 0.) {
1077  ele.setTrackFbrem((electronData.innMom.mag() - electronData.outMom.mag()) / electronData.innMom.mag());
1078  }
1079 
1080  // the supercluster is the refined one The seed is not necessarily the first cluster
1081  // hence the use of the electronCluster
1082  SuperClusterRef sc = ele.superCluster();
1083  if (!(sc.isNull())) {
1084  CaloClusterPtr cl = ele.electronCluster();
1085  if (sc->clustersSize() > 1) {
1086  float pf_fbrem = (sc->energy() - cl->energy()) / sc->energy();
1087  ele.setSuperClusterFbrem(pf_fbrem);
1088  } else {
1089  ele.setSuperClusterFbrem(0);
1090  }
1091  }
1092 
1093  //====================================================
1094  // classification and corrections
1095  //====================================================
1096  // classification
1097  const auto elClass = egamma::classifyElectron(ele);
1098  ele.setClassification(elClass);
1099 
1100  bool unexpectedClassification = elClass == GsfElectron::UNKNOWN || elClass > GsfElectron::GAP;
1101  if (unexpectedClassification) {
1102  edm::LogWarning("GsfElectronAlgo") << "unexpected classification";
1103  }
1104 
1105  // ecal energy
1106  if (cfg_.strategy.useEcalRegression) // new
1107  {
1108  regHelper_.applyEcalRegression(ele, *eventData.vertices, *eventData.barrelRecHits, *eventData.endcapRecHits);
1109  } else // original implementation
1110  {
1111  if (!EcalTools::isHGCalDet((DetId::Detector)region)) {
1112  if (ele.core()->ecalDrivenSeed()) {
1113  if (cfg_.strategy.ecalDrivenEcalEnergyFromClassBasedParameterization && !unexpectedClassification) {
1114  if (ele.isEcalEnergyCorrected()) {
1115  edm::LogWarning("ElectronEnergyCorrector::classBasedElectronEnergy") << "already done";
1116  } else {
1117  ele.setCorrectedEcalEnergy(
1119  }
1120  }
1122  ele.setCorrectedEcalEnergyError(egamma::classBasedElectronEnergyUncertainty(ele));
1123  }
1124  } else {
1126  ele.setCorrectedEcalEnergyError(egamma::simpleElectronEnergyUncertainty(ele));
1127  }
1128  }
1129  }
1130  }
1131 
1132  // momentum
1133  // Keep the default correction running first. The track momentum error is computed in there
1134  if (cfg_.strategy.useDefaultEnergyCorrection && ele.core()->ecalDrivenSeed() && !unexpectedClassification) {
1135  if (ele.p4Error(reco::GsfElectron::P4_COMBINATION) != 999.) {
1136  edm::LogWarning("ElectronMomentumCorrector::correct") << "already done";
1137  } else {
1138  auto p = egamma::correctElectronMomentum(ele, electronData.vtxTSOS);
1139  ele.correctMomentum(p.momentum, p.trackError, p.finalError);
1140  }
1141  }
1143  {
1145  }
1146 
1147  //====================================================
1148  // now isolation variables
1149  //====================================================
1151  dr03.tkSumPt = eventData.tkIsol03Calc(*ele.gsfTrack()).ptSum;
1152  dr04.tkSumPt = eventData.tkIsol04Calc(*ele.gsfTrack()).ptSum;
1153  dr03.tkSumPtHEEP = eventData.tkIsolHEEP03Calc(*ele.gsfTrack()).ptSum;
1154  dr04.tkSumPtHEEP = eventData.tkIsolHEEP04Calc(*ele.gsfTrack()).ptSum;
1155 
1156  if (!EcalTools::isHGCalDet((DetId::Detector)region)) {
1157  for (uint id = 0; id < dr03.hcalRecHitSumEt.size(); ++id) {
1158  dr03.hcalRecHitSumEt[id] = eventData.hadIsolation03.getHcalEtSum(&ele, id + 1);
1159  dr03.hcalRecHitSumEtBc[id] = eventData.hadIsolation03Bc.getHcalEtSumBc(&ele, id + 1);
1160 
1161  dr04.hcalRecHitSumEt[id] = eventData.hadIsolation04.getHcalEtSum(&ele, id + 1);
1162  dr04.hcalRecHitSumEtBc[id] = eventData.hadIsolation04Bc.getHcalEtSumBc(&ele, id + 1);
1163  }
1164 
1165  dr03.ecalRecHitSumEt = eventData.ecalBarrelIsol03.getEtSum(&ele);
1166  dr03.ecalRecHitSumEt += eventData.ecalEndcapIsol03.getEtSum(&ele);
1167 
1168  dr04.ecalRecHitSumEt = eventData.ecalBarrelIsol04.getEtSum(&ele);
1169  dr04.ecalRecHitSumEt += eventData.ecalEndcapIsol04.getEtSum(&ele);
1170  }
1171 
1172  dr03.pre7DepthHcal = false;
1173  dr04.pre7DepthHcal = false;
1174 
1175  ele.setIsolation03(dr03);
1176  ele.setIsolation04(dr04);
1177 
1178  //====================================================
1179  // PFclusters based ISO !
1180  // Added in CMSSW_12_0_1 at this stage to be able to use them in PF ID DNN
1181  //====================================================
1184  isoVariables.sumEcalClusterEt = ecalisoAlgo_->getSum(ele, eventData.ecalClustersHandle);
1185  isoVariables.sumHcalClusterEt = hcalisoAlgo_->getSum(ele, eventData.hcalClustersHandle);
1186  // Other Pfiso variables are initialized at 0 and not used
1187  ele.setPfIsolationVariables(isoVariables);
1188  }
1189 
1190  //====================================================
1191  // preselection flag
1192  //====================================================
1193 
1194  setCutBasedPreselectionFlag(ele, *eventData.beamspot);
1195  //setting mva flag, currently GedGsfElectron and GsfElectron pre-selection flags have desynced
1196  //this is for GedGsfElectrons, GsfElectrons (ie old pre 7X std reco) resets this later on
1197  //in the function "addPfInfo"
1198  //yes this is awful, we'll fix it once we work out how to...
1199  float mvaValue = hoc->sElectronMVAEstimator->mva(ele, *(eventData.vertices));
1200  ele.setPassMvaPreselection(mvaValue > cfg_.strategy.PreSelectMVA);
1201 
1202  //====================================================
1203  // Pixel match variables
1204  //====================================================
1206 
1207  LogTrace("GsfElectronAlgo") << "Constructed new electron with energy " << ele.p4().e();
1208 }
1209 
1210 // Pixel match variables
1212  int sd1 = 0;
1213  int sd2 = 0;
1214  float dPhi1 = 0;
1215  float dPhi2 = 0;
1216  float dRz1 = 0;
1217  float dRz2 = 0;
1218  edm::RefToBase<TrajectorySeed> seed = ele.gsfTrack()->extra()->seedRef();
1219  ElectronSeedRef elseed = seed.castTo<ElectronSeedRef>();
1220  if (seed.isNull()) {
1221  } else {
1222  if (elseed.isNull()) {
1223  } else {
1224  sd1 = elseed->subDet(0);
1225  sd2 = elseed->subDet(1);
1226  dPhi1 = (ele.charge() > 0) ? elseed->dPhiPos(0) : elseed->dPhiNeg(0);
1227  dPhi2 = (ele.charge() > 0) ? elseed->dPhiPos(1) : elseed->dPhiNeg(1);
1228  dRz1 = (ele.charge() > 0) ? elseed->dRZPos(0) : elseed->dRZNeg(0);
1229  dRz2 = (ele.charge() > 0) ? elseed->dRZPos(1) : elseed->dRZNeg(1);
1230  }
1231  }
1232  ele.setPixelMatchSubdetectors(sd1, sd2);
1233  ele.setPixelMatchDPhi1(dPhi1);
1234  ele.setPixelMatchDPhi2(dPhi2);
1235  ele.setPixelMatchDRz1(dRz1);
1236  ele.setPixelMatchDRz2(dRz2);
1237 }
TrajectoryStateOnSurface constrainAtBeamSpot(const reco::GsfTrack &, const reco::BeamSpot &) const
(multi)TSOS after including the beamspot
reco::GsfElectronCollection completeElectrons(edm::Event const &event, edm::EventSetup const &eventSetup, const HeavyObjectCache *hoc)
edm::EDGetTokenT< HBHERecHitCollection > hbheRecHitsTag
EleTkIsolFromCands tkIsol03Calc
EleTkIsolFromCands tkIsol04Calc
edm::Handle< reco::TrackCollection > originalCtfTracks
EgammaRecHitIsolation ecalEndcapIsol04
EgammaRecHitIsolation ecalBarrelIsol03
const edm::ESGetToken< TrackerGeometry, TrackerDigiGeometryRecord > trackerGeometryToken_
edm::Handle< reco::ElectronSeedCollection > seeds
EgammaHcalIsolation hadIsolation04Bc
const math::XYZPoint & position() const
cluster centroid position
Definition: CaloCluster.h:154
void applyCombinationRegression(reco::GsfElectron &ele) const
static bool isHGCalDet(DetId::Detector thedet)
identify HGCal cells
Definition: EcalTools.h:49
std::array< float, 7 > hcalRecHitSumEt
Definition: GsfElectron.h:540
void setCutBasedPreselectionFlag(reco::GsfElectron &ele, const reco::BeamSpot &) const
static bool isNextToEtaBoundary(EBDetId id)
Definition: EBDetId.cc:108
EgammaRecHitIsolation ecalEndcapIsol03
static reco::Conversion const * matchedConversion(const reco::GsfElectron &ele, const reco::ConversionCollection &convCol, const math::XYZPoint &beamspot, bool allowCkfMatch=true, float lxyMin=2.0, float probMin=1e-6, unsigned int nHitsBeforeVtxMax=0)
static const TGPicture * info(bool iBackgroundIsBlack)
void setPassCutBasedPreselection(bool flag)
Definition: GsfElectron.h:770
double classBasedElectronEnergyUncertainty(reco::GsfElectron const &)
bool isNonnull() const
Checks for non-null.
Definition: Ref.h:238
tuple cfg
Definition: looper.py:296
void setPixelMatchDRz2(float dRz2)
Definition: GsfElectron.h:933
double hcalESum(const reco::SuperCluster &, int depth) const
bool isEBEtaGap() const
Definition: GsfElectron.h:333
edm::EDGetTokenT< reco::ConversionCollection > conversions
uint16_t *__restrict__ id
float eSuperClusterOverP() const
Definition: GsfElectron.h:221
ProductID id() const
Definition: HandleBase.cc:29
void retreiveOriginalTrackCollections(const reco::TrackRef &, const reco::GsfTrackRef &)
void setPixelMatchDPhi1(float dPhi1)
Definition: GsfElectron.h:930
bool isEBEEGap() const
Definition: GsfElectron.h:331
int maxSeverityHB() const
constexpr bool isNotFinite(T x)
Definition: isFinite.h:9
double getEtSum(const reco::Candidate *emObject) const
edm::EDGetTokenT< reco::PFClusterCollection > pfClusterProducerHFEM
constexpr T normalizedPhi(T phi)
Definition: normalizedPhi.h:8
std::array< float, 7 > hcalRecHitSumEtBc
Definition: GsfElectron.h:541
edm::EDGetTokenT< reco::PFClusterCollection > pfClusterProducerHCAL
TrajectoryStateOnSurface sclTSOS
Global3DPoint GlobalPoint
Definition: GlobalPoint.h:10
edm::Handle< EcalRecHitCollection > endcapRecHits
void setPixelMatchInfomation(reco::GsfElectron &) const
EgammaHcalIsolation hadIsolation03
ConversionInfo findConversion(const reco::GsfElectronCore &gsfElectron, TrackTableView ctfTable, TrackTableView gsfTable, float bFieldAtOrigin, float minFracSharedHits=0.45f)
tuple magneticField
GsfElectronAlgo(const Tokens &, const StrategyConfiguration &, const CutsConfiguration &cutsCfg, const ElectronHcalHelper::Configuration &hcalCone, const ElectronHcalHelper::Configuration &hcalBc, const IsolationConfiguration &, const PFClusterIsolationConfiguration &, const EcalRecHitsConfiguration &, std::unique_ptr< EcalClusterFunctionBaseClass > &&crackCorrectionFunction, const RegressionHelper::Configuration &regCfg, const edm::ParameterSet &tkIsol03Cfg, const edm::ParameterSet &tkIsol04Cfg, const edm::ParameterSet &tkIsolHEEP03Cfg, const edm::ParameterSet &tkIsolHEEP04Cfg, edm::ConsumesCollector &&cc)
edm::Event const * event
bool isEERingGap() const
Definition: GsfElectron.h:337
edm::EDGetTokenT< reco::VertexCollection > vtxCollectionTag
void computeCharge(int &charge, reco::GsfElectron::ChargeInfo &info)
edm::EDGetTokenT< EcalRecHitCollection > endcapRecHitCollection
TrajectoryStateOnSurface innTSOS
bool isEEDeeGap() const
Definition: GsfElectron.h:336
std::vector< GsfElectron > GsfElectronCollection
collection of GsfElectron objects
edm::EDGetTokenT< reco::PFClusterCollection > pfClusterProducerHFHAD
bool isEE() const
Definition: GsfElectron.h:329
ProductID id() const
Accessor for product ID.
Definition: Ref.h:244
bool isEB() const
Definition: GsfElectron.h:328
tuple cl
Definition: haddnano.py:49
reco::GsfElectron::ShowerShape calculateShowerShape(const reco::SuperClusterRef &, ElectronHcalHelper const &hcalHelperCone, ElectronHcalHelper const &hcalHelperBc, EventData const &eventData, CaloTopology const &topology, CaloGeometry const &geometry, EcalPFRecHitThresholds const &thresholds) const
TrajectoryStateOnSurface outerStateOnSurface(const reco::GsfTrack &tk) const
void setPixelMatchSubdetectors(int sd1, int sd2)
Definition: GsfElectron.h:929
#define LogTrace(id)
static std::string const input
Definition: EdmProvDump.cc:47
edm::EDGetTokenT< reco::GsfElectronCoreCollection > gsfElectronCores
EgammaHcalIsolation hadIsolation03Bc
RegressionHelper regHelper_
const Configuration cfg_
TrajectoryStateOnSurface constrainedVtxTSOS
bool getData(T &iHolder) const
Definition: EventSetup.h:122
T barePhi() const
Definition: PV3DBase.h:65
void createElectron(reco::GsfElectronCollection &electrons, ElectronData &electronData, EventData &eventData, CaloTopology const &topology, CaloGeometry const &geometry, MultiTrajectoryStateTransform const &mtsTransform, double magneticFieldInTesla, const HeavyObjectCache *, egamma::conv::TrackTableView ctfTable, egamma::conv::TrackTableView gsfTable, EcalPFRecHitThresholds const &thresholds)
float hcalOverEcalBc(const ShowerShape &ss, int depth) const
Definition: GsfElectron.h:442
double simpleElectronEnergyUncertainty(reco::GsfElectron const &)
GsfTrackRef gsfTrack() const override
reference to a GsfTrack
Definition: GsfElectron.h:156
Handle< PROD > getHandle(EDGetTokenT< PROD > token) const
Definition: Event.h:563
std::array< float, 7 > hcalOverEcal
Definition: GsfElectron.h:371
const edm::ESGetToken< EcalPFRecHitThresholds, EcalPFRecHitThresholdsRcd > ecalPFRechitThresholdsToken_
float deltaEtaSuperClusterTrackAtVtx() const
Definition: GsfElectron.h:225
const std::vector< std::pair< DetId, float > > & hitsAndFractions() const
Definition: CaloCluster.h:210
static float getVtxFitProb(const reco::Conversion *conv)
TkSoA const *__restrict__ CAHitNtupletGeneratorKernelsGPU::QualityCuts cuts
T mag() const
Definition: PV3DBase.h:64
float sigmaIetaIeta() const
Definition: GsfElectron.h:419
TrajectoryStateOnSurface extrapolatedState(const TrajectoryStateOnSurface tsos, const GlobalPoint &point) const
edm::RefToBase< reco::Track > TrackBaseRef
persistent reference to a Track, using views
Definition: TrackFwd.h:35
const edm::ESGetToken< EcalSeverityLevelAlgo, EcalSeverityLevelAlgoRcd > ecalSeveretyLevelAlgoToken_
edm::soa::ViewFromTable_t< TrackTable > TrackTableView
void checkSetup(edm::EventSetup const &eventSetup)
bool positionFromModeCartesian(TrajectoryStateOnSurface const &tsos, GlobalPoint &position)
void beginEvent(const edm::Event &evt, const edm::EventSetup &eventSetup)
T sqrt(T t)
Definition: SSEVec.h:19
edm::Handle< reco::PFClusterCollection > ecalClustersHandle
static bool isNextToPhiBoundary(EBDetId id)
Definition: EBDetId.cc:113
edm::Handle< EcalRecHitCollection > barrelRecHits
float deltaPhiSuperClusterTrackAtVtx() const
Definition: GsfElectron.h:228
std::vector< GsfElectronCore > GsfElectronCoreCollection
edm::EDGetTokenT< reco::BeamSpot > beamSpotTag
def move
Definition: eostools.py:511
constexpr int subdetId() const
get the contents of the subdetector field (not cast into any detector&#39;s numbering enum) ...
Definition: DetId.h:48
const EleTkIsolFromCands::Configuration tkIsol03CalcCfg_
Abs< T >::type abs(const T &t)
Definition: Abs.h:22
HeavyObjectCache(const edm::ParameterSet &)
const edm::ESGetToken< CaloGeometry, CaloGeometryRecord > caloGeometryToken_
std::vector< CaloTowerDetId > hcalTowersBehindClusters
Definition: GsfElectron.h:374
std::unique_ptr< EcalClusterFunctionBaseClass > crackCorrectionFunction_
const IsolationConfiguration iso
static bool isNextToRingBoundary(EEDetId id)
Definition: EEDetId.cc:284
auto hcalTowersBehindClusters(const reco::SuperCluster &sc) const
edm::EDGetTokenT< reco::TrackCollection > ctfTracks
double energy() const
cluster energy
Definition: CaloCluster.h:149
edm::EDGetTokenT< reco::ElectronSeedCollection > seedsTag
const reco::BeamSpot * beamspot
float classBasedElectronEnergy(reco::GsfElectron const &, reco::BeamSpot const &, EcalClusterFunctionBaseClass const &crackCorrectionFunction)
edm::Handle< reco::ConversionCollection > conversions
static bool isNextToDBoundary(EEDetId id)
Definition: EEDetId.cc:279
void applyEcalRegression(reco::GsfElectron &electron, const reco::VertexCollection &vertices, const EcalRecHitCollection &rechitsEB, const EcalRecHitCollection &rechitsEE) const
bool isValid() const
Definition: HandleBase.h:70
std::vector< edm::Handle< reco::PFClusterCollection > > hcalClustersHandle
EleTkIsolFromCands tkIsolHEEP04Calc
bool isNull() const
Checks for null.
Definition: Ref.h:235
const edm::ESGetToken< MagneticField, IdealMagneticFieldRecord > magneticFieldToken_
const_iterator end() const
bool calculateTSOS(MultiTrajectoryStateTransform const &, GsfConstraintAtVertex const &)
const EleTkIsolFromCands::Configuration tkIsolHEEP04CalcCfg_
void setPixelMatchDPhi2(float dPhi2)
Definition: GsfElectron.h:931
reco::CaloClusterPtr getEleBasicCluster(MultiTrajectoryStateTransform const &)
Definition: DetId.h:17
edm::Handle< reco::VertexCollection > vertices
EgammaRecHitIsolation ecalBarrelIsol04
const PFClusterIsolationConfiguration pfiso
DetId seed() const
return DetId of seed
Definition: CaloCluster.h:219
edm::EDGetTokenT< reco::PFClusterCollection > pfClusterProducer
ElectronMomentum correctElectronMomentum(reco::GsfElectron const &, TrajectoryStateOnSurface const &)
float ecalClusterEnergyUncertaintyElectronSpecific(reco::SuperCluster const &superCluster)
bool hasActiveHcal(const reco::SuperCluster &sc) const
Detector
Definition: DetId.h:24
reco::GsfElectron::SaturationInfo calculateSaturationInfo(const reco::SuperClusterRef &, EventData const &eventData) const
REF castTo() const
Definition: RefToBase.h:257
bool isNull() const
Checks for null.
Definition: RefToBase.h:295
double getHcalEtSum(const reco::Candidate *c, int depth) const
T getParameter(std::string const &) const
Definition: ParameterSet.h:303
const reco::GsfTrackRef gsfTrackRef
void ele_convert(const Type1 &obj1, Type2 &obj2)
math::XYZTLorentzVector LorentzVector
Lorentz vector.
Definition: Candidate.h:36
virtual GsfElectronCoreRef core() const
Definition: GsfElectron.cc:8
std::array< float, 7 > hcalOverEcalBc
Definition: GsfElectron.h:373
const StrategyConfiguration strategy
edm::soa::AddColumns< edm::soa::PtEtaPhiTable, TrackTableSpecificColumns >::type TrackTable
std::vector< std::string > vweightsfiles
math::XYZVectorF momentumAtVtxWithConstraint
Definition: GsfElectron.h:262
const auto hcalTopology() const
TrajectoryStateOnSurface innerStateOnSurface(const reco::GsfTrack &tk) const
TrajectoryStateOnSurface seedTSOS
EgammaHcalIsolation hadIsolation04
iterator find(key_type k)
edm::Handle< reco::GsfTrackCollection > originalGsfTracks
const CutsConfiguration cuts
const EcalRecHitsConfiguration recHits
ElectronHcalHelper hcalHelperCone_
const reco::GsfElectronCoreRef coreRef
ElectronHcalHelper hcalHelperBc_
bool isEBPhiGap() const
Definition: GsfElectron.h:334
edm::Handle< reco::TrackCollection > currentCtfTracks
std::unique_ptr< ElectronHcalPFClusterIsolation > hcalisoAlgo_
float hcalOverEcal(const ShowerShape &ss, int depth) const
Definition: GsfElectron.h:425
std::unique_ptr< ElectronEcalPFClusterIsolation > ecalisoAlgo_
edm::EDGetTokenT< EcalRecHitCollection > barrelRecHitCollection
const reco::SuperClusterRef superClusterRef
TrajectoryStateOnSurface eleTSOS
const auto hcalSevLvlComputer() const
const auto hcalChannelQuality() const
const Point & position() const
position
Definition: BeamSpot.h:59
std::unique_ptr< const SoftElectronMVAEstimator > sElectronMVAEstimator
TrajectoryStateOnSurface outTSOS
trackerGeometryToken_(iC.esConsumes())
ElectronData(const reco::GsfElectronCoreRef &core, const reco::BeamSpot &bs)
double getHcalEtSumBc(const reco::Candidate *c, int depth) const
Log< level::Warning, false > LogWarning
bool momentumFromModeCartesian(TrajectoryStateOnSurface const &tsos, GlobalVector &momentum)
std::array< double, 4 > arrayHB
EventData beginEvent(edm::Event const &event, CaloGeometry const &caloGeometry, EcalSeverityLevelAlgo const &ecalSeveretyLevelAlgo)
edm::Handle< reco::GsfElectronCoreCollection > coreElectrons
int ietaAbs() const
get the absolute value of the crystal ieta
Definition: EBDetId.h:47
const EleTkIsolFromCands::Configuration tkIsolHEEP03CalcCfg_
const edm::ESGetToken< CaloTopology, CaloTopologyRecord > caloTopologyToken_
reco::GsfElectron::Classification classifyElectron(reco::GsfElectron const &)
const auto towerMap() const
void checkSetup(const edm::EventSetup &)
void setPixelMatchDRz1(float dRz1)
Definition: GsfElectron.h:932
SuperClusterRef superCluster() const override
reference to a SuperCluster
Definition: GsfElectron.h:155
const EleTkIsolFromCands::Configuration tkIsol04CalcCfg_
int maxSeverityHE() const
math::PtEtaPhiELorentzVectorF LorentzVector
int charge() const final
electric charge
Global3DVector GlobalVector
Definition: GlobalVector.h:10
TrajectoryStateOnSurface vtxTSOS
EleTkIsolFromCands tkIsolHEEP03Calc
constexpr Detector det() const
get the detector field from this detid
Definition: DetId.h:46
reco::Candidate::LorentzVector calculateMomentum()
const reco::BeamSpot beamSpot
std::array< double, 7 > arrayHE