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;
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) {
947 unsigned index = ecalElems.begin()->second;
948 std::multimap<double, unsigned> sortedTracks;
950 LogTrace(
"PFAlgo|elementLoop") <<
"The closest ECAL cluster is linked to " << sortedTracks.size()
951 <<
" tracks, with distance = " << ecalElems.begin()->first;
953 LogTrace(
"PFAlgo|elementLoop") <<
"Looping over sortedTracks";
955 for (
auto const& trk : sortedTracks) {
956 unsigned jTrack = trk.second;
957 LogTrace(
"PFAlgo|elementLoop") <<
"jTrack=" << jTrack;
961 LogTrace(
"PFAlgo|elementLoop") <<
"active[jTrack]=" << active[jTrack];
964 if (jTrack == iTrack)
966 LogTrace(
"PFAlgo|elementLoop") <<
"skipping jTrack=" << jTrack <<
" for same iTrack";
970 std::multimap<double, unsigned> sortedECAL;
972 if (sortedECAL.begin()->second !=
index)
974 LogTrace(
"PFAlgo|elementLoop") <<
" track " << jTrack <<
" with closest ECAL identical ";
977 std::multimap<double, unsigned> sortedHCAL;
979 if (sortedHCAL.empty())
981 LogTrace(
"PFAlgo|elementLoop") <<
" and with an HCAL cluster " << sortedHCAL.begin()->second;
984 block.setLink(iTrack, sortedHCAL.begin()->second, sortedECAL.begin()->first, linkData, PFBlock::LINKTEST_RECHIT);
991 if (!hcalElems.empty())
992 LogTrace(
"PFAlgo|elementLoop") <<
"Track linked back to HCAL due to ECAL sharing with other tracks";
998 std::vector<bool>& active,
1001 std::vector<bool>& deadArea) {
1002 LogTrace(
"PFAlgo|elementLoop") <<
"start of function PFAlgo::elementLoop, elements.size()" <<
elements.size();
1004 for (
unsigned iEle = 0; iEle <
elements.size(); iEle++) {
1007 LogTrace(
"PFAlgo|elementLoop") <<
"elements[iEle=" << iEle <<
"]=" <<
elements[iEle];
1011 if (ret_decideType == 1) {
1012 LogTrace(
"PFAlgo|elementLoop") <<
"ret_decideType==1, continuing";
1015 LogTrace(
"PFAlgo|elementLoop") <<
"ret_decideType=" << ret_decideType <<
" type=" <<
type;
1019 if (!active[iEle]) {
1020 LogTrace(
"PFAlgo|elementLoop") <<
"Already used by electrons, muons, conversions";
1027 LogTrace(
"PFAlgo|elementLoop") <<
"PFAlgo:processBlock" 1028 <<
" trackIs.size()=" << inds.
trackIs.size()
1029 <<
" ecalIs.size()=" << inds.
ecalIs.size() <<
" hcalIs.size()=" << inds.
hcalIs.size()
1030 <<
" hoIs.size()=" << inds.
hoIs.size() <<
" hfEmIs.size()=" << inds.
hfEmIs.size()
1031 <<
" hfHadIs.size()=" << inds.
hfHadIs.size();
1037 std::multimap<double, unsigned> ecalElems;
1040 std::multimap<double, unsigned> hcalElems;
1043 std::multimap<double, unsigned> hfEmElems;
1044 std::multimap<double, unsigned> hfHadElems;
1048 LogTrace(
"PFAlgo|elementLoop") <<
"\tTrack " << iEle <<
" is linked to " << ecalElems.size() <<
" ecal and " 1049 << hcalElems.size() <<
" hcal and " << hfEmElems.size() <<
" hfEm and " 1050 << hfHadElems.size() <<
" hfHad elements";
1053 for (
const auto& pair : ecalElems) {
1054 LogTrace(
"PFAlgo|elementLoop") <<
"ecal: dist " << pair.first <<
"\t elem " << pair.second;
1056 for (
const auto& pair : hcalElems) {
1057 LogTrace(
"PFAlgo|elementLoop") <<
"hcal: dist " << pair.first <<
"\t elem " << pair.second
1058 << (deadArea[pair.second] ?
" DEAD AREA MARKER" :
"");
1071 if (hcalElems.empty() && !ecalElems.empty() && !hasDeadHcal) {
1082 std::multimap<double, unsigned> gsfElems;
1085 if (hcalElems.empty()) {
1086 LogTrace(
"PFAlgo|elementLoop") <<
"no hcal element connected to track " << iEle;
1090 bool hcalFound =
false;
1091 bool hfhadFound =
false;
1093 LogTrace(
"PFAlgo|elementLoop") <<
"now looping on elements associated to the track: ecalElems";
1097 for (
auto const&
ecal : ecalElems) {
1102 double dist =
ecal.first;
1103 LogTrace(
"PFAlgo|elementLoop") <<
"\telement " <<
elements[
index] <<
" linked with distance = " << dist;
1105 LogTrace(
"PFAlgo|elementLoop") <<
"This ECAL is already used - skip it";
1117 if (!hcalElems.empty())
1118 LogTrace(
"PFAlgo|elementLoop") <<
"\t\tat least one hcal element connected to the track." 1119 <<
" Sparing Ecal cluster for the hcal loop";
1126 if (hcalElems.empty() && hfHadElems.empty()) {
1128 block, linkData,
elements, blockref, active, goodTrackDeadHcal, hasDeadHcal, iEle, ecalElems, trackRef);
1136 for (
auto const&
hcal : hcalElems) {
1143 LogTrace(
"PFAlgo|elementLoop") <<
"\telement " <<
elements[
index] <<
" linked with distance " << dist;
1150 LogTrace(
"PFAlgo|elementLoop") <<
"\t\tclosest hcal cluster, doing nothing";
1158 LogTrace(
"PFAlgo|elementLoop") <<
"\t\tsecondary hcal cluster. unlinking";
1159 block.setLink(iEle,
index, -1., linkData, PFBlock::LINKTEST_RECHIT);
1166 for (
auto const& hfhad : hfHadElems) {
1167 unsigned index = hfhad.second;
1173 LogTrace(
"PFAlgo|elementLoop") <<
"\telement " <<
elements[
index] <<
" linked with distance " << dist;
1180 LogTrace(
"PFAlgo|elementLoop") <<
"\t\tclosest hfhad cluster, doing nothing";
1186 LogTrace(
"PFAlgo|elementLoop") <<
"\t\tsecondary hfhad cluster. unlinking";
1187 block.setLink(iEle,
index, -1., linkData, PFBlock::LINKTEST_RECHIT);
1191 LogTrace(
"PFAlgo|elementLoop") <<
"end of loop over iEle";
1193 LogTrace(
"PFAlgo|elementLoop") <<
"end of function PFAlgo::elementLoop";
1201 std::vector<bool>& active,
1203 std::vector<bool>& deadArea,
1204 unsigned int iEle) {
1206 case PFBlockElement::TRACK:
1209 LogTrace(
"PFAlgo|decideType") <<
"TRACK, stored index, continue";
1214 inds.
ecalIs.push_back(iEle);
1215 LogTrace(
"PFAlgo|decideType") <<
"ECAL, stored index, continue";
1221 LogTrace(
"PFAlgo|decideType") <<
"HCAL DEAD AREA: remember and skip.";
1222 active[iEle] =
false;
1223 deadArea[iEle] =
true;
1226 inds.
hcalIs.push_back(iEle);
1227 LogTrace(
"PFAlgo|decideType") <<
"HCAL, stored index, continue";
1233 inds.
hoIs.push_back(iEle);
1234 LogTrace(
"PFAlgo|decideType") <<
"HO, stored index, continue";
1238 case PFBlockElement::HFEM:
1240 inds.
hfEmIs.push_back(iEle);
1241 LogTrace(
"PFAlgo|decideType") <<
"HFEM, stored index, continue";
1244 case PFBlockElement::HFHAD:
1247 LogTrace(
"PFAlgo|decideType") <<
"HFHAD, stored index, continue";
1253 LogTrace(
"PFAlgo|decideType") <<
"Did not match type to anything, return 0";
1260 std::vector<bool>& active,
1263 LogTrace(
"PFAlgo|createCandidatesHF") <<
"starting function PFAlgo::createCandidatesHF";
1265 bool trackInBlock = !inds.
trackIs.empty();
1269 for (
unsigned iEle = 0; iEle <
elements.size(); iEle++) {
1271 if (
type == PFBlockElement::TRACK) {
1272 trackInBlock =
true;
1287 std::multimap<double, unsigned> sortedTracks;
1288 std::multimap<double, unsigned> sortedTracksActive;
1290 std::multimap<unsigned, std::pair<double, unsigned>> associatedHfEms;
1292 std::multimap<double, std::pair<unsigned, double>> hfemSatellites;
1297 for (
unsigned iHfHad : inds.
hfHadIs) {
1304 sortedTracks.clear();
1305 sortedTracksActive.clear();
1306 associatedHfEms.clear();
1307 hfemSatellites.clear();
1310 block.associatedElements(
1313 LogTrace(
"PFAlgo|createCandidatesHF") <<
"elements[" << iHfHad <<
"]=" <<
elements[iHfHad];
1315 if (sortedTracks.empty()) {
1316 LogTrace(
"PFAlgo|createCandidatesHCF") <<
"\tno associated tracks, keep for later";
1321 active[iHfHad] =
false;
1323 LogTrace(
"PFAlgo|createCandidatesHF") << sortedTracks.size() <<
" associated tracks:";
1325 double totalChargedMomentum = 0.;
1326 double sumpError2 = 0.;
1331 for (
auto const& trk : sortedTracks) {
1332 unsigned iTrack = trk.second;
1335 if (!active[iTrack])
1350 sumpError2 +=
dp *
dp;
1353 sortedTracksActive.emplace(trk);
1356 std::multimap<double, unsigned> sortedHfEms;
1357 block.associatedElements(
1360 LogTrace(
"PFAlgo|createCandidatesHF") <<
"number of HfEm elements linked to this track: " << sortedHfEms.size();
1362 bool connectedToHfEm =
false;
1367 for (
auto const& hfem : sortedHfEms) {
1368 unsigned iHfEm = hfem.second;
1369 double dist = hfem.first;
1372 if (!active[iHfEm]) {
1373 LogTrace(
"PFAlgo|createCandidatesHF") <<
"cluster locked";
1384 std::multimap<double, unsigned> sortedTracksHfEm;
1385 block.associatedElements(
1387 unsigned jTrack = sortedTracksHfEm.begin()->second;
1388 if (jTrack != iTrack)
1392 double hfemEnergy = eclusterRef->energy();
1394 if (!connectedToHfEm) {
1397 connectedToHfEm =
true;
1398 std::pair<unsigned, double> satellite(iHfEm, hfemEnergy);
1399 hfemSatellites.emplace(-1., satellite);
1404 std::pair<unsigned, double> satellite(iHfEm, hfemEnergy);
1405 hfemSatellites.emplace(dist, satellite);
1408 std::pair<double, unsigned> associatedHfEm(distHfEm, iHfEm);
1409 associatedHfEms.emplace(iTrack, associatedHfEm);
1415 double uncalibratedenergyHfHad = hclusterRef->energy();
1416 double energyHfHad = uncalibratedenergyHfHad;
1419 uncalibratedenergyHfHad,
1420 hclusterRef->positionREP().Eta(),
1421 hclusterRef->positionREP().Phi());
1423 double calibFactorHfHad = (uncalibratedenergyHfHad > 0.) ? energyHfHad / uncalibratedenergyHfHad : 1.;
1426 double energyHfEmTmp = 0.;
1427 double uncalibratedenergyHfEmTmp = 0.;
1428 double energyHfEm = 0.;
1429 double uncalibratedenergyHfEm = 0.;
1435 double nsigmaHFEM =
nSigmaHFEM(totalChargedMomentum);
1436 double nsigmaHFHAD =
nSigmaHFHAD(totalChargedMomentum);
1439 if (sortedTracksActive.empty()) {
1441 std::multimap<double, unsigned> sortedHfEms;
1442 std::multimap<double, unsigned> sortedHfEmsActive;
1443 block.associatedElements(
1448 if (!sortedHfEms.empty()) {
1449 for (
auto const& hfem : sortedHfEms) {
1450 unsigned iHfEm = hfem.second;
1454 sortedHfEmsActive.emplace(hfem);
1457 double hfemEnergy = eclusterRef->energy();
1458 uncalibratedenergyHfEm += hfemEnergy;
1459 energyHfEm = uncalibratedenergyHfEm;
1462 uncalibratedenergyHfEm, 0.0, eclusterRef->positionREP().Eta(), eclusterRef->positionREP().Phi());
1464 0.0, uncalibratedenergyHfHad, hclusterRef->positionREP().Eta(), hclusterRef->positionREP().Phi());
1471 (*pfCandidates_)[tmpi].setHcalEnergy(uncalibratedenergyHfHad, energyHfHad);
1472 (*pfCandidates_)[tmpi].setEcalEnergy(uncalibratedenergyHfEm, energyHfEm);
1473 (*pfCandidates_)[tmpi].addElementInBlock(blockref, iHfHad);
1474 for (
auto const& hfem : sortedHfEmsActive) {
1475 unsigned iHfEm = hfem.second;
1476 (*pfCandidates_)[tmpi].addElementInBlock(blockref, iHfEm);
1477 active[iHfEm] =
false;
1484 else if ((energyHfHad - totalChargedMomentum) > nsigmaHFHAD * totalError) {
1485 assert(energyHfEm == 0.);
1487 double energyHfHadExcess =
max(energyHfHad - totalChargedMomentum, 0.);
1488 double uncalibratedenergyHfHadExcess = energyHfHadExcess / calibFactorHfHad;
1490 (*pfCandidates_)[tmpi].setHcalEnergy(uncalibratedenergyHfHadExcess, energyHfHadExcess);
1491 (*pfCandidates_)[tmpi].setEcalEnergy(0., 0.);
1492 (*pfCandidates_)[tmpi].addElementInBlock(blockref, iHfHad);
1493 energyHfHad =
max(energyHfHad - energyHfHadExcess, 0.);
1494 uncalibratedenergyHfHad =
max(uncalibratedenergyHfHad - uncalibratedenergyHfHadExcess, 0.);
1502 for (
auto const& hfemSatellite : hfemSatellites) {
1504 uncalibratedenergyHfEmTmp += std::get<1>(hfemSatellite.second);
1505 energyHfEmTmp = uncalibratedenergyHfEmTmp;
1506 double energyHfHadTmp = uncalibratedenergyHfHad;
1507 unsigned iHfEm = std::get<0>(hfemSatellite.second);
1509 assert(!eclusterRef.isNull());
1512 uncalibratedenergyHfEmTmp, 0.0, eclusterRef->positionREP().Eta(), eclusterRef->positionREP().Phi());
1514 0.0, uncalibratedenergyHfHad, hclusterRef->positionREP().Eta(), hclusterRef->positionREP().Phi());
1517 double caloEnergyTmp = energyHfEmTmp + energyHfHadTmp;
1518 double calibFactorHfEm = (uncalibratedenergyHfEmTmp > 0.) ? energyHfEmTmp / uncalibratedenergyHfEmTmp : 1.;
1522 if (hfemSatellite.first < 0. || caloEnergyTmp < totalChargedMomentum) {
1523 LogTrace(
"PFAlgo|createCandidatesHF")
1524 <<
"\t\t\tactive, adding " << std::get<1>(hfemSatellite.second) <<
" to HFEM energy, and locking";
1525 active[std::get<0>(hfemSatellite.second)] =
false;
1527 if (hfemSatellite.first < 0. && (caloEnergyTmp - totalChargedMomentum) > nsigmaHFEM * totalError) {
1529 double energyHfEmExcess =
max(caloEnergyTmp - totalChargedMomentum, 0.);
1530 double uncalibratedenergyHfEmExcess = energyHfEmExcess / calibFactorHfEm;
1532 (*pfCandidates_)[tmpi].setEcalEnergy(uncalibratedenergyHfEmExcess, energyHfEmExcess);
1533 (*pfCandidates_)[tmpi].setHcalEnergy(0, 0.);
1534 (*pfCandidates_)[tmpi].addElementInBlock(blockref, iHfEm);
1535 energyHfEmTmp =
max(energyHfEmTmp - energyHfEmExcess, 0.);
1536 uncalibratedenergyHfEmTmp =
max(uncalibratedenergyHfEmTmp - uncalibratedenergyHfEmExcess, 0.);
1538 energyHfEm = energyHfEmTmp;
1539 uncalibratedenergyHfEm = uncalibratedenergyHfEmTmp;
1540 energyHfHad = energyHfHadTmp;
1550 for (
auto const& trk : sortedTracksActive) {
1551 unsigned iTrack = trk.second;
1561 active[iTrack] =
false;
1562 (*pfCandidates_)[tmpi].addElementInBlock(blockref, iHfHad);
1563 auto myHfEms = associatedHfEms.equal_range(iTrack);
1564 for (
auto ii = myHfEms.first;
ii != myHfEms.second; ++
ii) {
1565 unsigned iHfEm =
ii->second.second;
1568 (*pfCandidates_)[tmpi].addElementInBlock(blockref, iHfEm);
1571 if (totalChargedMomentum)
1572 frac = trackRef->p() / totalChargedMomentum;
1573 (*pfCandidates_)[tmpi].setEcalEnergy(uncalibratedenergyHfEm *
frac, energyHfEm *
frac);
1574 (*pfCandidates_)[tmpi].setHcalEnergy(uncalibratedenergyHfHad *
frac, energyHfHad *
frac);
1583 for (
unsigned iHfEm = 0; iHfEm <
elements.size(); iHfEm++) {
1585 if (
type == PFBlockElement::HFEM && active[iHfEm]) {
1588 double uncalibratedenergyHF = 0.;
1595 uncalibratedenergyHF, eclusterRef->positionREP().Eta(), eclusterRef->positionREP().Phi());
1598 (*pfCandidates_)[tmpi].setEcalEnergy(uncalibratedenergyHF,
energyHF);
1599 (*pfCandidates_)[tmpi].setHcalEnergy(0., 0.);
1600 (*pfCandidates_)[tmpi].addElementInBlock(blockref, iHfEm);
1601 active[iHfEm] =
false;
1602 LogTrace(
"PFAlgo|createCandidatesHF") <<
"HF EM alone from blocks with tracks! " <<
energyHF;
1616 double uncalibratedenergyHF = 0.;
1618 switch (clusterRef->layer()) {
1625 uncalibratedenergyHF, clusterRef->positionREP().Eta(), clusterRef->positionREP().Phi());
1628 (*pfCandidates_)[tmpi].setEcalEnergy(uncalibratedenergyHF,
energyHF);
1629 (*pfCandidates_)[tmpi].setHcalEnergy(0., 0.);
1630 (*pfCandidates_)[tmpi].setHoEnergy(0., 0.);
1631 (*pfCandidates_)[tmpi].setPs1Energy(0.);
1632 (*pfCandidates_)[tmpi].setPs2Energy(0.);
1633 (*pfCandidates_)[tmpi].addElementInBlock(blockref, inds.
hfEmIs[0]);
1642 uncalibratedenergyHF, clusterRef->positionREP().Eta(), clusterRef->positionREP().Phi());
1645 (*pfCandidates_)[tmpi].setHcalEnergy(uncalibratedenergyHF,
energyHF);
1646 (*pfCandidates_)[tmpi].setEcalEnergy(0., 0.);
1647 (*pfCandidates_)[tmpi].setHoEnergy(0., 0.);
1648 (*pfCandidates_)[tmpi].setPs1Energy(0.);
1649 (*pfCandidates_)[tmpi].setPs2Energy(0.);
1650 (*pfCandidates_)[tmpi].addElementInBlock(blockref, inds.
hfHadIs[0]);
1665 edm::LogError(
"PFAlgo::createCandidatesHF") <<
"Error: 2 elements, but not 1 HFEM and 1 HFHAD";
1672 double energyHfEm = cem->energy();
1673 double energyHfHad = chad->energy();
1674 double uncalibratedenergyHfEm = energyHfEm;
1675 double uncalibratedenergyHfHad = energyHfHad;
1678 uncalibratedenergyHfEm, 0.0,
c0->positionREP().Eta(),
c0->positionREP().Phi());
1680 0.0, uncalibratedenergyHfHad,
c1->positionREP().Eta(),
c1->positionREP().Phi());
1683 cand.setEcalEnergy(uncalibratedenergyHfEm, energyHfEm);
1684 cand.setHcalEnergy(uncalibratedenergyHfHad, energyHfHad);
1685 cand.setHoEnergy(0., 0.);
1686 cand.setPs1Energy(0.);
1687 cand.setPs2Energy(0.);
1688 cand.addElementInBlock(blockref, inds.
hfEmIs[0]);
1689 cand.addElementInBlock(blockref, inds.
hfHadIs[0]);
1690 LogTrace(
"PFAlgo|createCandidatesHF") <<
"HF EM+HAD found ! " << energyHfEm <<
" " << energyHfHad;
1694 <<
"Warning: HF, but n elem different from 1 or 2 or >=3 or !trackIs.empty()";
1697 LogTrace(
"PFAlgo|createCandidateHF") <<
"end of function PFAlgo::createCandidateHF";
1703 std::vector<bool>& active,
1706 std::vector<bool>& deadArea) {
1707 LogTrace(
"PFAlgo|createCandidatesHCAL")
1708 <<
"start of function PFAlgo::createCandidatesHCAL, inds.hcalIs.size()=" << inds.
hcalIs.size();
1712 for (
unsigned iHcal : inds.
hcalIs) {
1717 LogTrace(
"PFAlgo|createCandidatesHCAL") <<
"elements[" << iHcal <<
"]=" <<
elements[iHcal];
1720 std::multimap<double, unsigned> sortedTracks;
1723 std::multimap<unsigned, std::pair<double, unsigned>> associatedEcals;
1725 std::map<unsigned, std::pair<double, double>> associatedPSs;
1727 std::multimap<double, std::pair<unsigned, bool>> associatedTracks;
1730 std::multimap<double, std::tuple<unsigned, ::math::XYZVector, double>>
1732 std::tuple<unsigned, ::math::XYZVector, double> fakeSatellite(iHcal, ::
math::XYZVector(0., 0., 0.), 1.);
1733 ecalSatellites.emplace(-1., fakeSatellite);
1735 std::multimap<unsigned, std::pair<double, unsigned>> associatedHOs;
1747 if (sortedTracks.empty()) {
1748 LogTrace(
"PFAlgo|createCandidatesHCAL") <<
"\tno associated tracks, keep for later";
1753 active[iHcal] =
false;
1760 LogTrace(
"PFAlgo|createCandidatesHCAL") << sortedTracks.size() <<
" associated tracks:";
1762 double totalChargedMomentum = 0;
1763 double sumpError2 = 0.;
1764 double totalHO = 0.;
1765 double totalEcal = 0.;
1766 double totalEcalEGMCalib = 0.;
1767 double totalHcal = hclusterref->energy();
1768 vector<double> hcalP;
1769 vector<double> hcalDP;
1770 vector<unsigned> tkIs;
1771 double maxDPovP = -9999.;
1774 vector<unsigned> chargedHadronsIndices;
1775 vector<unsigned> chargedHadronsInBlock;
1776 double mergedNeutralHadronEnergy = 0;
1777 double mergedPhotonEnergy = 0;
1778 double muonHCALEnergy = 0.;
1779 double muonECALEnergy = 0.;
1780 double muonHCALError = 0.;
1781 double muonECALError = 0.;
1785 std::vector<std::tuple<unsigned, ::math::XYZVector, double>>
1787 double sumEcalClusters = 0;
1789 hclusterref->position().X(), hclusterref->position().Y(), hclusterref->position().Z());
1790 hadronDirection = hadronDirection.Unit();
1794 for (
auto const& trk : sortedTracks) {
1795 unsigned iTrack = trk.second;
1798 if (!active[iTrack])
1810 ::math::XYZVector chargedDirection(chargedPosition.X(), chargedPosition.Y(), chargedPosition.Z());
1811 chargedDirection = chargedDirection.Unit();
1814 std::multimap<double, unsigned> sortedEcals;
1817 LogTrace(
"PFAlgo|createCandidatesHCAL") <<
"number of Ecal elements linked to this track: " << sortedEcals.size();
1820 std::multimap<double, unsigned> sortedHOs;
1824 LogTrace(
"PFAlgo|createCandidatesHCAL")
1825 <<
"PFAlgo : number of HO elements linked to this track: " << sortedHOs.size();
1832 bool thisIsALooseMuon =
false;
1839 LogTrace(
"PFAlgo|createCandidatesHCAL") <<
"This track is identified as a muon - remove it from the stack";
1846 (*pfCandidates_)[tmpi].addElementInBlock(blockref, iTrack);
1847 (*pfCandidates_)[tmpi].addElementInBlock(blockref, iHcal);
1853 bool letMuonEatCaloEnergy =
false;
1855 if (thisIsAnIsolatedMuon) {
1857 double totalCaloEnergy = totalHcal / 1.30;
1859 if (!sortedEcals.empty()) {
1860 iEcal = sortedEcals.begin()->second;
1862 totalCaloEnergy += eclusterref->energy();
1868 if (!sortedHOs.empty()) {
1869 iHO = sortedHOs.begin()->second;
1871 totalCaloEnergy += eclusterref->energy() / 1.30;
1876 letMuonEatCaloEnergy =
true;
1879 if (letMuonEatCaloEnergy)
1880 muonHcal = totalHcal;
1881 double muonEcal = 0.;
1883 if (!sortedEcals.empty()) {
1884 iEcal = sortedEcals.begin()->second;
1886 (*pfCandidates_)[tmpi].addElementInBlock(blockref, iEcal);
1888 if (letMuonEatCaloEnergy)
1889 muonEcal = eclusterref->energy();
1891 if (eclusterref->energy() - muonEcal < 0.2)
1892 active[iEcal] =
false;
1893 (*pfCandidates_)[tmpi].setEcalEnergy(eclusterref->energy(), muonEcal);
1898 if (!sortedHOs.empty()) {
1899 iHO = sortedHOs.begin()->second;
1901 (*pfCandidates_)[tmpi].addElementInBlock(blockref, iHO);
1903 if (letMuonEatCaloEnergy)
1904 muonHO = hoclusterref->energy();
1906 if (hoclusterref->energy() - muonHO < 0.2)
1907 active[iHO] =
false;
1908 (*pfCandidates_)[tmpi].setHcalEnergy(totalHcal, muonHcal);
1909 (*pfCandidates_)[tmpi].setHoEnergy(hoclusterref->energy(), muonHO);
1912 (*pfCandidates_)[tmpi].setHcalEnergy(totalHcal, muonHcal);
1916 if (letMuonEatCaloEnergy) {
1917 muonHCALEnergy += totalHcal;
1919 muonHCALEnergy += muonHO;
1920 muonHCALError += 0.;
1921 muonECALEnergy += muonEcal;
1922 muonECALError += 0.;
1923 photonAtECAL -= muonEcal * chargedDirection;
1924 hadronAtECAL -= totalHcal * chargedDirection;
1925 if (!sortedEcals.empty())
1926 active[iEcal] =
false;
1927 active[iHcal] =
false;
1928 if (
useHO_ && !sortedHOs.empty())
1929 active[iHO] =
false;
1941 photonAtECAL -=
muonECAL_[0] * chargedDirection;
1942 hadronAtECAL -=
muonHCAL_[0] * chargedDirection;
1946 active[iTrack] =
false;
1953 LogTrace(
"PFAlgo|createCandidatesHCAL") <<
"elements[iTrack=" << iTrack <<
"]=" <<
elements[iTrack];
1961 if (thisIsALooseMuon && !thisIsAMuon)
1967 double dpt = trackRef->ptError();
1972 if (isPrimaryOrSecondary)
1975 std::pair<unsigned, bool> tkmuon(iTrack, thisIsALooseMuon);
1976 associatedTracks.emplace(-dpt * blowError, tkmuon);
1980 sumpError2 +=
dp *
dp;
1982 bool connectedToEcal =
false;
1983 if (!sortedEcals.empty()) {
1986 for (
auto const&
ecal : sortedEcals) {
1987 unsigned iEcal =
ecal.second;
1988 double dist =
ecal.first;
1991 if (!active[iEcal]) {
1992 LogTrace(
"PFAlgo|createCandidatesHCAL") <<
"cluster locked";
2003 std::multimap<double, unsigned> sortedTracksEcal;
2004 block.associatedElements(
2006 unsigned jTrack = sortedTracksEcal.begin()->second;
2007 if (jTrack != iTrack)
2012 float ecalEnergyCalibrated = eclusterref->correctedEnergy();
2015 eclusterref->position().X(), eclusterref->position().Y(), eclusterref->position().Z());
2016 photonDirection = photonDirection.Unit();
2018 if (!connectedToEcal) {
2022 connectedToEcal =
true;
2028 std::tuple<unsigned, ::math::XYZVector, double> satellite(
2029 iEcal,
ecalEnergy * photonDirection, ecalCalibFactor);
2030 ecalSatellites.emplace(-1., satellite);
2036 std::tuple<unsigned, ::math::XYZVector, double> satellite(
2037 iEcal,
ecalEnergy * photonDirection, ecalCalibFactor);
2038 ecalSatellites.emplace(dist, satellite);
2041 std::pair<double, unsigned> associatedEcal(distEcal, iEcal);
2042 associatedEcals.emplace(iTrack, associatedEcal);
2047 if (
useHO_ && !sortedHOs.empty()) {
2050 for (
auto const&
ho : sortedHOs) {
2051 unsigned iHO =
ho.second;
2052 double distHO =
ho.first;
2056 LogTrace(
"PFAlgo|createCandidatesHCAL") <<
"cluster locked";
2067 std::multimap<double, unsigned> sortedTracksHO;
2068 block.associatedElements(
2070 unsigned jTrack = sortedTracksHO.begin()->second;
2071 if (jTrack != iTrack)
2080 totalHO += hoclusterref->energy();
2081 active[iHO] =
false;
2083 std::pair<double, unsigned> associatedHO(distHO, iHO);
2084 associatedHOs.emplace(iTrack, associatedHO);
2092 totalHcal += totalHO;
2096 double caloEnergy = 0.;
2097 double slopeEcal = 1.0;
2098 double calibEcal = 0.;
2099 double calibHcal = 0.;
2100 hadronDirection = hadronAtECAL.Unit();
2107 totalEcal -=
std::min(totalEcal, muonECALEnergy);
2108 totalEcalEGMCalib -=
std::min(totalEcalEGMCalib, muonECALEnergy);
2109 totalHcal -=
std::min(totalHcal, muonHCALEnergy);
2110 if (totalEcal < 1E-9)
2112 if (totalHcal < 1E-9)
2119 for (
auto const& ecalSatellite : ecalSatellites) {
2121 double previousCalibEcal = calibEcal;
2122 double previousCalibHcal = calibHcal;
2123 double previousCaloEnergy = caloEnergy;
2124 double previousSlopeEcal = slopeEcal;
2128 sqrt(std::get<1>(ecalSatellite.second).Mag2());
2129 totalEcalEGMCalib +=
sqrt(std::get<1>(ecalSatellite.second).Mag2()) *
2130 std::get<2>(ecalSatellite.second);
2131 photonAtECAL += std::get<1>(ecalSatellite.second) *
2132 std::get<2>(ecalSatellite.second);
2133 calibEcal =
std::max(0., totalEcal);
2134 calibHcal =
std::max(0., totalHcal);
2135 hadronAtECAL = calibHcal * hadronDirection;
2140 hclusterref->positionREP().Eta(),
2141 hclusterref->positionREP().Phi());
2142 caloEnergy = calibEcal + calibHcal;
2144 slopeEcal = calibEcal / totalEcal;
2146 hadronAtECAL = calibHcal * hadronDirection;
2150 if (ecalSatellite.first < 0. || caloEnergy - totalChargedMomentum <= 0.) {
2151 LogTrace(
"PFAlgo|createCandidatesHCAL")
2152 <<
"\t\t\tactive, adding " << std::get<1>(ecalSatellite.second) <<
" to ECAL energy, and locking";
2153 active[std::get<0>(ecalSatellite.second)] =
false;
2154 double clusterEnergy =
2155 sqrt(std::get<1>(ecalSatellite.second).Mag2()) *
2156 std::get<2>(ecalSatellite.second);
2157 if (clusterEnergy > 50) {
2159 sumEcalClusters += clusterEnergy;
2166 totalEcal -=
sqrt(std::get<1>(ecalSatellite.second).Mag2());
2167 totalEcalEGMCalib -=
sqrt(std::get<1>(ecalSatellite.second).Mag2()) * std::get<2>(ecalSatellite.second);
2168 photonAtECAL -= std::get<1>(ecalSatellite.second) * std::get<2>(ecalSatellite.second);
2169 calibEcal = previousCalibEcal;
2170 calibHcal = previousCalibHcal;
2171 hadronAtECAL = previousHadronAtECAL;
2172 slopeEcal = previousSlopeEcal;
2173 caloEnergy = previousCaloEnergy;
2196 for (
auto const& trk : associatedTracks) {
2198 if (!trk.second.second)
2201 const unsigned int iTrack = trk.second.first;
2203 if (!active[iTrack])
2209 std::multimap<double, unsigned> sortedEcals;
2210 block.associatedElements(
2212 std::multimap<double, unsigned> sortedHOs;
2218 muon.addElementInBlock(blockref, iTrack);
2219 muon.addElementInBlock(blockref, iHcal);
2222 muon.setHcalEnergy(totalHcal, muonHcal);
2223 if (!sortedEcals.empty()) {
2224 const unsigned int iEcal = sortedEcals.begin()->second;
2226 muon.addElementInBlock(blockref, iEcal);
2228 muon.setEcalEnergy(eclusterref->energy(), muonEcal);
2230 if (
useHO_ && !sortedHOs.empty()) {
2231 const unsigned int iHO = sortedHOs.begin()->second;
2233 muon.addElementInBlock(blockref, iHO);
2235 muon.setHcalEnergy(
max(totalHcal - totalHO, 0.0), muonHcal);
2236 muon.setHoEnergy(hoclusterref->energy(), muonHO);
2242 ::math::XYZVector chargedDirection(chargedPosition.X(), chargedPosition.Y(), chargedPosition.Z());
2243 chargedDirection = chargedDirection.Unit();
2253 photonAtECAL -=
muonECAL_[0] * chargedDirection;
2255 hadronAtECAL -=
muonHCAL_[0] * calibHcal / totalHcal * chargedDirection;
2256 caloEnergy = calibEcal + calibHcal;
2262 if (totalHcal > 0.) {
2269 active[iTrack] =
false;
2282 LogTrace(
"PFAlgo|createCandidatesHCAL") <<
"\tBefore Cleaning ";
2283 LogTrace(
"PFAlgo|createCandidatesHCAL") <<
"\tCompare Calo Energy to total charged momentum ";
2284 LogTrace(
"PFAlgo|createCandidatesHCAL") <<
"\t\tsum p = " << totalChargedMomentum <<
" +- " <<
sqrt(sumpError2);
2285 LogTrace(
"PFAlgo|createCandidatesHCAL") <<
"\t\tsum ecal = " << totalEcal;
2286 LogTrace(
"PFAlgo|createCandidatesHCAL") <<
"\t\tsum hcal = " << totalHcal;
2287 LogTrace(
"PFAlgo|createCandidatesHCAL") <<
"\t\t => Calo Energy = " << caloEnergy <<
" +- " <<
caloResolution;
2288 LogTrace(
"PFAlgo|createCandidatesHCAL")
2289 <<
"\t\t => Calo Energy- total charged momentum = " << caloEnergy - totalChargedMomentum <<
" +- " 2294 unsigned corrTrack = 10000000;
2295 double corrFact = 1.;
2298 for (
auto const& trk : associatedTracks) {
2299 const unsigned iTrack = trk.second.first;
2301 if (!active[iTrack])
2305 const double dptRel = fabs(trk.first) / trackref->pt() * 100;
2315 const double wouldBeTotalChargedMomentum = totalChargedMomentum - trackref->p();
2319 if (wouldBeTotalChargedMomentum > caloEnergy) {
2321 LogTrace(
"PFAlgo|createCandidatesHCAL")
2322 <<
"In bad track rejection step dptRel = " << dptRel <<
" dptRel_DispVtx_ = " <<
dptRel_DispVtx_;
2323 LogTrace(
"PFAlgo|createCandidatesHCAL")
2324 <<
"The calo energy would be still smaller even without this track but it is attached to a NI";
2329 active[iTrack] =
false;
2330 totalChargedMomentum = wouldBeTotalChargedMomentum;
2331 LogTrace(
"PFAlgo|createCandidatesHCAL")
2332 <<
"\tElement " <<
elements[iTrack] <<
" rejected (dpt = " << -trk.first
2333 <<
" GeV/c, algo = " << trackref->algo() <<
")";
2339 corrFact = (caloEnergy - wouldBeTotalChargedMomentum) /
elements[trk.second.first].trackRef()->p();
2340 if (trackref->p() * corrFact < 0.05) {
2342 active[iTrack] =
false;
2344 totalChargedMomentum -= trackref->p() * (1. - corrFact);
2345 LogTrace(
"PFAlgo|createCandidatesHCAL")
2346 <<
"\tElement " <<
elements[iTrack] <<
" (dpt = " << -trk.first <<
" GeV/c, algo = " << trackref->algo()
2347 <<
") rescaled by " << corrFact <<
" Now the total charged momentum is " << totalChargedMomentum;
2363 for (
auto const& trk : associatedTracks) {
2364 unsigned iTrack = trk.second.first;
2366 if (!active[iTrack])
2369 double dptRel = fabs(trk.first) / trackref->pt() * 100;
2376 active[iTrack] =
false;
2377 totalChargedMomentum -= trackref->p();
2379 LogTrace(
"PFAlgo|createCandidatesHCAL")
2380 <<
"\tElement " <<
elements[iTrack] <<
" rejected (dpt = " << -trk.first
2381 <<
" GeV/c, algo = " << trackref->algo() <<
")";
2393 for (
auto const& trk : associatedTracks) {
2394 unsigned iTrack = trk.second.first;
2395 if (!active[iTrack])
2402 (*pfCandidates_)[tmpi].addElementInBlock(blockref, iTrack);
2403 (*pfCandidates_)[tmpi].addElementInBlock(blockref, iHcal);
2405 auto myEcals = associatedEcals.equal_range(iTrack);
2406 for (
auto ii = myEcals.first;
ii != myEcals.second; ++
ii) {
2407 unsigned iEcal =
ii->second.second;
2410 (*pfCandidates_)[tmpi].addElementInBlock(blockref, iEcal);
2414 auto myHOs = associatedHOs.equal_range(iTrack);
2415 for (
auto ii = myHOs.first;
ii != myHOs.second; ++
ii) {
2416 unsigned iHO =
ii->second.second;
2419 (*pfCandidates_)[tmpi].addElementInBlock(blockref, iHO);
2423 if (iTrack == corrTrack) {
2426 auto& candRescale = (*pfCandidates_)[tmpi];
2427 LogTrace(
"PFAlgo|createCandidatesHCAL")
2428 <<
"\tBefore rescaling: momentum " << candRescale.p() <<
" pT " << candRescale.pt() <<
" energy " 2429 << candRescale.energy() <<
" mass " << candRescale.mass() << std::endl
2430 <<
"\tTo rescale by " << corrFact << std::endl;
2431 candRescale.rescaleMomentum(corrFact);
2432 LogTrace(
"PFAlgo|createCandidatesHCAL")
2433 <<
"\tRescaled candidate momentum " << candRescale.p() <<
" pT " << candRescale.pt() <<
" energy " 2434 << candRescale.energy() <<
" mass " << candRescale.mass() << std::endl;
2437 chargedHadronsIndices.push_back(tmpi);
2438 chargedHadronsInBlock.push_back(iTrack);
2439 active[iTrack] =
false;
2441 hcalDP.push_back(
dp);
2444 sumpError2 +=
dp *
dp;
2451 LogTrace(
"PFAlgo|createCandidatesHCAL")
2452 <<
"\tCompare Calo Energy to total charged momentum " << endl
2453 <<
"\t\tsum p = " << totalChargedMomentum <<
" +- " <<
sqrt(sumpError2) << endl
2454 <<
"\t\tsum ecal = " << totalEcal << endl
2455 <<
"\t\tsum hcal = " << totalHcal << endl
2456 <<
"\t\t => Calo Energy = " << caloEnergy <<
" +- " <<
caloResolution << endl
2457 <<
"\t\t => Calo Energy- total charged momentum = " << caloEnergy - totalChargedMomentum <<
" +- " 2464 double nsigma =
nSigmaHCAL(totalChargedMomentum, hclusterref->positionREP().Eta());
2466 if (
abs(totalChargedMomentum - caloEnergy) < nsigma * totalError) {
2471 LogTrace(
"PFAlgo|createCandidatesHCAL")
2472 <<
"\t\tcase 1: COMPATIBLE " 2473 <<
"|Calo Energy- total charged momentum| = " <<
abs(caloEnergy - totalChargedMomentum) <<
" < " << nsigma
2474 <<
" x " << totalError;
2476 LogTrace(
"PFAlgo|createCandidatesHCAL") <<
"\t\t\tmax DP/P = " << maxDPovP <<
" less than 0.1: do nothing ";
2478 LogTrace(
"PFAlgo|createCandidatesHCAL")
2479 <<
"\t\t\tmax DP/P = " << maxDPovP <<
" > 0.1: take weighted averages ";
2483 if (maxDPovP > 0.1) {
2486 int nrows = chargedHadronsIndices.size();
2487 TMatrixTSym<double>
a(nrows);
2489 TVectorD
check(nrows);
2491 for (
int i = 0;
i < nrows;
i++) {
2492 double sigma2i = hcalDP[
i] * hcalDP[
i];
2493 LogTrace(
"PFAlgo|createCandidatesHCAL")
2494 <<
"\t\t\ttrack associated to hcal " <<
i <<
" P = " << hcalP[
i] <<
" +- " << hcalDP[
i];
2495 a(
i,
i) = 1. / sigma2i + 1. / sigma2E;
2496 b(
i) = hcalP[
i] / sigma2i + caloEnergy / sigma2E;
2497 for (
int j = 0;
j < nrows;
j++) {
2500 a(
i,
j) = 1. / sigma2E;
2505 TDecompChol decomp(
a);
2507 TVectorD
x = decomp.Solve(
b,
ok);
2511 for (
int i = 0;
i < nrows;
i++) {
2513 unsigned ich = chargedHadronsIndices[
i];
2514 double rescaleFactor =
x(
i) / hcalP[
i];
2515 if (rescaleFactor < 0.)
2517 auto& candRescale = (*pfCandidates_)[ich];
2518 LogTrace(
"PFAlgo|createCandidatesHCAL")
2519 <<
"\tBefore rescaling: momentum " << candRescale.p() <<
" pT " << candRescale.pt() <<
" energy " 2520 << candRescale.energy() <<
" mass " << candRescale.mass() << std::endl
2521 <<
"\tTo rescale by " << rescaleFactor << std::endl;
2522 candRescale.rescaleMomentum(rescaleFactor);
2523 LogTrace(
"PFAlgo|createCandidatesHCAL")
2524 <<
"\tRescaled candidate momentum " << candRescale.p() <<
" pT " << candRescale.pt() <<
" energy " 2525 << candRescale.energy() <<
" mass " << candRescale.mass() << std::endl;
2527 LogTrace(
"PFAlgo|createCandidatesHCAL")
2528 <<
"\t\t\told p " << hcalP[
i] <<
" new p " <<
x(
i) <<
" rescale " << rescaleFactor;
2531 edm::LogError(
"PFAlgo::createCandidatesHCAL") <<
"TDecompChol.Solve returned ok=false";
2538 else if (caloEnergy > totalChargedMomentum) {
2543 double eNeutralHadron = caloEnergy - totalChargedMomentum;
2544 double ePhoton = (caloEnergy - totalChargedMomentum) /
2550 if (!sortedTracks.empty()) {
2551 LogTrace(
"PFAlgo|createCandidatesHCAL") <<
"\t\tcase 2: NEUTRAL DETECTION " << caloEnergy <<
" > " << nsigma
2552 <<
"x" << totalError <<
" + " << totalChargedMomentum;
2553 LogTrace(
"PFAlgo|createCandidatesHCAL") <<
"\t\tneutral activity detected: " << endl
2554 <<
"\t\t\t photon = " << ePhoton << endl
2555 <<
"\t\t\tor neutral hadron = " << eNeutralHadron;
2557 LogTrace(
"PFAlgo|createCandidatesHCAL") <<
"\t\tphoton or hadron ?";
2560 if (sortedTracks.empty())
2561 LogTrace(
"PFAlgo|createCandidatesHCAL") <<
"\t\tno track -> hadron ";
2563 LogTrace(
"PFAlgo|createCandidatesHCAL")
2564 <<
"\t\t" << sortedTracks.size() <<
" tracks -> check if the excess is photonic or hadronic";
2569 unsigned maxiEcal = 9999;
2573 LogTrace(
"PFAlgo|createCandidatesHCAL") <<
"loop over sortedTracks.size()=" << sortedTracks.size();
2574 for (
auto const& trk : sortedTracks) {
2575 unsigned iTrack = trk.second;
2583 auto iae = associatedEcals.find(iTrack);
2585 if (iae == associatedEcals.end())
2589 unsigned iEcal = iae->second.second;
2597 double pTrack = trackRef->p();
2598 double eECAL = clusterRef->energy();
2599 double eECALOverpTrack = eECAL / pTrack;
2603 maxEcalRef = clusterRef;
2609 std::vector<reco::PFClusterRef> pivotalClusterRef;
2610 std::vector<unsigned> iPivotal;
2611 std::vector<double> particleEnergy,
ecalEnergy, hcalEnergy, rawecalEnergy, rawhcalEnergy;
2612 std::vector<::math::XYZVector> particleDirection;
2616 if (ePhoton < totalEcal || eNeutralHadron - calibEcal < 1E-10) {
2617 if (!maxEcalRef.
isNull()) {
2619 mergedPhotonEnergy = ePhoton;
2623 if (!maxEcalRef.
isNull()) {
2625 mergedPhotonEnergy = totalEcalEGMCalib;
2628 mergedNeutralHadronEnergy = eNeutralHadron - calibEcal;
2631 if (mergedPhotonEnergy > 0) {
2641 sumEcalClusters =
sqrt(photonAtECAL.Mag2());
2644 const double clusterEnergyCalibrated =
2645 sqrt(std::get<1>(pae).Mag2()) *
2648 particleEnergy.push_back(mergedPhotonEnergy * clusterEnergyCalibrated / sumEcalClusters);
2649 particleDirection.push_back(std::get<1>(pae));
2650 ecalEnergy.push_back(mergedPhotonEnergy * clusterEnergyCalibrated / sumEcalClusters);
2651 hcalEnergy.push_back(0.);
2652 rawecalEnergy.push_back(totalEcal);
2653 rawhcalEnergy.push_back(0.);
2654 pivotalClusterRef.push_back(
elements[std::get<0>(pae)].clusterRef());
2655 iPivotal.push_back(std::get<0>(pae));
2659 if (mergedNeutralHadronEnergy > 1.0) {
2668 sumEcalClusters =
sqrt(hadronAtECAL.Mag2());
2671 const double clusterEnergyCalibrated =
2672 sqrt(std::get<1>(pae).Mag2()) *
2675 particleEnergy.push_back(mergedNeutralHadronEnergy * clusterEnergyCalibrated / sumEcalClusters);
2676 particleDirection.push_back(std::get<1>(pae));
2678 hcalEnergy.push_back(mergedNeutralHadronEnergy * clusterEnergyCalibrated / sumEcalClusters);
2679 rawecalEnergy.push_back(0.);
2680 rawhcalEnergy.push_back(totalHcal);
2681 pivotalClusterRef.push_back(hclusterref);
2682 iPivotal.push_back(iHcal);
2690 for (
unsigned iPivot = 0; iPivot < iPivotal.size(); ++iPivot) {
2691 if (particleEnergy[iPivot] < 0.)
2693 <<
"ALARM = Negative energy for iPivot=" << iPivot <<
", " << particleEnergy[iPivot];
2695 const bool useDirection =
true;
2697 particleEnergy[iPivot],
2699 particleDirection[iPivot].
X(),
2700 particleDirection[iPivot].
Y(),
2701 particleDirection[iPivot].
Z())];
2703 neutral.setEcalEnergy(rawecalEnergy[iPivot],
ecalEnergy[iPivot]);
2705 neutral.setHcalEnergy(rawhcalEnergy[iPivot], hcalEnergy[iPivot]);
2706 neutral.setHoEnergy(0., 0.);
2708 if (rawhcalEnergy[iPivot] == 0.) {
2709 neutral.setHcalEnergy(0., 0.);
2710 neutral.setHoEnergy(0., 0.);
2712 neutral.setHcalEnergy(
max(rawhcalEnergy[iPivot] - totalHO, 0.0),
2713 hcalEnergy[iPivot] *
max(1. - totalHO / rawhcalEnergy[iPivot], 0.));
2714 neutral.setHoEnergy(totalHO, totalHO * hcalEnergy[iPivot] / rawhcalEnergy[iPivot]);
2717 neutral.setPs1Energy(0.);
2718 neutral.setPs2Energy(0.);
2719 neutral.set_mva_nothing_gamma(-1.);
2722 neutral.addElementInBlock(blockref, iHcal);
2723 for (
unsigned iTrack : chargedHadronsInBlock) {
2724 neutral.addElementInBlock(blockref, iTrack);
2730 auto myEcals = associatedEcals.equal_range(iTrack);
2731 for (
auto ii = myEcals.first;
ii != myEcals.second; ++
ii) {
2732 unsigned iEcal =
ii->second.second;
2735 neutral.addElementInBlock(blockref, iEcal);
2750 double totalHcalEnergyCalibrated =
std::max(calibHcal - mergedNeutralHadronEnergy, 0.);
2752 double totalEcalEnergyCalibrated =
std::max(calibEcal - mergedPhotonEnergy, 0.);
2757 double chargedHadronsTotalEnergy = 0;
2758 for (
unsigned index : chargedHadronsIndices) {
2763 for (
unsigned index : chargedHadronsIndices) {
2772 fraction * totalHcalEnergyCalibrated * (1. - totalHO / totalHcal));
2780 for (
auto const& ecalSatellite : ecalSatellites) {
2782 unsigned iEcal = std::get<0>(ecalSatellite.second);
2793 active[iEcal] =
false;
2796 std::multimap<double, unsigned> assTracks;
2800 double ecalClusterEnergyCalibrated =
2801 sqrt(std::get<1>(ecalSatellite.second).Mag2()) *
2803 ecalSatellite.second);
2805 cand.setEcalEnergy(eclusterref->energy(), ecalClusterEnergyCalibrated);
2806 cand.setHcalEnergy(0., 0.);
2807 cand.setHoEnergy(0., 0.);
2808 cand.setPs1Energy(associatedPSs[iEcal].
first);
2809 cand.setPs2Energy(associatedPSs[iEcal].
second);
2810 cand.addElementInBlock(blockref, iEcal);
2811 cand.addElementInBlock(blockref, sortedTracks.begin()->second);
2813 if (fabs(eclusterref->energy() -
sqrt(std::get<1>(ecalSatellite.second).Mag2())) > 1
e-3 ||
2814 fabs(eclusterref->correctedEnergy() - ecalClusterEnergyCalibrated) > 1
e-3)
2816 <<
"ecalCluster vs ecalSatellites look inconsistent (eCluster E, calibE, ecalSatellite E, calib E): " 2817 << eclusterref->energy() <<
" " << eclusterref->correctedEnergy() <<
" " 2818 <<
sqrt(std::get<1>(ecalSatellite.second).Mag2()) <<
" " << ecalClusterEnergyCalibrated;
2824 LogTrace(
"PFAlgo|createCandidatesHCAL") <<
"end of function PFAlgo::createCandidatesHCAL";
2830 std::vector<bool>& active,
2833 std::vector<bool>& deadArea) {
2835 LogTrace(
"PFAlgo|createCandidatesHCALUnlinked")
2836 <<
"start of function PFAlgo::createCandidatesHCALUnlinked, hcalIs.size()=" << inds.
hcalIs.size();
2840 for (
unsigned iHcal : inds.
hcalIs) {
2842 std::vector<unsigned> ecalRefs;
2843 std::vector<unsigned> hoRefs;
2847 if (!active[iHcal]) {
2848 LogTrace(
"PFAlgo|createCandidatesHCALUnlinked") <<
"not active " << iHcal;
2853 std::multimap<double, unsigned> ecalElems;
2857 float totalEcal = 0.;
2860 for (
auto const&
ecal : ecalElems) {
2861 unsigned iEcal =
ecal.second;
2862 double dist =
ecal.first;
2889 std::multimap<double, unsigned> hcalElems;
2892 const bool isClosest = std::none_of(hcalElems.begin(), hcalElems.end(), [&](
auto const&
hcal) {
2893 return active[
hcal.second] &&
hcal.first < dist;
2900 LogTrace(
"PFAlgo|createCandidatesHCALUnlinked")
2901 <<
"\telement " <<
elements[iEcal] <<
" linked with dist " << dist;
2902 LogTrace(
"PFAlgo|createCandidatesHCALUnlinked") <<
"Added to HCAL cluster to form a neutral hadron";
2914 eClusterRef = eclusterRef;
2917 ecalRefs.push_back(iEcal);
2918 active[iEcal] =
false;
2923 double totalHO = 0.;
2927 std::multimap<double, unsigned> hoElems;
2935 for (
auto const&
ho : hoElems) {
2936 unsigned iHO =
ho.second;
2937 double dist =
ho.first;
2949 std::multimap<double, unsigned> hcalElems;
2952 const bool isClosest = std::none_of(hcalElems.begin(), hcalElems.end(), [&](
auto const&
hcal) {
2953 return active[
hcal.second] &&
hcal.first < dist;
2961 LogTrace(
"PFAlgo|createCandidatesHCALUnlinked")
2962 <<
"\telement " <<
elements[iHO] <<
" linked with dist " << dist;
2963 LogTrace(
"PFAlgo|createCandidatesHCALUnlinked") <<
"Added to HCAL cluster to form a neutral hadron";
2971 hoclusterRef->energy();
2973 totalHO += hoEnergy;
2974 if (hoEnergy > hoMax) {
2976 hoClusterRef = hoclusterRef;
2980 hoRefs.push_back(iHO);
2981 active[iHO] =
false;
2990 double totalHcal = hclusterRef->energy();
2993 totalHcal += totalHO;
2996 double calibEcal = totalEcal > 0. ? totalEcal : 0.;
2997 double calibHcal =
std::max(0., totalHcal);
2999 calibEcal = totalEcal;
3002 -1., calibEcal, calibHcal, hclusterRef->positionREP().Eta(), hclusterRef->positionREP().Phi());
3007 cand.setEcalEnergy(totalEcal, calibEcal);
3009 cand.setHcalEnergy(totalHcal, calibHcal);
3010 cand.setHoEnergy(0., 0.);
3012 cand.setHcalEnergy(
max(totalHcal - totalHO, 0.0), calibHcal * (1. - totalHO / totalHcal));
3013 cand.setHoEnergy(totalHO, totalHO * calibHcal / totalHcal);
3015 cand.setPs1Energy(0.);
3016 cand.setPs2Energy(0.);
3017 cand.addElementInBlock(blockref, iHcal);
3018 for (
auto const& ec : ecalRefs)
3019 cand.addElementInBlock(blockref, ec);
3020 for (
auto const&
ho : hoRefs)
3021 cand.addElementInBlock(blockref,
ho);
3029 std::vector<bool>& active,
3032 std::vector<bool>& deadArea) {
3033 LogTrace(
"PFAlgo|createCandidatesECAL")
3034 <<
"start of function PFAlgo::createCandidatesECAL(), ecalIs.size()=" << inds.
ecalIs.size();
3040 for (
unsigned i = 0;
i < inds.
ecalIs.size();
i++) {
3041 unsigned iEcal = inds.
ecalIs[
i];
3043 LogTrace(
"PFAlgo|createCandidatesECAL") <<
"elements[" << iEcal <<
"]=" <<
elements[iEcal];
3045 if (!active[iEcal]) {
3046 LogTrace(
"PFAlgo|createCandidatesECAL") <<
"iEcal=" << iEcal <<
" not active";
3056 active[iEcal] =
false;
3058 float ecalEnergy = clusterref->correctedEnergy();
3065 cand.setHcalEnergy(0., 0.);
3066 cand.setHoEnergy(0., 0.);
3067 cand.setPs1Energy(0.);
3068 cand.setPs2Energy(0.);
3069 cand.addElementInBlock(blockref, iEcal);
3072 LogTrace(
"PFAlgo|createCandidatesECAL") <<
"end of function PFALgo::createCandidatesECAL";
3076 std::list<reco::PFBlockRef>& hcalBlockRefs,
3077 std::list<reco::PFBlockRef>& ecalBlockRefs,
3082 LogTrace(
"PFAlgo|processBlock") <<
"start of function PFAlgo::processBlock, block=" <<
block;
3090 vector<bool> active(
elements.size(),
true);
3094 std::vector<reco::PFCandidate> tempElectronCandidates;
3095 tempElectronCandidates.clear();
3128 vector<bool> deadArea(
elements.size(),
false);
3137 if (!(inds.hfEmIs.empty() && inds.hfHadIs.empty())) {
3139 if (inds.hcalIs.empty() && inds.ecalIs.empty())
3142 <<
"Block contains HF clusters, and also contains ECAL or HCAL clusters. Continue.\n" 3151 LogTrace(
"PFAlgo|processBlock") <<
"end of function PFAlgo::processBlock";
3166 double pz =
track.pz();
3169 LogTrace(
"PFAlgo|reconstructTrack") <<
"Reconstructing PF candidate from track of pT = " <<
track.pt()
3170 <<
" eta = " <<
track.eta() <<
" phi = " <<
track.phi() <<
" px = " <<
px 3171 <<
" py = " <<
py <<
" pz = " << pz <<
" energy = " <<
energy;
3179 <<
", pt=" << momentum.pt() <<
", eta=" << momentum.eta()
3180 <<
", phi=" << momentum.phi();
3185 pfCandidates_->back().setPositionAtECALEntrance(eltTrack->positionAtECALEntrance());
3197 if ((!
isMuon) && isFromDisp) {
3198 double dpt = trackRef->ptError();
3199 double dptRel = dpt / trackRef->pt() * 100;
3204 LogTrace(
"PFAlgo|reconstructTrack")
3205 <<
"Not refitted px = " <<
px <<
" py = " <<
py <<
" pz = " << pz <<
" energy = " <<
energy;
3209 reco::Track trackRefit = vRef->refittedTrack(trackRef);
3212 trackRefit.
px(), trackRefit.
py(), trackRefit.
pz(),
sqrt(trackRefit.
p() * trackRefit.
p() + 0.13957 * 0.13957));
3213 LogTrace(
"PFAlgo|reconstructTrack")
3214 <<
"Refitted px = " <<
px <<
" py = " <<
py <<
" pz = " << pz <<
" energy = " <<
energy;
3235 double particleEnergy,
3240 LogTrace(
"PFAlgo|reconstructCluster") <<
"start of function PFAlgo::reconstructCluster, cluster=" << cluster
3241 <<
"particleEnergy=" << particleEnergy <<
"useDirection=" << useDirection
3242 <<
"particleX=" << particleX <<
"particleY=" << particleY
3243 <<
"particleZ=" << particleZ;
3253 switch (cluster.
layer()) {
3276 cluster.
position().Y() - vertexPos.Y(),
3277 cluster.
position().Z() - vertexPos.Z());
3279 particleX *
factor - vertexPos.X(), particleY *
factor - vertexPos.Y(), particleZ *
factor - vertexPos.Z());
3284 clusterPos = useDirection ? particleDirection.Unit() : clusterPos.Unit();
3285 clusterPos *= particleEnergy;
3291 ROOT::Math::LorentzVector<ROOT::Math::PxPyPzM4D<double>> momentum(
3292 clusterPos.X(), clusterPos.Y(), clusterPos.Z(),
mass);
3302 switch (cluster.
layer()) {
3323 <<
", pt=" <<
tmp.pt() <<
", eta=" <<
tmp.eta() <<
", phi=" <<
tmp.phi();
3346 std::array<double, 7> energyPerDepth;
3347 std::fill(energyPerDepth.begin(), energyPerDepth.end(), 0.0);
3349 const auto&
hit = *hitRefAndFrac.recHitRef();
3351 if (
hit.depth() == 0) {
3355 if (
hit.depth() < 1 ||
hit.depth() > 7) {
3356 throw cms::Exception(
"CorruptData") <<
"Bogus depth " <<
hit.depth() <<
" at detid " <<
hit.detId() <<
"\n";
3358 energyPerDepth[
hit.depth() - 1] += hitRefAndFrac.fraction() *
hit.energy();
3361 double sum = std::accumulate(energyPerDepth.begin(), energyPerDepth.end(), 0.);
3362 std::array<float, 7> depthFractions;
3364 for (
unsigned int i = 0;
i < depthFractions.size(); ++
i) {
3365 depthFractions[
i] = energyPerDepth[
i] / sum;
3368 std::fill(depthFractions.begin(), depthFractions.end(), 0.f);
3370 cand.setHcalDepthEnergyFractions(depthFractions);
3377 clusterEnergyHCAL =
std::max(clusterEnergyHCAL, 1.);
3379 double resol = fabs(
eta) < 1.48 ?
sqrt(1.02 * 1.02 / clusterEnergyHCAL + 0.065 * 0.065)
3380 :
sqrt(1.20 * 1.20 / clusterEnergyHCAL + 0.028 * 0.028);
3394 clusterEnergyHF =
std::max(clusterEnergyHF, 1.);
3418 out <<
"====== Particle Flow Algorithm ======= ";
3420 out <<
"nSigmaECAL_ " <<
algo.nSigmaECAL_ << endl;
3421 out <<
"nSigmaHCAL_ " <<
algo.nSigmaHCAL_ << endl;
3422 out <<
"nSigmaHFEM_ " <<
algo.nSigmaHFEM_ << endl;
3423 out <<
"nSigmaHFHAD_ " <<
algo.nSigmaHFHAD_ << endl;
3425 out <<
algo.calibration_ << endl;
3427 out <<
"reconstructed particles: " << endl;
3429 if (!
algo.pfCandidates_.get()) {
3430 out <<
"candidates already transfered" << endl;
3433 for (
auto const&
c : *
algo.pfCandidates_)
3444 std::vector<bool>& active,
3445 std::vector<double>& psEne) {
3452 std::multimap<double, unsigned> sortedPS;
3456 for (
auto const& ps : sortedPS) {
3458 unsigned iPS = ps.second;
3466 std::multimap<double, unsigned> sortedECAL;
3468 unsigned jEcal = sortedECAL.begin()->second;
3474 assert(pstype == psElementType);
3477 psEne[0] += psclusterref->energy();
3478 active[iPS] =
false;
3488 bool bPrimary = (
order.find(
"primary") != string::npos);
3489 bool bSecondary = (
order.find(
"secondary") != string::npos);
3490 bool bAll = (
order.find(
"all") != string::npos);
3495 if (bPrimary && isToDisp)
3497 if (bSecondary && isFromDisp)
3499 if (bAll && (isToDisp || isFromDisp))
3516 std::vector<unsigned int> pfCandidatesToBeRemoved;
3522 double met2 = metX * metX + metY * metY;
3527 double metXCor = metX;
3528 double metYCor = metY;
3529 double sumetCor = sumet;
3530 double met2Cor = met2;
3532 double deltaPhiPt = 100.;
3534 unsigned iCor = 1E9;
3538 double metReduc = -1.;
3552 const bool skip = std::any_of(
3553 pfCandidatesToBeRemoved.begin(), pfCandidatesToBeRemoved.end(), [&](
unsigned int j) {
return i ==
j; });
3564 double metXInt = metX - pfc.
px();
3565 double metYInt = metY - pfc.
py();
3566 double sumetInt = sumet - pfc.
pt();
3567 double met2Int = metXInt * metXInt + metYInt * metYInt;
3568 if (met2Int < met2Cor) {
3571 metReduc = (met2 - met2Int) / met2Int;
3573 sumetCor = sumetInt;
3574 significanceCor =
std::sqrt(met2Cor / sumetCor);
3581 pfCandidatesToBeRemoved.push_back(iCor);
3596 for (
unsigned int toRemove : pfCandidatesToBeRemoved) {
3597 edm::LogInfo(
"PFAlgo|postCleaning") <<
"Removed : " << (*pfCandidates_)[toRemove];
3599 (*pfCandidates_)[toRemove].rescaleMomentum(1E-6);
3609 if (cleanedHits.empty())
3616 std::vector<unsigned int> hitsToBeAdded;
3622 double met2 = metX * metX + metY * metY;
3623 double met2_Original = met2;
3627 double metXCor = metX;
3628 double metYCor = metY;
3629 double sumetCor = sumet;
3630 double met2Cor = met2;
3632 unsigned iCor = 1E9;
3636 double metReduc = -1.;
3638 for (
unsigned i = 0;
i < cleanedHits.size(); ++
i) {
3641 double px =
hit.energy() *
hit.position().
x() / length;
3642 double py =
hit.energy() *
hit.position().
y() / length;
3647 for (
unsigned int hitIdx : hitsToBeAdded) {
3657 double metXInt = metX +
px;
3658 double metYInt = metY +
py;
3659 double sumetInt = sumet +
pt;
3660 double met2Int = metXInt * metXInt + metYInt * metYInt;
3663 if (met2Int < met2Cor) {
3666 metReduc = (met2 - met2Int) / met2Int;
3668 sumetCor = sumetInt;
3677 hitsToBeAdded.push_back(iCor);
3690 LogTrace(
"PFAlgo|checkCleaning") << hitsToBeAdded.size() <<
" hits were re-added ";
3693 LogTrace(
"PFAlgo|checkCleaning") <<
"Added after cleaning check : ";
3694 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_
ROOT::Math::PositionVector3D< ROOT::Math::Cartesian3D< float > > XYZPointF
point in space with cartesian internal representation
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)
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
TupleMultiplicity< TrackerTraits > const *__restrict__ uint32_t nHits
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_
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