7 #include "TDecompChol.h" 24 nSigmaECAL_(nSigmaECAL),
25 nSigmaHCAL_(nSigmaHCAL),
26 nSigmaHFEM_(nSigmaHFEM),
27 nSigmaHFHAD_(nSigmaHFHAD),
30 thepfEnergyCalibrationHF_(thepfEnergyCalibrationHF),
40 muonHCAL_ =
pset.getParameter<std::vector<double>>(
"muon_HCAL");
41 muonECAL_ =
pset.getParameter<std::vector<double>>(
"muon_ECAL");
42 muonHO_ =
pset.getParameter<std::vector<double>>(
"muon_HO");
117 bool primaryVertexFound =
false;
122 primaryVertexFound =
true;
131 auto const&
blocks = *blockHandle;
136 LogTrace(
"PFAlgo|reconstructParticles")
137 <<
"start of function PFAlgo::reconstructParticles, blocks.size()=" <<
blocks.size();
140 std::list<reco::PFBlockRef> hcalBlockRefs;
141 std::list<reco::PFBlockRef> ecalBlockRefs;
142 std::list<reco::PFBlockRef> hoBlockRefs;
143 std::list<reco::PFBlockRef> otherBlockRefs;
145 for (
unsigned i = 0;
i <
blocks.size(); ++
i) {
151 bool singleEcalOrHcal =
false;
154 ecalBlockRefs.push_back(blockref);
155 singleEcalOrHcal =
true;
158 hcalBlockRefs.push_back(blockref);
159 singleEcalOrHcal =
true;
163 hoBlockRefs.push_back(blockref);
164 singleEcalOrHcal =
true;
168 if (!singleEcalOrHcal) {
169 otherBlockRefs.push_back(blockref);
173 LogTrace(
"PFAlgo|reconstructParticles")
174 <<
"# Ecal blocks: " << ecalBlockRefs.size() <<
", # Hcal blocks: " << hcalBlockRefs.size()
175 <<
", # HO blocks: " << hoBlockRefs.size() <<
", # Other blocks: " << otherBlockRefs.size();
181 for (
auto const&
other : otherBlockRefs) {
182 LogTrace(
"PFAlgo|reconstructParticles") <<
"processBlock, Block number " << nblcks++;
186 std::list<reco::PFBlockRef>
empty;
190 for (
auto const&
hcal : hcalBlockRefs) {
191 LogTrace(
"PFAlgo|reconstructParticles") <<
"processBlock, HCAL block number " << hblcks++;
197 for (
auto const&
ecal : ecalBlockRefs) {
198 LogTrace(
"PFAlgo|reconstructParticles") <<
"processBlock, ECAL block number " << eblcks++;
216 LogTrace(
"PFAlgo|reconstructParticles")
217 <<
"end of function PFAlgo::reconstructParticles, pfCandidates_->size()=" <<
pfCandidates_->size();
221 std::vector<bool>& active,
226 LogTrace(
"PFAlgo|egammaFilters") <<
"start of function PFAlgo::egammaFilters(), negmcandidates=" << negmcandidates;
228 for (
unsigned int ieg = 0; ieg < negmcandidates; ++ieg) {
233 PFCandidate::ElementsInBlocks::const_iterator iegfirst = theElements.begin();
234 bool sameBlock =
false;
235 bool isGoodElectron =
false;
236 bool isGoodPhoton =
false;
237 bool isPrimaryElectron =
false;
238 if (iegfirst->first == blockref)
241 LogTrace(
"PFAlgo|egammaFilters") <<
" I am in looping on EGamma Candidates: pt " << (*pfEgmRef).pt()
242 <<
" eta,phi " << (*pfEgmRef).eta() <<
", " << (*pfEgmRef).phi() <<
" charge " 243 << (*pfEgmRef).charge();
245 if ((*pfEgmRef).gsfTrackRef().isNonnull()) {
249 isPrimaryElectron = pfegamma->
isElectron(*gedEleRef);
252 <<
"** Good Electron, pt " << gedEleRef->pt() <<
" eta, phi " << gedEleRef->eta() <<
", " 253 << gedEleRef->phi() <<
" charge " << gedEleRef->charge() <<
" isPrimary " << isPrimaryElectron
255 << (gedEleRef->dr03TkSumPt() + gedEleRef->dr03EcalRecHitSumEt() + gedEleRef->dr03HcalTowerSumEt())
256 <<
" mva_isolated " << gedEleRef->mva_Isolated() <<
" mva_e_pi " << gedEleRef->mva_e_pi();
259 if ((*pfEgmRef).superClusterRef().isNonnull()) {
264 LogTrace(
"PFAlgo|egammaFilters") <<
"** Good Photon, pt " << gedPhoRef->pt() <<
" eta, phi " 265 << gedPhoRef->eta() <<
", " << gedPhoRef->phi() << endl;
270 if (isGoodElectron && isGoodPhoton) {
271 if (isPrimaryElectron)
272 isGoodPhoton =
false;
274 isGoodElectron =
false;
278 if (isGoodElectron) {
282 bool lockTracks =
false;
292 myPFElectron.
setCharge(gedEleRef->charge());
293 myPFElectron.
setP4(gedEleRef->p4());
303 LogTrace(
"PFAlgo|egammaFilters") <<
" PFAlgo: found an electron with NEW EGamma code ";
304 LogTrace(
"PFAlgo|egammaFilters") <<
" myPFElectron: pt " << myPFElectron.
pt() <<
" eta,phi " 305 << myPFElectron.
eta() <<
", " << myPFElectron.
phi() <<
" mva " 306 << myPFElectron.
mva_e_pi() <<
" charge " << myPFElectron.
charge();
308 LogTrace(
"PFAlgo|egammaFilters") <<
" THE BLOCK " << *blockref;
309 for (
auto const& eb : theElements) {
310 active[eb.second] =
false;
311 LogTrace(
"PFAlgo|egammaFilters") <<
" Elements used " << eb.second;
317 for (
auto const& trk : extraTracks) {
318 LogTrace(
"PFAlgo|egammaFilters") <<
" Extra locked track " << trk.second;
319 active[trk.second] =
false;
323 LogTrace(
"PFAlgo|egammaFilters") <<
"Creating PF electron: pt=" << myPFElectron.
pt()
324 <<
" eta=" << myPFElectron.
eta() <<
" phi=" << myPFElectron.
phi();
328 LogTrace(
"PFAlgo|egammaFilters") <<
"PFAlgo: Electron DISCARDED, NOT SAFE FOR JETMET ";
347 myPFPhoton.
setP4(gedPhoRef->p4());
350 LogTrace(
"PFAlgo|egammaFilters") <<
" PFAlgo: found a photon with NEW EGamma code ";
351 LogTrace(
"PFAlgo|egammaFilters") <<
" myPFPhoton: pt " << myPFPhoton.
pt() <<
" eta,phi " << myPFPhoton.
eta()
352 <<
", " << myPFPhoton.
phi() <<
" charge " << myPFPhoton.
charge();
355 LogTrace(
"PFAlgo|egammaFilters") <<
" THE BLOCK " << *blockref;
356 for (
auto const& eb : theElements) {
357 active[eb.second] =
false;
358 LogTrace(
"PFAlgo|egammaFilters") <<
" Elements used " << eb.second;
360 LogTrace(
"PFAlgo|egammaFilters") <<
"Creating PF photon: pt=" << myPFPhoton.
pt() <<
" eta=" << myPFPhoton.
eta()
361 <<
" phi=" << myPFPhoton.
phi();
367 LogTrace(
"PFAlgo|egammaFilters") <<
"end of function PFAlgo::egammaFilters";
371 LogTrace(
"PFAlgo|conversionAlgo") <<
"start of function PFAlgo::conversionAlgo(), elements.size()=" 373 for (
unsigned iEle = 0; iEle <
elements.size(); iEle++) {
375 if (
type == PFBlockElement::TRACK) {
376 LogTrace(
"PFAlgo|conversionAlgo") <<
"elements[" << iEle <<
"].type() == TRACK, active[" << iEle
377 <<
"]=" << active[iEle];
379 active[iEle] =
false;
382 LogTrace(
"PFAlgo|conversionAlgo") <<
"Track is high purity";
387 LogTrace(
"PFAlgo|conversionAlgo") <<
"!trackType(T_FROM_GAMMACONV)";
391 active[iEle] =
false;
393 LogTrace(
"PFAlgo|conversionAlgo") <<
"active[iEle=" << iEle <<
"]=" << active[iEle];
396 LogTrace(
"PFAlgo|conversionAlgo") <<
"end of function PFAlgo::conversionAlgo";
403 std::vector<bool>& active,
404 bool goodTrackDeadHcal,
407 std::multimap<double, unsigned>& ecalElems,
409 LogTrace(
"PFAlgo|recoTracksNotHCAL") <<
"start of function PFAlgo::recoTracksNotHCAL(), now dealing with tracks " 410 "linked to no HCAL clusters. Was HCal active? " 433 if (!ecalElems.empty()) {
434 unsigned thisEcal = ecalElems.begin()->second;
436 bool useCluster =
true;
438 std::multimap<double, unsigned> sortedTracks;
439 block.associatedElements(
441 useCluster = (sortedTracks.begin()->second == iTrack);
444 deficit -= clusterRef->energy();
453 active[iTrack] =
false;
454 LogTrace(
"PFAlgo|recoTracksNotHCAL")
456 <<
" deficit " << deficit <<
" > " <<
nSigmaTRACK_ <<
" x " <<
resol <<
" track pt " << trackRef->pt()
457 <<
" +- " << trackRef->ptError() <<
" layers valid " << trackRef->hitPattern().trackerLayersWithMeasurement()
458 <<
", lost " << trackRef->hitPattern().trackerLayersWithoutMeasurement(HitPattern::TRACK_HITS)
459 <<
", lost outer " << trackRef->hitPattern().trackerLayersWithoutMeasurement(HitPattern::MISSING_OUTER_HITS)
460 <<
", lost inner " << trackRef->hitPattern().trackerLayersWithoutMeasurement(HitPattern::MISSING_INNER_HITS)
461 <<
"(valid fraction " << trackRef->validFraction() <<
")" 462 <<
" chi2/ndf " << trackRef->normalizedChi2() <<
" |dxy| " 465 <<
"is probably a fake (1) --> lock the track";
473 std::vector<unsigned> tmpi;
474 std::vector<unsigned> kTrack;
477 double dpt = trackRef->ptError();
481 double dptRel = dpt / trackRef->pt() * 100;
487 unsigned nHits =
elements[iTrack].trackRef()->hitPattern().trackerLayersWithMeasurement();
488 unsigned int NLostHit = trackRef->hitPattern().trackerLayersWithoutMeasurement(HitPattern::TRACK_HITS);
490 LogTrace(
"PFAlgo|recoTracksNotHCAL") <<
"A track (algo = " << trackRef->algo() <<
") with momentum " 492 << dpt <<
" / " <<
elements[iTrack].trackRef()->eta()
493 <<
" without any link to ECAL/HCAL and with " <<
nHits <<
" (" << NLostHit
494 <<
") hits (lost hits) has been cleaned";
496 active[iTrack] =
false;
502 kTrack.push_back(iTrack);
503 active[iTrack] =
false;
506 if (ecalElems.empty()) {
507 (*pfCandidates_)[tmpi[0]].setEcalEnergy(0., 0.);
508 (*pfCandidates_)[tmpi[0]].setHcalEnergy(0., 0.);
509 (*pfCandidates_)[tmpi[0]].setHoEnergy(0., 0.);
510 (*pfCandidates_)[tmpi[0]].setPs1Energy(0);
511 (*pfCandidates_)[tmpi[0]].setPs2Energy(0);
512 (*pfCandidates_)[tmpi[0]].addElementInBlock(blockref, kTrack[0]);
517 const unsigned int thisEcal = ecalElems.begin()->second;
519 LogTrace(
"PFAlgo|recoTracksNotHCAL") <<
" is associated to " <<
elements[thisEcal];
523 (*pfCandidates_)[tmpi[0]].setEcalEnergy(clusterRef->energy(),
std::min(clusterRef->energy(),
muonECAL_[0]));
524 (*pfCandidates_)[tmpi[0]].setHcalEnergy(0., 0.);
525 (*pfCandidates_)[tmpi[0]].setHoEnergy(0., 0.);
526 (*pfCandidates_)[tmpi[0]].setPs1Energy(0);
527 (*pfCandidates_)[tmpi[0]].setPs2Energy(0);
528 (*pfCandidates_)[tmpi[0]].addElementInBlock(blockref, kTrack[0]);
531 double slopeEcal = 1.;
532 bool connectedToEcal =
false;
533 unsigned iEcal = 99999;
534 double calibEcal = 0.;
535 double calibHcal = 0.;
536 double totalEcal = thisIsAMuon ? -
muonECAL_[0] : 0.;
539 std::multimap<double, unsigned> sortedTracks;
541 LogTrace(
"PFAlgo|recoTracksNotHCAL") <<
"the closest ECAL cluster, id " << thisEcal <<
", has " << sortedTracks.size()
542 <<
" associated tracks, now processing them. ";
544 if (hasDeadHcal && !sortedTracks.empty()) {
546 LogTrace(
"PFAlgo|recoTracksNotHCAL") <<
" the closest track to ECAL " << thisEcal <<
" is " 547 << sortedTracks.begin()->second <<
" (distance " << sortedTracks.begin()->first
549 if (sortedTracks.begin()->second != iTrack) {
550 LogTrace(
"PFAlgo|recoTracksNotHCAL")
551 <<
" the closest track to ECAL " << thisEcal <<
" is " << sortedTracks.begin()->second
552 <<
" which is not the one being processed. Will skip ECAL linking for this track";
553 (*pfCandidates_)[tmpi[0]].setEcalEnergy(0., 0.);
554 (*pfCandidates_)[tmpi[0]].setHcalEnergy(0., 0.);
555 (*pfCandidates_)[tmpi[0]].setHoEnergy(0., 0.);
556 (*pfCandidates_)[tmpi[0]].setPs1Energy(0);
557 (*pfCandidates_)[tmpi[0]].setPs2Energy(0);
558 (*pfCandidates_)[tmpi[0]].addElementInBlock(blockref, kTrack[0]);
561 LogTrace(
"PFAlgo|recoTracksNotHCAL")
562 <<
" the closest track to ECAL " << thisEcal <<
" is " << sortedTracks.begin()->second
563 <<
" which is the one being processed. Will skip ECAL linking for all other track";
564 sortedTracks.clear();
568 for (
auto const& trk : sortedTracks) {
569 unsigned jTrack = trk.second;
576 if (jTrack == iTrack)
585 std::multimap<double, unsigned> sortedECAL;
587 if (sortedECAL.begin()->second != thisEcal)
592 LogTrace(
"PFAlgo|recoTracksNotHCAL") <<
" found track " << jTrack << (thatIsAMuon ?
" (muon) " :
" (non-muon)")
593 <<
", with distance = " << sortedECAL.begin()->first;
596 bool rejectFake =
false;
598 if (!thatIsAMuon && trackRef->ptError() >
ptError_) {
601 double deficit =
trackMomentum + trackRef->p() - clusterRef->energy();
607 kTrack.push_back(jTrack);
608 active[jTrack] =
false;
609 LogTrace(
"PFAlgo|recoTracksNotHCAL")
611 <<
"is probably a fake (2) --> lock the track" 612 <<
"(trackMomentum = " <<
trackMomentum <<
", clusterEnergy = " << clusterRef->energy()
614 <<
" assuming neutralHadronEnergyResolution " 625 LogTrace(
"PFAlgo|recoTracksNotHCAL") <<
"Track momentum increased from " <<
trackMomentum <<
" GeV ";
631 totalEcal =
std::max(totalEcal, 0.);
638 kTrack.push_back(jTrack);
639 active[jTrack] =
false;
642 (*pfCandidates_)[tmpi.back()].setEcalEnergy(clusterRef->energy(),
std::min(clusterRef->energy(),
muonECAL_[0]));
643 (*pfCandidates_)[tmpi.back()].setHcalEnergy(0., 0.);
644 (*pfCandidates_)[tmpi.back()].setHoEnergy(0., 0.);
645 (*pfCandidates_)[tmpi.back()].setPs1Energy(0);
646 (*pfCandidates_)[tmpi.back()].setPs2Energy(0);
647 (*pfCandidates_)[tmpi.back()].addElementInBlock(blockref, kTrack.back());
651 LogTrace(
"PFAlgo|recoTracksNotHCAL") <<
"Loop over all associated ECAL clusters";
653 for (
auto const&
ecal : ecalElems) {
660 if (!active[
index]) {
661 LogTrace(
"PFAlgo|recoTracksNotHCAL") <<
"is not active - ignore ";
668 const bool skip = std::none_of(
669 kTrack.begin(), kTrack.end(), [&](
unsigned iTrack) {
return sortedTracks.begin()->second == iTrack; });
672 LogTrace(
"PFAlgo|recoTracksNotHCAL") <<
"is closer to another track - ignore ";
680 LogTrace(
"PFAlgo|recoTracksNotHCAL") <<
"Ecal cluster with raw energy = " << clusterRef->energy()
681 <<
" linked with distance = " <<
ecal.first;
687 vector<double> ps1Ene{0.};
689 vector<double> ps2Ene{0.};
693 const double ecalEnergy = clusterRef->energy();
694 const double ecalEnergyCalibrated = clusterRef->correctedEnergy();
695 LogTrace(
"PFAlgo|recoTracksNotHCAL") <<
"Corrected ECAL(+PS) energy = " << ecalEnergy;
699 totalEcal += ecalEnergy;
700 const double previousCalibEcal = calibEcal;
701 const double previousSlopeEcal = slopeEcal;
702 calibEcal =
std::max(totalEcal, 0.);
705 trackMomentum, calibEcal, calibHcal, clusterRef->positionREP().Eta(), clusterRef->positionREP().Phi());
707 slopeEcal = calibEcal / totalEcal;
709 LogTrace(
"PFAlgo|recoTracksNotHCAL") <<
"The total calibrated energy so far amounts to = " << calibEcal
710 <<
" (slope = " << slopeEcal <<
")";
716 calibEcal = previousCalibEcal;
717 slopeEcal = previousSlopeEcal;
718 totalEcal = calibEcal / slopeEcal;
722 active[
index] =
false;
725 std::multimap<double, unsigned> assTracks;
729 *clusterRef, ecalEnergyCalibrated)];
730 ecalCand.setEcalEnergy(clusterRef->energy(), ecalEnergyCalibrated);
731 ecalCand.setHcalEnergy(0., 0.);
732 ecalCand.setHoEnergy(0., 0.);
733 ecalCand.setPs1Energy(ps1Ene[0]);
734 ecalCand.setPs2Energy(ps2Ene[0]);
735 ecalCand.addElementInBlock(blockref,
index);
737 if (!assTracks.empty()) {
738 ecalCand.addElementInBlock(blockref, assTracks.begin()->second);
743 ->positionAtECALEntrance();
750 connectedToEcal =
true;
752 active[
index] =
false;
753 for (
unsigned ic : tmpi)
754 (*pfCandidates_)[ic].addElementInBlock(blockref, iEcal);
758 bool bNeutralProduced =
false;
761 if (connectedToEcal) {
803 neutralEnergy /= slopeEcal;
805 (*pfCandidates_)[tmpj].setEcalEnergy(pivotalRef->energy(), neutralEnergy);
806 (*pfCandidates_)[tmpj].setHcalEnergy(0., 0.);
807 (*pfCandidates_)[tmpj].setHoEnergy(0., 0.);
808 (*pfCandidates_)[tmpj].setPs1Energy(0.);
809 (*pfCandidates_)[tmpj].setPs2Energy(0.);
810 (*pfCandidates_)[tmpj].addElementInBlock(blockref, iEcal);
811 bNeutralProduced =
true;
812 for (
unsigned ic = 0; ic < kTrack.size(); ++ic)
813 (*
pfCandidates_)[tmpj].addElementInBlock(blockref, kTrack[ic]);
817 for (
unsigned ic = 0; ic < tmpi.size(); ++ic) {
823 double ecalCal = bNeutralProduced ? (calibEcal - neutralEnergy * slopeEcal) *
fraction : calibEcal *
fraction;
824 double ecalRaw = totalEcal *
fraction;
826 LogTrace(
"PFAlgo|recoTracksNotHCAL")
827 <<
"The fraction after photon supression is " <<
fraction <<
" calibrated ecal = " << ecalCal;
829 (*pfCandidates_)[tmpi[ic]].setEcalEnergy(ecalRaw, ecalCal);
830 (*pfCandidates_)[tmpi[ic]].setHcalEnergy(0., 0.);
831 (*pfCandidates_)[tmpi[ic]].setHoEnergy(0., 0.);
832 (*pfCandidates_)[tmpi[ic]].setPs1Energy(0);
833 (*pfCandidates_)[tmpi[ic]].setPs2Energy(0);
834 (*pfCandidates_)[tmpi[ic]].addElementInBlock(blockref, kTrack[ic]);
840 for (
unsigned ic = 0; ic < tmpi.size(); ++ic) {
841 const PFCandidate& pfc = (*pfCandidates_)[tmpi[ic]];
843 if (eleInBlocks.empty()) {
844 LogTrace(
"PFAlgo|recoTracksNotHCAL") <<
"Single track / Fill element in block! ";
845 (*pfCandidates_)[tmpi[ic]].addElementInBlock(blockref, kTrack[ic]);
848 LogTrace(
"PFAlgo|recoTracksNotHCAL") <<
"end of function PFAlgo::recoTracksNotHCAL";
861 bool isPrimaryTrack =
862 elements[iElement].displacedVertexRef(PFBlockElement::T_TO_DISP)->displacedVertexRef()->isTherePrimaryTracks();
863 if (isPrimaryTrack) {
864 LogTrace(
"PFAlgo|elementLoop") <<
"Primary Track reconstructed alone";
867 (*pfCandidates_)[tmpi].addElementInBlock(blockref, iElement);
888 bool hasDeadHcal =
false;
889 if (!hcalElems.empty() && deadArea[hcalElems.begin()->second]) {
903 bool goodTrackDeadHcal =
false;
912 trackRef->hitPattern().pixelLayersWithMeasurement() >= 3 &&
913 trackRef->hitPattern().trackerLayersWithoutMeasurement(HitPattern::TRACK_HITS) == 0 &&
914 trackRef->hitPattern().trackerLayersWithoutMeasurement(HitPattern::MISSING_INNER_HITS) == 0 &&
915 trackRef->hitPattern().trackerLayersWithoutMeasurement(HitPattern::MISSING_OUTER_HITS) <=
923 goodTrackDeadHcal =
true;
928 <<
" track pt " << trackRef->pt() <<
" +- " << trackRef->ptError() <<
" layers valid " 929 << trackRef->hitPattern().trackerLayersWithMeasurement() <<
", lost " 930 << trackRef->hitPattern().trackerLayersWithoutMeasurement(HitPattern::TRACK_HITS) <<
", lost outer " 931 << trackRef->hitPattern().trackerLayersWithoutMeasurement(HitPattern::MISSING_OUTER_HITS) <<
", lost inner " 932 << trackRef->hitPattern().trackerLayersWithoutMeasurement(HitPattern::MISSING_INNER_HITS) <<
"(valid fraction " 933 << trackRef->validFraction() <<
")" 936 << trackRef->dzError() << (goodTrackDeadHcal ?
" passes " :
" fails ") <<
"quality cuts";
938 return goodTrackDeadHcal;
942 std::multimap<double, unsigned>& ecalElems,
943 std::multimap<double, unsigned>& hcalElems,
944 const std::vector<bool>& active,
946 unsigned int iTrack) {
948 unsigned index = ecalElems.begin()->second;
949 std::multimap<double, unsigned> sortedTracks;
951 LogTrace(
"PFAlgo|elementLoop") <<
"The closest ECAL cluster is linked to " << sortedTracks.size()
952 <<
" tracks, with distance = " << ecalElems.begin()->first;
954 LogTrace(
"PFAlgo|elementLoop") <<
"Looping over sortedTracks";
956 for (
auto const& trk : sortedTracks) {
957 unsigned jTrack = trk.second;
958 LogTrace(
"PFAlgo|elementLoop") <<
"jTrack=" << jTrack;
962 LogTrace(
"PFAlgo|elementLoop") <<
"active[jTrack]=" << active[jTrack];
965 if (jTrack == iTrack)
967 LogTrace(
"PFAlgo|elementLoop") <<
"skipping jTrack=" << jTrack <<
" for same iTrack";
971 std::multimap<double, unsigned> sortedECAL;
973 if (sortedECAL.begin()->second !=
index)
975 LogTrace(
"PFAlgo|elementLoop") <<
" track " << jTrack <<
" with closest ECAL identical ";
978 std::multimap<double, unsigned> sortedHCAL;
980 if (sortedHCAL.empty())
982 LogTrace(
"PFAlgo|elementLoop") <<
" and with an HCAL cluster " << sortedHCAL.begin()->second;
986 block.setLink(iTrack, sortedHCAL.begin()->second, sortedECAL.begin()->first, linkData, PFBlock::LINKTEST_RECHIT);
993 if (!hcalElems.empty())
994 LogTrace(
"PFAlgo|elementLoop") <<
"Track linked back to HCAL due to ECAL sharing with other tracks";
1000 std::vector<bool>& active,
1003 std::vector<bool>& deadArea) {
1004 LogTrace(
"PFAlgo|elementLoop") <<
"start of function PFAlgo::elementLoop, elements.size()" <<
elements.size();
1006 for (
unsigned iEle = 0; iEle <
elements.size(); iEle++) {
1009 LogTrace(
"PFAlgo|elementLoop") <<
"elements[iEle=" << iEle <<
"]=" <<
elements[iEle];
1013 if (ret_decideType == 1) {
1014 LogTrace(
"PFAlgo|elementLoop") <<
"ret_decideType==1, continuing";
1017 LogTrace(
"PFAlgo|elementLoop") <<
"ret_decideType=" << ret_decideType <<
" type=" <<
type;
1021 if (!active[iEle]) {
1022 LogTrace(
"PFAlgo|elementLoop") <<
"Already used by electrons, muons, conversions";
1029 LogTrace(
"PFAlgo|elementLoop") <<
"PFAlgo:processBlock" 1030 <<
" trackIs.size()=" << inds.
trackIs.size()
1031 <<
" ecalIs.size()=" << inds.
ecalIs.size() <<
" hcalIs.size()=" << inds.
hcalIs.size()
1032 <<
" hoIs.size()=" << inds.
hoIs.size() <<
" hfEmIs.size()=" << inds.
hfEmIs.size()
1033 <<
" hfHadIs.size()=" << inds.
hfHadIs.size();
1039 std::multimap<double, unsigned> ecalElems;
1042 std::multimap<double, unsigned> hcalElems;
1045 std::multimap<double, unsigned> hfEmElems;
1046 std::multimap<double, unsigned> hfHadElems;
1050 LogTrace(
"PFAlgo|elementLoop") <<
"\tTrack " << iEle <<
" is linked to " << ecalElems.size() <<
" ecal and " 1051 << hcalElems.size() <<
" hcal and " << hfEmElems.size() <<
" hfEm and " 1052 << hfHadElems.size() <<
" hfHad elements";
1055 for (
const auto& pair : ecalElems) {
1056 LogTrace(
"PFAlgo|elementLoop") <<
"ecal: dist " << pair.first <<
"\t elem " << pair.second;
1058 for (
const auto& pair : hcalElems) {
1059 LogTrace(
"PFAlgo|elementLoop") <<
"hcal: dist " << pair.first <<
"\t elem " << pair.second
1060 << (deadArea[pair.second] ?
" DEAD AREA MARKER" :
"");
1073 if (hcalElems.empty() && !ecalElems.empty() && !hasDeadHcal) {
1084 std::multimap<double, unsigned> gsfElems;
1087 if (hcalElems.empty()) {
1088 LogTrace(
"PFAlgo|elementLoop") <<
"no hcal element connected to track " << iEle;
1092 bool hcalFound =
false;
1093 bool hfhadFound =
false;
1095 LogTrace(
"PFAlgo|elementLoop") <<
"now looping on elements associated to the track: ecalElems";
1099 for (
auto const&
ecal : ecalElems) {
1104 double dist =
ecal.first;
1105 LogTrace(
"PFAlgo|elementLoop") <<
"\telement " <<
elements[
index] <<
" linked with distance = " << dist;
1107 LogTrace(
"PFAlgo|elementLoop") <<
"This ECAL is already used - skip it";
1119 if (!hcalElems.empty())
1120 LogTrace(
"PFAlgo|elementLoop") <<
"\t\tat least one hcal element connected to the track." 1121 <<
" Sparing Ecal cluster for the hcal loop";
1128 if (hcalElems.empty() && hfHadElems.empty()) {
1130 block, linkData,
elements, blockref, active, goodTrackDeadHcal, hasDeadHcal, iEle, ecalElems, trackRef);
1138 for (
auto const&
hcal : hcalElems) {
1145 LogTrace(
"PFAlgo|elementLoop") <<
"\telement " <<
elements[
index] <<
" linked with distance " << dist;
1152 LogTrace(
"PFAlgo|elementLoop") <<
"\t\tclosest hcal cluster, doing nothing";
1160 LogTrace(
"PFAlgo|elementLoop") <<
"\t\tsecondary hcal cluster. unlinking";
1161 block.setLink(iEle,
index, -1., linkData, PFBlock::LINKTEST_RECHIT);
1168 for (
auto const& hfhad : hfHadElems) {
1169 unsigned index = hfhad.second;
1175 LogTrace(
"PFAlgo|elementLoop") <<
"\telement " <<
elements[
index] <<
" linked with distance " << dist;
1182 LogTrace(
"PFAlgo|elementLoop") <<
"\t\tclosest hfhad cluster, doing nothing";
1188 LogTrace(
"PFAlgo|elementLoop") <<
"\t\tsecondary hfhad cluster. unlinking";
1189 block.setLink(iEle,
index, -1., linkData, PFBlock::LINKTEST_RECHIT);
1193 LogTrace(
"PFAlgo|elementLoop") <<
"end of loop over iEle";
1195 LogTrace(
"PFAlgo|elementLoop") <<
"end of function PFAlgo::elementLoop";
1203 std::vector<bool>& active,
1205 std::vector<bool>& deadArea,
1206 unsigned int iEle) {
1208 case PFBlockElement::TRACK:
1211 LogTrace(
"PFAlgo|decideType") <<
"TRACK, stored index, continue";
1216 inds.
ecalIs.push_back(iEle);
1217 LogTrace(
"PFAlgo|decideType") <<
"ECAL, stored index, continue";
1223 LogTrace(
"PFAlgo|decideType") <<
"HCAL DEAD AREA: remember and skip.";
1224 active[iEle] =
false;
1225 deadArea[iEle] =
true;
1228 inds.
hcalIs.push_back(iEle);
1229 LogTrace(
"PFAlgo|decideType") <<
"HCAL, stored index, continue";
1235 inds.
hoIs.push_back(iEle);
1236 LogTrace(
"PFAlgo|decideType") <<
"HO, stored index, continue";
1240 case PFBlockElement::HFEM:
1242 inds.
hfEmIs.push_back(iEle);
1243 LogTrace(
"PFAlgo|decideType") <<
"HFEM, stored index, continue";
1246 case PFBlockElement::HFHAD:
1249 LogTrace(
"PFAlgo|decideType") <<
"HFHAD, stored index, continue";
1255 LogTrace(
"PFAlgo|decideType") <<
"Did not match type to anything, return 0";
1262 std::vector<bool>& active,
1265 LogTrace(
"PFAlgo|createCandidatesHF") <<
"starting function PFAlgo::createCandidatesHF";
1267 bool trackInBlock = !inds.
trackIs.empty();
1271 for (
unsigned iEle = 0; iEle <
elements.size(); iEle++) {
1273 if (
type == PFBlockElement::TRACK) {
1274 trackInBlock =
true;
1289 std::multimap<double, unsigned> sortedTracks;
1290 std::multimap<double, unsigned> sortedTracksActive;
1292 std::multimap<unsigned, std::pair<double, unsigned>> associatedHfEms;
1294 std::multimap<double, std::pair<unsigned, double>> hfemSatellites;
1299 for (
unsigned iHfHad : inds.
hfHadIs) {
1306 sortedTracks.clear();
1307 sortedTracksActive.clear();
1308 associatedHfEms.clear();
1309 hfemSatellites.clear();
1312 block.associatedElements(
1315 LogTrace(
"PFAlgo|createCandidatesHF") <<
"elements[" << iHfHad <<
"]=" <<
elements[iHfHad];
1317 if (sortedTracks.empty()) {
1318 LogTrace(
"PFAlgo|createCandidatesHCF") <<
"\tno associated tracks, keep for later";
1323 active[iHfHad] =
false;
1325 LogTrace(
"PFAlgo|createCandidatesHF") << sortedTracks.size() <<
" associated tracks:";
1327 double totalChargedMomentum = 0.;
1328 double sumpError2 = 0.;
1333 for (
auto const& trk : sortedTracks) {
1334 unsigned iTrack = trk.second;
1337 if (!active[iTrack])
1352 sumpError2 +=
dp *
dp;
1355 sortedTracksActive.emplace(trk);
1358 std::multimap<double, unsigned> sortedHfEms;
1359 block.associatedElements(
1362 LogTrace(
"PFAlgo|createCandidatesHF") <<
"number of HfEm elements linked to this track: " << sortedHfEms.size();
1364 bool connectedToHfEm =
false;
1369 for (
auto const& hfem : sortedHfEms) {
1370 unsigned iHfEm = hfem.second;
1371 double dist = hfem.first;
1374 if (!active[iHfEm]) {
1375 LogTrace(
"PFAlgo|createCandidatesHF") <<
"cluster locked";
1386 std::multimap<double, unsigned> sortedTracksHfEm;
1387 block.associatedElements(
1389 unsigned jTrack = sortedTracksHfEm.begin()->second;
1390 if (jTrack != iTrack)
1394 double hfemEnergy = eclusterRef->energy();
1396 if (!connectedToHfEm) {
1399 connectedToHfEm =
true;
1400 std::pair<unsigned, double> satellite(iHfEm, hfemEnergy);
1401 hfemSatellites.emplace(-1., satellite);
1406 std::pair<unsigned, double> satellite(iHfEm, hfemEnergy);
1407 hfemSatellites.emplace(dist, satellite);
1410 std::pair<double, unsigned> associatedHfEm(distHfEm, iHfEm);
1411 associatedHfEms.emplace(iTrack, associatedHfEm);
1417 double uncalibratedenergyHfHad = hclusterRef->energy();
1418 double energyHfHad = uncalibratedenergyHfHad;
1421 uncalibratedenergyHfHad,
1422 hclusterRef->positionREP().Eta(),
1423 hclusterRef->positionREP().Phi());
1425 double calibFactorHfHad = (uncalibratedenergyHfHad > 0.) ? energyHfHad / uncalibratedenergyHfHad : 1.;
1428 double energyHfEmTmp = 0.;
1429 double uncalibratedenergyHfEmTmp = 0.;
1430 double energyHfEm = 0.;
1431 double uncalibratedenergyHfEm = 0.;
1435 caloResolution *= totalChargedMomentum;
1436 double totalError =
sqrt(caloResolution * caloResolution + sumpError2);
1437 double nsigmaHFEM =
nSigmaHFEM(totalChargedMomentum);
1438 double nsigmaHFHAD =
nSigmaHFHAD(totalChargedMomentum);
1441 if (sortedTracksActive.empty()) {
1443 std::multimap<double, unsigned> sortedHfEms;
1444 std::multimap<double, unsigned> sortedHfEmsActive;
1445 block.associatedElements(
1450 if (!sortedHfEms.empty()) {
1451 for (
auto const& hfem : sortedHfEms) {
1452 unsigned iHfEm = hfem.second;
1456 sortedHfEmsActive.emplace(hfem);
1459 double hfemEnergy = eclusterRef->energy();
1460 uncalibratedenergyHfEm += hfemEnergy;
1461 energyHfEm = uncalibratedenergyHfEm;
1464 uncalibratedenergyHfEm, 0.0, eclusterRef->positionREP().Eta(), eclusterRef->positionREP().Phi());
1466 0.0, uncalibratedenergyHfHad, hclusterRef->positionREP().Eta(), hclusterRef->positionREP().Phi());
1473 (*pfCandidates_)[tmpi].setHcalEnergy(uncalibratedenergyHfHad, energyHfHad);
1474 (*pfCandidates_)[tmpi].setEcalEnergy(uncalibratedenergyHfEm, energyHfEm);
1475 (*pfCandidates_)[tmpi].addElementInBlock(blockref, iHfHad);
1476 for (
auto const& hfem : sortedHfEmsActive) {
1477 unsigned iHfEm = hfem.second;
1478 (*pfCandidates_)[tmpi].addElementInBlock(blockref, iHfEm);
1479 active[iHfEm] =
false;
1486 else if ((energyHfHad - totalChargedMomentum) > nsigmaHFHAD * totalError) {
1487 assert(energyHfEm == 0.);
1489 double energyHfHadExcess =
max(energyHfHad - totalChargedMomentum, 0.);
1490 double uncalibratedenergyHfHadExcess = energyHfHadExcess / calibFactorHfHad;
1492 (*pfCandidates_)[tmpi].setHcalEnergy(uncalibratedenergyHfHadExcess, energyHfHadExcess);
1493 (*pfCandidates_)[tmpi].setEcalEnergy(0., 0.);
1494 (*pfCandidates_)[tmpi].addElementInBlock(blockref, iHfHad);
1495 energyHfHad =
max(energyHfHad - energyHfHadExcess, 0.);
1496 uncalibratedenergyHfHad =
max(uncalibratedenergyHfHad - uncalibratedenergyHfHadExcess, 0.);
1504 for (
auto const& hfemSatellite : hfemSatellites) {
1506 uncalibratedenergyHfEmTmp += std::get<1>(hfemSatellite.second);
1507 energyHfEmTmp = uncalibratedenergyHfEmTmp;
1508 double energyHfHadTmp = uncalibratedenergyHfHad;
1509 unsigned iHfEm = std::get<0>(hfemSatellite.second);
1511 assert(!eclusterRef.isNull());
1514 uncalibratedenergyHfEmTmp, 0.0, eclusterRef->positionREP().Eta(), eclusterRef->positionREP().Phi());
1516 0.0, uncalibratedenergyHfHad, hclusterRef->positionREP().Eta(), hclusterRef->positionREP().Phi());
1519 double caloEnergyTmp = energyHfEmTmp + energyHfHadTmp;
1520 double calibFactorHfEm = (uncalibratedenergyHfEmTmp > 0.) ? energyHfEmTmp / uncalibratedenergyHfEmTmp : 1.;
1524 if (hfemSatellite.first < 0. || caloEnergyTmp < totalChargedMomentum) {
1525 LogTrace(
"PFAlgo|createCandidatesHF")
1526 <<
"\t\t\tactive, adding " << std::get<1>(hfemSatellite.second) <<
" to HFEM energy, and locking";
1527 active[std::get<0>(hfemSatellite.second)] =
false;
1529 if (hfemSatellite.first < 0. && (caloEnergyTmp - totalChargedMomentum) > nsigmaHFEM * totalError) {
1531 double energyHfEmExcess =
max(caloEnergyTmp - totalChargedMomentum, 0.);
1532 double uncalibratedenergyHfEmExcess = energyHfEmExcess / calibFactorHfEm;
1534 (*pfCandidates_)[tmpi].setEcalEnergy(uncalibratedenergyHfEmExcess, energyHfEmExcess);
1535 (*pfCandidates_)[tmpi].setHcalEnergy(0, 0.);
1536 (*pfCandidates_)[tmpi].addElementInBlock(blockref, iHfEm);
1537 energyHfEmTmp =
max(energyHfEmTmp - energyHfEmExcess, 0.);
1538 uncalibratedenergyHfEmTmp =
max(uncalibratedenergyHfEmTmp - uncalibratedenergyHfEmExcess, 0.);
1540 energyHfEm = energyHfEmTmp;
1541 uncalibratedenergyHfEm = uncalibratedenergyHfEmTmp;
1542 energyHfHad = energyHfHadTmp;
1552 for (
auto const& trk : sortedTracksActive) {
1553 unsigned iTrack = trk.second;
1563 active[iTrack] =
false;
1564 (*pfCandidates_)[tmpi].addElementInBlock(blockref, iHfHad);
1565 auto myHfEms = associatedHfEms.equal_range(iTrack);
1566 for (
auto ii = myHfEms.first;
ii != myHfEms.second; ++
ii) {
1567 unsigned iHfEm =
ii->second.second;
1570 (*pfCandidates_)[tmpi].addElementInBlock(blockref, iHfEm);
1573 if (totalChargedMomentum)
1574 frac = trackRef->p() / totalChargedMomentum;
1575 (*pfCandidates_)[tmpi].setEcalEnergy(uncalibratedenergyHfEm *
frac, energyHfEm *
frac);
1576 (*pfCandidates_)[tmpi].setHcalEnergy(uncalibratedenergyHfHad *
frac, energyHfHad *
frac);
1585 for (
unsigned iHfEm = 0; iHfEm <
elements.size(); iHfEm++) {
1587 if (
type == PFBlockElement::HFEM && active[iHfEm]) {
1590 double uncalibratedenergyHF = 0.;
1597 uncalibratedenergyHF, eclusterRef->positionREP().Eta(), eclusterRef->positionREP().Phi());
1600 (*pfCandidates_)[tmpi].setEcalEnergy(uncalibratedenergyHF,
energyHF);
1601 (*pfCandidates_)[tmpi].setHcalEnergy(0., 0.);
1602 (*pfCandidates_)[tmpi].addElementInBlock(blockref, iHfEm);
1603 active[iHfEm] =
false;
1604 LogTrace(
"PFAlgo|createCandidatesHF") <<
"HF EM alone from blocks with tracks! " <<
energyHF;
1618 double uncalibratedenergyHF = 0.;
1620 switch (clusterRef->layer()) {
1627 uncalibratedenergyHF, clusterRef->positionREP().Eta(), clusterRef->positionREP().Phi());
1630 (*pfCandidates_)[tmpi].setEcalEnergy(uncalibratedenergyHF,
energyHF);
1631 (*pfCandidates_)[tmpi].setHcalEnergy(0., 0.);
1632 (*pfCandidates_)[tmpi].setHoEnergy(0., 0.);
1633 (*pfCandidates_)[tmpi].setPs1Energy(0.);
1634 (*pfCandidates_)[tmpi].setPs2Energy(0.);
1635 (*pfCandidates_)[tmpi].addElementInBlock(blockref, inds.
hfEmIs[0]);
1644 uncalibratedenergyHF, clusterRef->positionREP().Eta(), clusterRef->positionREP().Phi());
1647 (*pfCandidates_)[tmpi].setHcalEnergy(uncalibratedenergyHF,
energyHF);
1648 (*pfCandidates_)[tmpi].setEcalEnergy(0., 0.);
1649 (*pfCandidates_)[tmpi].setHoEnergy(0., 0.);
1650 (*pfCandidates_)[tmpi].setPs1Energy(0.);
1651 (*pfCandidates_)[tmpi].setPs2Energy(0.);
1652 (*pfCandidates_)[tmpi].addElementInBlock(blockref, inds.
hfHadIs[0]);
1667 edm::LogError(
"PFAlgo::createCandidatesHF") <<
"Error: 2 elements, but not 1 HFEM and 1 HFHAD";
1674 double energyHfEm = cem->energy();
1675 double energyHfHad = chad->energy();
1676 double uncalibratedenergyHfEm = energyHfEm;
1677 double uncalibratedenergyHfHad = energyHfHad;
1680 uncalibratedenergyHfEm, 0.0,
c0->positionREP().Eta(),
c0->positionREP().Phi());
1682 0.0, uncalibratedenergyHfHad,
c1->positionREP().Eta(),
c1->positionREP().Phi());
1685 cand.setEcalEnergy(uncalibratedenergyHfEm, energyHfEm);
1686 cand.setHcalEnergy(uncalibratedenergyHfHad, energyHfHad);
1687 cand.setHoEnergy(0., 0.);
1688 cand.setPs1Energy(0.);
1689 cand.setPs2Energy(0.);
1690 cand.addElementInBlock(blockref, inds.
hfEmIs[0]);
1691 cand.addElementInBlock(blockref, inds.
hfHadIs[0]);
1692 LogTrace(
"PFAlgo|createCandidatesHF") <<
"HF EM+HAD found ! " << energyHfEm <<
" " << energyHfHad;
1696 <<
"Warning: HF, but n elem different from 1 or 2 or >=3 or !trackIs.empty()";
1699 LogTrace(
"PFAlgo|createCandidateHF") <<
"end of function PFAlgo::createCandidateHF";
1705 std::vector<bool>& active,
1708 std::vector<bool>& deadArea) {
1709 LogTrace(
"PFAlgo|createCandidatesHCAL")
1710 <<
"start of function PFAlgo::createCandidatesHCAL, inds.hcalIs.size()=" << inds.
hcalIs.size();
1714 for (
unsigned iHcal : inds.
hcalIs) {
1719 LogTrace(
"PFAlgo|createCandidatesHCAL") <<
"elements[" << iHcal <<
"]=" <<
elements[iHcal];
1722 std::multimap<double, unsigned> sortedTracks;
1725 std::multimap<unsigned, std::pair<double, unsigned>> associatedEcals;
1727 std::map<unsigned, std::pair<double, double>> associatedPSs;
1729 std::multimap<double, std::pair<unsigned, bool>> associatedTracks;
1732 std::multimap<double, std::tuple<unsigned, ::math::XYZVector, double>>
1734 std::tuple<unsigned, ::math::XYZVector, double> fakeSatellite(iHcal, ::
math::XYZVector(0., 0., 0.), 1.);
1735 ecalSatellites.emplace(-1., fakeSatellite);
1737 std::multimap<unsigned, std::pair<double, unsigned>> associatedHOs;
1749 if (sortedTracks.empty()) {
1750 LogTrace(
"PFAlgo|createCandidatesHCAL") <<
"\tno associated tracks, keep for later";
1755 active[iHcal] =
false;
1762 LogTrace(
"PFAlgo|createCandidatesHCAL") << sortedTracks.size() <<
" associated tracks:";
1764 double totalChargedMomentum = 0;
1765 double sumpError2 = 0.;
1766 double totalHO = 0.;
1767 double totalEcal = 0.;
1768 double totalEcalEGMCalib = 0.;
1769 double totalHcal = hclusterref->energy();
1770 vector<double> hcalP;
1771 vector<double> hcalDP;
1772 vector<unsigned> tkIs;
1773 double maxDPovP = -9999.;
1776 vector<unsigned> chargedHadronsIndices;
1777 vector<unsigned> chargedHadronsInBlock;
1778 double mergedNeutralHadronEnergy = 0;
1779 double mergedPhotonEnergy = 0;
1780 double muonHCALEnergy = 0.;
1781 double muonECALEnergy = 0.;
1782 double muonHCALError = 0.;
1783 double muonECALError = 0.;
1787 std::vector<std::tuple<unsigned, ::math::XYZVector, double>>
1789 double sumEcalClusters = 0;
1791 hclusterref->position().X(), hclusterref->position().Y(), hclusterref->position().Z());
1792 hadronDirection = hadronDirection.Unit();
1796 for (
auto const& trk : sortedTracks) {
1797 unsigned iTrack = trk.second;
1800 if (!active[iTrack])
1812 ::math::XYZVector chargedDirection(chargedPosition.X(), chargedPosition.Y(), chargedPosition.Z());
1813 chargedDirection = chargedDirection.Unit();
1816 std::multimap<double, unsigned> sortedEcals;
1819 LogTrace(
"PFAlgo|createCandidatesHCAL") <<
"number of Ecal elements linked to this track: " << sortedEcals.size();
1822 std::multimap<double, unsigned> sortedHOs;
1826 LogTrace(
"PFAlgo|createCandidatesHCAL")
1827 <<
"PFAlgo : number of HO elements linked to this track: " << sortedHOs.size();
1834 bool thisIsALooseMuon =
false;
1841 LogTrace(
"PFAlgo|createCandidatesHCAL") <<
"This track is identified as a muon - remove it from the stack";
1848 (*pfCandidates_)[tmpi].addElementInBlock(blockref, iTrack);
1849 (*pfCandidates_)[tmpi].addElementInBlock(blockref, iHcal);
1855 bool letMuonEatCaloEnergy =
false;
1857 if (thisIsAnIsolatedMuon) {
1859 double totalCaloEnergy = totalHcal / 1.30;
1861 if (!sortedEcals.empty()) {
1862 iEcal = sortedEcals.begin()->second;
1864 totalCaloEnergy += eclusterref->energy();
1870 if (!sortedHOs.empty()) {
1871 iHO = sortedHOs.begin()->second;
1873 totalCaloEnergy += eclusterref->energy() / 1.30;
1878 letMuonEatCaloEnergy =
true;
1881 if (letMuonEatCaloEnergy)
1882 muonHcal = totalHcal;
1883 double muonEcal = 0.;
1885 if (!sortedEcals.empty()) {
1886 iEcal = sortedEcals.begin()->second;
1888 (*pfCandidates_)[tmpi].addElementInBlock(blockref, iEcal);
1890 if (letMuonEatCaloEnergy)
1891 muonEcal = eclusterref->energy();
1893 if (eclusterref->energy() - muonEcal < 0.2)
1894 active[iEcal] =
false;
1895 (*pfCandidates_)[tmpi].setEcalEnergy(eclusterref->energy(), muonEcal);
1900 if (!sortedHOs.empty()) {
1901 iHO = sortedHOs.begin()->second;
1903 (*pfCandidates_)[tmpi].addElementInBlock(blockref, iHO);
1905 if (letMuonEatCaloEnergy)
1906 muonHO = hoclusterref->energy();
1908 if (hoclusterref->energy() - muonHO < 0.2)
1909 active[iHO] =
false;
1910 (*pfCandidates_)[tmpi].setHcalEnergy(totalHcal, muonHcal);
1911 (*pfCandidates_)[tmpi].setHoEnergy(hoclusterref->energy(), muonHO);
1914 (*pfCandidates_)[tmpi].setHcalEnergy(totalHcal, muonHcal);
1918 if (letMuonEatCaloEnergy) {
1919 muonHCALEnergy += totalHcal;
1921 muonHCALEnergy += muonHO;
1922 muonHCALError += 0.;
1923 muonECALEnergy += muonEcal;
1924 muonECALError += 0.;
1925 photonAtECAL -= muonEcal * chargedDirection;
1926 hadronAtECAL -= totalHcal * chargedDirection;
1927 if (!sortedEcals.empty())
1928 active[iEcal] =
false;
1929 active[iHcal] =
false;
1930 if (
useHO_ && !sortedHOs.empty())
1931 active[iHO] =
false;
1943 photonAtECAL -=
muonECAL_[0] * chargedDirection;
1944 hadronAtECAL -=
muonHCAL_[0] * chargedDirection;
1948 active[iTrack] =
false;
1955 LogTrace(
"PFAlgo|createCandidatesHCAL") <<
"elements[iTrack=" << iTrack <<
"]=" <<
elements[iTrack];
1963 if (thisIsALooseMuon && !thisIsAMuon)
1969 double dpt = trackRef->ptError();
1974 if (isPrimaryOrSecondary)
1977 std::pair<unsigned, bool> tkmuon(iTrack, thisIsALooseMuon);
1978 associatedTracks.emplace(-dpt * blowError, tkmuon);
1982 sumpError2 +=
dp *
dp;
1984 bool connectedToEcal =
false;
1985 if (!sortedEcals.empty()) {
1988 for (
auto const&
ecal : sortedEcals) {
1989 unsigned iEcal =
ecal.second;
1990 double dist =
ecal.first;
1993 if (!active[iEcal]) {
1994 LogTrace(
"PFAlgo|createCandidatesHCAL") <<
"cluster locked";
2005 std::multimap<double, unsigned> sortedTracksEcal;
2006 block.associatedElements(
2008 unsigned jTrack = sortedTracksEcal.begin()->second;
2009 if (jTrack != iTrack)
2014 float ecalEnergyCalibrated = eclusterref->correctedEnergy();
2015 float ecalEnergy = eclusterref->energy();
2017 eclusterref->position().X(), eclusterref->position().Y(), eclusterref->position().Z());
2018 photonDirection = photonDirection.Unit();
2020 if (!connectedToEcal) {
2024 connectedToEcal =
true;
2029 double ecalCalibFactor = (ecalEnergy > 1E-9) ? ecalEnergyCalibrated / ecalEnergy : 1.;
2030 std::tuple<unsigned, ::math::XYZVector, double> satellite(
2031 iEcal, ecalEnergy * photonDirection, ecalCalibFactor);
2032 ecalSatellites.emplace(-1., satellite);
2037 double ecalCalibFactor = (ecalEnergy > 1E-9) ? ecalEnergyCalibrated / ecalEnergy : 1.;
2038 std::tuple<unsigned, ::math::XYZVector, double> satellite(
2039 iEcal, ecalEnergy * photonDirection, ecalCalibFactor);
2040 ecalSatellites.emplace(dist, satellite);
2043 std::pair<double, unsigned> associatedEcal(distEcal, iEcal);
2044 associatedEcals.emplace(iTrack, associatedEcal);
2049 if (
useHO_ && !sortedHOs.empty()) {
2052 for (
auto const&
ho : sortedHOs) {
2053 unsigned iHO =
ho.second;
2054 double distHO =
ho.first;
2058 LogTrace(
"PFAlgo|createCandidatesHCAL") <<
"cluster locked";
2069 std::multimap<double, unsigned> sortedTracksHO;
2070 block.associatedElements(
2072 unsigned jTrack = sortedTracksHO.begin()->second;
2073 if (jTrack != iTrack)
2082 totalHO += hoclusterref->energy();
2083 active[iHO] =
false;
2085 std::pair<double, unsigned> associatedHO(distHO, iHO);
2086 associatedHOs.emplace(iTrack, associatedHO);
2094 totalHcal += totalHO;
2098 double caloEnergy = 0.;
2099 double slopeEcal = 1.0;
2100 double calibEcal = 0.;
2101 double calibHcal = 0.;
2102 hadronDirection = hadronAtECAL.Unit();
2106 caloResolution *= totalChargedMomentum;
2108 caloResolution =
std::sqrt(caloResolution * caloResolution + muonHCALError + muonECALError);
2109 totalEcal -=
std::min(totalEcal, muonECALEnergy);
2110 totalEcalEGMCalib -=
std::min(totalEcalEGMCalib, muonECALEnergy);
2111 totalHcal -=
std::min(totalHcal, muonHCALEnergy);
2112 if (totalEcal < 1E-9)
2114 if (totalHcal < 1E-9)
2121 for (
auto const& ecalSatellite : ecalSatellites) {
2123 double previousCalibEcal = calibEcal;
2124 double previousCalibHcal = calibHcal;
2125 double previousCaloEnergy = caloEnergy;
2126 double previousSlopeEcal = slopeEcal;
2130 sqrt(std::get<1>(ecalSatellite.second).Mag2());
2131 totalEcalEGMCalib +=
sqrt(std::get<1>(ecalSatellite.second).Mag2()) *
2132 std::get<2>(ecalSatellite.second);
2133 photonAtECAL += std::get<1>(ecalSatellite.second) *
2134 std::get<2>(ecalSatellite.second);
2135 calibEcal =
std::max(0., totalEcal);
2136 calibHcal =
std::max(0., totalHcal);
2137 hadronAtECAL = calibHcal * hadronDirection;
2142 hclusterref->positionREP().Eta(),
2143 hclusterref->positionREP().Phi());
2144 caloEnergy = calibEcal + calibHcal;
2146 slopeEcal = calibEcal / totalEcal;
2148 hadronAtECAL = calibHcal * hadronDirection;
2152 if (ecalSatellite.first < 0. || caloEnergy - totalChargedMomentum <= 0.) {
2153 LogTrace(
"PFAlgo|createCandidatesHCAL")
2154 <<
"\t\t\tactive, adding " << std::get<1>(ecalSatellite.second) <<
" to ECAL energy, and locking";
2155 active[std::get<0>(ecalSatellite.second)] =
false;
2156 double clusterEnergy =
2157 sqrt(std::get<1>(ecalSatellite.second).Mag2()) *
2158 std::get<2>(ecalSatellite.second);
2159 if (clusterEnergy > 50) {
2161 sumEcalClusters += clusterEnergy;
2168 totalEcal -=
sqrt(std::get<1>(ecalSatellite.second).Mag2());
2169 totalEcalEGMCalib -=
sqrt(std::get<1>(ecalSatellite.second).Mag2()) * std::get<2>(ecalSatellite.second);
2170 photonAtECAL -= std::get<1>(ecalSatellite.second) * std::get<2>(ecalSatellite.second);
2171 calibEcal = previousCalibEcal;
2172 calibHcal = previousCalibHcal;
2173 hadronAtECAL = previousHadronAtECAL;
2174 slopeEcal = previousSlopeEcal;
2175 caloEnergy = previousCaloEnergy;
2195 if (totalChargedMomentum - caloEnergy >
nSigmaTRACK_ * caloResolution) {
2198 for (
auto const& trk : associatedTracks) {
2200 if (!trk.second.second)
2203 const unsigned int iTrack = trk.second.first;
2205 if (!active[iTrack])
2211 std::multimap<double, unsigned> sortedEcals;
2212 block.associatedElements(
2214 std::multimap<double, unsigned> sortedHOs;
2220 muon.addElementInBlock(blockref, iTrack);
2221 muon.addElementInBlock(blockref, iHcal);
2224 muon.setHcalEnergy(totalHcal, muonHcal);
2225 if (!sortedEcals.empty()) {
2226 const unsigned int iEcal = sortedEcals.begin()->second;
2228 muon.addElementInBlock(blockref, iEcal);
2230 muon.setEcalEnergy(eclusterref->energy(), muonEcal);
2232 if (
useHO_ && !sortedHOs.empty()) {
2233 const unsigned int iHO = sortedHOs.begin()->second;
2235 muon.addElementInBlock(blockref, iHO);
2237 muon.setHcalEnergy(
max(totalHcal - totalHO, 0.0), muonHcal);
2238 muon.setHoEnergy(hoclusterref->energy(), muonHO);
2244 ::math::XYZVector chargedDirection(chargedPosition.X(), chargedPosition.Y(), chargedPosition.Z());
2245 chargedDirection = chargedDirection.Unit();
2255 photonAtECAL -=
muonECAL_[0] * chargedDirection;
2257 hadronAtECAL -=
muonHCAL_[0] * calibHcal / totalHcal * chargedDirection;
2258 caloEnergy = calibEcal + calibHcal;
2264 if (totalHcal > 0.) {
2271 active[iTrack] =
false;
2278 caloResolution *= totalChargedMomentum;
2279 caloResolution =
std::sqrt(caloResolution * caloResolution + muonHCALError + muonECALError);
2284 LogTrace(
"PFAlgo|createCandidatesHCAL") <<
"\tBefore Cleaning ";
2285 LogTrace(
"PFAlgo|createCandidatesHCAL") <<
"\tCompare Calo Energy to total charged momentum ";
2286 LogTrace(
"PFAlgo|createCandidatesHCAL") <<
"\t\tsum p = " << totalChargedMomentum <<
" +- " <<
sqrt(sumpError2);
2287 LogTrace(
"PFAlgo|createCandidatesHCAL") <<
"\t\tsum ecal = " << totalEcal;
2288 LogTrace(
"PFAlgo|createCandidatesHCAL") <<
"\t\tsum hcal = " << totalHcal;
2289 LogTrace(
"PFAlgo|createCandidatesHCAL") <<
"\t\t => Calo Energy = " << caloEnergy <<
" +- " << caloResolution;
2290 LogTrace(
"PFAlgo|createCandidatesHCAL")
2291 <<
"\t\t => Calo Energy- total charged momentum = " << caloEnergy - totalChargedMomentum <<
" +- " 2292 <<
sqrt(sumpError2 + caloResolution * caloResolution);
2296 unsigned corrTrack = 10000000;
2297 double corrFact = 1.;
2300 for (
auto const& trk : associatedTracks) {
2301 const unsigned iTrack = trk.second.first;
2303 if (!active[iTrack])
2307 const double dptRel = fabs(trk.first) / trackref->pt() * 100;
2317 const double wouldBeTotalChargedMomentum = totalChargedMomentum - trackref->p();
2321 if (wouldBeTotalChargedMomentum > caloEnergy) {
2323 LogTrace(
"PFAlgo|createCandidatesHCAL")
2324 <<
"In bad track rejection step dptRel = " << dptRel <<
" dptRel_DispVtx_ = " <<
dptRel_DispVtx_;
2325 LogTrace(
"PFAlgo|createCandidatesHCAL")
2326 <<
"The calo energy would be still smaller even without this track but it is attached to a NI";
2331 active[iTrack] =
false;
2332 totalChargedMomentum = wouldBeTotalChargedMomentum;
2333 LogTrace(
"PFAlgo|createCandidatesHCAL")
2334 <<
"\tElement " <<
elements[iTrack] <<
" rejected (dpt = " << -trk.first
2335 <<
" GeV/c, algo = " << trackref->algo() <<
")";
2341 corrFact = (caloEnergy - wouldBeTotalChargedMomentum) /
elements[trk.second.first].trackRef()->p();
2342 if (trackref->p() * corrFact < 0.05) {
2344 active[iTrack] =
false;
2346 totalChargedMomentum -= trackref->p() * (1. - corrFact);
2347 LogTrace(
"PFAlgo|createCandidatesHCAL")
2348 <<
"\tElement " <<
elements[iTrack] <<
" (dpt = " << -trk.first <<
" GeV/c, algo = " << trackref->algo()
2349 <<
") rescaled by " << corrFact <<
" Now the total charged momentum is " << totalChargedMomentum;
2357 caloResolution *= totalChargedMomentum;
2358 caloResolution =
std::sqrt(caloResolution * caloResolution + muonHCALError + muonECALError);
2364 totalChargedMomentum - caloEnergy >
nSigmaTRACK_ * caloResolution) {
2365 for (
auto const& trk : associatedTracks) {
2366 unsigned iTrack = trk.second.first;
2368 if (!active[iTrack])
2371 double dptRel = fabs(trk.first) / trackref->pt() * 100;
2378 active[iTrack] =
false;
2379 totalChargedMomentum -= trackref->p();
2381 LogTrace(
"PFAlgo|createCandidatesHCAL")
2382 <<
"\tElement " <<
elements[iTrack] <<
" rejected (dpt = " << -trk.first
2383 <<
" GeV/c, algo = " << trackref->algo() <<
")";
2390 caloResolution *= totalChargedMomentum;
2391 caloResolution =
std::sqrt(caloResolution * caloResolution + muonHCALError + muonECALError);
2395 for (
auto const& trk : associatedTracks) {
2396 unsigned iTrack = trk.second.first;
2397 if (!active[iTrack])
2404 (*pfCandidates_)[tmpi].addElementInBlock(blockref, iTrack);
2405 (*pfCandidates_)[tmpi].addElementInBlock(blockref, iHcal);
2407 auto myEcals = associatedEcals.equal_range(iTrack);
2408 for (
auto ii = myEcals.first;
ii != myEcals.second; ++
ii) {
2409 unsigned iEcal =
ii->second.second;
2412 (*pfCandidates_)[tmpi].addElementInBlock(blockref, iEcal);
2416 auto myHOs = associatedHOs.equal_range(iTrack);
2417 for (
auto ii = myHOs.first;
ii != myHOs.second; ++
ii) {
2418 unsigned iHO =
ii->second.second;
2421 (*pfCandidates_)[tmpi].addElementInBlock(blockref, iHO);
2425 if (iTrack == corrTrack) {
2428 (*pfCandidates_)[tmpi].rescaleMomentum(corrFact);
2431 chargedHadronsIndices.push_back(tmpi);
2432 chargedHadronsInBlock.push_back(iTrack);
2433 active[iTrack] =
false;
2435 hcalDP.push_back(
dp);
2438 sumpError2 +=
dp *
dp;
2442 double totalError =
sqrt(sumpError2 + caloResolution * caloResolution);
2445 LogTrace(
"PFAlgo|createCandidatesHCAL")
2446 <<
"\tCompare Calo Energy to total charged momentum " << endl
2447 <<
"\t\tsum p = " << totalChargedMomentum <<
" +- " <<
sqrt(sumpError2) << endl
2448 <<
"\t\tsum ecal = " << totalEcal << endl
2449 <<
"\t\tsum hcal = " << totalHcal << endl
2450 <<
"\t\t => Calo Energy = " << caloEnergy <<
" +- " << caloResolution << endl
2451 <<
"\t\t => Calo Energy- total charged momentum = " << caloEnergy - totalChargedMomentum <<
" +- " 2458 double nsigma =
nSigmaHCAL(totalChargedMomentum, hclusterref->positionREP().Eta());
2460 if (
abs(totalChargedMomentum - caloEnergy) < nsigma * totalError) {
2465 LogTrace(
"PFAlgo|createCandidatesHCAL")
2466 <<
"\t\tcase 1: COMPATIBLE " 2467 <<
"|Calo Energy- total charged momentum| = " <<
abs(caloEnergy - totalChargedMomentum) <<
" < " << nsigma
2468 <<
" x " << totalError;
2470 LogTrace(
"PFAlgo|createCandidatesHCAL") <<
"\t\t\tmax DP/P = " << maxDPovP <<
" less than 0.1: do nothing ";
2472 LogTrace(
"PFAlgo|createCandidatesHCAL")
2473 <<
"\t\t\tmax DP/P = " << maxDPovP <<
" > 0.1: take weighted averages ";
2477 if (maxDPovP > 0.1) {
2480 int nrows = chargedHadronsIndices.size();
2481 TMatrixTSym<double>
a(nrows);
2483 TVectorD
check(nrows);
2484 double sigma2E = caloResolution * caloResolution;
2485 for (
int i = 0;
i < nrows;
i++) {
2486 double sigma2i = hcalDP[
i] * hcalDP[
i];
2487 LogTrace(
"PFAlgo|createCandidatesHCAL")
2488 <<
"\t\t\ttrack associated to hcal " <<
i <<
" P = " << hcalP[
i] <<
" +- " << hcalDP[
i];
2489 a(
i,
i) = 1. / sigma2i + 1. / sigma2E;
2490 b(
i) = hcalP[
i] / sigma2i + caloEnergy / sigma2E;
2491 for (
int j = 0;
j < nrows;
j++) {
2494 a(
i,
j) = 1. / sigma2E;
2499 TDecompChol decomp(
a);
2501 TVectorD
x = decomp.Solve(
b,
ok);
2505 for (
int i = 0;
i < nrows;
i++) {
2507 unsigned ich = chargedHadronsIndices[
i];
2508 double rescaleFactor =
x(
i) / hcalP[
i];
2509 if (rescaleFactor < 0.)
2511 (*pfCandidates_)[ich].rescaleMomentum(rescaleFactor);
2513 LogTrace(
"PFAlgo|createCandidatesHCAL")
2514 <<
"\t\t\told p " << hcalP[
i] <<
" new p " <<
x(
i) <<
" rescale " << rescaleFactor;
2517 edm::LogError(
"PFAlgo::createCandidatesHCAL") <<
"TDecompChol.Solve returned ok=false";
2524 else if (caloEnergy > totalChargedMomentum) {
2529 double eNeutralHadron = caloEnergy - totalChargedMomentum;
2530 double ePhoton = (caloEnergy - totalChargedMomentum) /
2536 if (!sortedTracks.empty()) {
2537 LogTrace(
"PFAlgo|createCandidatesHCAL") <<
"\t\tcase 2: NEUTRAL DETECTION " << caloEnergy <<
" > " << nsigma
2538 <<
"x" << totalError <<
" + " << totalChargedMomentum;
2539 LogTrace(
"PFAlgo|createCandidatesHCAL") <<
"\t\tneutral activity detected: " << endl
2540 <<
"\t\t\t photon = " << ePhoton << endl
2541 <<
"\t\t\tor neutral hadron = " << eNeutralHadron;
2543 LogTrace(
"PFAlgo|createCandidatesHCAL") <<
"\t\tphoton or hadron ?";
2546 if (sortedTracks.empty())
2547 LogTrace(
"PFAlgo|createCandidatesHCAL") <<
"\t\tno track -> hadron ";
2549 LogTrace(
"PFAlgo|createCandidatesHCAL")
2550 <<
"\t\t" << sortedTracks.size() <<
" tracks -> check if the excess is photonic or hadronic";
2555 unsigned maxiEcal = 9999;
2559 LogTrace(
"PFAlgo|createCandidatesHCAL") <<
"loop over sortedTracks.size()=" << sortedTracks.size();
2560 for (
auto const& trk : sortedTracks) {
2561 unsigned iTrack = trk.second;
2569 auto iae = associatedEcals.find(iTrack);
2571 if (iae == associatedEcals.end())
2575 unsigned iEcal = iae->second.second;
2583 double pTrack = trackRef->p();
2584 double eECAL = clusterRef->energy();
2585 double eECALOverpTrack = eECAL / pTrack;
2589 maxEcalRef = clusterRef;
2595 std::vector<reco::PFClusterRef> pivotalClusterRef;
2596 std::vector<unsigned> iPivotal;
2597 std::vector<double> particleEnergy, ecalEnergy, hcalEnergy, rawecalEnergy, rawhcalEnergy;
2598 std::vector<::math::XYZVector> particleDirection;
2602 if (ePhoton < totalEcal || eNeutralHadron - calibEcal < 1E-10) {
2603 if (!maxEcalRef.
isNull()) {
2605 mergedPhotonEnergy = ePhoton;
2609 if (!maxEcalRef.
isNull()) {
2611 mergedPhotonEnergy = totalEcalEGMCalib;
2614 mergedNeutralHadronEnergy = eNeutralHadron - calibEcal;
2617 if (mergedPhotonEnergy > 0) {
2627 sumEcalClusters =
sqrt(photonAtECAL.Mag2());
2630 const double clusterEnergyCalibrated =
2631 sqrt(std::get<1>(pae).Mag2()) *
2634 particleEnergy.push_back(mergedPhotonEnergy * clusterEnergyCalibrated / sumEcalClusters);
2635 particleDirection.push_back(std::get<1>(pae));
2636 ecalEnergy.push_back(mergedPhotonEnergy * clusterEnergyCalibrated / sumEcalClusters);
2637 hcalEnergy.push_back(0.);
2638 rawecalEnergy.push_back(totalEcal);
2639 rawhcalEnergy.push_back(0.);
2640 pivotalClusterRef.push_back(
elements[std::get<0>(pae)].clusterRef());
2641 iPivotal.push_back(std::get<0>(pae));
2645 if (mergedNeutralHadronEnergy > 1.0) {
2654 sumEcalClusters =
sqrt(hadronAtECAL.Mag2());
2657 const double clusterEnergyCalibrated =
2658 sqrt(std::get<1>(pae).Mag2()) *
2661 particleEnergy.push_back(mergedNeutralHadronEnergy * clusterEnergyCalibrated / sumEcalClusters);
2662 particleDirection.push_back(std::get<1>(pae));
2663 ecalEnergy.push_back(0.);
2664 hcalEnergy.push_back(mergedNeutralHadronEnergy * clusterEnergyCalibrated / sumEcalClusters);
2665 rawecalEnergy.push_back(0.);
2666 rawhcalEnergy.push_back(totalHcal);
2667 pivotalClusterRef.push_back(hclusterref);
2668 iPivotal.push_back(iHcal);
2676 for (
unsigned iPivot = 0; iPivot < iPivotal.size(); ++iPivot) {
2677 if (particleEnergy[iPivot] < 0.)
2679 <<
"ALARM = Negative energy for iPivot=" << iPivot <<
", " << particleEnergy[iPivot];
2681 const bool useDirection =
true;
2683 particleEnergy[iPivot],
2685 particleDirection[iPivot].
X(),
2686 particleDirection[iPivot].
Y(),
2687 particleDirection[iPivot].
Z())];
2689 neutral.setEcalEnergy(rawecalEnergy[iPivot], ecalEnergy[iPivot]);
2691 neutral.setHcalEnergy(rawhcalEnergy[iPivot], hcalEnergy[iPivot]);
2692 neutral.setHoEnergy(0., 0.);
2694 if (rawhcalEnergy[iPivot] == 0.) {
2695 neutral.setHcalEnergy(0., 0.);
2696 neutral.setHoEnergy(0., 0.);
2698 neutral.setHcalEnergy(
max(rawhcalEnergy[iPivot] - totalHO, 0.0),
2699 hcalEnergy[iPivot] *
max(1. - totalHO / rawhcalEnergy[iPivot], 0.));
2700 neutral.setHoEnergy(totalHO, totalHO * hcalEnergy[iPivot] / rawhcalEnergy[iPivot]);
2703 neutral.setPs1Energy(0.);
2704 neutral.setPs2Energy(0.);
2705 neutral.set_mva_nothing_gamma(-1.);
2708 neutral.addElementInBlock(blockref, iHcal);
2709 for (
unsigned iTrack : chargedHadronsInBlock) {
2710 neutral.addElementInBlock(blockref, iTrack);
2716 auto myEcals = associatedEcals.equal_range(iTrack);
2717 for (
auto ii = myEcals.first;
ii != myEcals.second; ++
ii) {
2718 unsigned iEcal =
ii->second.second;
2721 neutral.addElementInBlock(blockref, iEcal);
2736 double totalHcalEnergyCalibrated =
std::max(calibHcal - mergedNeutralHadronEnergy, 0.);
2738 double totalEcalEnergyCalibrated =
std::max(calibEcal - mergedPhotonEnergy, 0.);
2743 double chargedHadronsTotalEnergy = 0;
2744 for (
unsigned index : chargedHadronsIndices) {
2749 for (
unsigned index : chargedHadronsIndices) {
2758 fraction * totalHcalEnergyCalibrated * (1. - totalHO / totalHcal));
2766 for (
auto const& ecalSatellite : ecalSatellites) {
2768 unsigned iEcal = std::get<0>(ecalSatellite.second);
2779 active[iEcal] =
false;
2782 std::multimap<double, unsigned> assTracks;
2786 double ecalClusterEnergyCalibrated =
2787 sqrt(std::get<1>(ecalSatellite.second).Mag2()) *
2789 ecalSatellite.second);
2791 cand.setEcalEnergy(eclusterref->energy(), ecalClusterEnergyCalibrated);
2792 cand.setHcalEnergy(0., 0.);
2793 cand.setHoEnergy(0., 0.);
2794 cand.setPs1Energy(associatedPSs[iEcal].
first);
2795 cand.setPs2Energy(associatedPSs[iEcal].
second);
2796 cand.addElementInBlock(blockref, iEcal);
2797 cand.addElementInBlock(blockref, sortedTracks.begin()->second);
2799 if (fabs(eclusterref->energy() -
sqrt(std::get<1>(ecalSatellite.second).Mag2())) > 1
e-3 ||
2800 fabs(eclusterref->correctedEnergy() - ecalClusterEnergyCalibrated) > 1
e-3)
2802 <<
"ecalCluster vs ecalSatellites look inconsistent (eCluster E, calibE, ecalSatellite E, calib E): " 2803 << eclusterref->energy() <<
" " << eclusterref->correctedEnergy() <<
" " 2804 <<
sqrt(std::get<1>(ecalSatellite.second).Mag2()) <<
" " << ecalClusterEnergyCalibrated;
2810 LogTrace(
"PFAlgo|createCandidatesHCAL") <<
"end of function PFAlgo::createCandidatesHCAL";
2816 std::vector<bool>& active,
2819 std::vector<bool>& deadArea) {
2821 LogTrace(
"PFAlgo|createCandidatesHCALUnlinked")
2822 <<
"start of function PFAlgo::createCandidatesHCALUnlinked, hcalIs.size()=" << inds.
hcalIs.size();
2826 for (
unsigned iHcal : inds.
hcalIs) {
2828 std::vector<unsigned> ecalRefs;
2829 std::vector<unsigned> hoRefs;
2833 if (!active[iHcal]) {
2834 LogTrace(
"PFAlgo|createCandidatesHCALUnlinked") <<
"not active " << iHcal;
2839 std::multimap<double, unsigned> ecalElems;
2843 float totalEcal = 0.;
2846 for (
auto const&
ecal : ecalElems) {
2847 unsigned iEcal =
ecal.second;
2848 double dist =
ecal.first;
2875 std::multimap<double, unsigned> hcalElems;
2878 const bool isClosest = std::none_of(hcalElems.begin(), hcalElems.end(), [&](
auto const&
hcal) {
2879 return active[
hcal.second] &&
hcal.first < dist;
2886 LogTrace(
"PFAlgo|createCandidatesHCALUnlinked")
2887 <<
"\telement " <<
elements[iEcal] <<
" linked with dist " << dist;
2888 LogTrace(
"PFAlgo|createCandidatesHCALUnlinked") <<
"Added to HCAL cluster to form a neutral hadron";
2895 double ecalEnergy = eclusterRef->energy();
2897 totalEcal += ecalEnergy;
2898 if (ecalEnergy > ecalMax) {
2899 ecalMax = ecalEnergy;
2900 eClusterRef = eclusterRef;
2903 ecalRefs.push_back(iEcal);
2904 active[iEcal] =
false;
2909 double totalHO = 0.;
2913 std::multimap<double, unsigned> hoElems;
2921 for (
auto const&
ho : hoElems) {
2922 unsigned iHO =
ho.second;
2923 double dist =
ho.first;
2935 std::multimap<double, unsigned> hcalElems;
2938 const bool isClosest = std::none_of(hcalElems.begin(), hcalElems.end(), [&](
auto const&
hcal) {
2939 return active[
hcal.second] &&
hcal.first < dist;
2947 LogTrace(
"PFAlgo|createCandidatesHCALUnlinked")
2948 <<
"\telement " <<
elements[iHO] <<
" linked with dist " << dist;
2949 LogTrace(
"PFAlgo|createCandidatesHCALUnlinked") <<
"Added to HCAL cluster to form a neutral hadron";
2957 hoclusterRef->energy();
2959 totalHO += hoEnergy;
2960 if (hoEnergy > hoMax) {
2962 hoClusterRef = hoclusterRef;
2966 hoRefs.push_back(iHO);
2967 active[iHO] =
false;
2976 double totalHcal = hclusterRef->energy();
2979 totalHcal += totalHO;
2982 double calibEcal = totalEcal > 0. ? totalEcal : 0.;
2983 double calibHcal =
std::max(0., totalHcal);
2985 calibEcal = totalEcal;
2988 -1., calibEcal, calibHcal, hclusterRef->positionREP().Eta(), hclusterRef->positionREP().Phi());
2993 cand.setEcalEnergy(totalEcal, calibEcal);
2995 cand.setHcalEnergy(totalHcal, calibHcal);
2996 cand.setHoEnergy(0., 0.);
2998 cand.setHcalEnergy(
max(totalHcal - totalHO, 0.0), calibHcal * (1. - totalHO / totalHcal));
2999 cand.setHoEnergy(totalHO, totalHO * calibHcal / totalHcal);
3001 cand.setPs1Energy(0.);
3002 cand.setPs2Energy(0.);
3003 cand.addElementInBlock(blockref, iHcal);
3004 for (
auto const& ec : ecalRefs)
3005 cand.addElementInBlock(blockref, ec);
3006 for (
auto const&
ho : hoRefs)
3007 cand.addElementInBlock(blockref,
ho);
3015 std::vector<bool>& active,
3018 std::vector<bool>& deadArea) {
3019 LogTrace(
"PFAlgo|createCandidatesECAL")
3020 <<
"start of function PFAlgo::createCandidatesECAL(), ecalIs.size()=" << inds.
ecalIs.size();
3026 for (
unsigned i = 0;
i < inds.
ecalIs.size();
i++) {
3027 unsigned iEcal = inds.
ecalIs[
i];
3029 LogTrace(
"PFAlgo|createCandidatesECAL") <<
"elements[" << iEcal <<
"]=" <<
elements[iEcal];
3031 if (!active[iEcal]) {
3032 LogTrace(
"PFAlgo|createCandidatesECAL") <<
"iEcal=" << iEcal <<
" not active";
3042 active[iEcal] =
false;
3044 float ecalEnergy = clusterref->correctedEnergy();
3046 double particleEnergy = ecalEnergy;
3050 cand.setEcalEnergy(clusterref->energy(), ecalEnergy);
3051 cand.setHcalEnergy(0., 0.);
3052 cand.setHoEnergy(0., 0.);
3053 cand.setPs1Energy(0.);
3054 cand.setPs2Energy(0.);
3055 cand.addElementInBlock(blockref, iEcal);
3058 LogTrace(
"PFAlgo|createCandidatesECAL") <<
"end of function PFALgo::createCandidatesECAL";
3062 std::list<reco::PFBlockRef>& hcalBlockRefs,
3063 std::list<reco::PFBlockRef>& ecalBlockRefs,
3068 LogTrace(
"PFAlgo|processBlock") <<
"start of function PFAlgo::processBlock, block=" <<
block;
3076 vector<bool> active(
elements.size(),
true);
3080 std::vector<reco::PFCandidate> tempElectronCandidates;
3081 tempElectronCandidates.clear();
3114 vector<bool> deadArea(
elements.size(),
false);
3123 if (!(inds.hfEmIs.empty() && inds.hfHadIs.empty())) {
3125 if (inds.hcalIs.empty() && inds.ecalIs.empty())
3128 <<
"Block contains HF clusters, and also contains ECAL or HCAL clusters. Continue.\n" 3137 LogTrace(
"PFAlgo|processBlock") <<
"end of function PFAlgo::processBlock";
3152 double pz =
track.pz();
3155 LogTrace(
"PFAlgo|reconstructTrack") <<
"Reconstructing PF candidate from track of pT = " <<
track.pt()
3156 <<
" eta = " <<
track.eta() <<
" phi = " <<
track.phi() <<
" px = " <<
px 3157 <<
" py = " <<
py <<
" pz = " << pz <<
" energy = " <<
energy;
3165 <<
", pt=" << momentum.pt() <<
", eta=" << momentum.eta()
3166 <<
", phi=" << momentum.phi();
3171 pfCandidates_->back().setPositionAtECALEntrance(eltTrack->positionAtECALEntrance());
3183 if ((!
isMuon) && isFromDisp) {
3184 double dpt = trackRef->ptError();
3185 double dptRel = dpt / trackRef->pt() * 100;
3190 LogTrace(
"PFAlgo|reconstructTrack")
3191 <<
"Not refitted px = " <<
px <<
" py = " <<
py <<
" pz = " << pz <<
" energy = " <<
energy;
3195 reco::Track trackRefit = vRef->refittedTrack(trackRef);
3198 trackRefit.
px(), trackRefit.
py(), trackRefit.
pz(),
sqrt(trackRefit.
p() * trackRefit.
p() + 0.13957 * 0.13957));
3199 LogTrace(
"PFAlgo|reconstructTrack")
3200 <<
"Refitted px = " <<
px <<
" py = " <<
py <<
" pz = " << pz <<
" energy = " <<
energy;
3221 double particleEnergy,
3226 LogTrace(
"PFAlgo|reconstructCluster") <<
"start of function PFAlgo::reconstructCluster, cluster=" << cluster
3227 <<
"particleEnergy=" << particleEnergy <<
"useDirection=" << useDirection
3228 <<
"particleX=" << particleX <<
"particleY=" << particleY
3229 <<
"particleZ=" << particleZ;
3239 switch (cluster.
layer()) {
3262 cluster.
position().Y() - vertexPos.Y(),
3263 cluster.
position().Z() - vertexPos.Z());
3265 particleX *
factor - vertexPos.X(), particleY *
factor - vertexPos.Y(), particleZ *
factor - vertexPos.Z());
3270 clusterPos = useDirection ? particleDirection.Unit() : clusterPos.Unit();
3271 clusterPos *= particleEnergy;
3277 ROOT::Math::LorentzVector<ROOT::Math::PxPyPzM4D<double>> momentum(
3278 clusterPos.X(), clusterPos.Y(), clusterPos.Z(),
mass);
3288 switch (cluster.
layer()) {
3309 <<
", pt=" <<
tmp.pt() <<
", eta=" <<
tmp.eta() <<
", phi=" <<
tmp.phi();
3332 std::array<double, 7> energyPerDepth;
3333 std::fill(energyPerDepth.begin(), energyPerDepth.end(), 0.0);
3335 const auto&
hit = *hitRefAndFrac.recHitRef();
3337 if (
hit.depth() == 0) {
3341 if (
hit.depth() < 1 ||
hit.depth() > 7) {
3342 throw cms::Exception(
"CorruptData") <<
"Bogus depth " <<
hit.depth() <<
" at detid " <<
hit.detId() <<
"\n";
3344 energyPerDepth[
hit.depth() - 1] += hitRefAndFrac.fraction() *
hit.energy();
3347 double sum = std::accumulate(energyPerDepth.begin(), energyPerDepth.end(), 0.);
3348 std::array<float, 7> depthFractions;
3350 for (
unsigned int i = 0;
i < depthFractions.size(); ++
i) {
3351 depthFractions[
i] = energyPerDepth[
i] / sum;
3354 std::fill(depthFractions.begin(), depthFractions.end(), 0.f);
3356 cand.setHcalDepthEnergyFractions(depthFractions);
3363 clusterEnergyHCAL =
std::max(clusterEnergyHCAL, 1.);
3365 double resol = fabs(
eta) < 1.48 ?
sqrt(1.02 * 1.02 / clusterEnergyHCAL + 0.065 * 0.065)
3366 :
sqrt(1.20 * 1.20 / clusterEnergyHCAL + 0.028 * 0.028);
3380 clusterEnergyHF =
std::max(clusterEnergyHF, 1.);
3404 out <<
"====== Particle Flow Algorithm ======= ";
3406 out <<
"nSigmaECAL_ " <<
algo.nSigmaECAL_ << endl;
3407 out <<
"nSigmaHCAL_ " <<
algo.nSigmaHCAL_ << endl;
3408 out <<
"nSigmaHFEM_ " <<
algo.nSigmaHFEM_ << endl;
3409 out <<
"nSigmaHFHAD_ " <<
algo.nSigmaHFHAD_ << endl;
3411 out <<
algo.calibration_ << endl;
3413 out <<
"reconstructed particles: " << endl;
3415 if (!
algo.pfCandidates_.get()) {
3416 out <<
"candidates already transfered" << endl;
3419 for (
auto const&
c : *
algo.pfCandidates_)
3430 std::vector<bool>& active,
3431 std::vector<double>& psEne) {
3438 std::multimap<double, unsigned> sortedPS;
3442 double totalPS = 0.;
3443 for (
auto const& ps : sortedPS) {
3445 unsigned iPS = ps.second;
3453 std::multimap<double, unsigned> sortedECAL;
3455 unsigned jEcal = sortedECAL.begin()->second;
3461 assert(pstype == psElementType);
3464 totalPS += psclusterref->energy();
3465 psEne[0] += psclusterref->energy();
3466 active[iPS] =
false;
3476 bool bPrimary = (
order.find(
"primary") != string::npos);
3477 bool bSecondary = (
order.find(
"secondary") != string::npos);
3478 bool bAll = (
order.find(
"all") != string::npos);
3483 if (bPrimary && isToDisp)
3485 if (bSecondary && isFromDisp)
3487 if (bAll && (isToDisp || isFromDisp))
3504 std::vector<unsigned int> pfCandidatesToBeRemoved;
3510 double met2 = metX * metX + metY * metY;
3515 double metXCor = metX;
3516 double metYCor = metY;
3517 double sumetCor = sumet;
3518 double met2Cor = met2;
3520 double deltaPhiPt = 100.;
3522 unsigned iCor = 1E9;
3526 double metReduc = -1.;
3540 const bool skip = std::any_of(
3541 pfCandidatesToBeRemoved.begin(), pfCandidatesToBeRemoved.end(), [&](
unsigned int j) {
return i ==
j; });
3552 double metXInt = metX - pfc.
px();
3553 double metYInt = metY - pfc.
py();
3554 double sumetInt = sumet - pfc.
pt();
3555 double met2Int = metXInt * metXInt + metYInt * metYInt;
3556 if (met2Int < met2Cor) {
3559 metReduc = (met2 - met2Int) / met2Int;
3561 sumetCor = sumetInt;
3562 significanceCor =
std::sqrt(met2Cor / sumetCor);
3569 pfCandidatesToBeRemoved.push_back(iCor);
3584 for (
unsigned int toRemove : pfCandidatesToBeRemoved) {
3585 edm::LogInfo(
"PFAlgo|postCleaning") <<
"Removed : " << (*pfCandidates_)[toRemove];
3587 (*pfCandidates_)[toRemove].rescaleMomentum(1E-6);
3597 if (cleanedHits.empty())
3604 std::vector<unsigned int> hitsToBeAdded;
3610 double met2 = metX * metX + metY * metY;
3611 double met2_Original = met2;
3615 double metXCor = metX;
3616 double metYCor = metY;
3617 double sumetCor = sumet;
3618 double met2Cor = met2;
3620 unsigned iCor = 1E9;
3624 double metReduc = -1.;
3626 for (
unsigned i = 0;
i < cleanedHits.size(); ++
i) {
3629 double px =
hit.energy() *
hit.position().
x() / length;
3630 double py =
hit.energy() *
hit.position().
y() / length;
3635 for (
unsigned int hitIdx : hitsToBeAdded) {
3645 double metXInt = metX +
px;
3646 double metYInt = metY +
py;
3647 double sumetInt = sumet +
pt;
3648 double met2Int = metXInt * metXInt + metYInt * metYInt;
3651 if (met2Int < met2Cor) {
3654 metReduc = (met2 - met2Int) / met2Int;
3656 sumetCor = sumetInt;
3665 hitsToBeAdded.push_back(iCor);
3678 LogTrace(
"PFAlgo|checkCleaning") << hitsToBeAdded.size() <<
" hits were re-added ";
3681 LogTrace(
"PFAlgo|checkCleaning") <<
"Added after cleaning check : ";
3682 for (
unsigned int hitIdx : hitsToBeAdded) {
const math::XYZPoint & position() const
cluster centroid position
void set_dnn_e_sigIsolated(float mva)
bool checkHasDeadHcal(const std::multimap< double, unsigned > &hcalElems, const std::vector< bool > &deadArea)
edm::Ref< PFBlockCollection > PFBlockRef
persistent reference to PFCluster objects
Abstract base class for a PFBlock element (track, cluster...)
static bool isIsolatedMuon(const reco::PFBlockElement &elt)
float goodTrackDeadHcal_dxy_
std::vector< double > muonHCAL_
Variables for muons and fakes.
T getParameter(std::string const &) const
ParticleType
particle types
RefToBase< value_type > refAt(size_type i) const
double pt() const final
transverse momentum
std::vector< unsigned > hoIs
bool checkGoodTrackDeadHcal(const reco::TrackRef &trackRef, bool hasDeadHcal)
const double nSigmaHFEM_
number of sigma to judge energy excess in HF
double z() const
z coordinate
void set_mva_nothing_gamma(float mva)
set mva for gamma detection
bool isMuon(const Candidate &part)
Particle flow cluster, see clustering algorithm in PFClusterAlgo.
bool isPrimary(const SimTrack &simTrk, const PSimHit *simHit)
static bool isMuon(const reco::PFBlockElement &elt)
const double nSigmaHCAL_
number of sigma to judge energy excess in HCAL
std::unique_ptr< reco::PFCandidateCollection > pfCandidates_
unsigned reconstructCluster(const reco::PFCluster &cluster, double particleEnergy, bool useDirection=false, double particleX=0., double particleY=0., double particleZ=0.)
ret
prodAgent to be discontinued
const Point & position() const
position
void elementLoop(const reco::PFBlock &block, reco::PFBlock::LinkData &linkData, const edm::OwnVector< reco::PFBlockElement > &elements, std::vector< bool > &active, const reco::PFBlockRef &blockref, ElementIndices &inds, std::vector< bool > &deadArea)
double px() const
x coordinate of momentum vector
bool useProtectionsForJetMET_
const std::vector< double > resolHF_square_
double p() const
momentum vector magnitude
float goodPixelTrackDeadHcal_minEta_
void set_dnn_gamma(float mva)
void set_dnn_e_bkgNonIsolated(float mva)
double py() const
y coordinate of momentum vector
bool isNonnull() const
Checks for non-null.
const std::vector< reco::PFRecHitFraction > & recHitFractions() const
vector of rechit fractions
std::vector< Vertex > VertexCollection
collection of Vertex objects
std::map< unsigned int, Link > LinkData
std::vector< PFRecHit > PFRecHitCollection
collection of PFRecHit objects
const edm::ValueMap< reco::PhotonRef > * valueMapGedPhotons_
void checkCleaning(const reco::PFRecHitCollection &cleanedHF)
Check HF Cleaning.
const double nSigmaEConstHCAL
reco::PFCandidateCollection pfCleanedCandidates_
ROOT::Math::PositionVector3D< ROOT::Math::Cartesian3D< float > > XYZPointF
point in space with cartesian internal representation
void setDisplacedVerticesParameters(bool rejectTracks_Bad, bool rejectTracks_Step45, bool usePFNuclearInteractions, bool usePFConversions, bool usePFDecays, double dptRel_DispVtx)
void egammaFilters(const reco::PFBlockRef &blockref, std::vector< bool > &active, PFEGammaFilters const *pfegamma)
PFLayer::Layer layer() const
cluster layer, see PFLayer.h in this directory
Log< level::Error, false > LogError
bool isFromSecInt(const reco::PFBlockElement &eTrack, std::string order) const
float goodPixelTrackDeadHcal_dxy_
double energyEmHad(double uncalibratedEnergyECAL, double uncalibratedEnergyHCAL, double eta, double phi)
bool isElectron(const reco::GsfElectron &) const
bool rejectTracks_Step45_
double minSignificanceReduction_
std::vector< double > factors45_
void setVertex(const Point &vertex) override
set vertex
double hfEnergyResolution(double clusterEnergy) const
void setPFVertexParameters(bool useVertex, reco::VertexCollection const &primaryVertices)
std::vector< ElementInBlock > ElementsInBlocks
U second(std::pair< T, U > const &p)
reco::PFCandidateEGammaExtraRef egammaExtraRef() const
return a reference to the EGamma extra
std::vector< unsigned > hfHadIs
void setCharge(Charge q) final
set electric charge
XYZTLorentzVectorD XYZTLorentzVector
Lorentz vector with cylindrical internal representation using pseudorapidity.
void setPostHFCleaningParameters(bool postHFCleaning, const edm::ParameterSet &pfHFCleaningParams)
const bool & getcalibHF_use() const
void set_mva_e_pi(float mvaNI)
std::vector< unsigned > hcalIs
bool usePFNuclearInteractions_
const double nSigmaEConstHFEM
double px() const final
x coordinate of momentum vector
const ElementsInBlocks & elementsInBlocks() const
void setEGammaCollections(const edm::View< reco::PFCandidate > &pfEgammaCandidates, const edm::ValueMap< reco::GsfElectronRef > &valueMapGedElectrons, const edm::ValueMap< reco::PhotonRef > &valueMapGedPhotons)
Particle flow rechit (rechit + geometry and topology information). See clustering algorithm in PFClus...
void set_mva_Isolated(float mvaI)
const edm::View< reco::PFCandidate > * pfEgammaCandidates_
void createCandidatesECAL(const reco::PFBlock &block, reco::PFBlock::LinkData &linkData, const edm::OwnVector< reco::PFBlockElement > &elements, std::vector< bool > &active, const reco::PFBlockRef &blockref, ElementIndices &inds, std::vector< bool > &deadArea)
double energyEm(double uncalibratedEnergyECAL, double eta, double phi)
void associatePSClusters(unsigned iEcal, reco::PFBlockElement::Type psElementType, const reco::PFBlock &block, const edm::OwnVector< reco::PFBlockElement > &elements, const reco::PFBlock::LinkData &linkData, std::vector< bool > &active, std::vector< double > &psEne)
Associate PS clusters to a given ECAL cluster, and return their energy.
void setParticleType(ParticleType type)
set Particle Type
bool recoTracksNotHCAL(const reco::PFBlock &block, reco::PFBlock::LinkData &linkData, const edm::OwnVector< reco::PFBlockElement > &elements, const reco::PFBlockRef &blockref, std::vector< bool > &active, bool goodTrackDeadHcal, bool hasDeadHcal, unsigned int iTrack, std::multimap< double, unsigned > &ecalElems, reco::TrackRef &trackRef)
double nSigmaHFEM(double clusterEnergy) const
float goodTrackDeadHcal_validFr_
Abs< T >::type abs(const T &t)
reco::Vertex primaryVertex_
edm::Handle< reco::MuonCollection > muonHandle_
bool passElectronSelection(const reco::GsfElectron &, const reco::PFCandidate &, const int &) const
std::vector< double > muonECAL_
void setPositionAtECALEntrance(float x, float y, float z)
set position at ECAL entrance
PFEnergyCalibration & calibration_
bool isTimeValid() const
do we have a valid time information
const double nSigmaEConstHFHAD
double x() const
x coordinate
void energyEmHad(double t, double &e, double &h, double eta, double phi) const
double py() const final
y coordinate of momentum vector
bool isNull() const
Checks for null.
void processBlock(const reco::PFBlockRef &blockref, std::list< reco::PFBlockRef > &hcalBlockRefs, std::list< reco::PFBlockRef > &ecalBlockRefs, PFEGammaFilters const *pfegamma)
int goodPixelTrackDeadHcal_maxLost3Hit_
double y() const
y coordinate
void createCandidatesHCAL(const reco::PFBlock &block, reco::PFBlock::LinkData &linkData, const edm::OwnVector< reco::PFBlockElement > &elements, std::vector< bool > &active, const reco::PFBlockRef &blockref, ElementIndices &inds, std::vector< bool > &deadArea)
void set_dnn_e_sigNonIsolated(float mva)
virtual bool trackType(TrackType trType) const
void set_dnn_e_bkgPhoton(float mva)
PFAlgo(double nSigmaECAL, double nSigmaHCAL, double nSigmaHFEM, double nSigmaHFHAD, std::vector< double > resolHF_square, PFEnergyCalibration &calibration, PFEnergyCalibrationHF &thepfEnergyCalibrationHF, const edm::ParameterSet &pset)
constructor
void reconstructParticles(const reco::PFBlockHandle &blockHandle, PFEGammaFilters const *pfegamma)
reconstruct particles
Log< level::Info, false > LogInfo
float goodPixelTrackDeadHcal_maxPt_
std::vector< reco::PFCandidate > PFCandidateCollection
collection of PFCandidates
double nSigmaHFHAD(double clusterEnergy) const
int decideType(const edm::OwnVector< reco::PFBlockElement > &elements, const reco::PFBlockElement::Type type, std::vector< bool > &active, ElementIndices &inds, std::vector< bool > &deadArea, unsigned int iEle)
bool isElectronSafeForJetMET(const reco::GsfElectron &, const reco::PFCandidate &, const reco::Vertex &, bool &lockTracks) const
unsigned reconstructTrack(const reco::PFBlockElement &elt, bool allowLoose=false)
int goodTrackDeadHcal_layers_
bool passPhotonSelection(const reco::Photon &) const
std::vector< unsigned > hfEmIs
std::vector< double > muonHO_
double energyHad(double uncalibratedEnergyHCAL, double eta, double phi)
bool isPhotonSafeForJetMET(const reco::Photon &, const reco::PFCandidate &) const
float goodPixelTrackDeadHcal_ptErrRel_
XYZVectorD XYZVector
spatial vector with cartesian internal representation
static bool isLooseMuon(const reco::PFBlockElement &elt)
XYZPointD XYZPoint
point in space with cartesian internal representation
std::vector< unsigned > ecalIs
double pz() const
z coordinate of momentum vector
double neutralHadronEnergyResolution(double clusterEnergy, double clusterEta) const
todo: use PFClusterTools for this
void set_dnn_e_bkgTau(float mva)
caConstants::TupleMultiplicity const CAHitNtupletGeneratorKernelsGPU::HitToTuple const cms::cuda::AtomicPairCounter GPUCACell const *__restrict__ uint32_t const *__restrict__ gpuPixelDoublets::CellNeighborsVector const gpuPixelDoublets::CellTracksVector const GPUCACell::OuterHitOfCell const int32_t nHits
void relinkTrackToHcal(const reco::PFBlock &block, std::multimap< double, unsigned > &ecalElems, std::multimap< double, unsigned > &hcalElems, const std::vector< bool > &active, reco::PFBlock::LinkData &linkData, unsigned int iTrack)
const double nSigmaECAL_
number of sigma to judge energy excess in ECAL
PFEnergyCalibrationHF & thepfEnergyCalibrationHF_
void setHcalDepthInfo(reco::PFCandidate &cand, const reco::PFCluster &cluster) const
Particle reconstructed by the particle flow algorithm.
double nSigmaHCAL(double clusterEnergy, double clusterEta) const
void conversionAlgo(const edm::OwnVector< reco::PFBlockElement > &elements, std::vector< bool > &active)
void createCandidatesHF(const reco::PFBlock &block, reco::PFBlock::LinkData &linkData, const edm::OwnVector< reco::PFBlockElement > &elements, std::vector< bool > &active, const reco::PFBlockRef &blockref, ElementIndices &inds)
PFMuonAlgo * getPFMuonAlgo()
bool useEGammaFilters_
Variables for NEW EGAMMA selection.
void createCandidatesHCALUnlinked(const reco::PFBlock &block, reco::PFBlock::LinkData &linkData, const edm::OwnVector< reco::PFBlockElement > &elements, std::vector< bool > &active, const reco::PFBlockRef &blockref, ElementIndices &inds, std::vector< bool > &deadArea)
ostream & operator<<(ostream &out, const PFAlgo &algo)
float goodTrackDeadHcal_ptErrRel_
Variables for track cleaning in bad HCal areas.
int goodPixelTrackDeadHcal_maxLost4Hit_
const double nSigmaHFHAD_
float goodPixelTrackDeadHcal_chi2n_
Log< level::Warning, false > LogWarning
math::XYZVector XYZVector
std::vector< unsigned > trackIs
double phi() const final
momentum azimuthal angle
std::unique_ptr< PFMuonAlgo > pfmu_
void setP4(const LorentzVector &p4) final
set 4-momentum
float goodTrackDeadHcal_chi2n_
Power< A, B >::type pow(const A &a, const B &b)
float goodPixelTrackDeadHcal_dz_
bool checkAndReconstructSecondaryInteraction(const reco::PFBlockRef &blockref, const edm::OwnVector< reco::PFBlockElement > &elements, bool isActive, int iElement)
void setEGammaParameters(bool use_EGammaFilters, bool useProtectionsForJetMET)
float mva_e_pi() const
mva for electron-pion discrimination
int charge() const final
electric charge
const edm::ValueMap< reco::GsfElectronRef > * valueMapGedElectrons_
virtual ParticleType particleId() const
double eta() const final
momentum pseudorapidity