40 #include "Math/PxPyPzM4D.h" 41 #include "Math/LorentzVector.h" 42 #include "Math/DisplacementVector3D.h" 43 #include "Math/SMatrix.h" 44 #include "TDecompChol.h" 46 #include "boost/graph/adjacency_matrix.hpp" 47 #include "boost/graph/graph_utility.hpp" 53 using namespace boost;
55 typedef std::list< reco::PFBlockRef >::iterator
IBR;
81 const boost::shared_ptr<PFEnergyCalibration>& calibration,
82 const boost::shared_ptr<PFEnergyCalibrationHF>& thepfEnergyCalibrationHF) {
100 string mvaWeightFileEleID,
102 const boost::shared_ptr<PFSCEnergyCalibration>& thePFSCEnergyCalibration,
139 string err =
"PFAlgo: cannot open weight file '";
140 err += mvaWeightFileEleID;
142 throw invalid_argument( err );
146 thePFEnergyCalibration,
181 e(0, 0) = 0.0015 * 0.0015;
182 e(1, 1) = 0.0015 * 0.0015;
189 FILE * filePhotonConvID = fopen(mvaWeightFileConvID.c_str(),
"r");
190 if (filePhotonConvID) {
191 fclose(filePhotonConvID);
194 string err =
"PFAlgo: cannot open weight file '";
195 err += mvaWeightFileConvID;
197 throw invalid_argument( err );
205 thePFEnergyCalibration,
206 sumPtTrackIsoForPhoton,
207 sumPtTrackIsoSlopeForPhoton
215 double ele_iso_mva_barrel,
216 double ele_iso_mva_endcap,
217 double ele_iso_combIso_barrel,
218 double ele_iso_combIso_endcap,
219 double ele_noniso_mva,
220 unsigned int ele_missinghits,
227 double ph_sietaieta_eb,
228 double ph_sietaieta_ee,
237 FILE * fileEGamma_ele_iso_ID = fopen(ele_iso_path_mvaWeightFile.c_str(),
"r");
238 if (fileEGamma_ele_iso_ID) {
239 fclose(fileEGamma_ele_iso_ID);
242 string err =
"PFAlgo: cannot open weight file '";
243 err += ele_iso_path_mvaWeightFile;
245 throw invalid_argument( err );
256 ph_protectionsForJetMET,
257 ph_protectionsForBadHcal,
261 ele_iso_combIso_barrel,
262 ele_iso_combIso_endcap,
265 ele_iso_path_mvaWeightFile,
266 ele_protectionsForJetMET,
267 ele_protectionsForBadHcal);
302 GCorrForestBarrel, GCorrForestEndcapHr9,
303 GCorrForestEndcapLr9, PFEcalResolution);
325 assert (
muonHCAL_.size() == 2 && muonECAL_.size() == 2 && muonHO_.size() == 2);
329 assert ( factors45_.size() == 2 );
403 bool primaryVertexFound =
false;
404 nVtx_ = primaryVertices->size();
408 for (
unsigned short i=0 ;
i<primaryVertices->size();++
i)
410 if(primaryVertices->at(
i).isValid()&&(!primaryVertices->at(
i).isFake()))
413 primaryVertexFound =
true;
425 e(0, 0) = 0.0015 * 0.0015;
426 e(1, 1) = 0.0015 * 0.0015;
474 cout<<
"*********************************************************"<<endl;
475 cout<<
"***** Particle flow algorithm *****"<<endl;
476 cout<<
"*********************************************************"<<endl;
480 std::list< reco::PFBlockRef > hcalBlockRefs;
481 std::list< reco::PFBlockRef > ecalBlockRefs;
482 std::list< reco::PFBlockRef > hoBlockRefs;
483 std::list< reco::PFBlockRef > otherBlockRefs;
485 for(
unsigned i=0;
i<blocks.size(); ++
i ) {
493 bool singleEcalOrHcal =
false;
494 if( elements.
size() == 1 ){
496 ecalBlockRefs.push_back( blockref );
497 singleEcalOrHcal =
true;
500 hcalBlockRefs.push_back( blockref );
501 singleEcalOrHcal =
true;
505 hoBlockRefs.push_back( blockref );
506 singleEcalOrHcal =
true;
510 if(!singleEcalOrHcal) {
511 otherBlockRefs.push_back( blockref );
516 cout<<
"# Ecal blocks: "<<ecalBlockRefs.size()
517 <<
", # Hcal blocks: "<<hcalBlockRefs.size()
518 <<
", # HO blocks: "<<hoBlockRefs.size()
519 <<
", # Other blocks: "<<otherBlockRefs.size()<<endl;
527 for(
IBR io = otherBlockRefs.begin(); io!=otherBlockRefs.end(); ++io) {
532 std::list< reco::PFBlockRef >
empty;
536 for(
IBR ih = hcalBlockRefs.begin(); ih!=hcalBlockRefs.end(); ++ih) {
537 if (
debug_ )
std::cout <<
"HCAL block number " << hblcks++ << std::endl;
543 for(
IBR ie = ecalBlockRefs.begin(); ie!=ecalBlockRefs.end(); ++ie) {
544 if (
debug_ )
std::cout <<
"ECAL block number " << eblcks++ << std::endl;
561 std::list<reco::PFBlockRef>& hcalBlockRefs,
562 std::list<reco::PFBlockRef>& ecalBlockRefs ) {
565 assert(!blockref.
isNull() );
568 typedef std::multimap<double, unsigned>::iterator IE;
569 typedef std::multimap<double, std::pair<unsigned,::math::XYZVector> >::iterator IS;
570 typedef std::multimap<double, std::pair<unsigned,bool> >::iterator
IT;
571 typedef std::multimap< unsigned, std::pair<double, unsigned> >::iterator II;
574 cout<<
"#########################################################"<<endl;
575 cout<<
"##### Process Block: #####"<<endl;
576 cout<<
"#########################################################"<<endl;
586 vector<bool> active( elements.
size(),
true );
591 std::vector<reco::PFCandidate> tempElectronCandidates;
592 tempElectronCandidates.clear();
597 for ( std::vector<reco::PFCandidate>::const_iterator
ec=PFElectCandidates_.begin();
ec != PFElectCandidates_.end(); ++
ec )tempElectronCandidates.push_back(*
ec);
617 cout<<endl<<
"--------------- entering PFPhotonAlgo ----------------"<<endl;
618 vector<PFCandidatePhotonExtra> pfPhotonExtraCand;
623 tempElectronCandidates
633 unsigned int extracand =0;
641 pfPhotonExtraCand.clear();
646 for ( std::vector<reco::PFCandidate>::const_iterator
ec=tempElectronCandidates.begin();
ec != tempElectronCandidates.end(); ++
ec ){
649 tempElectronCandidates.clear();
657 bool egmLocalDebug =
debug_;
658 bool egmLocalBlockDebug =
false;
661 for(
unsigned int ieg=0 ; ieg < negmcandidates; ++ieg) {
666 PFCandidate::ElementsInBlocks::const_iterator iegfirst = theElements.begin();
667 bool sameBlock =
false;
668 bool isGoodElectron =
false;
669 bool isGoodPhoton =
false;
670 bool isPrimaryElectron =
false;
671 if(iegfirst->first == blockref)
676 cout <<
" I am in looping on EGamma Candidates: pt " << (*pfEgmRef).pt()
677 <<
" eta,phi " << (*pfEgmRef).eta() <<
", " << (*pfEgmRef).phi()
678 <<
" charge " << (*pfEgmRef).charge() << endl;
680 if((*pfEgmRef).gsfTrackRef().isNonnull()) {
688 cout <<
"** Good Electron, pt " << gedEleRef->pt()
689 <<
" eta, phi " << gedEleRef->eta() <<
", " << gedEleRef->phi()
690 <<
" charge " << gedEleRef->charge()
691 <<
" isPrimary " << isPrimaryElectron
692 <<
" isoDr03 " << (gedEleRef->dr03TkSumPt() + gedEleRef->dr03EcalRecHitSumEt() + gedEleRef->dr03HcalTowerSumEt())
693 <<
" mva_isolated " << gedEleRef->mva_Isolated()
694 <<
" mva_e_pi " << gedEleRef->mva_e_pi()
701 if((*pfEgmRef).superClusterRef().isNonnull()) {
708 cout <<
"** Good Photon, pt " << gedPhoRef->pt()
709 <<
" eta, phi " << gedPhoRef->eta() <<
", " << gedPhoRef->phi() << endl;
715 if(isGoodElectron && isGoodPhoton) {
716 if(isPrimaryElectron)
717 isGoodPhoton =
false;
719 isGoodElectron =
false;
727 bool lockTracks =
false;
737 myPFElectron.
setCharge(gedEleRef->charge());
738 myPFElectron.
setP4(gedEleRef->p4());
743 cout <<
" PFAlgo: found an electron with NEW EGamma code " << endl;
744 cout <<
" myPFElectron: pt " << myPFElectron.
pt()
745 <<
" eta,phi " << myPFElectron.
eta() <<
", " <<myPFElectron.
phi()
746 <<
" mva " << myPFElectron.
mva_e_pi()
747 <<
" charge " << myPFElectron.
charge() << endl;
752 if(egmLocalBlockDebug)
753 cout <<
" THE BLOCK " << *blockref << endl;
754 for (PFCandidate::ElementsInBlocks::const_iterator ieb = theElements.begin();
755 ieb<theElements.end(); ++ieb) {
756 active[ieb->second] =
false;
757 if(egmLocalBlockDebug||(
debug_&&egmLocalDebug))
758 cout <<
" Elements used " << ieb->second << endl;
764 for (PFCandidate::ElementsInBlocks::const_iterator itrk = extraTracks.begin();
765 itrk<extraTracks.end(); ++itrk) {
766 if(egmLocalBlockDebug||(
debug_&&egmLocalDebug))
767 cout <<
" Extra locked track " << itrk->second << endl;
768 active[itrk->second] =
false;
777 cout <<
"PFAlgo: Electron DISCARDED, NOT SAFE FOR JETMET " << endl;
797 myPFPhoton.
setP4(gedPhoRef->p4());
799 cout <<
" PFAlgo: found a photon with NEW EGamma code " << endl;
800 cout <<
" myPFPhoton: pt " << myPFPhoton.
pt()
801 <<
" eta,phi " << myPFPhoton.
eta() <<
", " <<myPFPhoton.
phi()
802 <<
" charge " << myPFPhoton.
charge() << endl;
806 if(egmLocalBlockDebug)
807 cout <<
" THE BLOCK " << *blockref << endl;
808 for (PFCandidate::ElementsInBlocks::const_iterator ieb = theElements.begin();
809 ieb<theElements.end(); ++ieb) {
810 active[ieb->second] =
false;
811 if(egmLocalBlockDebug||(
debug_&&egmLocalDebug))
812 cout <<
" Elements used " << ieb->second << endl;
826 for(
unsigned iEle=0; iEle<elements.
size(); iEle++) {
828 if(type==PFBlockElement::TRACK)
835 if(!elements[iEle].convRefs().
empty())active[iEle]=
false;
845 cout<<endl<<
"--------------- loop 1 ------------------"<<endl;
872 vector<unsigned> hcalIs;
873 vector<unsigned> hoIs;
874 vector<unsigned> ecalIs;
875 vector<unsigned> trackIs;
876 vector<unsigned> ps1Is;
877 vector<unsigned> ps2Is;
879 vector<unsigned> hfEmIs;
880 vector<unsigned> hfHadIs;
882 vector<bool> deadArea(elements.
size(),
false);
884 for(
unsigned iEle=0; iEle<elements.
size(); iEle++) {
887 if(
debug_ && type != PFBlockElement::BREM )
cout<<endl<<elements[iEle];
890 case PFBlockElement::TRACK:
891 if ( active[iEle] ) {
893 if(
debug_)
cout<<
"TRACK, stored index, continue"<<endl;
897 if ( active[iEle] ) {
898 ecalIs.push_back( iEle );
899 if(
debug_)
cout<<
"ECAL, stored index, continue"<<endl;
903 if ( active[iEle] ) {
905 if(
debug_)
cout<<
"HCAL DEAD AREA: remember and skip."<<endl;
906 active[iEle] =
false;
907 deadArea[iEle] =
true;
910 hcalIs.push_back( iEle );
911 if(
debug_)
cout<<
"HCAL, stored index, continue"<<endl;
916 if ( active[iEle] ) {
917 hoIs.push_back( iEle );
918 if(
debug_)
cout<<
"HO, stored index, continue"<<endl;
922 case PFBlockElement::HFEM:
923 if ( active[iEle] ) {
924 hfEmIs.push_back( iEle );
925 if(
debug_)
cout<<
"HFEM, stored index, continue"<<endl;
928 case PFBlockElement::HFHAD:
929 if ( active[iEle] ) {
930 hfHadIs.push_back( iEle );
931 if(
debug_)
cout<<
"HFHAD, stored index, continue"<<endl;
939 unsigned iTrack = iEle;
942 cout <<
"track " << iTrack <<
" has a valid muon reference. " << std::endl;
952 if (active[iTrack] &&
isFromSecInt(elements[iEle],
"primary")){
953 bool isPrimaryTrack = elements[iEle].displacedVertexRef(PFBlockElement::T_TO_DISP)->displacedVertexRef()->isTherePrimaryTracks();
954 if (isPrimaryTrack) {
955 if (
debug_)
cout <<
"Primary Track reconstructed alone" << endl;
958 (*pfCandidates_)[tmpi].addElementInBlock( blockref, iEle );
959 active[iTrack] =
false;
965 if ( !active[iTrack] )
966 cout <<
"Already used by electrons, muons, conversions" << endl;
971 if ( ! active[iTrack] )
continue;
974 assert( !trackRef.
isNull() );
977 cout <<
"PFAlgo:processBlock "<<
" "<<trackIs.size()<<
" "<<ecalIs.size()<<
" "<<hcalIs.size()<<
" "<<hoIs.size()<<endl;
984 std::multimap<double, unsigned> ecalElems;
985 block.associatedElements( iTrack, linkData,
990 std::multimap<double, unsigned> hcalElems;
991 block.associatedElements( iTrack, linkData,
997 std::cout <<
"\tTrack " << iTrack <<
" is linked to " << ecalElems.size() <<
" ecal and " << hcalElems.size() <<
" hcal elements" << std::endl;
998 for (
const auto & pair : ecalElems) {
999 std::cout <<
"ecal: dist " << pair.first <<
"\t elem " << pair.second << std::endl;
1001 for (
const auto & pair : hcalElems) {
1002 std::cout <<
"hcal: dist " << pair.first <<
"\t elem " << pair.second << (deadArea[pair.second] ?
" DEAD AREA MARKER" :
"") << std::endl;
1017 bool hasDeadHcal =
false;
1018 if (!hcalElems.empty() && deadArea[hcalElems.begin()->second]) {
1030 bool goodTrackDeadHcal =
false;
1038 if (!goodTrackDeadHcal &&
1040 trackRef->hitPattern().pixelLayersWithMeasurement() >= 3 &&
1041 trackRef->hitPattern().trackerLayersWithoutMeasurement(HitPattern::TRACK_HITS) == 0 &&
1042 trackRef->hitPattern().trackerLayersWithoutMeasurement(HitPattern::MISSING_INNER_HITS) == 0 &&
1043 trackRef->hitPattern().trackerLayersWithoutMeasurement(HitPattern::MISSING_OUTER_HITS) <= (
1044 trackRef->hitPattern().pixelLayersWithMeasurement() > 3 ?
1051 goodTrackDeadHcal =
true;
1055 if (
debug_)
cout <<
" track pt " << trackRef->pt() <<
" +- " << trackRef->ptError()
1056 <<
" layers valid " << trackRef->hitPattern().trackerLayersWithMeasurement()
1057 <<
", lost " << trackRef->hitPattern().trackerLayersWithoutMeasurement(HitPattern::TRACK_HITS)
1058 <<
", lost outer " << trackRef->hitPattern().trackerLayersWithoutMeasurement(HitPattern::MISSING_OUTER_HITS)
1059 <<
", lost inner " << trackRef->hitPattern().trackerLayersWithoutMeasurement(HitPattern::MISSING_INNER_HITS)
1060 <<
"(valid fraction " << trackRef->validFraction() <<
")" 1061 <<
" chi2/ndf " << trackRef->normalizedChi2()
1064 << (goodTrackDeadHcal ?
" passes " :
" fails ") <<
"quality cuts" << std::endl;
1070 if ( hcalElems.empty() && !ecalElems.empty() && !hasDeadHcal) {
1073 unsigned index = ecalElems.begin()->second;
1074 std::multimap<double, unsigned> sortedTracks;
1075 block.associatedElements( index, linkData,
1079 if (
debug_ )
std::cout <<
"The closest ECAL cluster is linked to " << sortedTracks.size() <<
" tracks, with distance = " << ecalElems.begin()->first << std::endl;
1082 for(IE ie = sortedTracks.begin(); ie != sortedTracks.end(); ++ie ) {
1083 unsigned jTrack = ie->second;
1086 if ( !active[jTrack] )
continue;
1090 if ( jTrack == iTrack )
continue;
1095 std::multimap<double, unsigned> sortedECAL;
1096 block.associatedElements( jTrack, linkData,
1100 if ( sortedECAL.begin()->second !=
index )
continue;
1101 if (
debug_ )
std::cout <<
" track " << jTrack <<
" with closest ECAL identical " << std::endl;
1105 std::multimap<double, unsigned> sortedHCAL;
1106 block.associatedElements( jTrack, linkData,
1110 if ( sortedHCAL.empty() )
continue;
1111 if (
debug_ )
std::cout <<
" and with an HCAL cluster " << sortedHCAL.begin()->second << std::endl;
1115 block.setLink( iTrack,
1116 sortedHCAL.begin()->second,
1117 sortedECAL.begin()->first,
1119 PFBlock::LINKTEST_RECHIT );
1124 block.associatedElements( iTrack, linkData,
1129 if (
debug_ && !hcalElems.empty() )
1130 std::cout <<
"Track linked back to HCAL due to ECAL sharing with other tracks" << std::endl;
1140 std::multimap<double,unsigned> gsfElems;
1142 block.associatedElements( iTrack, linkData,
1148 if(hcalElems.empty() &&
debug_) {
1149 cout<<
"no hcal element connected to track "<<iTrack<<endl;
1155 bool hcalFound =
false;
1158 cout<<
"now looping on elements associated to the track"<<endl;
1162 for(IE ie = ecalElems.begin(); ie != ecalElems.end(); ++ie ) {
1164 unsigned index = ie->second;
1168 double dist = ie->first;
1169 cout<<
"\telement "<<elements[
index]<<
" linked with distance = "<< dist <<endl;
1170 if ( ! active[index] )
cout <<
"This ECAL is already used - skip it" << endl;
1175 if ( ! active[index] )
continue;
1181 if( !hcalElems.empty() &&
debug_)
1182 cout<<
"\t\tat least one hcal element connected to the track." 1183 <<
" Sparing Ecal cluster for the hcal loop"<<endl;
1191 if( hcalElems.empty() ) {
1194 std::cout <<
"Now deals with tracks linked to no HCAL clusters. Was HCal active? " << (!hasDeadHcal) << std::endl;
1201 std::cout << elements[iTrack] << std::endl;
1207 if ( thisIsAMuon ) trackMomentum = 0.;
1211 bool rejectFake =
false;
1212 if ( !thisIsAMuon && elements[iTrack].trackRef()->ptError() >
ptError_ ) {
1216 elements[iTrack].trackRef()->
eta());
1219 if ( !ecalElems.empty() ) {
1220 unsigned thisEcal = ecalElems.begin()->second;
1222 bool useCluster =
true;
1224 std::multimap<double, unsigned> sortedTracks;
1225 block.associatedElements( thisEcal, linkData,
1229 useCluster = (sortedTracks.begin()->second == iTrack);
1232 deficit -= clusterRef->energy();
1234 clusterRef->positionREP().Eta());
1239 bool isPrimary =
isFromSecInt(elements[iTrack],
"primary");
1241 if ( deficit >
nSigmaTRACK_*resol && !isPrimary && !goodTrackDeadHcal) {
1243 active[iTrack] =
false;
1245 std::cout << elements[iTrack] << std::endl
1246 <<
" deficit " << deficit <<
" > " <<
nSigmaTRACK_ <<
" x " << resol
1247 <<
" track pt " << trackRef->pt() <<
" +- " << trackRef->ptError()
1248 <<
" layers valid " << trackRef->hitPattern().trackerLayersWithMeasurement()
1249 <<
", lost " << trackRef->hitPattern().trackerLayersWithoutMeasurement(HitPattern::TRACK_HITS)
1250 <<
", lost outer " << trackRef->hitPattern().trackerLayersWithoutMeasurement(HitPattern::MISSING_OUTER_HITS)
1251 <<
", lost inner " << trackRef->hitPattern().trackerLayersWithoutMeasurement(HitPattern::MISSING_INNER_HITS)
1252 <<
"(valid fraction " << trackRef->validFraction() <<
")" 1253 <<
" chi2/ndf " << trackRef->normalizedChi2()
1256 <<
"is probably a fake (1) --> lock the track" 1261 if ( rejectFake )
continue;
1266 std::vector<unsigned> tmpi;
1267 std::vector<unsigned> kTrack;
1270 double Dpt = trackRef->ptError();
1273 trackMomentum > 30. && Dpt > 0.5 &&
1275 && !goodTrackDeadHcal) ) {
1277 double dptRel = Dpt/trackRef->pt()*100;
1278 bool isPrimaryOrSecondary =
isFromSecInt(elements[iTrack],
"all");
1281 unsigned nHits = elements[iTrack].trackRef()->hitPattern().trackerLayersWithMeasurement();
1282 unsigned int NLostHit = trackRef->hitPattern().trackerLayersWithoutMeasurement(HitPattern::TRACK_HITS);
1285 std::cout <<
"A track (algo = " << trackRef->algo() <<
") with momentum " << trackMomentum
1286 <<
" / " << elements[iTrack].trackRef()->pt() <<
" +/- " << Dpt
1287 <<
" / " << elements[iTrack].trackRef()->eta()
1288 <<
" without any link to ECAL/HCAL and with " << nHits <<
" (" << NLostHit
1289 <<
") hits (lost hits) has been cleaned" << std::endl;
1290 active[iTrack] =
false;
1297 kTrack.push_back(iTrack);
1298 active[iTrack] =
false;
1301 if ( ecalElems.empty() ) {
1302 (*pfCandidates_)[tmpi[0]].setEcalEnergy( 0., 0. );
1303 (*pfCandidates_)[tmpi[0]].setHcalEnergy( 0., 0. );
1304 (*pfCandidates_)[tmpi[0]].setHoEnergy( 0., 0. );
1305 (*pfCandidates_)[tmpi[0]].setPs1Energy( 0 );
1306 (*pfCandidates_)[tmpi[0]].setPs2Energy( 0 );
1307 (*pfCandidates_)[tmpi[0]].addElementInBlock( blockref, kTrack[0] );
1312 unsigned thisEcal = ecalElems.begin()->second;
1314 if (
debug_ )
std::cout <<
" is associated to " << elements[thisEcal] << std::endl;
1318 if ( thisIsAMuon ) {
1319 (*pfCandidates_)[tmpi[0]].setEcalEnergy( clusterRef->energy(),
1321 (*pfCandidates_)[tmpi[0]].setHcalEnergy( 0., 0. );
1322 (*pfCandidates_)[tmpi[0]].setHoEnergy( 0., 0. );
1323 (*pfCandidates_)[tmpi[0]].setPs1Energy( 0 );
1324 (*pfCandidates_)[tmpi[0]].setPs2Energy( 0 );
1325 (*pfCandidates_)[tmpi[0]].addElementInBlock( blockref, kTrack[0] );
1328 double slopeEcal = 1.;
1329 bool connectedToEcal =
false;
1330 unsigned iEcal = 99999;
1331 double calibEcal = 0.;
1332 double calibHcal = 0.;
1333 double totalEcal = thisIsAMuon ? -
muonECAL_[0] : 0.;
1336 std::multimap<double, unsigned> sortedTracks;
1337 block.associatedElements( thisEcal, linkData,
1341 if (
debug_)
cout <<
"the closest ECAL cluster, id " << thisEcal <<
", has " << sortedTracks.size() <<
" associated tracks, now processing them. " << endl;
1343 if (hasDeadHcal && !sortedTracks.empty()) {
1345 if (
debug_)
cout <<
" the closest track to ECAL " << thisEcal <<
" is " << sortedTracks.begin()->second <<
" (distance " << sortedTracks.begin()->first <<
")" << endl;
1346 if (sortedTracks.begin()->second != iTrack) {
1347 if (
debug_)
cout <<
" the closest track to ECAL " << thisEcal <<
" is " << sortedTracks.begin()->second <<
" which is not the one being processed. Will skip ECAL linking for this track" << endl;
1348 (*pfCandidates_)[tmpi[0]].setEcalEnergy( 0., 0. );
1349 (*pfCandidates_)[tmpi[0]].setHcalEnergy( 0., 0. );
1350 (*pfCandidates_)[tmpi[0]].setHoEnergy( 0., 0. );
1351 (*pfCandidates_)[tmpi[0]].setPs1Energy( 0 );
1352 (*pfCandidates_)[tmpi[0]].setPs2Energy( 0 );
1353 (*pfCandidates_)[tmpi[0]].addElementInBlock( blockref, kTrack[0] );
1356 if (
debug_)
cout <<
" the closest track to ECAL " << thisEcal <<
" is " << sortedTracks.begin()->second <<
" which is the one being processed. Will skip ECAL linking for all other track" << endl;
1357 sortedTracks.clear();
1361 for(IE ie = sortedTracks.begin(); ie != sortedTracks.end(); ++ie ) {
1362 unsigned jTrack = ie->second;
1365 if ( !active[jTrack] )
continue;
1368 if ( jTrack == iTrack )
continue;
1376 std::multimap<double, unsigned> sortedECAL;
1377 block.associatedElements( jTrack, linkData,
1381 if ( sortedECAL.begin()->second != thisEcal )
continue;
1386 cout <<
" found track " << jTrack << (thatIsAMuon ?
" (muon) " :
" (non-muon)") <<
", with distance = " << sortedECAL.begin()->first << std::endl;
1391 bool rejectFake =
false;
1393 if ( !thatIsAMuon && trackRef->ptError() >
ptError_) {
1396 double deficit = trackMomentum + trackRef->p() - clusterRef->energy();
1398 clusterRef->positionREP().Eta());
1399 resol *= (trackMomentum+trackRef->p());
1400 if ( deficit >
nSigmaTRACK_*resol && !goodTrackDeadHcal) {
1402 kTrack.push_back(jTrack);
1403 active[jTrack] =
false;
1405 std::cout << elements[jTrack] << std::endl
1406 <<
"is probably a fake (2) --> lock the track" 1407 <<
"(trackMomentum = " << trackMomentum <<
", clusterEnergy = " << clusterRef->energy() <<
1408 ", deficit = " << deficit <<
" > " <<
nSigmaTRACK_ <<
" x " << resol <<
1409 " assuming neutralHadronEnergyResolution " <<
neutralHadronEnergyResolution(trackMomentum+trackRef->p(), clusterRef->positionREP().Eta()) <<
") " 1413 if ( rejectFake )
continue;
1419 if ( !thatIsAMuon ) {
1421 std::cout <<
"Track momentum increased from " << trackMomentum <<
" GeV ";
1422 trackMomentum += trackRef->p();
1424 std::cout <<
"to " << trackMomentum <<
" GeV." << std::endl;
1425 std::cout <<
"with " << elements[jTrack] << std::endl;
1429 totalEcal =
std::max(totalEcal, 0.);
1437 kTrack.push_back(jTrack);
1438 active[jTrack] =
false;
1440 if ( thatIsAMuon ) {
1441 (*pfCandidates_)[tmpi.back()].setEcalEnergy(clusterRef->energy(),
1443 (*pfCandidates_)[tmpi.back()].setHcalEnergy( 0., 0. );
1444 (*pfCandidates_)[tmpi.back()].setHoEnergy( 0., 0. );
1445 (*pfCandidates_)[tmpi.back()].setPs1Energy( 0 );
1446 (*pfCandidates_)[tmpi.back()].setPs2Energy( 0 );
1447 (*pfCandidates_)[tmpi.back()].addElementInBlock( blockref, kTrack.back() );
1452 if (
debug_ )
std::cout <<
"Loop over all associated ECAL clusters" << std::endl;
1454 for(IE ie = ecalElems.begin(); ie != ecalElems.end(); ++ie ) {
1456 unsigned index = ie->second;
1462 if (
debug_ && ! active[index] )
std::cout <<
"is not active - ignore " << std::endl;
1463 if ( ! active[index] )
continue;
1467 block.associatedElements( index, linkData,
1472 for (
unsigned ic=0; ic<kTrack.size();++ic) {
1473 if ( sortedTracks.begin()->second == kTrack[ic] ) {
1478 if (
debug_ && skip )
std::cout <<
"is closer to another track - ignore " << std::endl;
1479 if ( skip )
continue;
1484 assert( !clusterRef.
isNull() );
1487 double dist = ie->first;
1488 std::cout <<
"Ecal cluster with raw energy = " << clusterRef->energy()
1489 <<
" linked with distance = " << dist << std::endl;
1504 vector<double> ps1Ene(1,static_cast<double>(0.));
1506 vector<double> ps2Ene(1,static_cast<double>(0.));
1509 double ecalEnergy = clusterRef->correctedEnergy();
1511 std::cout <<
"Corrected ECAL(+PS) energy = " << ecalEnergy << std::endl;
1515 totalEcal += ecalEnergy;
1516 double previousCalibEcal = calibEcal;
1517 double previousSlopeEcal = slopeEcal;
1518 calibEcal =
std::max(totalEcal,0.);
1520 calibration_->energyEmHad(trackMomentum,calibEcal,calibHcal,
1521 clusterRef->positionREP().Eta(),
1522 clusterRef->positionREP().Phi());
1523 if ( totalEcal > 0.) slopeEcal = calibEcal/totalEcal;
1526 std::cout <<
"The total calibrated energy so far amounts to = " << calibEcal <<
" (slope = " << slopeEcal <<
")" << std::endl;
1530 if ( connectedToEcal && calibEcal - trackMomentum >= 0. ) {
1533 calibEcal = previousCalibEcal;
1534 slopeEcal = previousSlopeEcal;
1535 totalEcal = calibEcal/slopeEcal;
1539 active[
index] =
false;
1542 std::multimap<double, unsigned> assTracks;
1543 block.associatedElements( index, linkData,
1550 (*pfCandidates_)[tmpe].setEcalEnergy( clusterRef->energy(), ecalEnergy );
1551 (*pfCandidates_)[tmpe].setHcalEnergy( 0., 0. );
1552 (*pfCandidates_)[tmpe].setHoEnergy( 0., 0. );
1553 (*pfCandidates_)[tmpe].setPs1Energy( ps1Ene[0] );
1554 (*pfCandidates_)[tmpe].setPs2Energy( ps2Ene[0] );
1555 (*pfCandidates_)[tmpe].addElementInBlock( blockref, index );
1557 if(!assTracks.empty()) {
1558 (*pfCandidates_)[tmpe].addElementInBlock( blockref, assTracks.begin()->second );
1569 connectedToEcal =
true;
1571 active[
index] =
false;
1572 for (
unsigned ic=0; ic<tmpi.size();++ic)
1573 (*
pfCandidates_)[tmpi[ic]].addElementInBlock( blockref, iEcal );
1578 bool bNeutralProduced =
false;
1581 if( connectedToEcal ) {
1623 neutralEnergy /= slopeEcal;
1625 (*pfCandidates_)[tmpj].setEcalEnergy( pivotalRef->energy(), neutralEnergy );
1626 (*pfCandidates_)[tmpj].setHcalEnergy( 0., 0. );
1627 (*pfCandidates_)[tmpj].setHoEnergy( 0., 0. );
1628 (*pfCandidates_)[tmpj].setPs1Energy( 0. );
1629 (*pfCandidates_)[tmpj].setPs2Energy( 0. );
1630 (*pfCandidates_)[tmpj].addElementInBlock(blockref, iEcal);
1631 bNeutralProduced =
true;
1632 for (
unsigned ic=0; ic<kTrack.size();++ic)
1633 (*
pfCandidates_)[tmpj].addElementInBlock( blockref, kTrack[ic] );
1637 for (
unsigned ic=0; ic<tmpi.size();++ic) {
1642 double fraction = trackMomentum > 0 ? (*pfCandidates_)[tmpi[ic]].trackRef()->p()/trackMomentum : 0;
1643 double ecalCal = bNeutralProduced ?
1644 (calibEcal-neutralEnergy*slopeEcal)*fraction : calibEcal*fraction;
1645 double ecalRaw = totalEcal*
fraction;
1647 if (
debug_)
cout <<
"The fraction after photon supression is " << fraction <<
" calibrated ecal = " << ecalCal << endl;
1649 (*pfCandidates_)[tmpi[ic]].setEcalEnergy( ecalRaw, ecalCal );
1650 (*pfCandidates_)[tmpi[ic]].setHcalEnergy( 0., 0. );
1651 (*pfCandidates_)[tmpi[ic]].setHoEnergy( 0., 0. );
1652 (*pfCandidates_)[tmpi[ic]].setPs1Energy( 0 );
1653 (*pfCandidates_)[tmpi[ic]].setPs2Energy( 0 );
1654 (*pfCandidates_)[tmpi[ic]].addElementInBlock( blockref, kTrack[ic] );
1660 for (
unsigned ic=0; ic<tmpi.size();++ic) {
1661 const PFCandidate& pfc = (*pfCandidates_)[tmpi[ic]];
1663 if ( eleInBlocks.empty() ) {
1664 if (
debug_ )
std::cout <<
"Single track / Fill element in block! " << std::endl;
1665 (*pfCandidates_)[tmpi[ic]].addElementInBlock( blockref, kTrack[ic] );
1674 for(IE ie = hcalElems.begin(); ie != hcalElems.end(); ++ie ) {
1676 unsigned index = ie->second;
1682 cout<<
"\telement "<<elements[
index]<<
" linked with distance "<< dist <<endl;
1691 cout<<
"\t\tclosest hcal cluster, doing nothing"<<endl;
1701 cout<<
"\t\tsecondary hcal cluster. unlinking"<<endl;
1702 block.setLink( iTrack, index, -1., linkData,
1703 PFBlock::LINKTEST_RECHIT );
1711 if( !(hfEmIs.empty() && hfHadIs.empty() ) ) {
1714 assert( hfEmIs.size() + hfHadIs.size() == elements.
size() );
1716 if( elements.
size() == 1 ) {
1719 double energyHF = 0.;
1720 double uncalibratedenergyHF = 0.;
1722 switch( clusterRef->layer() ) {
1725 energyHF = clusterRef->energy();
1726 uncalibratedenergyHF = energyHF;
1729 clusterRef->positionREP().Eta(),
1730 clusterRef->positionREP().Phi());
1733 (*pfCandidates_)[tmpi].setEcalEnergy( uncalibratedenergyHF, energyHF );
1734 (*pfCandidates_)[tmpi].setHcalEnergy( 0., 0.);
1735 (*pfCandidates_)[tmpi].setHoEnergy( 0., 0.);
1736 (*pfCandidates_)[tmpi].setPs1Energy( 0. );
1737 (*pfCandidates_)[tmpi].setPs2Energy( 0. );
1738 (*pfCandidates_)[tmpi].addElementInBlock( blockref, hfEmIs[0] );
1743 energyHF = clusterRef->energy();
1744 uncalibratedenergyHF = energyHF;
1747 clusterRef->positionREP().Eta(),
1748 clusterRef->positionREP().Phi());
1751 (*pfCandidates_)[tmpi].setHcalEnergy( uncalibratedenergyHF, energyHF );
1752 (*pfCandidates_)[tmpi].setEcalEnergy( 0., 0.);
1753 (*pfCandidates_)[tmpi].setHoEnergy( 0., 0.);
1754 (*pfCandidates_)[tmpi].setPs1Energy( 0. );
1755 (*pfCandidates_)[tmpi].setPs2Energy( 0. );
1756 (*pfCandidates_)[tmpi].addElementInBlock( blockref, hfHadIs[0] );
1763 else if( elements.
size() == 2 ) {
1772 cerr<<
"Error: 2 elements, but not 1 HFEM and 1 HFHAD"<<endl;
1779 double energyHfEm = cem->energy();
1780 double energyHfHad = chad->energy();
1781 double uncalibratedenergyHFEm = energyHfEm;
1782 double uncalibratedenergyHFHad = energyHfHad;
1787 c0->positionREP().Eta(),
1788 c0->positionREP().Phi());
1790 uncalibratedenergyHFHad,
1791 c1->positionREP().Eta(),
1792 c1->positionREP().Phi());
1795 (*pfCandidates_)[tmpi].setEcalEnergy( uncalibratedenergyHFEm, energyHfEm );
1796 (*pfCandidates_)[tmpi].setHcalEnergy( uncalibratedenergyHFHad, energyHfHad);
1797 (*pfCandidates_)[tmpi].setHoEnergy( 0., 0.);
1798 (*pfCandidates_)[tmpi].setPs1Energy( 0. );
1799 (*pfCandidates_)[tmpi].setPs2Energy( 0. );
1800 (*pfCandidates_)[tmpi].addElementInBlock( blockref, hfEmIs[0] );
1801 (*pfCandidates_)[tmpi].addElementInBlock( blockref, hfHadIs[0] );
1807 cerr<<
"Warning: HF, but n elem different from 1 or 2"<<endl;
1818 cout<<endl<<
"--------------- loop hcal ---------------------"<<endl;
1827 for(
unsigned i=0;
i<hcalIs.size();
i++) {
1829 unsigned iHcal= hcalIs[
i];
1834 if(
debug_)
cout<<endl<<elements[iHcal]<<endl;
1840 std::multimap<double, unsigned> sortedTracks;
1841 block.associatedElements( iHcal, linkData,
1846 std::multimap< unsigned, std::pair<double, unsigned> > associatedEcals;
1848 std::map< unsigned, std::pair<double, double> > associatedPSs;
1850 std::multimap<double, std::pair<unsigned,bool> > associatedTracks;
1853 std::multimap<double,std::pair<unsigned,::math::XYZVector> > ecalSatellites;
1854 std::pair<unsigned,::math::XYZVector> fakeSatellite(iHcal,::
math::XYZVector(0.,0.,0.));
1855 ecalSatellites.emplace(-1., fakeSatellite);
1857 std::multimap< unsigned, std::pair<double, unsigned> > associatedHOs;
1859 PFClusterRef hclusterref = elements[iHcal].clusterRef();
1860 assert(!hclusterref.
isNull() );
1870 if( sortedTracks.empty() ) {
1872 cout<<
"\tno associated tracks, keep for later"<<endl;
1877 active[iHcal] =
false;
1885 if(
debug_)
cout<<
"\t"<<sortedTracks.size()<<
" associated tracks:"<<endl;
1887 double totalChargedMomentum = 0;
1888 double sumpError2 = 0.;
1889 double totalHO = 0.;
1890 double totalEcal = 0.;
1891 double totalHcal = hclusterref->energy();
1892 vector<double> hcalP;
1893 vector<double> hcalDP;
1894 vector<unsigned> tkIs;
1895 double maxDPovP = -9999.;
1898 vector< unsigned > chargedHadronsIndices;
1899 vector< unsigned > chargedHadronsInBlock;
1900 double mergedNeutralHadronEnergy = 0;
1901 double mergedPhotonEnergy = 0;
1902 double muonHCALEnergy = 0.;
1903 double muonECALEnergy = 0.;
1904 double muonHCALError = 0.;
1905 double muonECALError = 0.;
1910 std::vector<std::pair<unsigned,::math::XYZVector> >
ecalClusters;
1911 double sumEcalClusters=0;
1913 hclusterref->position().Y(),
1914 hclusterref->position().Z());
1915 hadronDirection = hadronDirection.Unit();
1919 for(IE ie = sortedTracks.begin(); ie != sortedTracks.end(); ++ie ) {
1921 unsigned iTrack = ie->second;
1924 if ( !active[iTrack] )
continue;
1930 assert( !trackRef.
isNull() );
1935 ::math::XYZVector chargedDirection(chargedPosition.X(),chargedPosition.Y(),chargedPosition.Z());
1936 chargedDirection = chargedDirection.Unit();
1939 std::multimap<double, unsigned> sortedEcals;
1940 block.associatedElements( iTrack, linkData,
1945 if(
debug_)
cout<<
"\t\t\tnumber of Ecal elements linked to this track: " 1946 <<sortedEcals.size()<<endl;
1949 std::multimap<double, unsigned> sortedHOs;
1951 block.associatedElements( iTrack, linkData,
1958 cout<<
"PFAlgo : number of HO elements linked to this track: " 1959 <<sortedHOs.size()<<endl;
1967 bool thisIsALooseMuon =
false;
1975 if ( thisIsAMuon ) {
1977 std::cout <<
"\t\tThis track is identified as a muon - remove it from the stack" << std::endl;
1978 std::cout <<
"\t\t" << elements[iTrack] << std::endl;
1986 (*pfCandidates_)[tmpi].addElementInBlock( blockref, iTrack );
1987 (*pfCandidates_)[tmpi].addElementInBlock( blockref, iHcal );
1993 bool letMuonEatCaloEnergy =
false;
1995 if(thisIsAnIsolatedMuon){
1997 double totalCaloEnergy = totalHcal / 1.30;
1999 if( !sortedEcals.empty() ) {
2000 iEcal = sortedEcals.begin()->second;
2001 PFClusterRef eclusterref = elements[iEcal].clusterRef();
2002 totalCaloEnergy += eclusterref->energy();
2008 if( !sortedHOs.empty() ) {
2009 iHO = sortedHOs.begin()->second;
2011 totalCaloEnergy += eclusterref->energy() / 1.30;
2017 if( (
pfCandidates_->back()).
p() > totalCaloEnergy ) letMuonEatCaloEnergy =
true;
2020 if(letMuonEatCaloEnergy) muonHcal = totalHcal;
2021 double muonEcal =0.;
2023 if( !sortedEcals.empty() ) {
2024 iEcal = sortedEcals.begin()->second;
2025 PFClusterRef eclusterref = elements[iEcal].clusterRef();
2026 (*pfCandidates_)[tmpi].addElementInBlock( blockref, iEcal);
2028 if(letMuonEatCaloEnergy) muonEcal = eclusterref->energy();
2030 if ( eclusterref->energy() - muonEcal < 0.2 ) active[iEcal] =
false;
2031 (*pfCandidates_)[tmpi].setEcalEnergy(eclusterref->energy(), muonEcal);
2036 if( !sortedHOs.empty() ) {
2037 iHO = sortedHOs.begin()->second;
2038 PFClusterRef hoclusterref = elements[iHO].clusterRef();
2039 (*pfCandidates_)[tmpi].addElementInBlock( blockref, iHO);
2041 if(letMuonEatCaloEnergy) muonHO = hoclusterref->energy();
2043 if ( hoclusterref->energy() - muonHO < 0.2 ) active[iHO] =
false;
2044 (*pfCandidates_)[tmpi].setHcalEnergy(totalHcal, muonHcal);
2045 (*pfCandidates_)[tmpi].setHoEnergy(hoclusterref->energy(), muonHO);
2048 (*pfCandidates_)[tmpi].setHcalEnergy(totalHcal, muonHcal);
2052 if(letMuonEatCaloEnergy){
2053 muonHCALEnergy += totalHcal;
2054 if (
useHO_) muonHCALEnergy +=muonHO;
2055 muonHCALError += 0.;
2056 muonECALEnergy += muonEcal;
2057 muonECALError += 0.;
2058 photonAtECAL -= muonEcal*chargedDirection;
2059 hadronAtECAL -= totalHcal*chargedDirection;
2060 if ( !sortedEcals.empty() ) active[iEcal] =
false;
2061 active[iHcal] =
false;
2062 if (
useHO_ && !sortedHOs.empty() ) active[iHO] =
false;
2068 if ( muonHO > 0. ) {
2075 photonAtECAL -= muonECAL_[0]*chargedDirection;
2076 hadronAtECAL -= muonHCAL_[0]*chargedDirection;
2080 active[iTrack] =
false;
2087 if(
debug_)
cout<<
"\t\t"<<elements[iTrack]<<endl;
2095 if ( thisIsALooseMuon && !thisIsAMuon ) nMuons += 1;
2100 double Dpt = trackRef->ptError();
2103 bool isPrimaryOrSecondary =
isFromSecInt(elements[iTrack],
"all");
2105 if ( isPrimaryOrSecondary ) blowError = 1.;
2107 std::pair<unsigned,bool> tkmuon(iTrack,thisIsALooseMuon);
2108 associatedTracks.emplace(-Dpt*blowError, tkmuon);
2111 double Dp = trackRef->qoverpError()*trackMomentum*
trackMomentum;
2112 sumpError2 += Dp*Dp;
2114 bool connectedToEcal =
false;
2115 if( !sortedEcals.empty() )
2119 for ( IE iec=sortedEcals.begin();
2120 iec!=sortedEcals.end(); ++iec ) {
2122 unsigned iEcal = iec->second;
2123 double dist = iec->first;
2126 if( !active[iEcal] ) {
2134 PFClusterRef eclusterref = elements[iEcal].clusterRef();
2135 assert(!eclusterref.
isNull() );
2138 std::multimap<double, unsigned> sortedTracksEcal;
2139 block.associatedElements( iEcal, linkData,
2143 unsigned jTrack = sortedTracksEcal.
begin()->second;
2144 if ( jTrack != iTrack )
continue;
2148 double distEcal = block.dist(jTrack,iEcal,linkData,
2155 float ecalEnergyCalibrated = eclusterref->correctedEnergy();
2157 eclusterref->position().Y(),
2158 eclusterref->position().Z());
2159 photonDirection = photonDirection.Unit();
2161 if ( !connectedToEcal ) {
2164 <<elements[iEcal]<<endl;
2166 connectedToEcal =
true;
2170 std::pair<unsigned,::math::XYZVector> satellite(iEcal,ecalEnergyCalibrated*photonDirection);
2171 ecalSatellites.emplace(-1., satellite);
2175 std::pair<unsigned,::math::XYZVector> satellite(iEcal,ecalEnergyCalibrated*photonDirection);
2176 ecalSatellites.emplace(dist, satellite);
2180 std::pair<double, unsigned> associatedEcal( distEcal, iEcal );
2181 associatedEcals.emplace(iTrack, associatedEcal);
2186 if(
useHO_ && !sortedHOs.empty() )
2190 for ( IE ieho=sortedHOs.begin(); ieho!=sortedHOs.end(); ++ieho ) {
2192 unsigned iHO = ieho->second;
2193 double distHO = ieho->first;
2196 if( !active[iHO] ) {
2204 PFClusterRef hoclusterref = elements[iHO].clusterRef();
2205 assert(!hoclusterref.
isNull() );
2208 std::multimap<double, unsigned> sortedTracksHO;
2209 block.associatedElements( iHO, linkData,
2213 unsigned jTrack = sortedTracksHO.
begin()->second;
2214 if ( jTrack != iTrack )
continue;
2222 totalHO += hoclusterref->energy();
2223 active[iHO] =
false;
2225 std::pair<double, unsigned> associatedHO( distHO, iHO );
2226 associatedHOs.emplace(iTrack, associatedHO);
2235 totalHcal += totalHO;
2239 double caloEnergy = 0.;
2240 double slopeEcal = 1.0;
2241 double calibEcal = 0.;
2242 double calibHcal = 0.;
2243 hadronDirection = hadronAtECAL.Unit();
2247 Caloresolution *= totalChargedMomentum;
2249 Caloresolution =
std::sqrt(Caloresolution*Caloresolution + muonHCALError + muonECALError);
2250 totalEcal -=
std::min(totalEcal,muonECALEnergy);
2251 totalHcal -=
std::min(totalHcal,muonHCALEnergy);
2259 for ( IS is = ecalSatellites.begin(); is != ecalSatellites.end(); ++is ) {
2262 double previousCalibEcal = calibEcal;
2263 double previousCalibHcal = calibHcal;
2264 double previousCaloEnergy = caloEnergy;
2265 double previousSlopeEcal = slopeEcal;
2268 totalEcal +=
sqrt(is->second.second.Mag2());
2269 photonAtECAL += is->second.second;
2270 calibEcal =
std::max(0.,totalEcal);
2271 calibHcal =
std::max(0.,totalHcal);
2272 hadronAtECAL = calibHcal * hadronDirection;
2274 calibration_->energyEmHad(totalChargedMomentum,calibEcal,calibHcal,
2275 hclusterref->positionREP().Eta(),
2276 hclusterref->positionREP().Phi());
2277 caloEnergy = calibEcal+calibHcal;
2278 if ( totalEcal > 0.) slopeEcal = calibEcal/totalEcal;
2280 hadronAtECAL = calibHcal * hadronDirection;
2284 if ( is->first < 0. || caloEnergy - totalChargedMomentum <= 0. ) {
2285 if(
debug_)
cout<<
"\t\t\tactive, adding "<<is->second.second
2286 <<
" to ECAL energy, and locking"<<endl;
2287 active[is->second.first] =
false;
2288 double clusterEnergy=
sqrt(is->second.second.Mag2());
2289 if(clusterEnergy>50) {
2290 ecalClusters.push_back(is->second);
2291 sumEcalClusters+=clusterEnergy;
2298 totalEcal -=
sqrt(is->second.second.Mag2());
2299 photonAtECAL -= is->second.second;
2300 calibEcal = previousCalibEcal;
2301 calibHcal = previousCalibHcal;
2302 hadronAtECAL = previousHadronAtECAL;
2303 slopeEcal = previousSlopeEcal;
2304 caloEnergy = previousCaloEnergy;
2311 assert(caloEnergy>=0);
2327 if ( totalChargedMomentum - caloEnergy >
nSigmaTRACK_*Caloresolution ) {
2342 for ( IT it = associatedTracks.begin(); it != associatedTracks.end(); ++it ) {
2343 unsigned iTrack = it->second.first;
2345 if ( !active[iTrack] )
continue;
2347 if ( !it->second.second )
continue;
2349 double trackMomentum = elements[it->second.first].trackRef()->p();
2352 std::multimap<double, unsigned> sortedEcals;
2353 block.associatedElements( iTrack, linkData,
2357 std::multimap<double, unsigned> sortedHOs;
2358 block.associatedElements( iTrack, linkData,
2366 (*pfCandidates_)[tmpi].addElementInBlock( blockref, iTrack );
2367 (*pfCandidates_)[tmpi].addElementInBlock( blockref, iHcal );
2370 (*pfCandidates_)[tmpi].setHcalEnergy(totalHcal,muonHcal);
2371 if( !sortedEcals.empty() ) {
2372 unsigned iEcal = sortedEcals.begin()->second;
2373 PFClusterRef eclusterref = elements[iEcal].clusterRef();
2374 (*pfCandidates_)[tmpi].addElementInBlock( blockref, iEcal);
2376 (*pfCandidates_)[tmpi].setEcalEnergy(eclusterref->energy(),muonEcal);
2378 if(
useHO_ && !sortedHOs.empty() ) {
2379 unsigned iHO = sortedHOs.begin()->second;
2380 PFClusterRef hoclusterref = elements[iHO].clusterRef();
2381 (*pfCandidates_)[tmpi].addElementInBlock( blockref, iHO);
2383 (*pfCandidates_)[tmpi].setHcalEnergy(
max(totalHcal-totalHO,0.0),muonHcal);
2384 (*pfCandidates_)[tmpi].setHoEnergy(hoclusterref->energy(),muonHO);
2390 ::math::XYZVector chargedDirection(chargedPosition.X(), chargedPosition.Y(), chargedPosition.Z());
2391 chargedDirection = chargedDirection.Unit();
2394 if ( totalEcal > 0. )
2396 if ( totalHcal > 0. )
2401 if ( totalHcal >
muonHCAL_[0] ) hadronAtECAL -=
muonHCAL_[0]*calibHcal/totalHcal * chargedDirection;
2402 caloEnergy = calibEcal+calibHcal;
2405 if ( muonHO > 0. ) {
2408 if ( totalHcal > 0. ) {
2409 calibHcal -=
std::min(calibHcal,muonHO_[0]*calibHcal/totalHcal);
2410 totalHcal -=
std::min(totalHcal,muonHO_[0]);
2415 active[iTrack] =
false;
2422 Caloresolution *= totalChargedMomentum;
2423 Caloresolution =
std::sqrt(Caloresolution*Caloresolution + muonHCALError + muonECALError);
2428 cout<<
"\tBefore Cleaning "<<endl;
2429 cout<<
"\tCompare Calo Energy to total charged momentum "<<endl;
2430 cout<<
"\t\tsum p = "<<totalChargedMomentum<<
" +- "<<
sqrt(sumpError2)<<endl;
2431 cout<<
"\t\tsum ecal = "<<totalEcal<<endl;
2432 cout<<
"\t\tsum hcal = "<<totalHcal<<endl;
2433 cout<<
"\t\t => Calo Energy = "<<caloEnergy<<
" +- "<<Caloresolution<<endl;
2434 cout<<
"\t\t => Calo Energy- total charged momentum = " 2435 <<caloEnergy-totalChargedMomentum<<
" +- "<<
sqrt(sumpError2 + Caloresolution*Caloresolution)<<endl;
2441 unsigned corrTrack = 10000000;
2442 double corrFact = 1.;
2445 totalChargedMomentum - caloEnergy >
nSigmaTRACK_*Caloresolution) {
2447 for ( IT it = associatedTracks.begin(); it != associatedTracks.end(); ++it ) {
2448 unsigned iTrack = it->second.first;
2450 if ( !active[iTrack] )
continue;
2451 const reco::TrackRef& trackref = elements[it->second.first].trackRef();
2453 double dptRel = fabs(it->first)/trackref->pt()*100;
2454 bool isSecondary =
isFromSecInt(elements[iTrack],
"secondary");
2455 bool isPrimary =
isFromSecInt(elements[iTrack],
"primary");
2459 if ( fabs(it->first) <
ptError_ )
break;
2461 double wouldBeTotalChargedMomentum =
2462 totalChargedMomentum - trackref->p();
2466 if ( wouldBeTotalChargedMomentum > caloEnergy ) {
2468 if (
debug_ && isSecondary) {
2469 cout <<
"In bad track rejection step dptRel = " << dptRel <<
" dptRel_DispVtx_ = " <<
dptRel_DispVtx_ << endl;
2470 cout <<
"The calo energy would be still smaller even without this track but it is attached to a NI"<< endl;
2475 active[iTrack] =
false;
2476 totalChargedMomentum = wouldBeTotalChargedMomentum;
2478 std::cout <<
"\tElement " << elements[iTrack]
2479 <<
" rejected (Dpt = " << -it->first
2480 <<
" GeV/c, algo = " << trackref->algo() <<
")" << std::endl;
2483 if(isPrimary)
break;
2485 corrFact = (caloEnergy - wouldBeTotalChargedMomentum)/elements[it->second.first].trackRef()->p();
2486 if ( trackref->p()*corrFact < 0.05 ) {
2488 active[iTrack] =
false;
2490 totalChargedMomentum -= trackref->p()*(1.-corrFact);
2492 std::cout <<
"\tElement " << elements[iTrack]
2493 <<
" (Dpt = " << -it->first
2494 <<
" GeV/c, algo = " << trackref->algo()
2495 <<
") rescaled by " << corrFact
2496 <<
" Now the total charged momentum is " << totalChargedMomentum << endl;
2504 Caloresolution *= totalChargedMomentum;
2505 Caloresolution =
std::sqrt(Caloresolution*Caloresolution + muonHCALError + muonECALError);
2511 sortedTracks.size() > 1 &&
2512 totalChargedMomentum - caloEnergy >
nSigmaTRACK_*Caloresolution ) {
2513 for ( IT it = associatedTracks.begin(); it != associatedTracks.end(); ++it ) {
2514 unsigned iTrack = it->second.first;
2516 if ( !active[iTrack] )
continue;
2518 double dptRel = fabs(it->first)/trackref->pt()*100;
2519 bool isPrimaryOrSecondary =
isFromSecInt(elements[iTrack],
"all");
2527 active[iTrack] =
false;
2528 totalChargedMomentum -= trackref->p();
2531 std::cout <<
"\tElement " << elements[iTrack]
2532 <<
" rejected (Dpt = " << -it->first
2533 <<
" GeV/c, algo = " << trackref->algo() <<
")" << std::endl;
2542 Caloresolution *= totalChargedMomentum;
2543 Caloresolution =
std::sqrt(Caloresolution*Caloresolution + muonHCALError + muonECALError);
2547 for ( IT it = associatedTracks.begin(); it != associatedTracks.end(); ++it ) {
2548 unsigned iTrack = it->second.first;
2549 if ( !active[iTrack] )
continue;
2552 double Dp = trackRef->qoverpError()*trackMomentum*
trackMomentum;
2556 (*pfCandidates_)[tmpi].addElementInBlock( blockref, iTrack );
2557 (*pfCandidates_)[tmpi].addElementInBlock( blockref, iHcal );
2559 std::pair<II,II> myEcals = associatedEcals.equal_range(iTrack);
2560 for (II
ii=myEcals.first;
ii!=myEcals.second; ++
ii ) {
2561 unsigned iEcal =
ii->second.second;
2562 if ( active[iEcal] )
continue;
2563 (*pfCandidates_)[tmpi].addElementInBlock( blockref, iEcal );
2567 std::pair<II,II> myHOs = associatedHOs.equal_range(iTrack);
2568 for (II
ii=myHOs.first;
ii!=myHOs.second; ++
ii ) {
2569 unsigned iHO =
ii->second.second;
2570 if ( active[iHO] )
continue;
2571 (*pfCandidates_)[tmpi].addElementInBlock( blockref, iHO );
2575 if ( iTrack == corrTrack ) {
2576 (*pfCandidates_)[tmpi].rescaleMomentum(corrFact);
2577 trackMomentum *= corrFact;
2579 chargedHadronsIndices.push_back( tmpi );
2580 chargedHadronsInBlock.push_back( iTrack );
2581 active[iTrack] =
false;
2582 hcalP.push_back(trackMomentum);
2583 hcalDP.push_back(Dp);
2584 if (Dp/trackMomentum > maxDPovP) maxDPovP = Dp/
trackMomentum;
2585 sumpError2 += Dp*Dp;
2589 double TotalError =
sqrt(sumpError2 + Caloresolution*Caloresolution);
2592 cout<<
"\tCompare Calo Energy to total charged momentum "<<endl;
2593 cout<<
"\t\tsum p = "<<totalChargedMomentum<<
" +- "<<
sqrt(sumpError2)<<endl;
2594 cout<<
"\t\tsum ecal = "<<totalEcal<<endl;
2595 cout<<
"\t\tsum hcal = "<<totalHcal<<endl;
2596 cout<<
"\t\t => Calo Energy = "<<caloEnergy<<
" +- "<<Caloresolution<<endl;
2597 cout<<
"\t\t => Calo Energy- total charged momentum = " 2598 <<caloEnergy-totalChargedMomentum<<
" +- "<<TotalError<<endl;
2605 double nsigma =
nSigmaHCAL(totalChargedMomentum,hclusterref->positionREP().Eta());
2607 if (
abs(totalChargedMomentum-caloEnergy)<nsigma*TotalError ) {
2613 cout<<
"\t\tcase 1: COMPATIBLE " 2614 <<
"|Calo Energy- total charged momentum| = " 2615 <<
abs(caloEnergy-totalChargedMomentum)
2616 <<
" < "<<nsigma<<
" x "<<TotalError<<endl;
2617 if (maxDPovP < 0.1 )
2618 cout<<
"\t\t\tmax DP/P = "<< maxDPovP
2619 <<
" less than 0.1: do nothing "<<endl;
2621 cout<<
"\t\t\tmax DP/P = "<< maxDPovP
2622 <<
" > 0.1: take weighted averages "<<endl;
2626 if (maxDPovP > 0.1) {
2630 int nrows = chargedHadronsIndices.size();
2631 TMatrixTSym<double>
a (nrows);
2633 TVectorD
check(nrows);
2634 double sigma2E = Caloresolution*Caloresolution;
2635 for(
int i=0;
i<nrows;
i++) {
2636 double sigma2i = hcalDP[
i]*hcalDP[
i];
2638 cout<<
"\t\t\ttrack associated to hcal "<<
i 2639 <<
" P = "<<hcalP[
i]<<
" +- " 2642 a(
i,
i) = 1./sigma2i + 1./sigma2E;
2643 b(
i) = hcalP[
i]/sigma2i + caloEnergy/sigma2E;
2644 for(
int j=0; j<nrows; j++) {
2646 a(
i,j) = 1./sigma2E;
2657 TDecompChol decomp(a);
2659 TVectorD
x = decomp.Solve(b, ok);
2663 for (
int i=0;
i<nrows;
i++){
2665 unsigned ich = chargedHadronsIndices[
i];
2666 double rescaleFactor =
x(
i)/hcalP[
i];
2667 (*pfCandidates_)[ich].rescaleMomentum( rescaleFactor );
2670 cout<<
"\t\t\told p "<<hcalP[
i]
2672 <<
" rescale "<<rescaleFactor<<endl;
2677 cerr<<
"not ok!"<<endl;
2684 else if( caloEnergy > totalChargedMomentum ) {
2703 double eNeutralHadron = caloEnergy - totalChargedMomentum;
2704 double ePhoton = (caloEnergy - totalChargedMomentum) / slopeEcal;
2707 if(!sortedTracks.empty() ){
2708 cout<<
"\t\tcase 2: NEUTRAL DETECTION " 2709 <<caloEnergy<<
" > "<<nsigma<<
"x"<<TotalError
2710 <<
" + "<<totalChargedMomentum<<endl;
2711 cout<<
"\t\tneutral activity detected: "<<endl
2712 <<
"\t\t\t photon = "<<ePhoton<<endl
2713 <<
"\t\t\tor neutral hadron = "<<eNeutralHadron<<endl;
2715 cout<<
"\t\tphoton or hadron ?"<<endl;}
2717 if(sortedTracks.empty() )
2718 cout<<
"\t\tno track -> hadron "<<endl;
2720 cout<<
"\t\t"<<sortedTracks.size()
2721 <<
" tracks -> check if the excess is photonic or hadronic"<<endl;
2725 double ratioMax = 0.;
2727 unsigned maxiEcal= 9999;
2731 for(IE ie = sortedTracks.begin(); ie != sortedTracks.end(); ++ie ) {
2733 unsigned iTrack = ie->second;
2739 assert( !trackRef.
isNull() );
2741 II iae = associatedEcals.find(iTrack);
2743 if( iae == associatedEcals.end() )
continue;
2746 unsigned iEcal = iae->second.second;
2752 assert( !clusterRef.
isNull() );
2754 double pTrack = trackRef->p();
2755 double eECAL = clusterRef->energy();
2756 double eECALOverpTrack = eECAL / pTrack;
2758 if ( eECALOverpTrack > ratioMax ) {
2759 ratioMax = eECALOverpTrack;
2760 maxEcalRef = clusterRef;
2766 std::vector<reco::PFClusterRef> pivotalClusterRef;
2767 std::vector<unsigned> iPivotal;
2768 std::vector<double> particleEnergy, ecalEnergy, hcalEnergy, rawecalEnergy, rawhcalEnergy;
2769 std::vector<::math::XYZVector> particleDirection;
2773 if ( ePhoton < totalEcal || eNeutralHadron-calibEcal < 1E-10 ) {
2774 if ( !maxEcalRef.
isNull() ) {
2776 mergedPhotonEnergy = ePhoton;
2780 if ( !maxEcalRef.
isNull() ) {
2782 mergedPhotonEnergy = totalEcal;
2785 mergedNeutralHadronEnergy = eNeutralHadron-calibEcal;
2788 if ( mergedPhotonEnergy > 0 ) {
2791 if ( ecalClusters.size()<=1 ) {
2792 ecalClusters.clear();
2793 ecalClusters.emplace_back(maxiEcal, photonAtECAL);
2794 sumEcalClusters=
sqrt(photonAtECAL.Mag2());
2796 for(std::vector<std::pair<unsigned,::math::XYZVector> >::const_iterator pae = ecalClusters.begin(); pae != ecalClusters.end(); ++pae ) {
2797 double clusterEnergy=
sqrt(pae->second.Mag2());
2798 particleEnergy.push_back(mergedPhotonEnergy*clusterEnergy/sumEcalClusters);
2799 particleDirection.push_back(pae->second);
2800 ecalEnergy.push_back(mergedPhotonEnergy*clusterEnergy/sumEcalClusters);
2801 hcalEnergy.push_back(0.);
2802 rawecalEnergy.push_back(totalEcal);
2803 rawhcalEnergy.push_back(totalHcal);
2804 pivotalClusterRef.push_back(elements[pae->first].clusterRef());
2805 iPivotal.push_back(pae->first);
2809 if ( mergedNeutralHadronEnergy > 1.0 ) {
2812 if ( ecalClusters.size()<=1 ) {
2813 ecalClusters.clear();
2814 ecalClusters.emplace_back(iHcal, hadronAtECAL);
2815 sumEcalClusters=
sqrt(hadronAtECAL.Mag2());
2817 for(std::vector<std::pair<unsigned,::math::XYZVector> >::const_iterator pae = ecalClusters.begin(); pae != ecalClusters.end(); ++pae ) {
2818 double clusterEnergy=
sqrt(pae->second.Mag2());
2819 particleEnergy.push_back(mergedNeutralHadronEnergy*clusterEnergy/sumEcalClusters);
2820 particleDirection.push_back(pae->second);
2821 ecalEnergy.push_back(0.);
2822 hcalEnergy.push_back(mergedNeutralHadronEnergy*clusterEnergy/sumEcalClusters);
2823 rawecalEnergy.push_back(totalEcal);
2824 rawhcalEnergy.push_back(totalHcal);
2825 pivotalClusterRef.push_back(hclusterref);
2826 iPivotal.push_back(iHcal);
2834 for (
unsigned iPivot=0; iPivot<iPivotal.size(); ++iPivot ) {
2836 if ( particleEnergy[iPivot] < 0. )
2837 std::cout <<
"ALARM = Negative energy ! " 2838 << particleEnergy[iPivot] << std::endl;
2840 bool useDirection =
true;
2842 particleEnergy[iPivot],
2844 particleDirection[iPivot].
X(),
2845 particleDirection[iPivot].
Y(),
2846 particleDirection[iPivot].
Z());
2849 (*pfCandidates_)[tmpi].setEcalEnergy( rawecalEnergy[iPivot],ecalEnergy[iPivot] );
2851 (*pfCandidates_)[tmpi].setHcalEnergy( rawhcalEnergy[iPivot],hcalEnergy[iPivot] );
2852 (*pfCandidates_)[tmpi].setHoEnergy(0., 0.);
2854 (*pfCandidates_)[tmpi].setHcalEnergy(
max(rawhcalEnergy[iPivot]-totalHO,0.0),hcalEnergy[iPivot]*(1.-totalHO/rawhcalEnergy[iPivot]));
2855 (*pfCandidates_)[tmpi].setHoEnergy(totalHO, totalHO * hcalEnergy[iPivot]/rawhcalEnergy[iPivot]);
2857 (*pfCandidates_)[tmpi].setPs1Energy( 0. );
2858 (*pfCandidates_)[tmpi].setPs2Energy( 0. );
2859 (*pfCandidates_)[tmpi].set_mva_nothing_gamma( -1. );
2862 (*pfCandidates_)[tmpi].addElementInBlock( blockref, iHcal );
2863 for (
unsigned ich=0; ich<chargedHadronsInBlock.size(); ++ich) {
2864 unsigned iTrack = chargedHadronsInBlock[ich];
2865 (*pfCandidates_)[tmpi].addElementInBlock( blockref, iTrack );
2871 std::pair<II,II> myEcals = associatedEcals.equal_range(iTrack);
2872 for (II
ii=myEcals.first;
ii!=myEcals.second; ++
ii ) {
2873 unsigned iEcal =
ii->second.second;
2874 if ( active[iEcal] )
continue;
2875 (*pfCandidates_)[tmpi].addElementInBlock( blockref, iEcal );
2887 double totalHcalEnergyCalibrated = calibHcal;
2888 double totalEcalEnergyCalibrated = calibEcal;
2903 totalHcalEnergyCalibrated -= mergedNeutralHadronEnergy;
2905 totalEcalEnergyCalibrated -= mergedPhotonEnergy;
2910 double chargedHadronsTotalEnergy = 0;
2911 for(
unsigned ich=0; ich<chargedHadronsIndices.size(); ++ich ) {
2912 unsigned index = chargedHadronsIndices[ich];
2914 chargedHadronsTotalEnergy += chargedHadron.
energy();
2917 for(
unsigned ich=0; ich<chargedHadronsIndices.size(); ++ich ) {
2918 unsigned index = chargedHadronsIndices[ich];
2920 float fraction = chargedHadron.
energy()/chargedHadronsTotalEnergy;
2923 chargedHadron.
setHcalEnergy( fraction * totalHcal, fraction * totalHcalEnergyCalibrated );
2926 chargedHadron.
setHcalEnergy( fraction *
max(totalHcal-totalHO,0.0), fraction * totalHcalEnergyCalibrated * (1.-totalHO/totalHcal) );
2927 chargedHadron.
setHoEnergy( fraction * totalHO, fraction * totalHO * totalHcalEnergyCalibrated / totalHcal );
2930 chargedHadron.
setEcalEnergy( fraction * totalEcal, fraction * totalEcalEnergyCalibrated );
2934 for ( IS is = ecalSatellites.begin(); is != ecalSatellites.end(); ++is ) {
2937 unsigned iEcal = is->second.first;
2938 if ( !active[iEcal] )
continue;
2943 PFClusterRef eclusterref = elements[iEcal].clusterRef();
2944 assert(!eclusterref.
isNull() );
2947 active[iEcal] =
false;
2950 std::multimap<double, unsigned> assTracks;
2951 block.associatedElements( iEcal, linkData,
2958 (*pfCandidates_)[tmpi].setEcalEnergy( eclusterref->energy(),
sqrt(is->second.second.Mag2()) );
2959 (*pfCandidates_)[tmpi].setHcalEnergy( 0., 0. );
2960 (*pfCandidates_)[tmpi].setHoEnergy( 0., 0. );
2961 (*pfCandidates_)[tmpi].setPs1Energy( associatedPSs[iEcal].
first );
2962 (*pfCandidates_)[tmpi].setPs2Energy( associatedPSs[iEcal].
second );
2963 (*pfCandidates_)[tmpi].addElementInBlock( blockref, iEcal );
2964 (*pfCandidates_)[tmpi].addElementInBlock( blockref, sortedTracks.begin()->second) ;
2978 <<
"---- loop remaining hcal ------- "<<endl;
2984 for(
unsigned ihcluster=0; ihcluster<hcalIs.size(); ihcluster++) {
2985 unsigned iHcal = hcalIs[ihcluster];
2988 std::vector<unsigned> ecalRefs;
2989 std::vector<unsigned> hoRefs;
2992 cout<<endl<<elements[iHcal]<<
" ";
2995 if( !active[iHcal] ) {
2997 cout<<
"not active"<<endl;
3002 std::multimap<double, unsigned> ecalElems;
3003 block.associatedElements( iHcal, linkData,
3009 float totalEcal = 0.;
3012 for(IE ie = ecalElems.begin(); ie != ecalElems.end(); ++ie ) {
3014 unsigned iEcal = ie->second;
3015 double dist = ie->first;
3020 if( !active[iEcal] )
continue;
3041 std::multimap<double, unsigned> hcalElems;
3042 block.associatedElements( iEcal, linkData,
3047 bool isClosest =
true;
3048 for(IE ih = hcalElems.begin(); ih != hcalElems.end(); ++ih ) {
3050 unsigned jHcal = ih->second;
3051 double distH = ih->first;
3053 if ( !active[jHcal] )
continue;
3055 if ( distH < dist ) {
3062 if (!isClosest)
continue;
3066 cout<<
"\telement "<<elements[iEcal]<<
" linked with dist "<< dist<<endl;
3067 cout<<
"Added to HCAL cluster to form a neutral hadron"<<endl;
3071 assert( !eclusterRef.
isNull() );
3073 double ecalEnergy = eclusterRef->correctedEnergy();
3077 totalEcal += ecalEnergy;
3078 if ( ecalEnergy > ecalMax ) {
3079 ecalMax = ecalEnergy;
3080 eClusterRef = eclusterRef;
3083 ecalRefs.push_back(iEcal);
3084 active[iEcal] =
false;
3090 double totalHO = 0.;
3094 std::multimap<double, unsigned> hoElems;
3095 block.associatedElements( iHcal, linkData,
3105 for(IE ie = hoElems.begin(); ie != hoElems.end(); ++ie ) {
3107 unsigned iHO = ie->second;
3108 double dist = ie->first;
3113 if( !active[iHO] )
continue;
3119 std::multimap<double, unsigned> hcalElems;
3120 block.associatedElements( iHO, linkData,
3125 bool isClosest =
true;
3126 for(IE ih = hcalElems.begin(); ih != hcalElems.end(); ++ih ) {
3128 unsigned jHcal = ih->second;
3129 double distH = ih->first;
3131 if ( !active[jHcal] )
continue;
3133 if ( distH < dist ) {
3140 if (!isClosest)
continue;
3143 cout<<
"\telement "<<elements[iHO]<<
" linked with dist "<< dist<<endl;
3144 cout<<
"Added to HCAL cluster to form a neutral hadron"<<endl;
3148 assert( !hoclusterRef.
isNull() );
3150 double hoEnergy = hoclusterRef->energy();
3152 totalHO += hoEnergy;
3153 if ( hoEnergy > hoMax ) {
3155 hoClusterRef = hoclusterRef;
3159 hoRefs.push_back(iHO);
3160 active[iHO] =
false;
3166 = elements[iHcal].clusterRef();
3167 assert( !hclusterRef.
isNull() );
3170 double totalHcal = hclusterRef->energy();
3172 if (
useHO_ ) totalHcal += totalHO;
3180 double calibEcal = totalEcal > 0. ? totalEcal : 0.;
3181 double calibHcal =
std::max(0.,totalHcal);
3185 calibEcal = totalEcal;
3188 hclusterRef->positionREP().Eta(),
3189 hclusterRef->positionREP().Phi());
3202 calibEcal+calibHcal );
3205 (*pfCandidates_)[tmpi].setEcalEnergy( totalEcal, calibEcal );
3207 (*pfCandidates_)[tmpi].setHcalEnergy( totalHcal, calibHcal );
3208 (*pfCandidates_)[tmpi].setHoEnergy(0.,0.);
3210 (*pfCandidates_)[tmpi].setHcalEnergy(
max(totalHcal-totalHO,0.0), calibHcal*(1.-totalHO/totalHcal));
3211 (*pfCandidates_)[tmpi].setHoEnergy(totalHO,totalHO*calibHcal/totalHcal);
3213 (*pfCandidates_)[tmpi].setPs1Energy( 0. );
3214 (*pfCandidates_)[tmpi].setPs2Energy( 0. );
3215 (*pfCandidates_)[tmpi].addElementInBlock( blockref, iHcal );
3216 for (
unsigned iec=0; iec<ecalRefs.size(); ++iec)
3217 (*
pfCandidates_)[tmpi].addElementInBlock( blockref, ecalRefs[iec] );
3218 for (
unsigned iho=0; iho<hoRefs.size(); ++iho)
3219 (*
pfCandidates_)[tmpi].addElementInBlock( blockref, hoRefs[iho] );
3228 if(
debug_)
cout<<endl<<
"---- loop ecal------- "<<endl;
3233 for(
unsigned i=0;
i<ecalIs.size();
i++) {
3234 unsigned iEcal = ecalIs[
i];
3237 cout<<endl<<elements[iEcal]<<
" ";
3239 if( ! active[iEcal] ) {
3241 cout<<
"not active"<<endl;
3248 PFClusterRef clusterref = elements[iEcal].clusterRef();
3249 assert(!clusterref.
isNull() );
3251 active[iEcal] =
false;
3253 float ecalEnergy = clusterref->correctedEnergy();
3255 double particleEnergy = ecalEnergy;
3260 (*pfCandidates_)[tmpi].setEcalEnergy( clusterref->energy(),ecalEnergy );
3261 (*pfCandidates_)[tmpi].setHcalEnergy( 0., 0. );
3262 (*pfCandidates_)[tmpi].setHoEnergy( 0., 0. );
3263 (*pfCandidates_)[tmpi].setPs1Energy( 0. );
3264 (*pfCandidates_)[tmpi].setPs2Energy( 0. );
3265 (*pfCandidates_)[tmpi].addElementInBlock( blockref, iEcal );
3284 double px = track.
px();
3285 double py = track.
py();
3286 double pz = track.
pz();
3287 double energy =
sqrt(track.
p()*track.
p() + 0.13957*0.13957);
3289 if (
debug_)
cout <<
"Reconstructing PF candidate from track of pT = " << track.
pt() <<
" eta = " << track.
eta() <<
" phi = " << track.
phi() <<
" px = " << px <<
" py = " << py <<
" pz = " << pz <<
" energy = " << energy << endl;
3302 pfCandidates_->back().setVertexSource( PFCandidate::kTrkVertex );
3317 if ((!isMuon) && isFromDisp) {
3318 double Dpt = trackRef->ptError();
3319 double dptRel = Dpt/trackRef->pt()*100;
3325 cout <<
"Not refitted px = " << px <<
" py = " << py <<
" pz = " << pz <<
" energy = " << energy << endl;
3328 reco::Track trackRefit = vRef->refittedTrack(trackRef);
3333 sqrt(trackRefit.
p()*trackRefit.
p() + 0.13957*0.13957));
3335 cout <<
"Refitted px = " << px <<
" py = " << py <<
" pz = " << pz <<
" energy = " << energy << endl;
3354 double particleEnergy,
3367 if ( useDirection ) {
3368 switch( cluster.
layer() ) {
3371 factor =
std::sqrt(cluster.
position().Perp2()/(particleX*particleX+particleY*particleY));
3377 factor = cluster.
position().Z()/particleZ;
3392 cluster.
position().Y()-vertexPos.Y(),
3393 cluster.
position().Z()-vertexPos.Z());
3395 particleY*factor-vertexPos.Y(),
3396 particleZ*factor-vertexPos.Z() );
3401 clusterPos = useDirection ? particleDirection.Unit() : clusterPos.Unit();
3402 clusterPos *= particleEnergy;
3408 ROOT::Math::LorentzVector<ROOT::Math::PxPyPzM4D<double> >
3409 momentum( clusterPos.X(), clusterPos.Y(), clusterPos.Z(),
mass);
3419 switch( cluster.
layer() ) {
3426 particleType = PFCandidate::h0;
3429 particleType = PFCandidate::h_HF;
3432 particleType = PFCandidate::egamma_HF;
3468 std::array<double,7> energyPerDepth;
3469 std::fill(energyPerDepth.begin(), energyPerDepth.end(), 0.0);
3471 const auto &
hit = *hitRefAndFrac.recHitRef();
3473 if (
hit.depth() == 0) {
3477 if (
hit.depth() < 1 ||
hit.depth() > 7) {
3478 throw cms::Exception(
"CorruptData") <<
"Bogus depth " <<
hit.depth() <<
" at detid " <<
hit.detId() <<
"\n";
3480 energyPerDepth[
hit.depth()-1] += hitRefAndFrac.fraction()*
hit.energy();
3483 double sum = std::accumulate(energyPerDepth.begin(), energyPerDepth.end(), 0.);
3484 std::array<float,7> depthFractions;
3486 for (
unsigned int i = 0;
i < depthFractions.size(); ++
i) {
3487 depthFractions[
i] = energyPerDepth[
i]/sum;
3490 std::fill(depthFractions.begin(), depthFractions.end(), 0.f);
3501 if ( clusterEnergyHCAL < 1. ) clusterEnergyHCAL = 1.;
3503 double resol = fabs(eta) < 1.48 ?
3504 sqrt (1.02*1.02/clusterEnergyHCAL + 0.065*0.065)
3506 sqrt (1.20*1.20/clusterEnergyHCAL + 0.028*0.028);
3514 double nS = fabs(eta) < 1.48 ?
3524 if(!out )
return out;
3526 out<<
"====== Particle Flow Algorithm ======= ";
3533 out<<
"reconstructed particles: "<<endl;
3537 if(!candidates.get() ) {
3538 out<<
"candidates already transfered"<<endl;
3567 std::vector<bool>& active,
3568 std::vector<double>& psEne) {
3576 std::multimap<double, unsigned> sortedPS;
3577 typedef std::multimap<double, unsigned>::iterator IE;
3579 sortedPS, psElementType,
3583 double totalPS = 0.;
3584 for ( IE ips=sortedPS.begin(); ips!=sortedPS.end(); ++ips ) {
3587 unsigned iPS = ips->second;
3591 if (!active[iPS])
continue;
3594 std::multimap<double, unsigned> sortedECAL;
3599 unsigned jEcal = sortedECAL.begin()->second;
3600 if ( jEcal != iEcal )
continue;
3604 assert( pstype == psElementType );
3605 PFClusterRef psclusterref = elements[iPS].clusterRef();
3606 assert(!psclusterref.
isNull() );
3607 totalPS += psclusterref->energy();
3608 psEne[0] += psclusterref->energy();
3609 active[iPS] =
false;
3624 bool bPrimary = (order.find(
"primary") != string::npos);
3625 bool bSecondary = (order.find(
"secondary") != string::npos);
3626 bool bAll = (order.find(
"all") != string::npos);
3631 if (bPrimary && isToDisp)
return true;
3632 if (bSecondary && isFromDisp )
return true;
3633 if (bAll && ( isToDisp || isFromDisp ) )
return true;
3662 std::vector<unsigned int> pfCandidatesToBeRemoved;
3669 double met2 = metX*metX+metY*metY;
3671 double significance =
std::sqrt(met2/sumet);
3672 double significanceCor = significance;
3675 double metXCor = metX;
3676 double metYCor = metY;
3677 double sumetCor = sumet;
3678 double met2Cor = met2;
3680 double deltaPhiPt = 100.;
3682 unsigned iCor = 1E9;
3687 double metReduc = -1.;
3701 for(
unsigned j=0; j<pfCandidatesToBeRemoved.size(); ++j) {
3702 if (
i == pfCandidatesToBeRemoved[j] ) skip =
true;
3705 if ( skip )
continue;
3708 deltaPhi = std::acos((metX*pfc.
px()+metY*pfc.
py())/(pfc.
pt()*
std::sqrt(met2)));
3709 deltaPhiPt = deltaPhi*pfc.
pt();
3713 double metXInt = metX - pfc.
px();
3714 double metYInt = metY - pfc.
py();
3715 double sumetInt = sumet - pfc.
pt();
3716 double met2Int = metXInt*metXInt+metYInt*metYInt;
3717 if ( met2Int < met2Cor ) {
3720 metReduc = (met2-met2Int)/met2Int;
3722 sumetCor = sumetInt;
3723 significanceCor =
std::sqrt(met2Cor/sumetCor);
3730 pfCandidatesToBeRemoved.push_back(iCor);
3744 std::cout <<
"Significance reduction = " << significance <<
" -> " 3745 << significanceCor <<
" = " << significanceCor - significance
3747 for(
unsigned j=0; j<pfCandidatesToBeRemoved.size(); ++j) {
3748 std::cout <<
"Removed : " << (*pfCandidates_)[pfCandidatesToBeRemoved[j]] << std::endl;
3750 (*pfCandidates_)[pfCandidatesToBeRemoved[j]].rescaleMomentum(1E-6);
3764 if ( cleanedHits.empty() )
return;
3770 std::vector<unsigned int> hitsToBeAdded;
3777 double met2 = metX*metX+metY*metY;
3778 double met2_Original = met2;
3782 double metXCor = metX;
3783 double metYCor = metY;
3784 double sumetCor = sumet;
3785 double met2Cor = met2;
3787 unsigned iCor = 1E9;
3792 double metReduc = -1.;
3794 for(
unsigned i=0;
i<cleanedHits.size(); ++
i) {
3803 for(
unsigned j=0; j<hitsToBeAdded.size(); ++j) {
3804 if (
i == hitsToBeAdded[j] ) skip =
true;
3807 if ( skip )
continue;
3810 double metXInt = metX + px;
3811 double metYInt = metY + py;
3812 double sumetInt = sumet +
pt;
3813 double met2Int = metXInt*metXInt+metYInt*metYInt;
3816 if ( met2Int < met2Cor ) {
3819 metReduc = (met2-met2Int)/met2Int;
3821 sumetCor = sumetInt;
3830 hitsToBeAdded.push_back(iCor);
3844 std::cout << hitsToBeAdded.size() <<
" hits were re-added " << std::endl;
3848 std::cout <<
"Added after cleaning check : " << std::endl;
3850 for(
unsigned j=0; j<hitsToBeAdded.size(); ++j) {
3851 const PFRecHit&
hit = cleanedHits[hitsToBeAdded[j]];
3870 for(
unsigned ic=0;ic<
size;++ic) {
3879 (*pfCandidates_)[ic].setPFElectronExtraRef(theRef);
3891 (*pfCandidates_)[ic].set_mva_e_pi(it->mvaVariable(PFCandidateElectronExtra::MVA_MVA));
3893 (*pfCandidates_)[ic].setPFElectronExtraRef(theRef);
3894 (*pfCandidates_)[ic].setGsfTrackRef(it->gsfTrackRef());
3902 for(
unsigned ic=0;ic<
size;++ic) {
3910 (*pfElectronCandidates_)[ic].setPFElectronExtraRef(theRef);
3921 for(
unsigned ic=0;ic<
size;++ic) {
3926 for(
unsigned pcextra=0;pcextra<sizePhExtra;++pcextra) {
3929 (*pfCandidates_)[ic].setPFPhotonExtraRef(theRef);
PFLayer::Layer layer() const
cluster layer, see PFLayer.h in this directory
sumPtTrackIsoForEgammaSC_barrel
double p() const
momentum vector magnitude
T getParameter(std::string const &) const
unsigned int nTrackIsoForEgammaSC_
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)
const math::XYZPoint & position() const
cluster centroid position
bool isFromSecInt(const reco::PFBlockElement &eTrack, std::string order) const
float goodTrackDeadHcal_dxy_
std::vector< double > muonHCAL_
Variables for muons and fakes.
ParticleType
particle types
bool isNonnull() const
Checks for non-null.
T y() const
Cartesian y coordinate.
double eta() const final
momentum pseudorapidity
sumPtTrackIsoForEgammaSC_endcap
void setPFMuonAndFakeParameters(const edm::ParameterSet &pset)
T x() const
Cartesian x coordinate.
void addMissingMuons(edm::Handle< reco::MuonCollection >, reco::PFCandidateCollection *cands)
double sumEtEcalIsoForEgammaSC_endcap_
bool isElectronSafeForJetMET(const reco::GsfElectron &, const reco::PFCandidate &, const reco::Vertex &, bool &lockTracks)
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 isPhotonValidCandidate(const reco::PFBlockRef &blockRef, std::vector< bool > &active, std::unique_ptr< reco::PFCandidateCollection > &pfPhotonCandidates, std::vector< reco::PFCandidatePhotonExtra > &pfPhotonExtraCandidates, std::vector< reco::PFCandidate > &tempElectronCandidates)
edm::Ref< PFCandidatePhotonExtraCollection > PFCandidatePhotonExtraRef
persistent reference to a PFCandidatePhotonExtra
double coneEcalIsoForEgammaSC_
static bool isMuon(const reco::PFBlockElement &elt)
const std::vector< reco::PFCandidate > & getAllElectronCandidates()
float time() const
timing for cleaned hits
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.)
void reconstructParticles(const reco::PFBlockHandle &blockHandle)
const std::unique_ptr< reco::PFCandidateCollection > & pfCandidates() const
double y() const
y coordinate
bool useProtectionsForJetMET_
double coneTrackIsoForEgammaSC_
void setParameters(const edm::ParameterSet &)
float goodPixelTrackDeadHcal_minEta_
const reco::TrackRef & trackRef() const override
double px() const final
x coordinate of momentum vector
double nSigmaHCAL_
number of sigma to judge energy excess in HCAL
std::map< unsigned int, Link > LinkData
virtual void processBlock(const reco::PFBlockRef &blockref, std::list< reco::PFBlockRef > &hcalBlockRefs, std::list< reco::PFBlockRef > &ecalBlockRefs)
void setMuonHandle(const edm::Handle< reco::MuonCollection > &)
bool trackType(TrackType trType) const override
math::Error< dimension >::type Error
covariance error matrix (3x3)
void setVertex(const math::XYZPoint &p) override
set vertex
std::vector< Variable::Flags > flags
double phi() const
azimuthal angle of momentum vector
double pt() const final
transverse momentum
std::vector< Vertex > VertexCollection
collection of Vertex objects
const edm::OwnVector< reco::PFBlockElement > & elements() const
int charge() const final
electric charge
std::vector< PFRecHit > PFRecHitCollection
collection of PFRecHit objects
sumEtEcalIsoForEgammaSC_endcap
const edm::ValueMap< reco::PhotonRef > * valueMapGedPhotons_
void checkCleaning(const reco::PFRecHitCollection &cleanedHF)
Check HF Cleaning.
edm::Ref< PFCandidateElectronExtraCollection > PFCandidateElectronExtraRef
persistent reference to a PFCandidateElectronExtra
bool passElectronSelection(const reco::GsfElectron &, const reco::PFCandidate &, const int &)
ROOT::Math::PositionVector3D< ROOT::Math::Cartesian3D< float > > XYZPointF
point in space with cartesian internal representation
double px() const
x coordinate of momentum vector
void setDisplacedVerticesParameters(bool rejectTracks_Bad, bool rejectTracks_Step45, bool usePFNuclearInteractions, bool usePFConversions, bool usePFDecays, double dptRel_DispVtx)
PFCandidateCollection::const_iterator PFCandidateConstIterator
iterator
double sumEtEcalIsoForEgammaSC_barrel_
void setPFEleParameters(double mvaEleCut, std::string mvaWeightFileEleID, bool usePFElectrons, const boost::shared_ptr< PFSCEnergyCalibration > &thePFSCEnergyCalibration, const boost::shared_ptr< PFEnergyCalibration > &thePFEnergyCalibration, double sumEtEcalIsoForEgammaSC_barrel, double sumEtEcalIsoForEgammaSC_endcap, double coneEcalIsoForEgammaSC, double sumPtTrackIsoForEgammaSC_barrel, double sumPtTrackIsoForEgammaSC_endcap, unsigned int nTrackIsoForEgammaSC, double coneTrackIsoForEgammaSC, bool applyCrackCorrections=false, bool usePFSCEleCalib=true, bool useEGElectrons=false, bool useEGammaSupercluster=true)
float goodPixelTrackDeadHcal_dxy_
void setPFVertexParameters(bool useVertex, const reco::VertexCollection *primaryVertices)
void setEGElectronCollection(const reco::GsfElectronCollection &egelectrons)
const Point & position() const
position
static bool isGlobalTightMuon(const reco::PFBlockElement &elt)
std::vector< GsfElectron > GsfElectronCollection
collection of GsfElectron objects
bool rejectTracks_Step45_
const math::XYZPointF & positionAtECALEntrance() const
PositionType const & position() const
rechit cell centre x, y, z
std::vector< ElementInBlock > ElementsInBlocks
double minSignificanceReduction_
void setPFPhotonParameters(bool usePFPhoton, std::string mvaWeightFileConvID, double mvaConvCut, bool useReg, std::string X0_Map, const boost::shared_ptr< PFEnergyCalibration > &thePFEnergyCalibration, double sumPtTrackIsoForPhoton, double sumPtTrackIsoSlopeForPhoton)
std::vector< double > factors45_
PFLayer::Layer layer() const
rechit layer
RefToBase< value_type > refAt(size_type i) const
bool useEGammaSupercluster_
U second(std::pair< T, U > const &p)
void setCharge(Charge q) final
set electric charge
std::unique_ptr< reco::PFCandidateCollection > pfCleanedCandidates_
XYZTLorentzVectorD XYZTLorentzVector
Lorentz vector with cylindrical internal representation using pseudorapidity.
bool isElectron(const reco::GsfElectron &)
void set_mva_e_pi(float mvaNI)
bool isTimeValid() const
do we have a valid time information
bool usePFNuclearInteractions_
double eta() const
pseudorapidity of momentum vector
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 setBadHcalTrackParams(const edm::ParameterSet &pset)
void set_mva_Isolated(float mvaI)
boost::shared_ptr< PFEnergyCalibration > thePFEnergyCalibration()
return the pointer to the calibration function
void setParameters(double nSigmaECAL, double nSigmaHCAL, const boost::shared_ptr< PFEnergyCalibration > &calibration, const boost::shared_ptr< PFEnergyCalibrationHF > &thepfEnergyCalibrationHF)
T z() const
Cartesian z coordinate.
const edm::View< reco::PFCandidate > * pfEgammaCandidates_
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.
std::string mvaWeightFileEleID_
Variables for PFElectrons.
void setParticleType(ParticleType type)
set Particle Type
bool passPhotonSelection(const reco::Photon &)
double pt() const
track transverse momentum
const std::vector< reco::PFCandidateElectronExtra > & getElectronExtra()
float goodTrackDeadHcal_validFr_
double energy() const final
energy
void setPFPhotonRegWeights(const GBRForest *LCorrForestEB, const GBRForest *LCorrForestEE, const GBRForest *GCorrForestBarrel, const GBRForest *GCorrForestEndcapHr9, const GBRForest *GCorrForestEndcapLr9, const GBRForest *PFEcalResolution)
Abs< T >::type abs(const T &t)
double z() const
z coordinate
reco::Vertex primaryVertex_
double nSigmaHCAL(double clusterEnergy, double clusterEta) const
edm::Handle< reco::MuonCollection > muonHandle_
std::vector< double > muonECAL_
void setPositionAtECALEntrance(float x, float y, float z)
set position at ECAL entrance
math::XYZPoint Point
point in the space
float energy() const
rechit energy
std::vector< LinkConnSpec >::const_iterator IT
sumEtEcalIsoForEgammaSC_barrel
void setPostHFCleaningParameters(bool postHFCleaning, double minHFCleaningPt, double minSignificance, double maxSignificance, double minSignificanceReduction, double maxDeltaPhiPt, double minDeltaMet)
std::vector< PFBlock > PFBlockCollection
collection of PFBlock objects
PFEGammaFilters * pfegamma_
bool isNull() const
Checks for null.
int goodPixelTrackDeadHcal_maxLost3Hit_
reco::PFBlockRef createBlockRef(const reco::PFBlockCollection &blocks, unsigned bi)
reco::PFCandidatePhotonExtraCollection pfPhotonExtra_
the extra photon collection
double pz() const
z coordinate of momentum vector
void setEcalEnergy(float eeRaw, float eeCorr)
set corrected Ecal energy
float mva_e_pi() const
mva for electron-pion discrimination
void setHcalDepthEnergyFractions(const std::array< float, 7 > &fracs)
set the fraction of hcal energy as function of depth (index 0..6 for depth 1..7)
std::unique_ptr< reco::PFCandidateCollection > pfPhotonCandidates_
the unfiltered photon collection
const PFDisplacedTrackerVertexRef & displacedVertexRef(TrackType trType) const override
const std::vector< reco::PFCandidate > & getElectronCandidates()
float goodPixelTrackDeadHcal_maxPt_
std::vector< reco::PFCandidate > PFCandidateCollection
collection of PFCandidates
double x() const
x coordinate
std::list< reco::PFBlockRef >::iterator IBR
unsigned reconstructTrack(const reco::PFBlockElement &elt, bool allowLoose=false)
int goodTrackDeadHcal_layers_
std::vector< double > muonHO_
float goodPixelTrackDeadHcal_ptErrRel_
XYZVectorD XYZVector
spatial vector with cartesian internal representation
void setGBRForest(const GBRForest *LCorrForest, const GBRForest *GCorrForest, const GBRForest *ResForest)
void associatedElements(unsigned i, const LinkData &linkData, std::multimap< double, unsigned > &sortedAssociates, reco::PFBlockElement::Type type=PFBlockElement::NONE, LinkTest test=LINKTEST_RECHIT) const
static bool isLooseMuon(const reco::PFBlockElement &elt)
XYZPointD XYZPoint
point in space with cartesian internal representation
boost::shared_ptr< PFEnergyCalibration > calibration_
reco::PFBlockHandle blockHandle_
input block handle (full framework case)
double py() const final
y coordinate of momentum vector
virtual bool trackType(TrackType trType) const
boost::shared_ptr< PFSCEnergyCalibration > thePFSCEnergyCalibration_
void setEGammaParameters(bool use_EGammaFilters, std::string ele_iso_path_mvaWeightFile, double ele_iso_pt, double ele_iso_mva_barrel, double ele_iso_mva_endcap, double ele_iso_combIso_barrel, double ele_iso_combIso_endcap, double ele_noniso_mva, unsigned int ele_missinghits, bool useProtectionsForJetMET, const edm::ParameterSet &ele_protectionsForJetMET, const edm::ParameterSet &ele_protectionsForBadHcal, double ph_MinEt, double ph_combIso, double ph_HoE, double ph_sietaieta_eb, double ph_sietaieta_ee, const edm::ParameterSet &ph_protectionsForJetMET, const edm::ParameterSet &ph_protectionsForBadHcal)
virtual ~PFAlgo()
destructor
void setHoEnergy(float eoRaw, float eoCorr)
set corrected Hcal energy
std::vector< std::vector< double > > tmp
bool isElectronValidCandidate(const reco::PFBlockRef &blockRef, std::vector< bool > &active, const reco::Vertex &primaryVertex)
Particle reconstructed by the particle flow algorithm.
boost::shared_ptr< PFEnergyCalibrationHF > thepfEnergyCalibrationHF_
reco::PFCandidateEGammaExtraRef egammaExtraRef() const
return a reference to the EGamma extra
PFMuonAlgo * getPFMuonAlgo()
bool useEGammaFilters_
Variables for NEW EGAMMA selection.
const std::vector< reco::PFRecHitFraction > & recHitFractions() const
vector of rechit fractions
void setPhotonExtraRef(const edm::OrphanHandle< reco::PFCandidatePhotonExtraCollection > &pf_extrah)
bool applyCrackCorrectionsElectrons_
int charge() const
track electric charge
float goodTrackDeadHcal_ptErrRel_
Variables for track cleaning in bad HCal areas.
sumPtTrackIsoSlopeForPhoton
double sumPtTrackIsoForEgammaSC_endcap_
std::unique_ptr< reco::PFCandidateCollection > pfElectronCandidates_
the unfiltered electron collection
void setPhotonPrimaryVtx(const reco::Vertex &primary)
int goodPixelTrackDeadHcal_maxLost4Hit_
const reco::MuonRef & muonRef() const override
float goodPixelTrackDeadHcal_chi2n_
virtual ParticleType particleId() const
double neutralHadronEnergyResolution(double clusterEnergy, double clusterEta) const
todo: use PFClusterTools for this
void postClean(reco::PFCandidateCollection *)
reco::PFCandidateElectronExtraCollection pfElectronExtra_
the unfiltered electron collection
const ElementsInBlocks & elementsInBlocks() const
void setInputsForCleaning(const reco::VertexCollection *)
double phi() const final
momentum azimuthal angle
bool isPhotonSafeForJetMET(const reco::Photon &, const reco::PFCandidate &)
void setP4(const LorentzVector &p4) final
set 4-momentum
float goodTrackDeadHcal_chi2n_
double sumPtTrackIsoForEgammaSC_barrel_
float goodPixelTrackDeadHcal_dz_
void setHcalEnergy(float ehRaw, float ehCorr)
set corrected Hcal energy
void setHcalDepthInfo(reco::PFCandidate &cand, const reco::PFCluster &cluster) const
double py() const
y coordinate of momentum vector
static bool isTrackerTightMuon(const reco::PFBlockElement &elt)
const edm::ValueMap< reco::GsfElectronRef > * valueMapGedElectrons_
friend std::ostream & operator<<(std::ostream &out, const PFAlgo &algo)
void setElectronExtraRef(const edm::OrphanHandle< reco::PFCandidateElectronExtraCollection > &extrah)
T mag2() const
The vector magnitude squared. Equivalent to vec.dot(vec)
void setEGElectronCollection(const reco::GsfElectronCollection &egelectrons)
bool reconstructMuon(reco::PFCandidate &, const reco::MuonRef &, bool allowLoose=false)
double nSigmaECAL_
number of sigma to judge energy excess in ECAL