30 #include <Math/Point3D.h>
43 sElectronMVAEstimator = std::make_unique<SoftElectronMVAEstimator>(sconfig);
47 iElectronMVAEstimator = std::make_unique<ElectronMVAEstimator>(iconfig);
87 bool originalCtfTrackCollectionRetreived =
false;
88 bool originalGsfTrackCollectionRetreived =
false;
111 void calculateMode();
131 if ((!originalCtfTrackCollectionRetreived) && (ctfTrack.
isNonnull())) {
132 event->get(ctfTrack.
id(), originalCtfTracks);
133 originalCtfTrackCollectionRetreived =
true;
135 if ((!originalGsfTrackCollectionRetreived) && (gsfTrack.
isNonnull())) {
136 event->get(gsfTrack.
id(), originalGsfTracks);
137 originalGsfTrackCollectionRetreived =
true;
143 gsfTrackRef(coreRef->gsfTrack()),
144 superClusterRef(coreRef->superCluster()),
145 ctfTrackRef(coreRef->ctfTrack()),
146 shFracInnerHits(coreRef->ctfGsfOverlap()),
159 info.scPixCharge = -1;
161 info.scPixCharge = 1;
164 int chargeGsf = gsfTrackRef->charge();
165 info.isGsfScPixConsistent = ((chargeGsf *
info.scPixCharge) > 0);
166 info.isGsfCtfConsistent = (ctfTrackRef.isNonnull() && ((chargeGsf * ctfTrackRef->charge()) > 0));
167 info.isGsfCtfScPixConsistent = (
info.isGsfScPixConsistent &&
info.isGsfCtfConsistent);
170 if (
info.isGsfScPixConsistent || ctfTrackRef.isNull()) {
173 charge = ctfTrackRef->charge();
181 float dphimin = 1.e30;
182 for (
auto const& bc : superClusterRef->clusters()) {
183 GlobalPoint posclu(bc->position().x(), bc->position().y(), bc->position().z());
185 if (!tempTSOS.isValid())
202 if (!innTSOS.isValid())
210 if (!vtxTSOS.isValid())
215 if (!outTSOS.isValid())
220 GlobalPoint(superClusterRef->seed()->position().x(),
221 superClusterRef->seed()->position().y(),
222 superClusterRef->seed()->position().z()));
223 if (!seedTSOS.isValid())
228 innTSOS,
GlobalPoint(superClusterRef->x(), superClusterRef->y(), superClusterRef->z()));
229 if (!sclTSOS.isValid())
255 double scale = superClusterRef->energy() / vtxMom.mag();
257 vtxMom.x() *
scale, vtxMom.y() *
scale, vtxMom.z() *
scale, superClusterRef->energy());
273 int nSaturatedXtals = 0;
274 bool isSeedSaturated =
false;
275 for (
auto&& hitFractionPair : theClus->hitsAndFractions()) {
279 if (
ecalRecHit->checkFlag(EcalRecHit::Flags::kSaturated)) {
282 isSeedSaturated =
true;
291 template <
bool full5x5>
307 std::vector<int> recHitFlagsToBeExcluded;
308 std::vector<int> recHitSeverityToBeExcluded;
319 const auto& covariances = ClusterTools::covariances(seedCluster,
recHits, &topology, &
geometry);
323 const auto& localCovariances = full5x5 ? ClusterTools::localCovariances(seedCluster,
330 : ClusterTools::localCovariances(seedCluster,
recHits, &topology);
337 showerShape.
e2x5Max = ClusterTools::e2x5Max(seedCluster,
recHits, &topology);
338 showerShape.
e5x5 = ClusterTools::e5x5(seedCluster,
recHits, &topology);
339 showerShape.
r9 = ClusterTools::e3x3(seedCluster,
recHits, &topology) / theClus->rawEnergy();
341 const float scale = full5x5 ? showerShape.
e5x5 : theClus->energy();
355 if (see_by_spp > 0) {
356 showerShape.
sigmaIetaIphi = localCovariances[1] / see_by_spp;
357 }
else if (localCovariances[1] > 0) {
363 showerShape.
e2nd = ClusterTools::e2nd(seedCluster,
recHits);
364 showerShape.
eTop = ClusterTools::eTop(seedCluster,
recHits, &topology);
365 showerShape.
eLeft = ClusterTools::eLeft(seedCluster,
recHits, &topology);
366 showerShape.
eRight = ClusterTools::eRight(seedCluster,
recHits, &topology);
367 showerShape.
eBottom = ClusterTools::eBottom(seedCluster,
recHits, &topology);
369 showerShape.
e2x5Left = ClusterTools::e2x5Left(seedCluster,
recHits, &topology);
370 showerShape.
e2x5Right = ClusterTools::e2x5Right(seedCluster,
recHits, &topology);
371 showerShape.
e2x5Top = ClusterTools::e2x5Top(seedCluster,
recHits, &topology);
372 showerShape.
e2x5Bottom = ClusterTools::e2x5Bottom(seedCluster,
recHits, &topology);
387 std::unique_ptr<EcalClusterFunctionBaseClass>&& crackCorrectionFunction,
395 tkIsol03CalcCfg_(tkIsol03),
396 tkIsol04CalcCfg_(tkIsol04),
397 tkIsolHEEP03CalcCfg_(tkIsolHEEP03),
398 tkIsolHEEP04CalcCfg_(tkIsolHEEP04),
399 magneticFieldToken_{
cc.esConsumes()},
400 caloGeometryToken_{
cc.esConsumes()},
401 caloTopologyToken_{
cc.esConsumes()},
402 trackerGeometryToken_{
cc.esConsumes()},
403 ecalSeveretyLevelAlgoToken_{
cc.esConsumes()},
404 ecalPFRechitThresholdsToken_{
cc.esConsumes()},
406 crackCorrectionFunction_{std::forward<std::unique_ptr<EcalClusterFunctionBaseClass>>(crackCorrectionFunction)},
407 regHelper_{reg, cfg_.strategy.useEcalRegression, cfg_.strategy.useCombinationRegression,
cc}
426 float egHcalIsoConeSizeOutSmall = 0.3, egHcalIsoConeSizeOutLarge = 0.4;
428 int egHcalDepth1 = 1, egHcalDepth2 = 2;
430 float egIsoConeSizeOutSmall = 0.3, egIsoConeSizeOutLarge = 0.4, egIsoJurassicWidth =
cfg_.
iso.
jurassicWidth;
452 .hadDepth1Isolation03 =
454 .hadDepth1Isolation04 =
456 .hadDepth2Isolation03 =
458 .hadDepth2Isolation04 =
460 .hadDepth1Isolation03Bc =
462 .hadDepth1Isolation04Bc =
464 .hadDepth2Isolation03Bc =
466 .hadDepth2Isolation04Bc =
469 egIsoConeSizeInBarrel,
475 &ecalSeveretyLevelAlgo,
478 egIsoConeSizeInBarrel,
484 &ecalSeveretyLevelAlgo,
487 egIsoConeSizeInEndcap,
493 &ecalSeveretyLevelAlgo,
496 egIsoConeSizeInEndcap,
502 &ecalSeveretyLevelAlgo,
508 .originalCtfTracks = {},
509 .originalGsfTracks = {}};
513 eventData.ecalBarrelIsol03.doSeverityChecks(eventData.barrelRecHits.product(),
518 eventData.ecalBarrelIsol04.doSeverityChecks(eventData.barrelRecHits.product(),
523 eventData.ecalEndcapIsol03.doSeverityChecks(eventData.endcapRecHits.product(),
528 eventData.ecalEndcapIsol04.doSeverityChecks(eventData.endcapRecHits.product(),
551 auto eventData =
beginEvent(
event, caloGeometry, ecalSeveretyLevelAlgo);
557 std::optional<egamma::conv::TrackTable> ctfTrackTable = std::nullopt;
558 std::optional<egamma::conv::TrackTable> gsfTrackTable = std::nullopt;
561 for (
unsigned int i = 0;
i < coreCollection->size(); ++
i) {
566 if (coreRef->superCluster().
isNull())
570 ElectronData electronData(coreRef, *eventData.beamspot);
573 if (!electronData.
calculateTSOS(mtsTransform, constraintAtVtx))
576 eventData.retreiveOriginalTrackCollections(electronData.
ctfTrackRef, electronData.
coreRef->gsfTrack());
578 if (!eventData.originalCtfTracks.isValid()) {
579 eventData.originalCtfTracks = eventData.currentCtfTracks;
582 if (ctfTrackTable == std::nullopt) {
585 if (gsfTrackTable == std::nullopt) {
595 magneticFieldInTesla,
597 ctfTrackTable.value(),
598 gsfTrackTable.value(),
610 bool eg = ele.
core()->ecalDrivenSeed();
611 bool pf = ele.
core()->trackerDrivenSeed() && !ele.
core()->ecalDrivenSeed();
613 throw cms::Exception(
"GsfElectronAlgo|BothEcalAndPureTrackerDriven")
614 <<
"An electron cannot be both egamma and purely pflow";
616 if ((!eg) && (!
pf)) {
617 throw cms::Exception(
"GsfElectronAlgo|NeitherEcalNorPureTrackerDriven")
618 <<
"An electron cannot be neither egamma nor purely pflow";
625 double etValue = ele.
superCluster()->energy() / cosh(etaValue);
626 LogTrace(
"GsfElectronAlgo") <<
"Et : " << etValue;
627 if (ele.
isEB() && (etValue <
cfg.minSCEtBarrel))
629 if (ele.
isEE() && (etValue <
cfg.minSCEtEndcaps))
631 LogTrace(
"GsfElectronAlgo") <<
"Et criteria are satisfied";
635 LogTrace(
"GsfElectronAlgo") <<
"E/p : " << eopValue;
636 if (ele.
isEB() && (eopValue >
cfg.maxEOverPBarrel))
638 if (ele.
isEE() && (eopValue >
cfg.maxEOverPEndcaps))
640 if (ele.
isEB() && (eopValue <
cfg.minEOverPBarrel))
642 if (ele.
isEE() && (eopValue <
cfg.minEOverPEndcaps))
644 LogTrace(
"GsfElectronAlgo") <<
"E/p criteria are satisfied";
652 bool HoEveto =
false;
656 HoEveto = hoeCone * scle <
cfg.maxHBarrelCone || hoeTower * scle <
cfg.maxHBarrelTower ||
657 hoeCone <
cfg.maxHOverEBarrelCone || hoeTower <
cfg.maxHOverEBarrelTower;
659 HoEveto = hoeCone * scle <
cfg.maxHEndcapsCone || hoeTower * scle <
cfg.maxHEndcapsTower ||
660 hoeCone <
cfg.maxHOverEEndcapsCone || hoeTower <
cfg.maxHOverEEndcapsTower;
664 LogTrace(
"GsfElectronAlgo") <<
"H/E criteria are satisfied";
668 LogTrace(
"GsfElectronAlgo") <<
"delta eta : " << deta;
673 LogTrace(
"GsfElectronAlgo") <<
"Delta eta criteria are satisfied";
677 LogTrace(
"GsfElectronAlgo") <<
"delta phi : " << dphi;
682 LogTrace(
"GsfElectronAlgo") <<
"Delta phi criteria are satisfied";
690 LogTrace(
"GsfElectronAlgo") <<
"Sigma ieta ieta criteria are satisfied";
693 if (!ele.
isEB() &&
cfg.isBarrel)
695 if (!ele.
isEE() &&
cfg.isEndcaps)
697 if (
cfg.isFiducial &&
700 LogTrace(
"GsfElectronAlgo") <<
"Fiducial flags criteria are satisfied";
707 throw cms::Exception(
"GsfElectronAlgo|NotElectronSeed") <<
"The GsfTrack seed is not an ElectronSeed ?!";
709 if (elseed->subDet(1) == 6)
717 LogTrace(
"GsfElectronAlgo") <<
"TIP criterion is satisfied";
719 LogTrace(
"GsfElectronAlgo") <<
"All cut based criteria are satisfied";
729 double magneticFieldInTesla,
815 fiducialFlags.
isEB =
true;
828 fiducialFlags.
isEE =
true;
841 fiducialFlags.
isEE =
true;
846 <<
"createElectron(): do not know if it is a barrel or endcap seed cluster !!!!";
862 showerShape = calculateShowerShape<false>(
864 full5x5_showerShape = calculateShowerShape<true>(
886 <<
"ProductID of ctf track collection does not match ProductID of electron's CTF track! \n";
889 <<
"ProductID of gsf track collection does not match ProductID of electron's GSF track! \n";
901 conversionVars.
flags = conversionInfo.flag;
902 conversionVars.
dist = conversionInfo.dist;
903 conversionVars.
dcot = conversionInfo.dcot;
904 conversionVars.
radius = conversionInfo.radiusOfConversion;
915 if (conversionInfo.conversionPartnerCtfTkIdx) {
917 }
else if (conversionInfo.conversionPartnerGsfTkIdx) {
940 ele.setP4(GsfElectron::P4_FROM_SUPER_CLUSTER, momentum, 0,
true);
955 if (sc->clustersSize() > 1) {
956 float pf_fbrem = (sc->energy() -
cl->energy()) / sc->energy();
957 ele.setSuperClusterFbrem(pf_fbrem);
959 ele.setSuperClusterFbrem(0);
968 ele.setClassification(elClass);
971 if (unexpectedClassification) {
982 if (ele.core()->ecalDrivenSeed()) {
984 if (ele.isEcalEnergyCorrected()) {
985 edm::LogWarning(
"ElectronEnergyCorrector::classBasedElectronEnergy") <<
"already done";
987 ele.setCorrectedEcalEnergy(
1006 edm::LogWarning(
"ElectronMomentumCorrector::correct") <<
"already done";
1009 ele.correctMomentum(
p.momentum,
p.trackError,
p.finalError);
1044 ele.setIsolation03(dr03);
1045 ele.setIsolation04(dr04);
1064 LogTrace(
"GsfElectronAlgo") <<
"Constructed new electron with energy " << ele.p4().e();
1077 if (
seed.isNull()) {
1081 sd1 = elseed->subDet(0);
1082 sd2 = elseed->subDet(1);
1083 dPhi1 = (ele.
charge() > 0) ? elseed->dPhiPos(0) : elseed->dPhiNeg(0);
1084 dPhi2 = (ele.
charge() > 0) ? elseed->dPhiPos(1) : elseed->dPhiNeg(1);
1085 dRz1 = (ele.
charge() > 0) ? elseed->dRZPos(0) : elseed->dRZNeg(0);
1086 dRz2 = (ele.
charge() > 0) ? elseed->dRZPos(1) : elseed->dRZNeg(1);