30 #include <Math/Point3D.h>
43 sElectronMVAEstimator = std::make_unique<SoftElectronMVAEstimator>(sconfig);
47 iElectronMVAEstimator = std::make_unique<ElectronMVAEstimator>(iconfig);
85 bool originalCtfTrackCollectionRetreived =
false;
86 bool originalGsfTrackCollectionRetreived =
false;
109 void calculateMode();
129 if ((!originalCtfTrackCollectionRetreived) && (ctfTrack.
isNonnull())) {
130 event->get(ctfTrack.
id(), originalCtfTracks);
131 originalCtfTrackCollectionRetreived =
true;
133 if ((!originalGsfTrackCollectionRetreived) && (gsfTrack.
isNonnull())) {
134 event->get(gsfTrack.
id(), originalGsfTracks);
135 originalGsfTrackCollectionRetreived =
true;
141 gsfTrackRef(coreRef->gsfTrack()),
142 superClusterRef(coreRef->superCluster()),
143 ctfTrackRef(coreRef->ctfTrack()),
144 shFracInnerHits(coreRef->ctfGsfOverlap()),
157 info.scPixCharge = -1;
159 info.scPixCharge = 1;
162 int chargeGsf = gsfTrackRef->charge();
163 info.isGsfScPixConsistent = ((chargeGsf *
info.scPixCharge) > 0);
164 info.isGsfCtfConsistent = (ctfTrackRef.isNonnull() && ((chargeGsf * ctfTrackRef->charge()) > 0));
165 info.isGsfCtfScPixConsistent = (
info.isGsfScPixConsistent &&
info.isGsfCtfConsistent);
168 if (
info.isGsfScPixConsistent || ctfTrackRef.isNull()) {
171 charge = ctfTrackRef->charge();
179 float dphimin = 1.e30;
180 for (
auto const& bc : superClusterRef->clusters()) {
181 GlobalPoint posclu(bc->position().x(), bc->position().y(), bc->position().z());
183 if (!tempTSOS.isValid())
200 if (!innTSOS.isValid())
208 if (!vtxTSOS.isValid())
213 if (!outTSOS.isValid())
218 GlobalPoint(superClusterRef->seed()->position().x(),
219 superClusterRef->seed()->position().y(),
220 superClusterRef->seed()->position().z()));
221 if (!seedTSOS.isValid())
226 innTSOS,
GlobalPoint(superClusterRef->x(), superClusterRef->y(), superClusterRef->z()));
227 if (!sclTSOS.isValid())
253 double scale = superClusterRef->energy() / vtxMom.mag();
255 vtxMom.x() *
scale, vtxMom.y() *
scale, vtxMom.z() *
scale, superClusterRef->energy());
271 int nSaturatedXtals = 0;
272 bool isSeedSaturated =
false;
273 for (
auto&& hitFractionPair : theClus->hitsAndFractions()) {
277 if (
ecalRecHit->checkFlag(EcalRecHit::Flags::kSaturated)) {
280 isSeedSaturated =
true;
289 template <
bool full5x5>
306 std::vector<int> recHitFlagsToBeExcluded;
307 std::vector<int> recHitSeverityToBeExcluded;
318 const auto& covariances = ClusterTools::covariances(seedCluster,
recHits, &topology, &
geometry);
322 const auto& localCovariances = full5x5 ? ClusterTools::localCovariances(seedCluster,
329 : ClusterTools::localCovariances(seedCluster,
recHits, &topology);
336 showerShape.
e2x5Max = ClusterTools::e2x5Max(seedCluster,
recHits, &topology);
337 showerShape.
e5x5 = ClusterTools::e5x5(seedCluster,
recHits, &topology);
338 showerShape.
r9 = ClusterTools::e3x3(seedCluster,
recHits, &topology) / theClus->rawEnergy();
340 const float scale = full5x5 ? showerShape.
e5x5 : theClus->energy();
352 if (see_by_spp > 0) {
353 showerShape.
sigmaIetaIphi = localCovariances[1] / see_by_spp;
354 }
else if (localCovariances[1] > 0) {
360 showerShape.
e2nd = ClusterTools::e2nd(seedCluster,
recHits);
361 showerShape.
eTop = ClusterTools::eTop(seedCluster,
recHits, &topology);
362 showerShape.
eLeft = ClusterTools::eLeft(seedCluster,
recHits, &topology);
363 showerShape.
eRight = ClusterTools::eRight(seedCluster,
recHits, &topology);
364 showerShape.
eBottom = ClusterTools::eBottom(seedCluster,
recHits, &topology);
366 showerShape.
e2x5Left = ClusterTools::e2x5Left(seedCluster,
recHits, &topology);
367 showerShape.
e2x5Right = ClusterTools::e2x5Right(seedCluster,
recHits, &topology);
368 showerShape.
e2x5Top = ClusterTools::e2x5Top(seedCluster,
recHits, &topology);
369 showerShape.
e2x5Bottom = ClusterTools::e2x5Bottom(seedCluster,
recHits, &topology);
385 std::unique_ptr<EcalClusterFunctionBaseClass>&& crackCorrectionFunction,
393 tkIsol03CalcCfg_(tkIsol03),
394 tkIsol04CalcCfg_(tkIsol04),
395 tkIsolHEEP03CalcCfg_(tkIsolHEEP03),
396 tkIsolHEEP04CalcCfg_(tkIsolHEEP04),
397 magneticFieldToken_{
cc.esConsumes()},
398 caloGeometryToken_{
cc.esConsumes()},
399 caloTopologyToken_{
cc.esConsumes()},
400 trackerGeometryToken_{
cc.esConsumes()},
401 ecalSeveretyLevelAlgoToken_{
cc.esConsumes()},
402 ecalPFRechitThresholdsToken_{
cc.esConsumes()},
405 crackCorrectionFunction_{std::forward<std::unique_ptr<EcalClusterFunctionBaseClass>>(crackCorrectionFunction)},
406 regHelper_{reg, cfg_.strategy.useEcalRegression, cfg_.strategy.useCombinationRegression,
cc}
425 float egHcalIsoConeSizeOutSmall = 0.3, egHcalIsoConeSizeOutLarge = 0.4;
428 float egIsoConeSizeOutSmall = 0.3, egIsoConeSizeOutLarge = 0.4, egIsoJurassicWidth =
cfg_.
iso.
jurassicWidth;
453 egHcalIsoConeSizeOutSmall,
476 egHcalIsoConeSizeOutLarge,
499 egHcalIsoConeSizeOutSmall,
522 egHcalIsoConeSizeOutLarge,
545 egIsoConeSizeInBarrel,
551 &ecalSeveretyLevelAlgo,
554 egIsoConeSizeInBarrel,
560 &ecalSeveretyLevelAlgo,
563 egIsoConeSizeInEndcap,
569 &ecalSeveretyLevelAlgo,
572 egIsoConeSizeInEndcap,
578 &ecalSeveretyLevelAlgo,
584 .originalCtfTracks = {},
585 .originalGsfTracks = {}};
589 eventData.ecalBarrelIsol03.doSeverityChecks(eventData.barrelRecHits.product(),
594 eventData.ecalBarrelIsol04.doSeverityChecks(eventData.barrelRecHits.product(),
599 eventData.ecalEndcapIsol03.doSeverityChecks(eventData.endcapRecHits.product(),
604 eventData.ecalEndcapIsol04.doSeverityChecks(eventData.endcapRecHits.product(),
628 auto eventData =
beginEvent(
event, caloGeometry, ecalSeveretyLevelAlgo);
634 std::optional<egamma::conv::TrackTable> ctfTrackTable = std::nullopt;
635 std::optional<egamma::conv::TrackTable> gsfTrackTable = std::nullopt;
638 for (
unsigned int i = 0;
i < coreCollection->size(); ++
i) {
643 if (coreRef->superCluster().
isNull())
647 ElectronData electronData(coreRef, *eventData.beamspot);
650 if (!electronData.
calculateTSOS(mtsTransform, constraintAtVtx))
653 eventData.retreiveOriginalTrackCollections(electronData.
ctfTrackRef, electronData.
coreRef->gsfTrack());
655 if (!eventData.originalCtfTracks.isValid()) {
656 eventData.originalCtfTracks = eventData.currentCtfTracks;
659 if (ctfTrackTable == std::nullopt) {
662 if (gsfTrackTable == std::nullopt) {
672 magneticFieldInTesla,
674 ctfTrackTable.value(),
675 gsfTrackTable.value(),
687 bool eg = ele.
core()->ecalDrivenSeed();
688 bool pf = ele.
core()->trackerDrivenSeed() && !ele.
core()->ecalDrivenSeed();
690 throw cms::Exception(
"GsfElectronAlgo|BothEcalAndPureTrackerDriven")
691 <<
"An electron cannot be both egamma and purely pflow";
693 if ((!eg) && (!
pf)) {
694 throw cms::Exception(
"GsfElectronAlgo|NeitherEcalNorPureTrackerDriven")
695 <<
"An electron cannot be neither egamma nor purely pflow";
702 double etValue = ele.
superCluster()->energy() / cosh(etaValue);
703 LogTrace(
"GsfElectronAlgo") <<
"Et : " << etValue;
704 if (ele.
isEB() && (etValue <
cfg.minSCEtBarrel))
706 if (ele.
isEE() && (etValue <
cfg.minSCEtEndcaps))
708 LogTrace(
"GsfElectronAlgo") <<
"Et criteria are satisfied";
712 LogTrace(
"GsfElectronAlgo") <<
"E/p : " << eopValue;
713 if (ele.
isEB() && (eopValue >
cfg.maxEOverPBarrel))
715 if (ele.
isEE() && (eopValue >
cfg.maxEOverPEndcaps))
717 if (ele.
isEB() && (eopValue <
cfg.minEOverPBarrel))
719 if (ele.
isEE() && (eopValue <
cfg.minEOverPEndcaps))
721 LogTrace(
"GsfElectronAlgo") <<
"E/p criteria are satisfied";
729 bool HoEveto =
false;
733 HoEveto = hoeCone * scle <
cfg.maxHBarrelCone || hoeBc * scle <
cfg.maxHBarrelBc ||
734 hoeCone <
cfg.maxHOverEBarrelCone || hoeBc <
cfg.maxHOverEBarrelBc;
736 HoEveto = hoeCone * scle <
cfg.maxHEndcapsCone || hoeBc * scle <
cfg.maxHEndcapsBc ||
737 hoeCone <
cfg.maxHOverEEndcapsCone || hoeBc <
cfg.maxHOverEEndcapsBc;
741 LogTrace(
"GsfElectronAlgo") <<
"H/E criteria are satisfied";
745 LogTrace(
"GsfElectronAlgo") <<
"delta eta : " << deta;
750 LogTrace(
"GsfElectronAlgo") <<
"Delta eta criteria are satisfied";
754 LogTrace(
"GsfElectronAlgo") <<
"delta phi : " << dphi;
759 LogTrace(
"GsfElectronAlgo") <<
"Delta phi criteria are satisfied";
767 LogTrace(
"GsfElectronAlgo") <<
"Sigma ieta ieta criteria are satisfied";
770 if (!ele.
isEB() &&
cfg.isBarrel)
772 if (!ele.
isEE() &&
cfg.isEndcaps)
774 if (
cfg.isFiducial &&
777 LogTrace(
"GsfElectronAlgo") <<
"Fiducial flags criteria are satisfied";
784 throw cms::Exception(
"GsfElectronAlgo|NotElectronSeed") <<
"The GsfTrack seed is not an ElectronSeed ?!";
786 if (elseed->subDet(1) == 6)
794 LogTrace(
"GsfElectronAlgo") <<
"TIP criterion is satisfied";
796 LogTrace(
"GsfElectronAlgo") <<
"All cut based criteria are satisfied";
806 double magneticFieldInTesla,
892 fiducialFlags.
isEB =
true;
905 fiducialFlags.
isEE =
true;
918 fiducialFlags.
isEE =
true;
923 <<
"createElectron(): do not know if it is a barrel or endcap seed cluster !!!!";
939 showerShape = calculateShowerShape<false>(
941 full5x5_showerShape = calculateShowerShape<true>(
963 <<
"ProductID of ctf track collection does not match ProductID of electron's CTF track! \n";
966 <<
"ProductID of gsf track collection does not match ProductID of electron's GSF track! \n";
978 conversionVars.
flags = conversionInfo.flag;
979 conversionVars.
dist = conversionInfo.dist;
980 conversionVars.
dcot = conversionInfo.dcot;
981 conversionVars.
radius = conversionInfo.radiusOfConversion;
992 if (conversionInfo.conversionPartnerCtfTkIdx) {
994 }
else if (conversionInfo.conversionPartnerGsfTkIdx) {
1011 full5x5_showerShape,
1017 ele.setP4(GsfElectron::P4_FROM_SUPER_CLUSTER, momentum, 0,
true);
1032 if (sc->clustersSize() > 1) {
1033 float pf_fbrem = (sc->energy() -
cl->energy()) / sc->energy();
1034 ele.setSuperClusterFbrem(pf_fbrem);
1036 ele.setSuperClusterFbrem(0);
1045 ele.setClassification(elClass);
1048 if (unexpectedClassification) {
1059 if (ele.core()->ecalDrivenSeed()) {
1061 if (ele.isEcalEnergyCorrected()) {
1062 edm::LogWarning(
"ElectronEnergyCorrector::classBasedElectronEnergy") <<
"already done";
1064 ele.setCorrectedEcalEnergy(
1083 edm::LogWarning(
"ElectronMomentumCorrector::correct") <<
"already done";
1086 ele.correctMomentum(
p.momentum,
p.trackError,
p.finalError);
1122 ele.setIsolation03(dr03);
1123 ele.setIsolation04(dr04);
1142 LogTrace(
"GsfElectronAlgo") <<
"Constructed new electron with energy " << ele.p4().e();
1155 if (
seed.isNull()) {
1159 sd1 = elseed->subDet(0);
1160 sd2 = elseed->subDet(1);
1161 dPhi1 = (ele.
charge() > 0) ? elseed->dPhiPos(0) : elseed->dPhiNeg(0);
1162 dPhi2 = (ele.
charge() > 0) ? elseed->dPhiPos(1) : elseed->dPhiNeg(1);
1163 dRz1 = (ele.
charge() > 0) ? elseed->dRZPos(0) : elseed->dRZNeg(0);
1164 dRz2 = (ele.
charge() > 0) ? elseed->dRZPos(1) : elseed->dRZNeg(1);