32 #include "combination.hpp" 38 #define docast(x, y) dynamic_cast<x>(y) 39 #define LOGVERB(x) edm::LogVerbatim(x) 40 #define LOGWARN(x) edm::LogWarning(x) 41 #define LOGERR(x) edm::LogError(x) 42 #define LOGDRESSED(x) edm::LogInfo(x) 44 #define docast(x, y) reinterpret_cast<x>(y) 45 #define LOGVERB(x) LogTrace(x) 46 #define LOGWARN(x) edm::LogWarning(x) 47 #define LOGERR(x) edm::LogError(x) 48 #define LOGDRESSED(x) LogDebug(x) 58 typedef std::pair<CaloClusterPtr::key_type, CaloClusterPtr> EEtoPSElement;
61 class SeedMatchesToProtoObject {
66 if (scfromseed_.isNonnull()) {
72 if (scfromseed_.isNull() || !po.
parentSC)
85 template <
bool useConvs = false>
91 const float EoPin_cut = 1.0e6) {
99 const ClusterElement* elemasclus =
reinterpret_cast<const ClusterElement*
>(&(block->elements()[
test]));
100 float cluster_e = elemasclus->clusterRef()->correctedEnergy();
101 float trk_pin = elemasgsf->
Pin().P();
102 if (cluster_e / trk_pin > EoPin_cut) {
103 LOGDRESSED(
"elementNotCloserToOther") <<
"GSF track failed EoP cut to match with cluster!";
111 const ClusterElement* elemasclus =
reinterpret_cast<const ClusterElement*
>(&(block->elements()[
test]));
112 float cluster_e = elemasclus->clusterRef()->correctedEnergy();
114 if (cluster_e / trk_pin > EoPin_cut) {
115 LOGDRESSED(
"elementNotCloserToOther") <<
"KF track failed EoP cut to match with cluster!";
127 std::multimap<double, unsigned> dists_to_val;
130 for (
const auto& valdist : dists_to_val) {
131 const size_t idx = valdist.second;
137 if (!useConvs && elemasgsf->
trackType(ConvType))
140 const ClusterElement* elemasclus =
docast(
const ClusterElement*, &(block->elements()[
test]));
141 float cluster_e = elemasclus->clusterRef()->correctedEnergy();
142 float trk_pin = elemasgsf->
Pin().P();
143 if (cluster_e / trk_pin > EoPin_cut)
150 if (!useConvs && elemaskf->
trackType(ConvType))
153 const ClusterElement* elemasclus =
reinterpret_cast<const ClusterElement*
>(&(block->elements()[
test]));
154 float cluster_e = elemasclus->clusterRef()->correctedEnergy();
156 if (cluster_e / trk_pin > EoPin_cut)
163 if (valdist.first < dist && idx != key) {
165 <<
"key element of type " << keytype <<
" is closer to another element of type" << valtype << std::endl;
172 template <
class Element1,
class Element2>
173 bool compatibleEoPOut(
const Element1&
e,
const Element2&
comp) {
177 const ClusterElement& elemascluster =
docast(ClusterElement
const&, e);
178 const float gsf_eta_diff =
std::abs(comp.positionAtECALEntrance().eta() - comp.Pout().eta());
180 return (gsf_eta_diff <= 0.3 && cRef->
energy() / comp.Pout().t() <= 5);
185 template <PFBlockElement::Type keytype, PFBlockElement::Type valtype,
bool useConv = false>
187 struct NotCloserToOther {
190 const float EoPin_cut;
192 :
comp(e),
block(b), EoPin_cut(EoPcut) {}
194 bool operator()(
const T& e) {
195 if (!e.flag() || valtype != e->type())
197 return elementNotCloserToOther<useConv>(
block, keytype, comp->index(), valtype, e->index(), EoPin_cut);
201 struct LesserByDistance {
211 dist1 = (dist1 == -1.0 ? 1e6 : dist1);
212 dist2 = (dist2 == -1.0 ? 1e6 : dist2);
213 return dist1 < dist2;
221 LOGDRESSED(
"isROLinkedByClusterOrTrack") <<
"cannot merge, both have GSFs!" << std::endl;
227 LOGDRESSED(
"isROLinkedByClusterOrTrack") <<
"cannot merge, different ECAL types!" << std::endl;
236 not_closer = elementNotCloserToOther(blk, cluster->type(), cluster->
index(), primgsf->type(), primgsf->index());
238 LOGDRESSED(
"isROLinkedByClusterOrTrack") <<
"merged by cluster to primary GSF" << std::endl;
241 LOGDRESSED(
"isROLinkedByClusterOrTrack") <<
"cluster to primary GSF failed since" 242 <<
" cluster closer to another GSF" << std::endl;
246 not_closer = elementNotCloserToOther(blk, cluster->type(), cluster->
index(), primkf->type(), primkf->index());
248 LOGDRESSED(
"isROLinkedByClusterOrTrack") <<
"merged by cluster to primary KF" << std::endl;
253 not_closer = elementNotCloserToOther(blk, cluster->type(), cluster->
index(), secdkf->type(), secdkf->index());
255 LOGDRESSED(
"isROLinkedByClusterOrTrack") <<
"merged by cluster to secondary KF" << std::endl;
260 for (
const auto& brem : RO2.
brems) {
261 not_closer = elementNotCloserToOther(blk, cluster->type(), cluster->
index(), brem->type(), brem->index());
263 LOGDRESSED(
"isROLinkedByClusterOrTrack") <<
"merged by cluster to brem KF" << std::endl;
271 not_closer = elementNotCloserToOther(blk, primgsf->type(), primgsf->
index(), secdkf->type(), secdkf->index());
273 LOGDRESSED(
"isROLinkedByClusterOrTrack") <<
"merged by GSF to secondary KF" << std::endl;
281 not_closer = elementNotCloserToOther(blk, primkf->type(), primkf->
index(), secdkf->type(), secdkf->index());
283 LOGDRESSED(
"isROLinkedByClusterOrTrack") <<
"merged by primary KF to secondary KF" << std::endl;
292 elementNotCloserToOther<true>(blk, secdkf1->type(), secdkf1->
index(), secdkf2->type(), secdkf2->index());
294 LOGDRESSED(
"isROLinkedByClusterOrTrack") <<
"merged by secondary KF to secondary KF" << std::endl;
303 const bool result = (isROLinkedByClusterOrTrack(comp, ro) || isROLinkedByClusterOrTrack(ro, comp));
307 std::vector<const ClusterElement*> getSCAssociatedECALsSafe(
309 std::vector<const ClusterElement*> cluster_list;
310 auto sccl = scref->clustersBegin();
311 auto scend = scref->clustersEnd();
312 auto pfc = ecals.begin();
313 auto pfcend = ecals.end();
314 for (; sccl != scend; ++sccl) {
315 std::vector<const ClusterElement*> matched_pfcs;
316 const double eg_energy = (*sccl)->energy();
318 for (pfc = ecals.begin(); pfc != pfcend; ++pfc) {
319 const ClusterElement* pfcel =
docast(
const ClusterElement*, pfc->get());
323 if (matched && pfcel->clusterRef()->energy() < 1.2 * scref->energy()) {
324 matched_pfcs.push_back(pfcel);
327 std::sort(matched_pfcs.begin(), matched_pfcs.end());
329 double min_residual = 1e6;
330 std::vector<const ClusterElement*> best_comb;
331 for (
size_t i = 1;
i <= matched_pfcs.size(); ++
i) {
336 double energy = std::accumulate(
337 matched_pfcs.begin(), matched_pfcs.begin() +
i, 0.0, [](
const double a,
const ClusterElement*
c) {
338 return a +
c->clusterRef()->energy();
340 const double resid =
std::abs(energy - eg_energy);
341 if (resid < min_residual) {
343 best_comb.reserve(
i);
344 min_residual = resid;
345 best_comb.insert(best_comb.begin(), matched_pfcs.begin(), matched_pfcs.begin() +
i);
349 for (
const auto& clelem : best_comb) {
350 if (
std::find(cluster_list.begin(), cluster_list.end(), clelem) == cluster_list.end()) {
351 cluster_list.push_back(clelem);
364 if (clayer == blayer) {
382 *gsfCluster_noassc =
nullptr;
384 int nBremClusters = 0;
386 float mDist_gsf(maxDist), mDist_gsf_noassc(maxDist), mDist_kf(maxDist);
390 elementNotCloserToOther(parent,
gsf->type(),
gsf->index(), cluster->type(), cluster->index());
391 const float deta =
std::abs(cluster->clusterRef()->positionREP().eta() -
gsf->positionAtECALEntrance().eta());
393 TVector2::Phi_mpi_pi(cluster->clusterRef()->positionREP().phi() -
gsf->positionAtECALEntrance().phi()));
394 const float dist = std::hypot(deta, dphi);
395 if (hasclu && dist < mDist_gsf) {
396 gsfCluster = cluster.get();
398 }
else if (dist < mDist_gsf_noassc) {
399 gsfCluster_noassc = cluster.get();
400 mDist_gsf_noassc = dist;
404 const bool hasclu = elementNotCloserToOther(parent, kf->type(), kf->
index(), cluster->type(), cluster->index());
406 if (hasclu && dist < mDist_kf) {
407 kfCluster = cluster.
get();
411 for (
const auto& brem : RO.
brems) {
413 elementNotCloserToOther(parent, brem->type(), brem->
index(), cluster->type(), cluster->index());
416 if (!firstBrem || (firstBrem->
indTrajPoint() - 2 > brem->indTrajPoint() - 2)) {
419 if (!lastBrem || (lastBrem->indTrajPoint() - 2 < brem->indTrajPoint() - 2)) {
421 bremCluster = cluster.get();
426 if (!gsfCluster && !kfCluster && !bremCluster) {
427 gsfCluster = gsfCluster_noassc;
433 }
else if (kfCluster) {
436 if (bremCluster && !gsfCluster && !kfCluster) {
441 if (bremCluster == gsfCluster)
448 : gbrForests_(gbrForests), cfg_(cfg) {}
452 unsigned int trackIndex) {
458 const float chi2 = elements[trackIndex].trackRef()->chi2() / elements[trackIndex].trackRef()->ndof();
459 const float nlost = elements[trackIndex].trackRef()->hitPattern().numberOfLostHits(HitPattern::MISSING_INNER_HITS);
460 const float nLayers = elements[trackIndex].trackRef()->hitPattern().trackerLayersWithMeasurement();
461 const float trackPt = elements[trackIndex].trackRef()->pt();
462 const float stip = elements[trackIndex].trackRefPF()->STIP();
466 std::multimap<double, unsigned int> ecalAssoTrack;
469 std::multimap<double, unsigned int> hcalAssoTrack;
472 if (!ecalAssoTrack.empty()) {
473 for (
auto& itecal : ecalAssoTrack) {
474 linkedE = linkedE + elements[itecal.second].clusterRef()->energy();
477 if (!hcalAssoTrack.empty()) {
478 for (
auto& ithcal : hcalAssoTrack) {
479 linkedH = linkedH + elements[ithcal.second].clusterRef()->energy();
482 const float eOverPt = linkedE / elements[trackIndex].trackRef()->pt();
483 const float hOverPt = linkedH / elements[trackIndex].trackRef()->pt();
484 GlobalVector rvtx(elements[trackIndex].trackRef()->innerPosition().
X() - primaryVtx.
x(),
485 elements[trackIndex].trackRef()->innerPosition().Y() - primaryVtx.
y(),
486 elements[trackIndex].trackRef()->innerPosition().Z() - primaryVtx.
z());
487 double vtxPhi = rvtx.
phi();
489 float delPhi = fabs(
deltaPhi(vtxPhi, elements[trackIndex].trackRef()->innerMomentum().
Phi()));
497 switch (pfbe.
type()) {
500 std::multimap<double, unsigned> tks;
503 for (
const auto& tk : tks) {
519 LOGVERB(
"PFEGammaAlgo") <<
"Resetting PFEGammaAlgo for new block and running!" << std::endl;
527 std::list<ProtoEGObject> refinableObjects;
535 LOGVERB(
"PFEGammaAlgo") <<
"Splaying block" << std::endl;
542 const size_t itype = (size_t)pfelement.type();
550 std::stringstream splayout;
551 for (
size_t itype = 0; itype <
_splayedblock.size(); ++itype) {
552 splayout <<
"\tType: " << itype <<
" indices: ";
554 splayout << flaggedelement->index() <<
' ';
557 splayout << std::endl;
559 LOGVERB(
"PFEGammaAlgo") << splayout.str();
567 LOGDRESSED(
"PFEGammaAlgo") <<
"Initialized " << refinableObjects.size() <<
" proto-EGamma objects" << std::endl;
578 for (
auto& RO : refinableObjects) {
593 LOGDRESSED(
"PFEGammaAlgo") <<
"Dumping after GSF and KF Track (Primary) Linking : " << std::endl;
599 LOGDRESSED(
"PFEGammaAlgo") <<
"Dumping after first merging operation : " << std::endl;
605 for (
auto& RO : refinableObjects) {
615 LOGDRESSED(
"PFEGammaAlgo") <<
"Dumping after ECAL to Track (Secondary) Linking : " << std::endl;
621 LOGDRESSED(
"PFEGammaAlgo") <<
"There are " << refinableObjects.size() <<
" after the 2nd merging step." << std::endl;
625 for (
auto& RO : refinableObjects) {
632 std::sort(RO.ecalclusters.begin(), RO.ecalclusters.end(), [](
auto const&
a,
auto const&
b) {
633 return (
a->clusterRef()->correctedEnergy() >
b->clusterRef()->correctedEnergy());
635 setROElectronCluster(RO);
638 LOGDRESSED(
"PFEGammaAlgo") <<
"There are " << refinableObjects.size() <<
" after the unlinking and vetos step." 651 LOGDRESSED(
"PFEGammaAlgo") <<
"creating SC-based proto-object" << std::endl
652 <<
"\tSC at index: " << element->index() <<
" has type: " << element->type()
654 element.setFlag(
false);
677 egobjs.insert(egobjs.end(), fromSC);
685 LOGDRESSED(
"PFEGammaAlgo") <<
"creating GSF-based proto-object" << std::endl
686 <<
"\tGSF at index: " << element->index() <<
" has type: " << element->type()
692 element.setFlag(
false);
705 std::stringstream gsf_err;
706 elementAsGSF->
Dump(gsf_err,
"\t");
708 <<
"Found a GSF track with no seed! This should not happen!" << std::endl
709 << gsf_err.str() << std::endl;
713 element.setFlag(
false);
720 if (dist == 0.001
f) {
722 fromGSF.
brems.push_back(eAsBrem);
733 LOGDRESSED(
"PFEGammaAlgo") <<
"GSF-based proto-object is ECAL driven, merging SC-cand" << std::endl;
737 SeedMatchesToProtoObject sctoseedmatch(fromGSF.
electronSeed);
738 auto objsbegin = egobjs.begin();
739 auto objsend = egobjs.end();
741 auto clusmatch = std::find_if(objsbegin, objsend, sctoseedmatch);
742 if (clusmatch != objsend) {
743 fromGSF.
parentSC = clusmatch->parentSC;
746 egobjs.erase(clusmatch);
751 LOGDRESSED(
"PFEGammaAlgo") <<
"Encountered the known GSF-SC splitting bug " 752 <<
" in PFBlockAlgo! We should really fix this!" << std::endl;
754 std::stringstream gsf_err;
755 elementAsGSF->
Dump(gsf_err,
"\t");
757 <<
"Expected SuperCluster from ECAL driven GSF seed " 758 <<
"was not found in the block!" << std::endl
759 << gsf_err.str() << std::endl;
763 egobjs.insert(egobjs.end(), fromGSF);
770 ecalclusters.clear();
772 LOGVERB(
"PFEGammaAlgo") <<
"Pointer to SC element: 0x" << std::hex << thesc <<
std::dec << std::endl
773 <<
"cleared ecalclusters and ecal2ps!" << std::endl;
778 if (ecalbegin == ecalend && hgcalbegin == hgcalend) {
779 LOGERR(
"PFEGammaAlgo::unwrapSuperCluster()") <<
"There are no ECAL elements in a block with imported SC!" 780 <<
" This is a bug we should fix this!" << std::endl;
787 <<
"SuperCluster pointed to by block element is null!" << std::endl;
789 LOGDRESSED(
"PFEGammaAlgo") <<
"Got a valid super cluster ref! 0x" << std::hex << scref.
get() <<
std::dec << std::endl;
790 const size_t nscclusters = scref->clustersSize();
791 const size_t nscpsclusters = scref->preshowerClustersSize();
792 size_t npfpsclusters = 0;
793 size_t npfclusters = 0;
794 LOGDRESSED(
"PFEGammaAlgo") <<
"Precalculated cluster multiplicities: " << nscclusters <<
' ' << nscpsclusters
796 NotCloserToOther<reco::PFBlockElement::SC, reco::PFBlockElement::ECAL> ecalClustersInSC(
_currentblock, thesc);
797 NotCloserToOther<reco::PFBlockElement::SC, reco::PFBlockElement::HGCAL> hgcalClustersInSC(
_currentblock, thesc);
798 auto ecalfirstnotinsc = std::partition(ecalbegin, ecalend, ecalClustersInSC);
799 auto hgcalfirstnotinsc = std::partition(hgcalbegin, hgcalend, hgcalClustersInSC);
809 std::vector<const ClusterElement*> safePFClusters =
810 is_pf_sc ? std::vector<const ClusterElement*>()
813 if (ecalfirstnotinsc == ecalbegin && hgcalfirstnotinsc == hgcalbegin) {
814 LOGERR(
"PFEGammaAlgo::unwrapSuperCluster()") <<
"No associated block elements to SuperCluster!" 815 <<
" This is a bug we should fix!" << std::endl;
821 if (is_pf_sc && nscclusters != npfclusters) {
822 std::stringstream sc_err;
823 thesc->
Dump(sc_err,
"\t");
825 <<
"The number of found ecal elements (" << nscclusters <<
") in block is not the same as" 826 <<
" the number of ecal PF clusters reported by the PFSuperCluster" 827 <<
" itself (" << npfclusters <<
")! This should not happen!" << std::endl
828 << sc_err.str() << std::endl;
830 for (
auto ecalitr = ecalbegin; ecalitr != ecalfirstnotinsc; ++ecalitr) {
835 if (!is_pf_sc &&
std::find(safePFClusters.begin(), safePFClusters.end(), elemascluster) == safePFClusters.end())
839 ecalclusters.emplace_back(elemascluster,
true);
841 ecalitr->setFlag(
false);
845 auto emplaceresult = ecal2ps.emplace(elemascluster, ClusterMap::mapped_type());
846 if (!emplaceresult.second) {
847 std::stringstream clus_err;
848 elemascluster->
Dump(clus_err,
"\t");
850 <<
"List of pointers to ECAL block elements contains non-unique items!" 851 <<
" This is very bad!" << std::endl
852 <<
"cluster ptr = 0x" << std::hex << elemascluster <<
std::dec << std::endl
853 << clus_err.str() << std::endl;
855 ClusterMap::mapped_type& eslist = emplaceresult.first->second;
859 for (
auto hgcalitr = hgcalbegin; hgcalitr != hgcalfirstnotinsc; ++hgcalitr) {
864 if (!is_pf_sc &&
std::find(safePFClusters.begin(), safePFClusters.end(), elemascluster) == safePFClusters.end())
868 ecalclusters.emplace_back(elemascluster,
true);
870 hgcalitr->setFlag(
false);
887 LOGDRESSED(
"PFEGammaAlgo") <<
" Unwrapped SC has " << npfclusters <<
" ECAL sub-clusters" 888 <<
" and " << npfpsclusters <<
" PreShower layers 1 & 2 clusters!" << std::endl;
896 EEtoPSElement ecalkey(clusptr.
key(), clusptr);
898 std::equal_range(
eetops_->cbegin(),
eetops_->cend(), ecalkey, [](
const EEtoPSElement&
a,
const EEtoPSElement&
b) {
899 return a.first <
b.first;
903 for (
auto pscl = assc_ps.first; pscl != assc_ps.second; ++pscl) {
904 if (pscl->second == temp) {
905 const ClusterElement* pstemp =
docast(
const ClusterElement*, ps1.get());
906 eslist.emplace_back(pstemp);
912 for (
auto pscl = assc_ps.first; pscl != assc_ps.second; ++pscl) {
913 if (pscl->second == temp) {
914 const ClusterElement* pstemp =
docast(
const ClusterElement*, ps2.get());
915 eslist.emplace_back(pstemp);
919 return eslist.size();
926 <<
"Dumping " << refinableObjects.size() <<
" refinable objects for this block: " << std::endl;
927 for (
const auto& ro : refinableObjects) {
928 std::stringstream
info;
929 info <<
"Refinable Object:" << std::endl;
931 info <<
"\tSuperCluster element attached to object:" << std::endl <<
'\t';
932 ro.parentSC->Dump(info,
"\t");
935 if (ro.electronSeed.isNonnull()) {
936 info <<
"\tGSF element attached to object:" << std::endl;
937 ro.primaryGSFs.front()->Dump(info,
"\t");
939 info <<
"firstBrem : " << ro.firstBrem <<
" lateBrem : " << ro.lateBrem
940 <<
" nBrems with cluster : " << ro.nBremsWithClusters << std::endl;
942 if (ro.electronClusters.size() && ro.electronClusters[0]) {
943 info <<
"electron cluster : ";
944 ro.electronClusters[0]->Dump(info,
"\t");
947 info <<
" no electron cluster." << std::endl;
950 if (ro.primaryKFs.size()) {
951 info <<
"\tPrimary KF tracks attached to object: " << std::endl;
952 for (
const auto& kf : ro.primaryKFs) {
953 kf->Dump(info,
"\t");
957 if (ro.secondaryKFs.size()) {
958 info <<
"\tSecondary KF tracks attached to object: " << std::endl;
959 for (
const auto& kf : ro.secondaryKFs) {
960 kf->Dump(info,
"\t");
964 if (ro.brems.size()) {
965 info <<
"\tBrem tangents attached to object: " << std::endl;
966 for (
const auto& brem : ro.brems) {
967 brem->Dump(info,
"\t");
971 if (ro.ecalclusters.size()) {
972 info <<
"\tECAL clusters attached to object: " << std::endl;
973 for (
const auto& clus : ro.ecalclusters) {
974 clus->Dump(info,
"\t");
976 if (ro.ecal2ps.find(clus) != ro.ecal2ps.end()) {
977 for (
const auto& psclus : ro.ecal2ps.at(clus)) {
978 info <<
"\t\t Attached PS Cluster: ";
979 psclus->Dump(info,
"");
992 typedef std::multimap<double, unsigned> MatchedMap;
996 MatchedMap matchedGSFs, matchedECALs;
997 std::unordered_map<GsfTrackElementPtr, MatchedMap> gsf_ecal_cache;
1002 if (matchedGSFs.empty()) {
1006 std::partial_sort(ecalbegin, ecalbegin + 1, ecalend, closestTrackToECAL);
1014 if (dist_sc != -1.0
f) {
1020 if (dist != -1.0
f && closestECAL.flag()) {
1021 bool gsflinked =
false;
1023 for (
const auto& gsfflag :
_splayedblock[reco::PFBlockElement::GSF]) {
1029 if (!gsf_ecal_cache.count(elemasgsf)) {
1030 matchedECALs.clear();
1036 gsf_ecal_cache.emplace(elemasgsf, matchedECALs);
1037 MatchedMap().swap(matchedECALs);
1039 const MatchedMap& ecal_matches = gsf_ecal_cache[elemasgsf];
1040 if (!ecal_matches.empty()) {
1041 if (ecal_matches.begin()->second == closestECAL->index()) {
1047 if (!gsflinked && !inSC) {
1052 const int nexhits = trackref->hitPattern().numberOfLostHits(HitPattern::MISSING_INNER_HITS);
1053 bool fromprimaryvertex =
false;
1056 fromprimaryvertex =
true;
1062 closestECAL.setFlag(
false);
1073 bool check_for_merge =
true;
1074 while (check_for_merge) {
1079 for (
auto it1 = ROs.begin(); it1 != ROs.end(); ++it1) {
1080 auto find_start = it1;
1082 auto has_merge = std::find_if(find_start, ROs.end(), std::bind(testIfROMergableByLink, _1, *it1));
1083 if (has_merge != ROs.end() && it1 != ROs.begin()) {
1089 auto mergestart = ROs.begin();
1091 auto nomerge = std::partition(mergestart, ROs.end(), std::bind(testIfROMergableByLink, _1, thefront));
1092 if (nomerge != mergestart) {
1093 LOGDRESSED(
"PFEGammaAlgo::mergeROsByAnyLink()")
1094 <<
"Found objects " <<
std::distance(mergestart, nomerge) <<
" to merge by links to the front!" << std::endl;
1095 for (
auto roToMerge = mergestart; roToMerge != nomerge; ++roToMerge) {
1098 if (!thefront.
ecalclusters.empty() && !roToMerge->ecalclusters.empty()) {
1099 if (thefront.
ecalclusters.front()->clusterRef()->layer() !=
1100 roToMerge->ecalclusters.front()->clusterRef()->layer()) {
1101 LOGWARN(
"PFEGammaAlgo::mergeROsByAnyLink") <<
"Tried to merge EB and EE clusters! Skipping!";
1102 ROs.push_back(*roToMerge);
1108 thefront.
ecalclusters.end(), roToMerge->ecalclusters.begin(), roToMerge->ecalclusters.end());
1109 thefront.
ecal2ps.insert(roToMerge->ecal2ps.begin(), roToMerge->ecal2ps.end());
1111 thefront.
secondaryKFs.end(), roToMerge->secondaryKFs.begin(), roToMerge->secondaryKFs.end());
1115 if (!thefront.
parentSC && roToMerge->parentSC) {
1116 thefront.
parentSC = roToMerge->parentSC;
1121 thefront.
primaryGSFs.end(), roToMerge->primaryGSFs.begin(), roToMerge->primaryGSFs.end());
1123 thefront.
primaryKFs.end(), roToMerge->primaryKFs.begin(), roToMerge->primaryKFs.end());
1124 thefront.
brems.insert(thefront.
brems.end(), roToMerge->brems.begin(), roToMerge->brems.end());
1127 thefront.
firstBrem = roToMerge->firstBrem;
1128 thefront.
lateBrem = roToMerge->lateBrem;
1130 LOGDRESSED(
"PFEGammaAlgo::mergeROsByAnyLink")
1131 <<
"Need to implement proper merging of two gsf candidates!" << std::endl;
1134 ROs.erase(mergestart, nomerge);
1136 ROs.push_back(ROs.front());
1139 check_for_merge =
false;
1142 LOGDRESSED(
"PFEGammaAlgo::mergeROsByAnyLink()")
1143 <<
"After merging by links there are: " << ROs.size() <<
" refinable EGamma objects!" << std::endl;
1161 NotCloserToOther<reco::PFBlockElement::GSF, reco::PFBlockElement::TRACK> gsfTrackToKFs(
_currentblock, seedtk);
1163 auto notlinked = std::partition(KFbegin, KFend, gsfTrackToKFs);
1165 for (
auto kft = KFbegin; kft != notlinked; ++kft) {
1170 kft->setFlag(
false);
1173 }
else if (elemaskf->
trackType(convType)) {
1174 kft->setFlag(
false);
1190 if (primkf->trackType(convType)) {
1191 throw cms::Exception(
"PFEGammaAlgo::linkRefinableObjectPrimaryKFsToSecondaryKFs()")
1192 <<
"A KF track from conversion has been assigned as a primary!!" << std::endl;
1194 NotCloserToOther<reco::PFBlockElement::TRACK, reco::PFBlockElement::TRACK, true> kfTrackToKFs(
_currentblock,
1197 auto notlinked = std::partition(KFbegin, KFend, kfTrackToKFs);
1199 for (
auto kft = KFbegin; kft != notlinked; ++kft) {
1204 kft->setFlag(
false);
1221 NotCloserToOther<reco::PFBlockElement::GSF, reco::PFBlockElement::ECAL> gsfTracksToECALs(
_currentblock, primgsf);
1223 auto notmatched_blk = std::partition(ECALbegin, ECALend, gsfTracksToECALs);
1225 std::partition(ECALbegin, notmatched_blk, [&primgsf](
auto const&
x) {
return compatibleEoPOut(*
x, *primgsf); });
1228 notmatched_sc = std::partition(
1229 RO.
ecalclusters.begin(), notmatched_sc, [&primgsf](
auto const&
x) {
return compatibleEoPOut(*
x, *primgsf); });
1234 LOGDRESSED(
"PFEGammaAlgo::linkGSFTracktoECAL()") <<
"Found a cluster already in RO by GSF extrapolation" 1235 <<
" at ECAL surface!" << std::endl
1236 << *elemascluster << std::endl;
1241 for (
auto ecal = ECALbegin;
ecal != notmatched_blk; ++
ecal) {
1243 LOGDRESSED(
"PFEGammaAlgo::linkGSFTracktoECAL()") <<
"Found a cluster not already in RO by GSF extrapolation" 1244 <<
" at ECAL surface!" << std::endl
1245 << *elemascluster << std::endl;
1246 if (addPFClusterToROSafe(elemascluster, RO)) {
1249 ecal->setFlag(
false);
1262 NotCloserToOther<reco::PFBlockElement::GSF, reco::PFBlockElement::HCAL> gsfTracksToHCALs(
_currentblock, primgsf);
1263 auto notmatched = std::partition(HCALbegin, HCALend, gsfTracksToHCALs);
1264 for (
auto hcal = HCALbegin;
hcal != notmatched; ++
hcal) {
1267 LOGDRESSED(
"PFEGammaAlgo::linkGSFTracktoECAL()")
1268 <<
"Found an HCAL cluster associated to GSF extrapolation" << std::endl;
1271 hcal->setFlag(
false);
1287 std::vector<FlaggedPtr<const PFClusterElement>>& currentECAL = RO.
ecalclusters;
1290 NotCloserToOther<reco::PFBlockElement::TRACK, reco::PFBlockElement::ECAL> kfTrackToECALs(
_currentblock, kfflagged);
1291 NotCloserToOther<reco::PFBlockElement::GSF, reco::PFBlockElement::ECAL> kfTrackGSFToECALs(
_currentblock, kfflagged);
1293 auto notmatched_sc = std::partition(currentECAL.begin(), currentECAL.end(), kfTrackToECALs);
1295 notmatched_sc = std::partition(currentECAL.begin(), notmatched_sc, kfTrackGSFToECALs);
1296 for (
auto ecalitr = currentECAL.begin(); ecalitr != notmatched_sc; ++ecalitr) {
1300 LOGDRESSED(
"PFEGammaAlgo::linkKFTracktoECAL()") <<
"Found a cluster already in RO by KF extrapolation" 1301 <<
" at ECAL surface!" << std::endl
1302 << *elemascluster << std::endl;
1306 auto notmatched_blk = std::partition(ECALbegin, ECALend, kfTrackToECALs);
1308 notmatched_blk = std::partition(ECALbegin, notmatched_blk, kfTrackGSFToECALs);
1309 for (
auto ecalitr = ECALbegin; ecalitr != notmatched_blk; ++ecalitr) {
1311 if (addPFClusterToROSafe(elemascluster, RO)) {
1313 ecalitr->setFlag(
false);
1315 LOGDRESSED(
"PFEGammaAlgo::linkKFTracktoECAL()") <<
"Found a cluster not in RO by KF extrapolation" 1316 <<
" at ECAL surface!" << std::endl
1317 << *elemascluster << std::endl;
1324 if (RO.
brems.empty())
1328 int lastBremTrajPos = -1;
1329 for (
auto& brem : RO.
brems) {
1330 bool has_clusters =
false;
1331 TrajPos = (brem->indTrajPoint()) - 2;
1334 NotCloserToOther<reco::PFBlockElement::BREM, reco::PFBlockElement::ECAL> BremToECALs(
_currentblock, brem);
1338 auto notmatched_rsc = std::partition(RSCBegin, RSCEnd, BremToECALs);
1339 for (
auto ecal = RSCBegin;
ecal != notmatched_rsc; ++
ecal) {
1340 float deta =
std::abs((*ecal)->clusterRef()->positionREP().eta() - brem->positionAtECALEntrance().eta());
1342 has_clusters =
true;
1343 if (lastBremTrajPos == -1 || lastBremTrajPos < TrajPos) {
1344 lastBremTrajPos = TrajPos;
1346 if (FirstBrem == -1 || TrajPos < FirstBrem) {
1347 FirstBrem = TrajPos;
1350 LOGDRESSED(
"PFEGammaAlgo::linkBremToECAL()") <<
"Found a cluster already in SC linked to brem extrapolation" 1351 <<
" at ECAL surface!" << std::endl;
1356 auto notmatched_block = std::partition(ECALbegin, ECALend, BremToECALs);
1357 for (
auto ecal = ECALbegin;
ecal != notmatched_block; ++
ecal) {
1358 float deta =
std::abs((*ecal)->clusterRef()->positionREP().eta() - brem->positionAtECALEntrance().eta());
1360 has_clusters =
true;
1361 if (lastBremTrajPos == -1 || lastBremTrajPos < TrajPos) {
1362 lastBremTrajPos = TrajPos;
1364 if (FirstBrem == -1 || TrajPos < FirstBrem) {
1366 FirstBrem = TrajPos;
1370 if (addPFClusterToROSafe(elemasclus, RO)) {
1374 ecal->setFlag(
false);
1375 LOGDRESSED(
"PFEGammaAlgo::linkBremToECAL()") <<
"Found a cluster not already associated by brem extrapolation" 1376 <<
" at ECAL surface!" << std::endl;
1393 auto ronotconv = std::partition(BeginROskfs, EndROskfs, [](
auto const&
x) {
return x->trackType(ConvType); });
1395 for (
size_t idx = 0;
idx < convkfs_end; ++
idx) {
1396 auto const& secKFs =
1398 NotCloserToOther<reco::PFBlockElement::TRACK, reco::PFBlockElement::TRACK, true> TracksToTracks(
_currentblock,
1400 auto notmatched = std::partition(KFbegin, KFend, TracksToTracks);
1401 notmatched = std::partition(KFbegin, notmatched, [](
auto const&
x) {
return x->trackType(ConvType); });
1402 for (
auto kf = KFbegin; kf != notmatched; ++kf) {
1415 NotCloserToOther<reco::PFBlockElement::ECAL, reco::PFBlockElement::TRACK, true> ECALToTracks(
_currentblock,
1417 auto notmatchedkf = std::partition(KFbegin, KFend, ECALToTracks);
1418 auto notconvkf = std::partition(KFbegin, notmatchedkf, [](
auto const&
x) {
return x->trackType(ConvType); });
1420 for (
auto kf = KFbegin; kf != notconvkf; ++kf) {
1427 for (
auto kf = notconvkf; kf != notmatchedkf; ++kf) {
1445 NotCloserToOther<reco::PFBlockElement::TRACK, reco::PFBlockElement::ECAL, false> TracksToECALwithCut(
1447 auto notmatched = std::partition(ECALbegin, ECALend, TracksToECALwithCut);
1448 for (
auto ecal = ECALbegin;
ecal != notmatched; ++
ecal) {
1450 if (addPFClusterToROSafe(elemascluster, RO)) {
1453 ecal->setFlag(
false);
1467 for (
auto& RO : ROs) {
1473 if (!RO.primaryGSFs.empty() || !RO.primaryKFs.empty()) {
1478 if (!RO.primaryKFs.empty()) {
1479 cand.
setCharge(RO.primaryKFs[0]->trackRef()->charge());
1484 if (!RO.primaryGSFs.empty()) {
1485 cand.
setCharge(RO.primaryGSFs[0]->GsftrackRef()->chargeMode());
1498 for (
const auto& brem : RO.brems) {
1502 for (
const auto&
ecal : RO.ecalclusters) {
1505 if (RO.ecal2ps.count(clus)) {
1506 for (
auto& psclus : RO.ecal2ps.at(clus)) {
1512 for (
const auto& kf : RO.secondaryKFs) {
1515 bool no_conv_ref =
true;
1516 for (
const auto& convref : convrefs) {
1517 if (convref.isNonnull() && convref.isAvailable()) {
1519 no_conv_ref =
false;
1526 const auto& mvavalmapped = RO.singleLegConversionMvaMap.find(kf);
1529 float mvaval = (mvavalmapped != RO.singleLegConversionMvaMap.end()
1530 ? mvavalmapped->second
1541 float trkTime = 0, trkTimeErr = -1;
1542 if (!RO.primaryGSFs.empty() && RO.primaryGSFs[0]->isTimeValid()) {
1543 trkTime = RO.primaryGSFs[0]->time();
1544 trkTimeErr = RO.primaryGSFs[0]->timeError();
1545 }
else if (!RO.primaryKFs.empty() && RO.primaryKFs[0]->isTimeValid()) {
1546 trkTime = RO.primaryKFs[0]->time();
1547 trkTimeErr = RO.primaryKFs[0]->timeError();
1549 if (trkTimeErr >= 0) {
1550 cand.
setTime(trkTime, trkTimeErr);
1558 const double scE = the_sc.
energy();
1562 egDir = egDir.Unit();
1583 xtra.
setMVA(eleMVAValue);
1604 const double eInGsf = std::hypot(refGsf->pMode(), mEl);
1605 double dEtGsfEcal = 1e6;
1607 const double eneHcalGsf =
1609 return a +
b->clusterRef()->energy();
1614 const double eOutGsf = gsfElement->
Pout().t();
1616 double firstEcalGsfEnergy{0.0};
1617 double otherEcalGsfEnergy{0.0};
1618 double ecalBremEnergy{0.0};
1620 std::vector<const reco::PFCluster*> gsfCluster;
1622 const double cenergy =
ecal->clusterRef()->correctedEnergy();
1625 bool hasbrem =
false;
1626 for (
const auto& brem : ro.
brems) {
1632 ecalBremEnergy += cenergy;
1636 otherEcalGsfEnergy += cenergy;
1638 ecalBremEnergy += cenergy;
1639 if (!(hasgsf || haskf))
1640 otherEcalGsfEnergy += cenergy;
1647 firstEcalGsfEnergy = cref->correctedEnergy();
1648 dEtGsfEcal = cref->positionREP().eta() - etaOutGsf;
1649 gsfCluster.push_back(cref.
get());
1655 float firstBrem{-1.0f};
1656 float earlyBrem{-1.0f};
1657 float lateBrem{-1.0f};
1660 earlyBrem = ro.
firstBrem < 4 ? 1.0f : 0.0f;
1661 lateBrem = ro.
lateBrem == 1 ? 1.0f : 0.0f;
1665 if (firstEcalGsfEnergy > 0.0) {
1666 if (refGsf.isNonnull()) {
1669 const float ptGsf = refGsf->ptMode();
1670 const float etaGsf = refGsf->etaMode();
1672 const double ptModeErrorGsf = refGsf->ptModeError();
1673 float ptModeErrOverPtGsf = (ptModeErrorGsf > 0. ? ptModeErrorGsf / ptGsf : 1.0);
1674 float chi2Gsf = refGsf->normalizedChi2();
1675 float dPtOverPtGsf = (ptGsf - gsfElement->
Pout().pt()) / ptGsf;
1677 float nHitKf = refKf.
isNonnull() ? refKf->hitPattern().trackerLayersWithMeasurement() : 0;
1678 float chi2Kf = refKf.
isNonnull() ? refKf->normalizedChi2() : -0.01;
1681 float eTotPinMode = (firstEcalGsfEnergy + otherEcalGsfEnergy + ecalBremEnergy) / eInGsf;
1682 float eGsfPoutMode = firstEcalGsfEnergy / eOutGsf;
1683 float eTotBremPinPoutMode = (ecalBremEnergy + otherEcalGsfEnergy) / (eInGsf - eOutGsf);
1684 float dEtaGsfEcalClust =
std::abs(dEtGsfEcal);
1685 float logSigmaEtaEta =
std::log(sigmaEtaEta);
1686 float hOverHe = eneHcalGsf / (eneHcalGsf + firstEcalGsfEnergy);
1693 dPtOverPtGsf = std::clamp(dPtOverPtGsf, -0.2
f, 1.0
f);
1694 ptModeErrOverPtGsf =
std::min(ptModeErrOverPtGsf, 0.3
f);
1697 eTotPinMode = std::clamp(eTotPinMode, 0.0
f, 5.0
f);
1698 eGsfPoutMode = std::clamp(eGsfPoutMode, 0.0
f, 5.0
f);
1699 eTotBremPinPoutMode = std::clamp(eTotBremPinPoutMode, 0.0
f, 5.0
f);
1700 dEtaGsfEcalClust =
std::min(dEtaGsfEcalClust, 0.1
f);
1701 logSigmaEtaEta =
std::max(logSigmaEtaEta, -14.0
f);
1743 eTotBremPinPoutMode,
1762 NotCloserToOther<reco::PFBlockElement::ECAL, reco::PFBlockElement::TRACK, true> ECALToTracks(
_currentblock,
1764 auto notmatchedkf = std::partition(KFbegin, KFend, ECALToTracks);
1765 auto notconvkf = std::partition(KFbegin, notmatchedkf, [](
auto const&
x) {
return x->trackType(ConvType); });
1767 for (
auto kf = notconvkf; kf != notmatchedkf; ++kf) {
1785 std::vector<const reco::PFCluster*> bare_ptrs;
1787 double posX(0),
posY(0), posZ(0), rawSCEnergy(0), corrSCEnergy(0), corrPSEnergy(0), PS1_clus_sum(0), PS2_clus_sum(0),
1788 ePS1(0), ePS2(0), ps1_energy(0.0), ps2_energy(0.0);
1789 int condP1(1), condP2(1);
1794 clusptr = edm::refToPtr<reco::PFClusterCollection>(clus->clusterRef());
1795 bare_ptrs.push_back(clusptr.
get());
1797 const double cluseraw = clusptr->
energy();
1800 posX += cluseraw * cluspos.X();
1801 posY += cluseraw * cluspos.Y();
1802 posZ += cluseraw * cluspos.Z();
1804 if (isEE && RO.
ecal2ps.count(clus.get())) {
1807 condP1 = condP2 = 1;
1809 const auto& psclusters = RO.
ecal2ps.at(clus.get());
1811 for (
auto i_ps = psclusters.begin(); i_ps != psclusters.end(); ++i_ps) {
1814 auto const& recH_Frac = psclus->recHitFractions();
1816 switch (psclus->layer()) {
1818 for (
auto const& recH : recH_Frac) {
1819 ESDetId strip1 = recH.recHitRef()->detId();
1824 if (status_p1->getStatusCode() == 0)
1830 for (
auto const& recH : recH_Frac) {
1831 ESDetId strip2 = recH.recHitRef()->detId();
1834 if (status_p2->getStatusCode() == 0)
1844 auto sumPSEnergy = [](
double a,
const ClusterElement*
b,
PFLayer::Layer layer) {
1845 return a + (layer == b->clusterRef()->layer()) * b->clusterRef()->energy();
1849 std::accumulate(psclusters.begin(), psclusters.end(), 0.0, std::bind(sumPSEnergy, _1, _2,
PFLayer::PS1));
1851 std::accumulate(psclusters.begin(), psclusters.end(), 0.0, std::bind(sumPSEnergy, _1, _2,
PFLayer::PS2));
1866 rawSCEnergy += cluseraw;
1867 corrSCEnergy += cluscalibe;
1870 corrPSEnergy += ePS1 + ePS2;
1872 posX /= rawSCEnergy;
1873 posY /= rawSCEnergy;
1874 posZ /= rawSCEnergy;
1879 clusptr = edm::refToPtr<reco::PFClusterCollection>(RO.
ecalclusters.front()->clusterRef());
1886 clusptr = edm::refToPtr<reco::PFClusterCollection>(clus->clusterRef());
1889 for (
auto& hit_and_fraction : hits_and_fractions) {
1893 if (RO.
ecal2ps.count(clus.get())) {
1894 const auto& cluspsassociation = RO.
ecal2ps.at(clus.get());
1898 for (
const auto& pscluselem : cluspsassociation) {
1901 auto found_pscluster =
1908 throw cms::Exception(
"PFECALSuperClusterAlgo::buildSuperCluster")
1909 <<
"Found a PS cluster matched to more than one EE cluster!" << std::endl
1910 << std::hex << psclus.
get() <<
" == " << found_pscluster->get() <<
std::dec << std::endl;
1933 const double Pin_gsf = RO.
primaryGSFs.front()->GsftrackRef()->pMode();
1934 const double gsfOuterEta = RO.
primaryGSFs.front()->positionAtECALEntrance().Eta();
1935 double tot_ecal = 0.0;
1936 std::vector<double> min_brem_dists;
1937 std::vector<double> closest_brem_eta;
1940 tot_ecal +=
ecal->clusterRef()->correctedEnergy();
1943 double min_brem_dist = 5000.0;
1944 double eta = -999.0;
1945 for (
const auto& brem : RO.
brems) {
1947 if (dist < min_brem_dist && dist != -1.0
f) {
1948 min_brem_dist = dist;
1949 eta = brem->positionAtECALEntrance().Eta();
1952 min_brem_dists.push_back(min_brem_dist);
1953 closest_brem_eta.push_back(eta);
1960 const float secpin = (*secd_kf)->trackRef()->p();
1961 bool remove_this_kf =
false;
1964 const float minbremdist = min_brem_dists[bremidx];
1965 const double ecalenergy = (*ecal)->clusterRef()->correctedEnergy();
1966 const double Epin = ecalenergy / secpin;
1967 const double detaGsf =
std::abs(gsfOuterEta - (*ecal)->clusterRef()->positionREP().Eta());
1968 const double detaBrem =
std::abs(closest_brem_eta[bremidx] - (*ecal)->clusterRef()->positionREP().Eta());
1972 const float tkdist =
1978 if (Epin > 3 && kf_matched && tkdist != -1.0
f && tkdist < minbremdist && detaGsf > 0.05 && detaBrem > 0.015) {
1979 double res_with =
std::abs((tot_ecal - Pin_gsf) / Pin_gsf);
1980 double res_without =
std::abs((tot_ecal - ecalenergy - Pin_gsf) / Pin_gsf);
1981 if (res_without < res_with) {
1982 LOGDRESSED(
"PFEGammaAlgo") <<
" REJECTED_RES totenergy " << tot_ecal <<
" Pin_gsf " << Pin_gsf
1983 <<
" cluster to secondary " << ecalenergy <<
" res_with " << res_with
1984 <<
" res_without " << res_without << std::endl;
1985 tot_ecal -= ecalenergy;
1986 remove_this_kf =
true;
1993 if (remove_this_kf) {
2002 bool removeFreeECAL,
2003 bool removeSCEcal) {
2004 std::vector<bool> cluster_in_sc;
2010 bool remove_this_kf =
false;
2011 NotCloserToOther<reco::PFBlockElement::TRACK, reco::PFBlockElement::HCAL> tracksToHCALs(
_currentblock, *secd_kf);
2015 const float secpin = trkRef->p();
2017 for (
auto ecal = ecal_begin;
ecal != ecal_end; ++
ecal) {
2018 const double ecalenergy = (*ecal)->clusterRef()->correctedEnergy();
2021 if (cluster_in_sc.size() < clus_idx + 1) {
2026 cluster_in_sc.push_back(dist != -1.0
f);
2034 auto hcal_matched = std::partition(hcal_begin, hcal_end, tracksToHCALs);
2035 for (
auto hcalclus = hcal_begin; hcalclus != hcal_matched; ++hcalclus) {
2038 const double hcalenergy = clusthcal->
clusterRef()->energy();
2039 const double hpluse = ecalenergy + hcalenergy;
2040 const bool isHoHE = ((hcalenergy / hpluse) > 0.1 && goodTrack);
2041 const bool isHoE = (hcalenergy > ecalenergy);
2042 const bool isPoHE = (secpin > hpluse);
2043 if (cluster_in_sc[clus_idx]) {
2044 if (isHoE || isPoHE) {
2045 LOGDRESSED(
"PFEGammaAlgo") <<
"REJECTED TRACK FOR H/E or P/(H+E), CLUSTER IN SC" 2046 <<
" H/H+E " << (hcalenergy / hpluse) <<
" H/E " << (hcalenergy > ecalenergy)
2047 <<
" P/(H+E) " << (secpin / hpluse) <<
" HCAL ENE " << hcalenergy
2048 <<
" ECAL ENE " << ecalenergy <<
" secPIN " << secpin <<
" Algo Track " 2049 << trkRef->algo() << std::endl;
2050 remove_this_kf =
true;
2054 LOGDRESSED(
"PFEGammaAlgo") <<
"REJECTED TRACK FOR H/H+E, CLUSTER NOT IN SC" 2055 <<
" H/H+E " << (hcalenergy / hpluse) <<
" H/E " << (hcalenergy > ecalenergy)
2056 <<
" P/(H+E) " << (secpin / hpluse) <<
" HCAL ENE " << hcalenergy
2057 <<
" ECAL ENE " << ecalenergy <<
" secPIN " << secpin <<
" Algo Track " 2058 << trkRef->algo() << std::endl;
2059 remove_this_kf =
true;
2065 if (remove_this_kf) {
2074 bool isPrimary =
false;
2080 PFRecTrackRef kfPfRef_fromGsf = (*gsfPfRef).kfPFRecTrackRef();
2085 if (kfref == kfref_fromGsf)
const SuperClusterRef & superClusterRef() const
const math::XYZTLorentzVector & Pout() const
std::vector< PFGSFElement const * > primaryGSFs
Abstract base class for a PFBlock element (track, cluster...)
const math::XYZPoint & position() const
cluster centroid position
CaloCluster_iterator preshowerClustersBegin() const
fist iterator over PreshowerCluster constituents
float evaluateSingleLegMVA(const reco::PFBlockRef &blockref, const reco::Vertex &primaryVtx, unsigned int trackIndex)
reco::PFCandidateEGammaExtraCollection candidateExtras
const reco::GsfTrackRef & GsftrackRef() const
GBRForests const & gbrForests_
static bool overlap(const reco::CaloCluster &sc1, const reco::CaloCluster &sc, float minfrac=0.01, bool debug=false)
bool isNonnull() const
Checks for non-null.
void setSuperClusterRef(reco::SuperClusterRef sc)
set reference to the corresponding supercluster
bool unwrapSuperCluster(const reco::PFBlockElementSuperCluster *, std::vector< FlaggedPtr< const PFClusterElement >> &, ClusterMap &)
Ptr< typename C::value_type > refToPtr(Ref< C, typename C::value_type, refhelper::FindUsingAdvance< C, typename C::value_type > > const &ref)
double correctedEnergy() const
void addHitAndFraction(DetId id, float fraction)
reco::PFBlockRef parentBlock
void Dump(std::ostream &out=std::cout, const char *tab=" ") const override
print the object inside the element
void unlinkRefinableObjectKFandECALWithBadEoverP(ProtoEGObject &)
trackRef_iterator tracks_end() const
last iterator over tracks
static bool isMuon(const reco::PFBlockElement &elt)
void setPositionAtECALEntrance(const math::XYZPointF &pos)
set position at ECAL entrance
void setGsfElectronClusterRef(const reco::PFBlockRef &blk, const reco::PFBlockElementCluster &ref)
set gsf electron cluster ref
const PFClusterRef & clusterRef() const override
void addSingleLegConvTrackRefMva(const std::pair< reco::TrackRef, float > &trackrefmva)
add Single Leg Conversion TrackRef
const PFEGConfigInfo cfg_
void setPreshowerEnergyPlane2(double preshowerEnergy2)
const self & getMap() const
T const * get() const
Returns C++ pointer to the item.
double y() const
y coordinate
void setHadEnergy(float val)
set the had energy. The cluster energies should be entered before
const math::XYZPointF & positionAtECALEntrance() const
const reco::TrackRef & trackRef() const override
void Dump(std::ostream &out=std::cout, const char *tab=" ") const override
print the object inside the element
Geom::Phi< T > phi() const
double pflowPhiWidth() const
bool isPrimaryTrack(const reco::PFBlockElementTrack &KfEl, const reco::PFBlockElementGsfTrack &GsfEl)
bool trackType(TrackType trType) const override
void linkRefinableObjectPrimaryGSFTrackToECAL(ProtoEGObject &)
const GsfPFRecTrackRef & GsftrackRefPF() const
reco::SuperClusterCollection refinedSuperClusters
std::map< unsigned int, Link > LinkData
edm::Ref< TrackExtraCollection > TrackExtraRef
persistent reference to a TrackExtra
std::vector< const PFClusterElement * > electronClusters
unsigned int index
index type
const LinkData & linkData() const
void setSeed(const CaloClusterPtr &r)
list of used xtals by DetId // now inherited by CaloCluster
const math::XYZTLorentzVector & Pin() const
edm::Ptr< CaloCluster > CaloClusterPtr
void linkRefinableObjectBremTangentsToECAL(ProtoEGObject &)
ROOT::Math::PositionVector3D< ROOT::Math::Cartesian3D< float > > XYZPointF
point in space with cartesian internal representation
unsigned int indTrajPoint() const
void find(edm::Handle< EcalRecHitCollection > &hits, DetId thisDet, std::vector< EcalRecHitCollection::const_iterator > &hit, bool debug=false)
reco::PFBlockRef _currentblock
void setGsfTrackRef(const reco::GsfTrackRef &ref)
set gsftrack reference
void setPhiWidth(double pw)
const Point & position() const
position
double pflowEtaWidth() const
const math::XYZPointF & positionAtECALEntrance() const
const std::unique_ptr< const GBRForest > singleLeg_
void linkRefinableObjectECALToSingleLegConv(ProtoEGObject &)
std::vector< PFKFElement const * > primaryKFs
void setCharge(Charge q) final
set electric charge
XYZTLorentzVectorD XYZTLorentzVector
Lorentz vector with cylindrical internal representation using pseudorapidity.
void set_mva_e_pi(float mvaNI)
static double delPhi(const double phi1, const double phi2)
void setEtaWidth(double ew)
void concatenate(CommutativePairs< T > const &other)
Add the pairs from another CommutativePairs to this.
void setSigmaEtaEta(float val)
set the sigmaetaeta
const std::vector< std::pair< DetId, float > > & hitsAndFractions() const
void dumpCurrentRefinableObjects() const
void initializeProtoCands(std::list< ProtoEGObject > &)
void linkRefinableObjectPrimaryKFsToSecondaryKFs(ProtoEGObject &)
bool goodTrack(const reco::Track *pTrack, math::XYZPoint leadPV, trackSelectionParameters parameters, bool debug=false)
double pflowSigmaEtaEta() const
bool fromPFSuperCluster() const
void setCorrectedEnergy(double cenergy)
void addElementInBlock(const reco::PFBlockRef &blockref, unsigned elementIndex)
add an element to the current PFCandidate
void swap(edm::DataFrameContainer &lhs, edm::DataFrameContainer &rhs)
std::vector< PFKFElement const * > secondaryKFs
reco::PFCluster::EEtoPSAssociation EEtoPSAssociation
bool produceEGCandsWithNoSuperCluster
const PFSCElement * parentSC
std::vector< FlaggedPtr< const PFClusterElement > > ecalclusters
bool trackType(TrackType trType) const override
const_iterator find(uint32_t rawId) const
void setEarlyBrem(float val)
set EarlyBrem
Abs< T >::type abs(const T &t)
double z() const
z coordinate
void setGsfTrackPout(const math::XYZTLorentzVector &pout)
set the pout (not trivial to get from the GSF track)
void insert(T const &a, T const &b)
reco::Vertex const * primaryVertex_
double energy() const
cluster energy
std::vector< PFBremElement const * > brems
T const * get() const
Returns C++ pointer to the item.
void linkKFTrackToECAL(PFKFElement const *, ProtoEGObject &)
KFValMap singleLegConversionMvaMap
bool isNull() const
Checks for null.
void Dump(std::ostream &out=std::cout, const char *tab=" ") const override
print the object inside the element
double energy() const
cluster energy
bool isNonnull() const
Checks for non-null.
CommutativePairs< const reco::PFBlockElement * > localMap
void setEcalEnergy(float eeRaw, float eeCorr)
set corrected Ecal energy
reco::PFBlock::LinkData _currentlinks
reco::PFCluster::EEtoPSAssociation const * eetops_
double x() const
x coordinate
double rawEnergy() const
raw uncorrected energy (sum of energies of component BasicClusters)
bool isMuon(const reco::PFBlockElement &)
void fillExtraInfo(const ProtoEGObject &, reco::PFCandidateEGammaExtra &)
bool applyCrackCorrections
bool contains(T const &a, T const &b) const
void setDeltaEta(float val)
set the delta eta
PFEGammaAlgo(const PFEGConfigInfo &, GBRForests const &gbrForests)
void setGsfTrackRef(const reco::GsfTrackRef &ref)
set gsftrack reference
reco::ElectronSeedRef electronSeed
float calculateEleMVA(const ProtoEGObject &, reco::PFCandidateEGammaExtra &) const
XYZVectorD XYZVector
spatial vector with cartesian internal representation
EgammaObjects operator()(const reco::PFBlockRef &block)
void associatedElements(unsigned i, const LinkData &linkData, std::multimap< double, unsigned > &sortedAssociates, reco::PFBlockElement::Type type=PFBlockElement::NONE, LinkTest test=LINKTEST_RECHIT) const
XYZPointD XYZPoint
point in space with cartesian internal representation
void addPreshowerCluster(const CaloClusterPtr &r)
add reference to constituent BasicCluster
reco::PFCandidateCollection candidates
void linkRefinableObjectGSFTracksToKFs(ProtoEGObject &)
void setSuperClusterPFECALRef(reco::SuperClusterRef sc)
set reference to the corresponding supercluster
void addConversionRef(const reco::ConversionRef &convref)
add Conversions from PF
std::vector< Item >::const_iterator const_iterator
double energyEm(const reco::PFCluster &clusterEcal, std::vector< double > &EclustersPS1, std::vector< double > &EclustersPS2, bool crackCorrection=true) const
void addCluster(const CaloClusterPtr &r)
add reference to constituent BasicCluster
void removeOrLinkECALClustersToKFTracks()
Particle reconstructed by the particle flow algorithm.
reco::SuperCluster buildRefinedSuperCluster(const ProtoEGObject &)
EgammaObjects fillPFCandidates(const std::list< ProtoEGObject > &)
void unlinkRefinableObjectKFandECALMatchedToHCAL(ProtoEGObject &, bool removeFreeECAL=false, bool removeSCECAL=false)
std::vector< PFClusterElement const * > hcalClusters
void mergeROsByAnyLink(std::list< ProtoEGObject > &)
std::vector< std::vector< FlaggedPtr< const reco::PFBlockElement > > > _splayedblock
const PFRecTrackRef & trackRefPF() const override
PFEnergyCalibration thePFEnergyCalibration_
void setSuperClusterRef(const reco::SuperClusterRef &scRef)
int attachPSClusters(const PFClusterElement *, ClusterMap::mapped_type &)
void linkRefinableObjectKFTracksToECAL(ProtoEGObject &)
void setKfTrackRef(const reco::TrackRef &ref)
set kf track reference
const std::unique_ptr< const GBRForest > ele_
const CaloClusterPtr & seed() const
seed BasicCluster
void setMVA(float val)
set the result (mostly for debugging)
void linkRefinableObjectSecondaryKFsToECAL(ProtoEGObject &)
void setLateBrem(float val)
set LateBrem
trackRef_iterator tracks_begin() const
first iterator over tracks
void linkRefinableObjectConvSecondaryKFsToSecondaryKFs(ProtoEGObject &)
std::unordered_map< PFClusterElement const *, std::vector< PFClusterElement const * >> ClusterMap
const edm::OwnVector< reco::PFBlockElement > & elements() const
void setTrackRef(const reco::TrackRef &ref)
set track reference
bool next_combination(BidIt n_begin, BidIt n_end, BidIt r_begin, BidIt r_end)
void setTime(float time, float timeError=0.f)
the timing information
void setPdgId(int pdgId) final
void setPreshowerEnergyPlane1(double preshowerEnergy1)
void setP4(const LorentzVector &p4) final
set 4-momentum
const ESChannelStatus * channelStatus_
CaloCluster_iterator preshowerClustersEnd() const
last iterator over PreshowerCluster constituents
void addExtraNonConvTrack(const reco::PFBlockRef &blk, const reco::PFBlockElementTrack &tkref)
track counting for electrons and photons
void setPreshowerEnergy(double preshowerEnergy)
void linkRefinableObjectPrimaryGSFTrackToHCAL(ProtoEGObject &)