39 #include "Math/PxPyPzM4D.h"
40 #include "Math/LorentzVector.h"
41 #include "Math/DisplacementVector3D.h"
42 #include "Math/SMatrix.h"
43 #include "TDecompChol.h"
45 #include "boost/graph/adjacency_matrix.hpp"
46 #include "boost/graph/graph_utility.hpp"
52 using namespace boost;
54 typedef std::list< reco::PFBlockRef >::iterator
IBR;
80 const boost::shared_ptr<PFEnergyCalibration>& calibration,
81 const boost::shared_ptr<PFEnergyCalibrationHF>& thepfEnergyCalibrationHF) {
99 string mvaWeightFileEleID,
101 const boost::shared_ptr<PFSCEnergyCalibration>& thePFSCEnergyCalibration,
102 const boost::shared_ptr<PFEnergyCalibration>& thePFEnergyCalibration,
103 double sumEtEcalIsoForEgammaSC_barrel,
104 double sumEtEcalIsoForEgammaSC_endcap,
105 double coneEcalIsoForEgammaSC,
106 double sumPtTrackIsoForEgammaSC_barrel,
107 double sumPtTrackIsoForEgammaSC_endcap,
108 unsigned int nTrackIsoForEgammaSC,
109 double coneTrackIsoForEgammaSC,
110 bool applyCrackCorrections,
111 bool usePFSCEleCalib,
113 bool useEGammaSupercluster) {
138 string err =
"PFAlgo: cannot open weight file '";
139 err += mvaWeightFileEleID;
141 throw invalid_argument( err );
145 thePFEnergyCalibration,
165 const boost::shared_ptr<PFEnergyCalibration>& thePFEnergyCalibration,
166 double sumPtTrackIsoForPhoton,
167 double sumPtTrackIsoSlopeForPhoton)
180 e(0, 0) = 0.0015 * 0.0015;
181 e(1, 1) = 0.0015 * 0.0015;
188 FILE * filePhotonConvID = fopen(mvaWeightFileConvID.c_str(),
"r");
189 if (filePhotonConvID) {
190 fclose(filePhotonConvID);
193 string err =
"PFAlgo: cannot open weight file '";
194 err += mvaWeightFileConvID;
196 throw invalid_argument( err );
204 thePFEnergyCalibration,
205 sumPtTrackIsoForPhoton,
206 sumPtTrackIsoSlopeForPhoton
214 double ele_iso_mva_barrel,
215 double ele_iso_mva_endcap,
216 double ele_iso_combIso_barrel,
217 double ele_iso_combIso_endcap,
218 double ele_noniso_mva,
219 unsigned int ele_missinghits,
220 bool useProtectionsForJetMET,
225 double ph_sietaieta_eb,
226 double ph_sietaieta_ee,
234 FILE * fileEGamma_ele_iso_ID = fopen(ele_iso_path_mvaWeightFile.c_str(),
"r");
235 if (fileEGamma_ele_iso_ID) {
236 fclose(fileEGamma_ele_iso_ID);
239 string err =
"PFAlgo: cannot open weight file '";
240 err += ele_iso_path_mvaWeightFile;
242 throw invalid_argument( err );
253 ph_protectionsForJetMET,
257 ele_iso_combIso_barrel,
258 ele_iso_combIso_endcap,
261 ele_iso_path_mvaWeightFile,
262 ele_protectionsForJetMET);
297 GCorrForestBarrel, GCorrForestEndcapHr9,
298 GCorrForestEndcapLr9, PFEcalResolution);
320 assert (
muonHCAL_.size() == 2 && muonECAL_.size() == 2 && muonHO_.size() == 2);
324 assert ( factors45_.size() == 2 );
337 double minHFCleaningPt,
338 double minSignificance,
339 double maxSignificance,
340 double minSignificanceReduction,
341 double maxDeltaPhiPt,
342 double minDeltaMet) {
354 bool rejectTracks_Step45,
355 bool usePFNuclearInteractions,
356 bool usePFConversions,
358 double dptRel_DispVtx){
380 bool primaryVertexFound =
false;
381 nVtx_ = primaryVertices->size();
385 for (
unsigned short i=0 ;
i<primaryVertices->size();++
i)
387 if(primaryVertices->at(
i).isValid()&&(!primaryVertices->at(
i).isFake()))
390 primaryVertexFound =
true;
402 e(0, 0) = 0.0015 * 0.0015;
403 e(1, 1) = 0.0015 * 0.0015;
451 cout<<
"*********************************************************"<<endl;
452 cout<<
"***** Particle flow algorithm *****"<<endl;
453 cout<<
"*********************************************************"<<endl;
457 std::list< reco::PFBlockRef > hcalBlockRefs;
458 std::list< reco::PFBlockRef > ecalBlockRefs;
459 std::list< reco::PFBlockRef > hoBlockRefs;
460 std::list< reco::PFBlockRef > otherBlockRefs;
462 for(
unsigned i=0;
i<blocks.size(); ++
i ) {
470 bool singleEcalOrHcal =
false;
471 if( elements.
size() == 1 ){
473 ecalBlockRefs.push_back( blockref );
474 singleEcalOrHcal =
true;
477 hcalBlockRefs.push_back( blockref );
478 singleEcalOrHcal =
true;
482 hoBlockRefs.push_back( blockref );
483 singleEcalOrHcal =
true;
487 if(!singleEcalOrHcal) {
488 otherBlockRefs.push_back( blockref );
493 cout<<
"# Ecal blocks: "<<ecalBlockRefs.size()
494 <<
", # Hcal blocks: "<<hcalBlockRefs.size()
495 <<
", # HO blocks: "<<hoBlockRefs.size()
496 <<
", # Other blocks: "<<otherBlockRefs.size()<<endl;
504 for(
IBR io = otherBlockRefs.begin(); io!=otherBlockRefs.end(); ++io) {
509 std::list< reco::PFBlockRef >
empty;
513 for(
IBR ih = hcalBlockRefs.begin(); ih!=hcalBlockRefs.end(); ++ih) {
514 if (
debug_ )
std::cout <<
"HCAL block number " << hblcks++ << std::endl;
520 for(
IBR ie = ecalBlockRefs.begin(); ie!=ecalBlockRefs.end(); ++ie) {
521 if (
debug_ )
std::cout <<
"ECAL block number " << eblcks++ << std::endl;
538 std::list<reco::PFBlockRef>& hcalBlockRefs,
539 std::list<reco::PFBlockRef>& ecalBlockRefs ) {
542 assert(!blockref.
isNull() );
545 typedef std::multimap<double, unsigned>::iterator IE;
546 typedef std::multimap<double, std::pair<unsigned,::math::XYZVector> >::iterator IS;
547 typedef std::multimap<double, std::pair<unsigned,bool> >::iterator
IT;
548 typedef std::multimap< unsigned, std::pair<double, unsigned> >::iterator II;
551 cout<<
"#########################################################"<<endl;
552 cout<<
"##### Process Block: #####"<<endl;
553 cout<<
"#########################################################"<<endl;
563 vector<bool> active( elements.
size(),
true );
568 std::vector<reco::PFCandidate> tempElectronCandidates;
569 tempElectronCandidates.clear();
574 for ( std::vector<reco::PFCandidate>::const_iterator ec=PFElectCandidates_.begin(); ec != PFElectCandidates_.end(); ++ec )tempElectronCandidates.push_back(*ec);
594 cout<<endl<<
"--------------- entering PFPhotonAlgo ----------------"<<endl;
595 vector<PFCandidatePhotonExtra> pfPhotonExtraCand;
600 tempElectronCandidates
610 unsigned int extracand =0;
618 pfPhotonExtraCand.clear();
623 for ( std::vector<reco::PFCandidate>::const_iterator ec=tempElectronCandidates.begin(); ec != tempElectronCandidates.end(); ++ec ){
626 tempElectronCandidates.clear();
634 bool egmLocalDebug =
false;
635 bool egmLocalBlockDebug =
false;
638 for(
unsigned int ieg=0 ; ieg < negmcandidates; ++ieg) {
643 PFCandidate::ElementsInBlocks::const_iterator iegfirst = theElements.begin();
644 bool sameBlock =
false;
645 bool isGoodElectron =
false;
646 bool isGoodPhoton =
false;
647 bool isPrimaryElectron =
false;
648 if(iegfirst->first == blockref)
653 cout <<
" I am in looping on EGamma Candidates: pt " << (*pfEgmRef).pt()
654 <<
" eta,phi " << (*pfEgmRef).eta() <<
", " << (*pfEgmRef).phi()
655 <<
" charge " << (*pfEgmRef).charge() << endl;
657 if((*pfEgmRef).gsfTrackRef().isNonnull()) {
665 cout <<
"** Good Electron, pt " << gedEleRef->pt()
666 <<
" eta, phi " << gedEleRef->eta() <<
", " << gedEleRef->phi()
667 <<
" charge " << gedEleRef->charge()
668 <<
" isPrimary " << isPrimaryElectron << endl;
674 if((*pfEgmRef).superClusterRef().isNonnull()) {
681 cout <<
"** Good Photon, pt " << gedPhoRef->pt()
682 <<
" eta, phi " << gedPhoRef->eta() <<
", " << gedPhoRef->phi() << endl;
688 if(isGoodElectron && isGoodPhoton) {
689 if(isPrimaryElectron)
690 isGoodPhoton =
false;
692 isGoodElectron =
false;
700 bool lockTracks =
false;
710 myPFElectron.
setCharge(gedEleRef->charge());
711 myPFElectron.
setP4(gedEleRef->p4());
715 cout <<
" PFAlgo: found an electron with NEW EGamma code " << endl;
716 cout <<
" myPFElectron: pt " << myPFElectron.
pt()
717 <<
" eta,phi " << myPFElectron.
eta() <<
", " <<myPFElectron.
phi()
718 <<
" mva " << myPFElectron.
mva_e_pi()
719 <<
" charge " << myPFElectron.
charge() << endl;
724 if(egmLocalBlockDebug)
725 cout <<
" THE BLOCK " << *blockref << endl;
726 for (PFCandidate::ElementsInBlocks::const_iterator ieb = theElements.begin();
727 ieb<theElements.end(); ++ieb) {
728 active[ieb->second] =
false;
729 if(egmLocalBlockDebug)
730 cout <<
" Elements used " << ieb->second << endl;
736 for (PFCandidate::ElementsInBlocks::const_iterator itrk = extraTracks.begin();
737 itrk<extraTracks.end(); ++itrk) {
738 active[itrk->second] =
false;
747 cout <<
"PFAlgo: Electron DISCARDED, NOT SAFE FOR JETMET " << endl;
767 myPFPhoton.
setP4(gedPhoRef->p4());
769 cout <<
" PFAlgo: found a photon with NEW EGamma code " << endl;
770 cout <<
" myPFPhoton: pt " << myPFPhoton.
pt()
771 <<
" eta,phi " << myPFPhoton.
eta() <<
", " <<myPFPhoton.
phi()
772 <<
" charge " << myPFPhoton.
charge() << endl;
776 if(egmLocalBlockDebug)
777 cout <<
" THE BLOCK " << *blockref << endl;
778 for (PFCandidate::ElementsInBlocks::const_iterator ieb = theElements.begin();
779 ieb<theElements.end(); ++ieb) {
780 active[ieb->second] =
false;
781 if(egmLocalBlockDebug)
782 cout <<
" Elements used " << ieb->second << endl;
796 for(
unsigned iEle=0; iEle<elements.
size(); iEle++) {
798 if(type==PFBlockElement::TRACK)
800 if(elements[iEle].trackRef()->algo() == 12)
805 if(elements[iEle].convRefs().
size())active[iEle]=
false;
815 cout<<endl<<
"--------------- loop 1 ------------------"<<endl;
842 vector<unsigned> hcalIs;
843 vector<unsigned> hoIs;
844 vector<unsigned> ecalIs;
845 vector<unsigned> trackIs;
846 vector<unsigned> ps1Is;
847 vector<unsigned> ps2Is;
849 vector<unsigned> hfEmIs;
850 vector<unsigned> hfHadIs;
853 for(
unsigned iEle=0; iEle<elements.
size(); iEle++) {
856 if(
debug_ && type != PFBlockElement::BREM )
cout<<endl<<elements[iEle];
859 case PFBlockElement::TRACK:
860 if ( active[iEle] ) {
862 if(
debug_)
cout<<
"TRACK, stored index, continue"<<endl;
866 if ( active[iEle] ) {
867 ecalIs.push_back( iEle );
868 if(
debug_)
cout<<
"ECAL, stored index, continue"<<endl;
872 if ( active[iEle] ) {
873 hcalIs.push_back( iEle );
874 if(
debug_)
cout<<
"HCAL, stored index, continue"<<endl;
877 case PFBlockElement::HO:
879 if ( active[iEle] ) {
880 hoIs.push_back( iEle );
881 if(
debug_)
cout<<
"HO, stored index, continue"<<endl;
885 case PFBlockElement::HFEM:
886 if ( active[iEle] ) {
887 hfEmIs.push_back( iEle );
888 if(
debug_)
cout<<
"HFEM, stored index, continue"<<endl;
891 case PFBlockElement::HFHAD:
892 if ( active[iEle] ) {
893 hfHadIs.push_back( iEle );
894 if(
debug_)
cout<<
"HFHAD, stored index, continue"<<endl;
902 unsigned iTrack = iEle;
908 if (active[iTrack] &&
isFromSecInt(elements[iEle],
"primary")){
909 bool isPrimaryTrack = elements[iEle].displacedVertexRef(PFBlockElement::T_TO_DISP)->displacedVertexRef()->isTherePrimaryTracks();
910 if (isPrimaryTrack) {
911 if (
debug_)
cout <<
"Primary Track reconstructed alone" << endl;
914 (*pfCandidates_)[tmpi].addElementInBlock( blockref, iEle );
915 active[iTrack] =
false;
921 if ( !active[iTrack] )
922 cout <<
"Already used by electrons, muons, conversions" << endl;
927 if ( ! active[iTrack] )
continue;
930 assert( !trackRef.
isNull() );
933 cout <<
"PFAlgo:processBlock "<<
" "<<trackIs.size()<<
" "<<ecalIs.size()<<
" "<<hcalIs.size()<<
" "<<hoIs.size()<<endl;
940 std::multimap<double, unsigned> ecalElems;
941 block.associatedElements( iTrack, linkData,
946 std::multimap<double, unsigned> hcalElems;
947 block.associatedElements( iTrack, linkData,
955 if ( hcalElems.empty() && !ecalElems.empty() ) {
958 unsigned index = ecalElems.begin()->second;
959 std::multimap<double, unsigned> sortedTracks;
960 block.associatedElements( index, linkData,
967 for(IE ie = sortedTracks.begin(); ie != sortedTracks.end(); ++ie ) {
968 unsigned jTrack = ie->second;
971 if ( !active[jTrack] )
continue;
975 if ( jTrack == iTrack )
continue;
980 std::multimap<double, unsigned> sortedECAL;
981 block.associatedElements( jTrack, linkData,
985 if ( sortedECAL.begin()->second !=
index )
continue;
990 std::multimap<double, unsigned> sortedHCAL;
991 block.associatedElements( jTrack, linkData,
995 if ( !sortedHCAL.size() )
continue;
1000 block.setLink( iTrack,
1001 sortedHCAL.begin()->second,
1002 sortedECAL.begin()->first,
1004 PFBlock::LINKTEST_RECHIT );
1009 block.associatedElements( iTrack, linkData,
1014 if (
debug_ && hcalElems.size() )
1015 std::cout <<
"Track linked back to HCAL due to ECAL sharing with other tracks" << std::endl;
1025 std::multimap<double,unsigned> gsfElems;
1027 block.associatedElements( iTrack, linkData,
1033 if(hcalElems.empty() &&
debug_) {
1034 cout<<
"no hcal element connected to track "<<iTrack<<endl;
1040 bool hcalFound =
false;
1043 cout<<
"now looping on elements associated to the track"<<endl;
1047 for(IE ie = ecalElems.begin(); ie != ecalElems.end(); ++ie ) {
1049 unsigned index = ie->second;
1053 double dist = ie->first;
1054 cout<<
"\telement "<<elements[
index]<<
" linked with distance = "<< dist <<endl;
1055 if ( ! active[index] )
cout <<
"This ECAL is already used - skip it" << endl;
1060 if ( ! active[index] )
continue;
1066 if( !hcalElems.empty() &&
debug_)
1067 cout<<
"\t\tat least one hcal element connected to the track."
1068 <<
" Sparing Ecal cluster for the hcal loop"<<endl;
1076 if( hcalElems.empty() ) {
1079 std::cout <<
"Now deals with tracks linked to no HCAL clusters" << std::endl;
1086 std::cout << elements[iTrack] << std::endl;
1092 if ( thisIsAMuon ) trackMomentum = 0.;
1096 bool rejectFake =
false;
1097 if ( !thisIsAMuon && elements[iTrack].trackRef()->ptError() >
ptError_ ) {
1101 elements[iTrack].trackRef()->
eta());
1104 if ( !ecalElems.empty() ) {
1105 unsigned thisEcal = ecalElems.begin()->second;
1107 deficit -= clusterRef->energy();
1109 clusterRef->positionREP().Eta());
1113 bool isPrimary =
isFromSecInt(elements[iTrack],
"primary");
1117 active[iTrack] =
false;
1119 std::cout << elements[iTrack] << std::endl
1120 <<
"is probably a fake (1) --> lock the track"
1125 if ( rejectFake )
continue;
1130 std::vector<unsigned> tmpi;
1131 std::vector<unsigned> kTrack;
1134 double Dpt = trackRef->ptError();
1137 trackMomentum > 30. && Dpt > 0.5 &&
1138 ( trackRef->algo() == TrackBase::iter4 ||
1139 trackRef->algo() == TrackBase::iter5 ||
1140 trackRef->algo() == TrackBase::iter6 ) ) {
1143 double dptRel = Dpt/trackRef->pt()*100;
1144 bool isPrimaryOrSecondary =
isFromSecInt(elements[iTrack],
"all");
1147 unsigned nHits = elements[iTrack].trackRef()->hitPattern().trackerLayersWithMeasurement();
1148 unsigned int NLostHit = trackRef->hitPattern().trackerLayersWithoutMeasurement();
1151 std::cout <<
"A track (algo = " << trackRef->algo() <<
") with momentum " << trackMomentum
1152 <<
" / " << elements[iTrack].trackRef()->pt() <<
" +/- " << Dpt
1153 <<
" / " << elements[iTrack].trackRef()->eta()
1154 <<
" without any link to ECAL/HCAL and with " << nHits <<
" (" << NLostHit
1155 <<
") hits (lost hits) has been cleaned" << std::endl;
1156 active[iTrack] =
false;
1163 kTrack.push_back(iTrack);
1164 active[iTrack] =
false;
1167 if ( ecalElems.empty() ) {
1168 (*pfCandidates_)[tmpi[0]].setEcalEnergy( 0., 0. );
1169 (*pfCandidates_)[tmpi[0]].setHcalEnergy( 0., 0. );
1170 (*pfCandidates_)[tmpi[0]].setHoEnergy( 0., 0. );
1171 (*pfCandidates_)[tmpi[0]].setPs1Energy( 0 );
1172 (*pfCandidates_)[tmpi[0]].setPs2Energy( 0 );
1173 (*pfCandidates_)[tmpi[0]].addElementInBlock( blockref, kTrack[0] );
1178 unsigned thisEcal = ecalElems.begin()->second;
1180 if (
debug_ )
std::cout <<
" is associated to " << elements[thisEcal] << std::endl;
1184 if ( thisIsAMuon ) {
1185 (*pfCandidates_)[tmpi[0]].setEcalEnergy( clusterRef->energy(),
1187 (*pfCandidates_)[tmpi[0]].setHcalEnergy( 0., 0. );
1188 (*pfCandidates_)[tmpi[0]].setHoEnergy( 0., 0. );
1189 (*pfCandidates_)[tmpi[0]].setPs1Energy( 0 );
1190 (*pfCandidates_)[tmpi[0]].setPs2Energy( 0 );
1191 (*pfCandidates_)[tmpi[0]].addElementInBlock( blockref, kTrack[0] );
1194 double slopeEcal = 1.;
1195 bool connectedToEcal =
false;
1196 unsigned iEcal = 99999;
1197 double calibEcal = 0.;
1198 double calibHcal = 0.;
1199 double totalEcal = thisIsAMuon ? -
muonECAL_[0] : 0.;
1202 std::multimap<double, unsigned> sortedTracks;
1203 block.associatedElements( thisEcal, linkData,
1208 for(IE ie = sortedTracks.begin(); ie != sortedTracks.end(); ++ie ) {
1209 unsigned jTrack = ie->second;
1212 if ( !active[jTrack] )
continue;
1215 if ( jTrack == iTrack )
continue;
1220 std::multimap<double, unsigned> sortedECAL;
1221 block.associatedElements( jTrack, linkData,
1225 if ( sortedECAL.begin()->second != thisEcal )
continue;
1232 bool rejectFake =
false;
1234 if ( !thatIsAMuon && trackRef->ptError() >
ptError_) {
1235 double deficit = trackMomentum + trackRef->p() - clusterRef->energy();
1237 clusterRef->positionREP().Eta());
1238 resol *= (trackMomentum+trackRef->p());
1241 kTrack.push_back(jTrack);
1242 active[jTrack] =
false;
1244 std::cout << elements[jTrack] << std::endl
1245 <<
"is probably a fake (2) --> lock the track"
1249 if ( rejectFake )
continue;
1255 if ( !thatIsAMuon ) {
1257 std::cout <<
"Track momentum increased from " << trackMomentum <<
" GeV ";
1258 trackMomentum += trackRef->p();
1260 std::cout <<
"to " << trackMomentum <<
" GeV." << std::endl;
1261 std::cout <<
"with " << elements[jTrack] << std::endl;
1265 totalEcal =
std::max(totalEcal, 0.);
1273 kTrack.push_back(jTrack);
1274 active[jTrack] =
false;
1276 if ( thatIsAMuon ) {
1277 (*pfCandidates_)[tmpi.back()].setEcalEnergy(clusterRef->energy(),
1279 (*pfCandidates_)[tmpi.back()].setHcalEnergy( 0., 0. );
1280 (*pfCandidates_)[tmpi.back()].setHoEnergy( 0., 0. );
1281 (*pfCandidates_)[tmpi.back()].setPs1Energy( 0 );
1282 (*pfCandidates_)[tmpi.back()].setPs2Energy( 0 );
1283 (*pfCandidates_)[tmpi.back()].addElementInBlock( blockref, kTrack.back() );
1288 if (
debug_ )
std::cout <<
"Loop over all associated ECAL clusters" << std::endl;
1290 for(IE ie = ecalElems.begin(); ie != ecalElems.end(); ++ie ) {
1292 unsigned index = ie->second;
1298 if (
debug_ && ! active[index] )
std::cout <<
"is not active - ignore " << std::endl;
1299 if ( ! active[index] )
continue;
1303 block.associatedElements( index, linkData,
1308 for (
unsigned ic=0; ic<kTrack.size();++ic) {
1309 if ( sortedTracks.begin()->second == kTrack[ic] ) {
1314 if (
debug_ && skip )
std::cout <<
"is closer to another track - ignore " << std::endl;
1315 if ( skip )
continue;
1320 assert( !clusterRef.
isNull() );
1323 double dist = ie->first;
1324 std::cout <<
"Ecal cluster with raw energy = " << clusterRef->energy()
1325 <<
" linked with distance = " << dist << std::endl;
1338 vector<double> ps1Ene(1,static_cast<double>(0.));
1340 vector<double> ps2Ene(1,static_cast<double>(0.));
1344 bool crackCorrection =
false;
1345 double ecalEnergy =
calibration_->energyEm(*clusterRef,ps1Ene,ps2Ene,crackCorrection);
1347 std::cout <<
"Corrected ECAL(+PS) energy = " << ecalEnergy << std::endl;
1351 totalEcal += ecalEnergy;
1352 double previousCalibEcal = calibEcal;
1353 double previousSlopeEcal = slopeEcal;
1354 calibEcal =
std::max(totalEcal,0.);
1356 calibration_->energyEmHad(trackMomentum,calibEcal,calibHcal,
1357 clusterRef->positionREP().Eta(),
1358 clusterRef->positionREP().Phi());
1359 if ( totalEcal > 0.) slopeEcal = calibEcal/totalEcal;
1362 std::cout <<
"The total calibrated energy so far amounts to = " << calibEcal << std::endl;
1366 if ( connectedToEcal && calibEcal - trackMomentum >= 0. ) {
1369 calibEcal = previousCalibEcal;
1370 slopeEcal = previousSlopeEcal;
1371 totalEcal = calibEcal/slopeEcal;
1375 active[
index] =
false;
1378 std::multimap<double, unsigned> assTracks;
1379 block.associatedElements( index, linkData,
1386 (*pfCandidates_)[tmpe].setEcalEnergy( clusterRef->energy(), ecalEnergy );
1387 (*pfCandidates_)[tmpe].setHcalEnergy( 0., 0. );
1388 (*pfCandidates_)[tmpe].setHoEnergy( 0., 0. );
1389 (*pfCandidates_)[tmpe].setPs1Energy( ps1Ene[0] );
1390 (*pfCandidates_)[tmpe].setPs2Energy( ps2Ene[0] );
1391 (*pfCandidates_)[tmpe].addElementInBlock( blockref, index );
1393 if(assTracks.size()) {
1394 (*pfCandidates_)[tmpe].addElementInBlock( blockref, assTracks.begin()->second );
1405 connectedToEcal =
true;
1407 active[
index] =
false;
1408 for (
unsigned ic=0; ic<tmpi.size();++ic)
1409 (*
pfCandidates_)[tmpi[ic]].addElementInBlock( blockref, iEcal );
1414 bool bNeutralProduced =
false;
1417 if( connectedToEcal ) {
1459 neutralEnergy /= slopeEcal;
1461 (*pfCandidates_)[tmpj].setEcalEnergy( pivotalRef->energy(), neutralEnergy );
1462 (*pfCandidates_)[tmpj].setHcalEnergy( 0., 0. );
1463 (*pfCandidates_)[tmpj].setHoEnergy( 0., 0. );
1464 (*pfCandidates_)[tmpj].setPs1Energy( 0. );
1465 (*pfCandidates_)[tmpj].setPs2Energy( 0. );
1466 (*pfCandidates_)[tmpj].addElementInBlock(blockref, iEcal);
1467 bNeutralProduced =
true;
1468 for (
unsigned ic=0; ic<kTrack.size();++ic)
1469 (*
pfCandidates_)[tmpj].addElementInBlock( blockref, kTrack[ic] );
1473 for (
unsigned ic=0; ic<tmpi.size();++ic) {
1478 double fraction = (*pfCandidates_)[tmpi[ic]].trackRef()->p()/
trackMomentum;
1479 double ecalCal = bNeutralProduced ?
1480 (calibEcal-neutralEnergy*slopeEcal)*fraction : calibEcal*fraction;
1481 double ecalRaw = totalEcal*fraction;
1483 if (
debug_)
cout <<
"The fraction after photon supression is " << fraction <<
" calibrated ecal = " << ecalCal << endl;
1485 (*pfCandidates_)[tmpi[ic]].setEcalEnergy( ecalRaw, ecalCal );
1486 (*pfCandidates_)[tmpi[ic]].setHcalEnergy( 0., 0. );
1487 (*pfCandidates_)[tmpi[ic]].setHoEnergy( 0., 0. );
1488 (*pfCandidates_)[tmpi[ic]].setPs1Energy( 0 );
1489 (*pfCandidates_)[tmpi[ic]].setPs2Energy( 0 );
1490 (*pfCandidates_)[tmpi[ic]].addElementInBlock( blockref, kTrack[ic] );
1496 for (
unsigned ic=0; ic<tmpi.size();++ic) {
1497 const PFCandidate& pfc = (*pfCandidates_)[tmpi[ic]];
1499 if ( eleInBlocks.size() == 0 ) {
1500 if (
debug_ )
std::cout <<
"Single track / Fill element in block! " << std::endl;
1501 (*pfCandidates_)[tmpi[ic]].addElementInBlock( blockref, kTrack[ic] );
1510 for(IE ie = hcalElems.begin(); ie != hcalElems.end(); ++ie ) {
1512 unsigned index = ie->second;
1518 cout<<
"\telement "<<elements[
index]<<
" linked with distance "<< dist <<endl;
1527 cout<<
"\t\tclosest hcal cluster, doing nothing"<<endl;
1537 cout<<
"\t\tsecondary hcal cluster. unlinking"<<endl;
1538 block.setLink( iTrack, index, -1., linkData,
1539 PFBlock::LINKTEST_RECHIT );
1547 if( !(hfEmIs.empty() && hfHadIs.empty() ) ) {
1550 assert( hfEmIs.size() + hfHadIs.size() == elements.
size() );
1552 if( elements.
size() == 1 ) {
1555 double energyHF = 0.;
1556 double uncalibratedenergyHF = 0.;
1558 switch( clusterRef->layer() ) {
1561 energyHF = clusterRef->energy();
1562 uncalibratedenergyHF = energyHF;
1565 clusterRef->positionREP().Eta(),
1566 clusterRef->positionREP().Phi());
1569 (*pfCandidates_)[tmpi].setEcalEnergy( uncalibratedenergyHF, energyHF );
1570 (*pfCandidates_)[tmpi].setHcalEnergy( 0., 0.);
1571 (*pfCandidates_)[tmpi].setHoEnergy( 0., 0.);
1572 (*pfCandidates_)[tmpi].setPs1Energy( 0. );
1573 (*pfCandidates_)[tmpi].setPs2Energy( 0. );
1574 (*pfCandidates_)[tmpi].addElementInBlock( blockref, hfEmIs[0] );
1579 energyHF = clusterRef->energy();
1580 uncalibratedenergyHF = energyHF;
1583 clusterRef->positionREP().Eta(),
1584 clusterRef->positionREP().Phi());
1587 (*pfCandidates_)[tmpi].setHcalEnergy( uncalibratedenergyHF, energyHF );
1588 (*pfCandidates_)[tmpi].setEcalEnergy( 0., 0.);
1589 (*pfCandidates_)[tmpi].setHoEnergy( 0., 0.);
1590 (*pfCandidates_)[tmpi].setPs1Energy( 0. );
1591 (*pfCandidates_)[tmpi].setPs2Energy( 0. );
1592 (*pfCandidates_)[tmpi].addElementInBlock( blockref, hfHadIs[0] );
1599 else if( elements.
size() == 2 ) {
1608 cerr<<
"Error: 2 elements, but not 1 HFEM and 1 HFHAD"<<endl;
1615 double energyHfEm = cem->energy();
1616 double energyHfHad = chad->energy();
1617 double uncalibratedenergyHFEm = energyHfEm;
1618 double uncalibratedenergyHFHad = energyHfHad;
1623 c0->positionREP().Eta(),
1624 c0->positionREP().Phi());
1626 uncalibratedenergyHFHad,
1627 c1->positionREP().Eta(),
1628 c1->positionREP().Phi());
1631 (*pfCandidates_)[tmpi].setEcalEnergy( uncalibratedenergyHFEm, energyHfEm );
1632 (*pfCandidates_)[tmpi].setHcalEnergy( uncalibratedenergyHFHad, energyHfHad);
1633 (*pfCandidates_)[tmpi].setHoEnergy( 0., 0.);
1634 (*pfCandidates_)[tmpi].setPs1Energy( 0. );
1635 (*pfCandidates_)[tmpi].setPs2Energy( 0. );
1636 (*pfCandidates_)[tmpi].addElementInBlock( blockref, hfEmIs[0] );
1637 (*pfCandidates_)[tmpi].addElementInBlock( blockref, hfHadIs[0] );
1643 cerr<<
"Warning: HF, but n elem different from 1 or 2"<<endl;
1654 cout<<endl<<
"--------------- loop hcal ---------------------"<<endl;
1663 for(
unsigned i=0;
i<hcalIs.size();
i++) {
1665 unsigned iHcal= hcalIs[
i];
1670 if(
debug_)
cout<<endl<<elements[iHcal]<<endl;
1676 std::multimap<double, unsigned> sortedTracks;
1677 block.associatedElements( iHcal, linkData,
1682 std::multimap< unsigned, std::pair<double, unsigned> > associatedEcals;
1684 std::map< unsigned, std::pair<double, double> > associatedPSs;
1686 std::multimap<double, std::pair<unsigned,bool> > associatedTracks;
1689 std::multimap<double,std::pair<unsigned,::math::XYZVector> > ecalSatellites;
1690 std::pair<unsigned,::math::XYZVector> fakeSatellite = make_pair(iHcal,::
math::XYZVector(0.,0.,0.));
1691 ecalSatellites.insert( make_pair(-1., fakeSatellite) );
1693 std::multimap< unsigned, std::pair<double, unsigned> > associatedHOs;
1695 PFClusterRef hclusterref = elements[iHcal].clusterRef();
1696 assert(!hclusterref.
isNull() );
1706 if( sortedTracks.empty() ) {
1708 cout<<
"\tno associated tracks, keep for later"<<endl;
1713 active[iHcal] =
false;
1721 if(
debug_)
cout<<
"\t"<<sortedTracks.size()<<
" associated tracks:"<<endl;
1723 double totalChargedMomentum = 0;
1724 double sumpError2 = 0.;
1725 double totalHO = 0.;
1726 double totalEcal = 0.;
1727 double totalHcal = hclusterref->energy();
1728 vector<double> hcalP;
1729 vector<double> hcalDP;
1730 vector<unsigned> tkIs;
1731 double maxDPovP = -9999.;
1734 vector< unsigned > chargedHadronsIndices;
1735 vector< unsigned > chargedHadronsInBlock;
1736 double mergedNeutralHadronEnergy = 0;
1737 double mergedPhotonEnergy = 0;
1738 double muonHCALEnergy = 0.;
1739 double muonECALEnergy = 0.;
1740 double muonHCALError = 0.;
1741 double muonECALError = 0.;
1742 unsigned nMuons = 0;
1747 hclusterref->position().Y(),
1748 hclusterref->position().Z());
1749 hadronDirection = hadronDirection.Unit();
1753 for(IE ie = sortedTracks.begin(); ie != sortedTracks.end(); ++ie ) {
1755 unsigned iTrack = ie->second;
1758 if ( !active[iTrack] )
continue;
1764 assert( !trackRef.
isNull() );
1769 ::math::XYZVector chargedDirection(chargedPosition.X(),chargedPosition.Y(),chargedPosition.Z());
1770 chargedDirection = chargedDirection.Unit();
1773 std::multimap<double, unsigned> sortedEcals;
1774 block.associatedElements( iTrack, linkData,
1779 if(
debug_)
cout<<
"\t\t\tnumber of Ecal elements linked to this track: "
1780 <<sortedEcals.size()<<endl;
1783 std::multimap<double, unsigned> sortedHOs;
1785 block.associatedElements( iTrack, linkData,
1792 cout<<
"PFAlgo : number of HO elements linked to this track: "
1793 <<sortedHOs.size()<<endl;
1801 bool thisIsALooseMuon =
false;
1809 if ( thisIsAMuon ) {
1811 std::cout <<
"\t\tThis track is identified as a muon - remove it from the stack" << std::endl;
1812 std::cout <<
"\t\t" << elements[iTrack] << std::endl;
1820 (*pfCandidates_)[tmpi].addElementInBlock( blockref, iTrack );
1821 (*pfCandidates_)[tmpi].addElementInBlock( blockref, iHcal );
1827 bool letMuonEatCaloEnergy =
false;
1829 if(thisIsAnIsolatedMuon){
1831 double totalCaloEnergy = totalHcal / 1.30;
1833 if( !sortedEcals.empty() ) {
1834 iEcal = sortedEcals.begin()->second;
1835 PFClusterRef eclusterref = elements[iEcal].clusterRef();
1836 totalCaloEnergy += eclusterref->energy();
1842 if( !sortedHOs.empty() ) {
1843 iHO = sortedHOs.begin()->second;
1845 totalCaloEnergy += eclusterref->energy() / 1.30;
1851 if( (
pfCandidates_->back()).
p() > totalCaloEnergy ) letMuonEatCaloEnergy =
true;
1854 if(letMuonEatCaloEnergy) muonHcal = totalHcal;
1855 double muonEcal =0.;
1857 if( !sortedEcals.empty() ) {
1858 iEcal = sortedEcals.begin()->second;
1859 PFClusterRef eclusterref = elements[iEcal].clusterRef();
1860 (*pfCandidates_)[tmpi].addElementInBlock( blockref, iEcal);
1862 if(letMuonEatCaloEnergy) muonEcal = eclusterref->energy();
1864 if ( eclusterref->energy() - muonEcal < 0.2 ) active[iEcal] =
false;
1865 (*pfCandidates_)[tmpi].setEcalEnergy(eclusterref->energy(), muonEcal);
1870 if( !sortedHOs.empty() ) {
1871 iHO = sortedHOs.begin()->second;
1872 PFClusterRef hoclusterref = elements[iHO].clusterRef();
1873 (*pfCandidates_)[tmpi].addElementInBlock( blockref, iHO);
1875 if(letMuonEatCaloEnergy) muonHO = hoclusterref->energy();
1877 if ( hoclusterref->energy() - muonHO < 0.2 ) active[iHO] =
false;
1878 (*pfCandidates_)[tmpi].setHcalEnergy(totalHcal, muonHcal);
1879 (*pfCandidates_)[tmpi].setHoEnergy(hoclusterref->energy(), muonHO);
1882 (*pfCandidates_)[tmpi].setHcalEnergy(totalHcal, muonHcal);
1885 if(letMuonEatCaloEnergy){
1886 muonHCALEnergy += totalHcal;
1887 if (
useHO_) muonHCALEnergy +=muonHO;
1888 muonHCALError += 0.;
1889 muonECALEnergy += muonEcal;
1890 muonECALError += 0.;
1891 photonAtECAL -= muonEcal*chargedDirection;
1892 hadronAtECAL -= totalHcal*chargedDirection;
1893 if ( !sortedEcals.empty() ) active[iEcal] =
false;
1894 active[iHcal] =
false;
1895 if (
useHO_ && !sortedHOs.empty() ) active[iHO] =
false;
1901 if ( muonHO > 0. ) {
1908 photonAtECAL -= muonECAL_[0]*chargedDirection;
1909 hadronAtECAL -= muonHCAL_[0]*chargedDirection;
1913 active[iTrack] =
false;
1920 if(
debug_)
cout<<
"\t\t"<<elements[iTrack]<<endl;
1928 if ( thisIsALooseMuon && !thisIsAMuon ) nMuons += 1;
1933 double Dpt = trackRef->ptError();
1934 double blowError = 1.;
1935 switch (trackRef->algo()) {
1936 case TrackBase::ctf:
1937 case TrackBase::iter0:
1938 case TrackBase::iter1:
1939 case TrackBase::iter2:
1940 case TrackBase::iter3:
1941 case TrackBase::iter4:
1944 case TrackBase::iter5:
1947 case TrackBase::iter6:
1955 bool isPrimaryOrSecondary =
isFromSecInt(elements[iTrack],
"all");
1957 if ( isPrimaryOrSecondary ) blowError = 1.;
1959 std::pair<unsigned,bool> tkmuon = make_pair(iTrack,thisIsALooseMuon);
1960 associatedTracks.insert( make_pair(-Dpt*blowError, tkmuon) );
1963 double Dp = trackRef->qoverpError()*trackMomentum*
trackMomentum;
1964 sumpError2 += Dp*Dp;
1966 bool connectedToEcal =
false;
1967 if( !sortedEcals.empty() )
1971 for ( IE iec=sortedEcals.begin();
1972 iec!=sortedEcals.end(); ++iec ) {
1974 unsigned iEcal = iec->second;
1975 double dist = iec->first;
1978 if( !active[iEcal] ) {
1986 PFClusterRef eclusterref = elements[iEcal].clusterRef();
1987 assert(!eclusterref.
isNull() );
1990 std::multimap<double, unsigned> sortedTracksEcal;
1991 block.associatedElements( iEcal, linkData,
1995 unsigned jTrack = sortedTracksEcal.
begin()->second;
1996 if ( jTrack != iTrack )
continue;
2000 double distEcal = block.dist(jTrack,iEcal,linkData,
2008 vector<double> ps1Ene(1,static_cast<double>(0.));
2010 block, elements, linkData, active,
2012 vector<double> ps2Ene(1,static_cast<double>(0.));
2014 block, elements, linkData, active,
2016 std::pair<double,double> psEnes = make_pair(ps1Ene[0],
2018 associatedPSs.insert(make_pair(iEcal,psEnes));
2021 bool crackCorrection =
false;
2022 float ecalEnergyCalibrated =
calibration_->energyEm(*eclusterref,ps1Ene,ps2Ene,crackCorrection);
2024 eclusterref->position().Y(),
2025 eclusterref->position().Z());
2026 photonDirection = photonDirection.Unit();
2028 if ( !connectedToEcal ) {
2031 <<elements[iEcal]<<endl;
2033 connectedToEcal =
true;
2037 std::pair<unsigned,::math::XYZVector> satellite =
2038 make_pair(iEcal,ecalEnergyCalibrated*photonDirection);
2039 ecalSatellites.insert( make_pair(-1., satellite) );
2043 std::pair<unsigned,::math::XYZVector> satellite =
2044 make_pair(iEcal,ecalEnergyCalibrated*photonDirection);
2045 ecalSatellites.insert( make_pair(dist, satellite) );
2049 std::pair<double, unsigned> associatedEcal
2050 = make_pair( distEcal, iEcal );
2051 associatedEcals.insert( make_pair(iTrack, associatedEcal) );
2056 if(
useHO_ && !sortedHOs.empty() )
2060 for ( IE ieho=sortedHOs.begin(); ieho!=sortedHOs.end(); ++ieho ) {
2062 unsigned iHO = ieho->second;
2063 double distHO = ieho->first;
2066 if( !active[iHO] ) {
2073 assert( type == PFBlockElement::HO );
2074 PFClusterRef hoclusterref = elements[iHO].clusterRef();
2075 assert(!hoclusterref.
isNull() );
2078 std::multimap<double, unsigned> sortedTracksHO;
2079 block.associatedElements( iHO, linkData,
2083 unsigned jTrack = sortedTracksHO.
begin()->second;
2084 if ( jTrack != iTrack )
continue;
2092 totalHO += hoclusterref->energy();
2093 active[iHO] =
false;
2095 std::pair<double, unsigned> associatedHO
2096 = make_pair( distHO, iHO );
2097 associatedHOs.insert( make_pair(iTrack, associatedHO) );
2106 totalHcal += totalHO;
2110 double caloEnergy = 0.;
2111 double slopeEcal = 1.0;
2112 double calibEcal = 0.;
2113 double calibHcal = 0.;
2114 hadronDirection = hadronAtECAL.Unit();
2118 Caloresolution *= totalChargedMomentum;
2120 Caloresolution =
std::sqrt(Caloresolution*Caloresolution + muonHCALError + muonECALError);
2121 totalEcal -=
std::min(totalEcal,muonECALEnergy);
2122 totalHcal -=
std::min(totalHcal,muonHCALEnergy);
2130 for ( IS is = ecalSatellites.begin(); is != ecalSatellites.end(); ++is ) {
2133 double previousCalibEcal = calibEcal;
2134 double previousCalibHcal = calibHcal;
2135 double previousCaloEnergy = caloEnergy;
2136 double previousSlopeEcal = slopeEcal;
2139 totalEcal +=
sqrt(is->second.second.Mag2());
2140 photonAtECAL += is->second.second;
2141 calibEcal =
std::max(0.,totalEcal);
2142 calibHcal =
std::max(0.,totalHcal);
2143 hadronAtECAL = calibHcal * hadronDirection;
2145 calibration_->energyEmHad(totalChargedMomentum,calibEcal,calibHcal,
2146 hclusterref->positionREP().Eta(),
2147 hclusterref->positionREP().Phi());
2148 caloEnergy = calibEcal+calibHcal;
2149 if ( totalEcal > 0.) slopeEcal = calibEcal/totalEcal;
2151 hadronAtECAL = calibHcal * hadronDirection;
2155 if ( is->first < 0. || caloEnergy - totalChargedMomentum <= 0. ) {
2156 if(
debug_)
cout<<
"\t\t\tactive, adding "<<is->second.second
2157 <<
" to ECAL energy, and locking"<<endl;
2158 active[is->second.first] =
false;
2164 totalEcal -=
sqrt(is->second.second.Mag2());
2165 photonAtECAL -= is->second.second;
2166 calibEcal = previousCalibEcal;
2167 calibHcal = previousCalibHcal;
2168 hadronAtECAL = previousHadronAtECAL;
2169 slopeEcal = previousSlopeEcal;
2170 caloEnergy = previousCaloEnergy;
2177 assert(caloEnergy>=0);
2190 double TotalError =
sqrt(sumpError2 + Caloresolution*Caloresolution);
2194 if ( totalChargedMomentum - caloEnergy >
nSigmaTRACK_*Caloresolution ) {
2209 for ( IT it = associatedTracks.begin(); it != associatedTracks.end(); ++it ) {
2210 unsigned iTrack = it->second.first;
2212 if ( !active[iTrack] )
continue;
2214 if ( !it->second.second )
continue;
2216 double trackMomentum = elements[it->second.first].trackRef()->p();
2219 std::multimap<double, unsigned> sortedEcals;
2220 block.associatedElements( iTrack, linkData,
2224 std::multimap<double, unsigned> sortedHOs;
2225 block.associatedElements( iTrack, linkData,
2233 (*pfCandidates_)[tmpi].addElementInBlock( blockref, iTrack );
2234 (*pfCandidates_)[tmpi].addElementInBlock( blockref, iHcal );
2237 (*pfCandidates_)[tmpi].setHcalEnergy(totalHcal,muonHcal);
2238 if( !sortedEcals.empty() ) {
2239 unsigned iEcal = sortedEcals.begin()->second;
2240 PFClusterRef eclusterref = elements[iEcal].clusterRef();
2241 (*pfCandidates_)[tmpi].addElementInBlock( blockref, iEcal);
2243 (*pfCandidates_)[tmpi].setEcalEnergy(eclusterref->energy(),muonEcal);
2245 if(
useHO_ && !sortedHOs.empty() ) {
2246 unsigned iHO = sortedHOs.begin()->second;
2247 PFClusterRef hoclusterref = elements[iHO].clusterRef();
2248 (*pfCandidates_)[tmpi].addElementInBlock( blockref, iHO);
2250 (*pfCandidates_)[tmpi].setHcalEnergy(totalHcal-totalHO,muonHcal);
2251 (*pfCandidates_)[tmpi].setHoEnergy(hoclusterref->energy(),muonHO);
2256 ::math::XYZVector chargedDirection(chargedPosition.X(), chargedPosition.Y(), chargedPosition.Z());
2257 chargedDirection = chargedDirection.Unit();
2260 if ( totalEcal > 0. )
2262 if ( totalHcal > 0. )
2267 if ( totalHcal >
muonHCAL_[0] ) hadronAtECAL -=
muonHCAL_[0]*calibHcal/totalHcal * chargedDirection;
2268 caloEnergy = calibEcal+calibHcal;
2271 if ( muonHO > 0. ) {
2274 if ( totalHcal > 0. ) {
2275 calibHcal -=
std::min(calibHcal,muonHO_[0]*calibHcal/totalHcal);
2276 totalHcal -=
std::min(totalHcal,muonHO_[0]);
2281 active[iTrack] =
false;
2288 Caloresolution *= totalChargedMomentum;
2289 Caloresolution =
std::sqrt(Caloresolution*Caloresolution + muonHCALError + muonECALError);
2307 unsigned corrTrack = 10000000;
2308 double corrFact = 1.;
2311 totalChargedMomentum - caloEnergy >
nSigmaTRACK_*Caloresolution) {
2313 for ( IT it = associatedTracks.begin(); it != associatedTracks.end(); ++it ) {
2314 unsigned iTrack = it->second.first;
2316 if ( !active[iTrack] )
continue;
2317 const reco::TrackRef& trackref = elements[it->second.first].trackRef();
2319 double dptRel = fabs(it->first)/trackref->pt()*100;
2320 bool isSecondary =
isFromSecInt(elements[iTrack],
"secondary");
2321 bool isPrimary =
isFromSecInt(elements[iTrack],
"primary");
2325 if ( fabs(it->first) <
ptError_ )
break;
2327 double wouldBeTotalChargedMomentum =
2328 totalChargedMomentum - trackref->p();
2332 if ( wouldBeTotalChargedMomentum > caloEnergy ) {
2334 if (
debug_ && isSecondary) {
2335 cout <<
"In bad track rejection step dptRel = " << dptRel <<
" dptRel_DispVtx_ = " <<
dptRel_DispVtx_ << endl;
2336 cout <<
"The calo energy would be still smaller even without this track but it is attached to a NI"<< endl;
2341 active[iTrack] =
false;
2342 totalChargedMomentum = wouldBeTotalChargedMomentum;
2344 std::cout <<
"\tElement " << elements[iTrack]
2345 <<
" rejected (Dpt = " << -it->first
2346 <<
" GeV/c, algo = " << trackref->algo() <<
")" << std::endl;
2349 if(isPrimary)
break;
2351 corrFact = (caloEnergy - wouldBeTotalChargedMomentum)/elements[it->second.first].trackRef()->p();
2352 if ( trackref->p()*corrFact < 0.05 ) {
2354 active[iTrack] =
false;
2356 totalChargedMomentum -= trackref->p()*(1.-corrFact);
2358 std::cout <<
"\tElement " << elements[iTrack]
2359 <<
" (Dpt = " << -it->first
2360 <<
" GeV/c, algo = " << trackref->algo()
2361 <<
") rescaled by " << corrFact
2362 <<
" Now the total charged momentum is " << totalChargedMomentum << endl;
2370 Caloresolution *= totalChargedMomentum;
2371 Caloresolution =
std::sqrt(Caloresolution*Caloresolution + muonHCALError + muonECALError);
2377 sortedTracks.size() > 1 &&
2378 totalChargedMomentum - caloEnergy >
nSigmaTRACK_*Caloresolution ) {
2379 for ( IT it = associatedTracks.begin(); it != associatedTracks.end(); ++it ) {
2380 unsigned iTrack = it->second.first;
2382 if ( !active[iTrack] )
continue;
2384 double dptRel = fabs(it->first)/trackref->pt()*100;
2385 bool isPrimaryOrSecondary =
isFromSecInt(elements[iTrack],
"all");
2392 switch (trackref->algo()) {
2393 case TrackBase::ctf:
2394 case TrackBase::iter0:
2395 case TrackBase::iter1:
2396 case TrackBase::iter2:
2397 case TrackBase::iter3:
2398 case TrackBase::iter4:
2400 case TrackBase::iter5:
2401 case TrackBase::iter6:
2402 active[iTrack] =
false;
2403 totalChargedMomentum -= trackref->p();
2406 std::cout <<
"\tElement " << elements[iTrack]
2407 <<
" rejected (Dpt = " << -it->first
2408 <<
" GeV/c, algo = " << trackref->algo() <<
")" << std::endl;
2418 Caloresolution *= totalChargedMomentum;
2419 Caloresolution =
std::sqrt(Caloresolution*Caloresolution + muonHCALError + muonECALError);
2423 for ( IT it = associatedTracks.begin(); it != associatedTracks.end(); ++it ) {
2424 unsigned iTrack = it->second.first;
2425 if ( !active[iTrack] )
continue;
2428 double Dp = trackRef->qoverpError()*trackMomentum*
trackMomentum;
2432 (*pfCandidates_)[tmpi].addElementInBlock( blockref, iTrack );
2433 (*pfCandidates_)[tmpi].addElementInBlock( blockref, iHcal );
2434 std::pair<II,II> myEcals = associatedEcals.equal_range(iTrack);
2435 for (II
ii=myEcals.first;
ii!=myEcals.second; ++
ii ) {
2436 unsigned iEcal =
ii->second.second;
2437 if ( active[iEcal] )
continue;
2438 (*pfCandidates_)[tmpi].addElementInBlock( blockref, iEcal );
2442 std::pair<II,II> myHOs = associatedHOs.equal_range(iTrack);
2443 for (II
ii=myHOs.first;
ii!=myHOs.second; ++
ii ) {
2444 unsigned iHO =
ii->second.second;
2445 if ( active[iHO] )
continue;
2446 (*pfCandidates_)[tmpi].addElementInBlock( blockref, iHO );
2450 if ( iTrack == corrTrack ) {
2451 (*pfCandidates_)[tmpi].rescaleMomentum(corrFact);
2452 trackMomentum *= corrFact;
2454 chargedHadronsIndices.push_back( tmpi );
2455 chargedHadronsInBlock.push_back( iTrack );
2456 active[iTrack] =
false;
2457 hcalP.push_back(trackMomentum);
2458 hcalDP.push_back(Dp);
2459 if (Dp/trackMomentum > maxDPovP) maxDPovP = Dp/
trackMomentum;
2460 sumpError2 += Dp*Dp;
2464 TotalError =
sqrt(sumpError2 + Caloresolution*Caloresolution);
2467 cout<<
"\tCompare Calo Energy to total charged momentum "<<endl;
2468 cout<<
"\t\tsum p = "<<totalChargedMomentum<<
" +- "<<
sqrt(sumpError2)<<endl;
2469 cout<<
"\t\tsum ecal = "<<totalEcal<<endl;
2470 cout<<
"\t\tsum hcal = "<<totalHcal<<endl;
2471 cout<<
"\t\t => Calo Energy = "<<caloEnergy<<
" +- "<<Caloresolution<<endl;
2472 cout<<
"\t\t => Calo Energy- total charged momentum = "
2473 <<caloEnergy-totalChargedMomentum<<
" +- "<<TotalError<<endl;
2480 double nsigma =
nSigmaHCAL(totalChargedMomentum,hclusterref->positionREP().Eta());
2482 if (
abs(totalChargedMomentum-caloEnergy)<nsigma*TotalError ) {
2488 cout<<
"\t\tcase 1: COMPATIBLE "
2489 <<
"|Calo Energy- total charged momentum| = "
2490 <<
abs(caloEnergy-totalChargedMomentum)
2491 <<
" < "<<nsigma<<
" x "<<TotalError<<endl;
2492 if (maxDPovP < 0.1 )
2493 cout<<
"\t\t\tmax DP/P = "<< maxDPovP
2494 <<
" less than 0.1: do nothing "<<endl;
2496 cout<<
"\t\t\tmax DP/P = "<< maxDPovP
2497 <<
" > 0.1: take weighted averages "<<endl;
2501 if (maxDPovP > 0.1) {
2505 int nrows = chargedHadronsIndices.size();
2506 TMatrixTSym<double>
a (nrows);
2508 TVectorD
check(nrows);
2509 double sigma2E = Caloresolution*Caloresolution;
2510 for(
int i=0;
i<nrows;
i++) {
2511 double sigma2i = hcalDP[
i]*hcalDP[
i];
2513 cout<<
"\t\t\ttrack associated to hcal "<<
i
2514 <<
" P = "<<hcalP[
i]<<
" +- "
2517 a(
i,
i) = 1./sigma2i + 1./sigma2E;
2518 b(
i) = hcalP[
i]/sigma2i + caloEnergy/sigma2E;
2519 for(
int j=0;
j<nrows;
j++) {
2521 a(
i,
j) = 1./sigma2E;
2532 TDecompChol decomp(a);
2534 TVectorD
x = decomp.Solve(b, ok);
2538 for (
int i=0;
i<nrows;
i++){
2540 unsigned ich = chargedHadronsIndices[
i];
2541 double rescaleFactor =
x(
i)/hcalP[
i];
2542 (*pfCandidates_)[ich].rescaleMomentum( rescaleFactor );
2545 cout<<
"\t\t\told p "<<hcalP[
i]
2547 <<
" rescale "<<rescaleFactor<<endl;
2552 cerr<<
"not ok!"<<endl;
2559 else if( caloEnergy > totalChargedMomentum ) {
2578 double eNeutralHadron = caloEnergy - totalChargedMomentum;
2579 double ePhoton = (caloEnergy - totalChargedMomentum) / slopeEcal;
2582 if(!sortedTracks.empty() ){
2583 cout<<
"\t\tcase 2: NEUTRAL DETECTION "
2584 <<caloEnergy<<
" > "<<nsigma<<
"x"<<TotalError
2585 <<
" + "<<totalChargedMomentum<<endl;
2586 cout<<
"\t\tneutral activity detected: "<<endl
2587 <<
"\t\t\t photon = "<<ePhoton<<endl
2588 <<
"\t\t\tor neutral hadron = "<<eNeutralHadron<<endl;
2590 cout<<
"\t\tphoton or hadron ?"<<endl;}
2592 if(sortedTracks.empty() )
2593 cout<<
"\t\tno track -> hadron "<<endl;
2595 cout<<
"\t\t"<<sortedTracks.size()
2596 <<
"tracks -> check if the excess is photonic or hadronic"<<endl;
2600 double ratioMax = 0.;
2602 unsigned maxiEcal= 9999;
2606 for(IE ie = sortedTracks.begin(); ie != sortedTracks.end(); ++ie ) {
2608 unsigned iTrack = ie->second;
2614 assert( !trackRef.
isNull() );
2616 II iae = associatedEcals.find(iTrack);
2618 if( iae == associatedEcals.end() )
continue;
2621 unsigned iEcal = iae->second.second;
2627 assert( !clusterRef.
isNull() );
2629 double pTrack = trackRef->p();
2630 double eECAL = clusterRef->energy();
2631 double eECALOverpTrack = eECAL / pTrack;
2633 if ( eECALOverpTrack > ratioMax ) {
2634 ratioMax = eECALOverpTrack;
2635 maxEcalRef = clusterRef;
2641 std::vector<reco::PFClusterRef> pivotalClusterRef;
2642 std::vector<unsigned> iPivotal;
2643 std::vector<double> particleEnergy, ecalEnergy, hcalEnergy, rawecalEnergy, rawhcalEnergy;
2644 std::vector<::math::XYZVector> particleDirection;
2648 if ( ePhoton < totalEcal || eNeutralHadron-calibEcal < 1E-10 ) {
2650 if ( !maxEcalRef.
isNull() ) {
2651 particleEnergy.push_back(ePhoton);
2652 particleDirection.push_back(photonAtECAL);
2653 ecalEnergy.push_back(ePhoton);
2654 hcalEnergy.push_back(0.);
2655 rawecalEnergy.push_back(totalEcal);
2656 rawhcalEnergy.push_back(totalHcal);
2657 pivotalClusterRef.push_back(maxEcalRef);
2658 iPivotal.push_back(maxiEcal);
2660 mergedPhotonEnergy = ePhoton;
2666 if ( !maxEcalRef.
isNull() ) {
2667 pivotalClusterRef.push_back(maxEcalRef);
2668 particleEnergy.push_back(totalEcal);
2669 particleDirection.push_back(photonAtECAL);
2670 ecalEnergy.push_back(totalEcal);
2671 hcalEnergy.push_back(0.);
2672 rawecalEnergy.push_back(totalEcal);
2673 rawhcalEnergy.push_back(totalHcal);
2674 iPivotal.push_back(maxiEcal);
2676 mergedPhotonEnergy = totalEcal;
2680 mergedNeutralHadronEnergy = eNeutralHadron-calibEcal;
2681 if ( mergedNeutralHadronEnergy > 1.0 ) {
2682 pivotalClusterRef.push_back(hclusterref);
2683 particleEnergy.push_back(mergedNeutralHadronEnergy);
2684 particleDirection.push_back(hadronAtECAL);
2685 ecalEnergy.push_back(0.);
2686 hcalEnergy.push_back(mergedNeutralHadronEnergy);
2687 rawecalEnergy.push_back(totalEcal);
2688 rawhcalEnergy.push_back(totalHcal);
2689 iPivotal.push_back(iHcal);
2699 for (
unsigned iPivot=0; iPivot<iPivotal.size(); ++iPivot ) {
2701 if ( particleEnergy[iPivot] < 0. )
2702 std::cout <<
"ALARM = Negative energy ! "
2703 << particleEnergy[iPivot] << std::endl;
2705 bool useDirection =
true;
2707 particleEnergy[iPivot],
2709 particleDirection[iPivot].
X(),
2710 particleDirection[iPivot].Y(),
2711 particleDirection[iPivot].
Z());
2714 (*pfCandidates_)[tmpi].setEcalEnergy( rawecalEnergy[iPivot],ecalEnergy[iPivot] );
2716 (*pfCandidates_)[tmpi].setHcalEnergy( rawhcalEnergy[iPivot],hcalEnergy[iPivot] );
2717 (*pfCandidates_)[tmpi].setHoEnergy(0., 0.);
2719 (*pfCandidates_)[tmpi].setHcalEnergy( rawhcalEnergy[iPivot]-totalHO,hcalEnergy[iPivot]*(1.-totalHO/rawhcalEnergy[iPivot]));
2720 (*pfCandidates_)[tmpi].setHoEnergy(totalHO, totalHO * hcalEnergy[iPivot]/rawhcalEnergy[iPivot]);
2722 (*pfCandidates_)[tmpi].setPs1Energy( 0. );
2723 (*pfCandidates_)[tmpi].setPs2Energy( 0. );
2724 (*pfCandidates_)[tmpi].set_mva_nothing_gamma( -1. );
2727 (*pfCandidates_)[tmpi].addElementInBlock( blockref, iHcal );
2728 for (
unsigned ich=0; ich<chargedHadronsInBlock.size(); ++ich) {
2729 unsigned iTrack = chargedHadronsInBlock[ich];
2730 (*pfCandidates_)[tmpi].addElementInBlock( blockref, iTrack );
2736 std::pair<II,II> myEcals = associatedEcals.equal_range(iTrack);
2737 for (II
ii=myEcals.first;
ii!=myEcals.second; ++
ii ) {
2738 unsigned iEcal =
ii->second.second;
2739 if ( active[iEcal] )
continue;
2740 (*pfCandidates_)[tmpi].addElementInBlock( blockref, iEcal );
2752 double totalHcalEnergyCalibrated = calibHcal;
2753 double totalEcalEnergyCalibrated = calibEcal;
2768 totalHcalEnergyCalibrated -= mergedNeutralHadronEnergy;
2770 totalEcalEnergyCalibrated -= mergedPhotonEnergy;
2775 double chargedHadronsTotalEnergy = 0;
2776 for(
unsigned ich=0; ich<chargedHadronsIndices.size(); ++ich ) {
2777 unsigned index = chargedHadronsIndices[ich];
2779 chargedHadronsTotalEnergy += chargedHadron.
energy();
2782 for(
unsigned ich=0; ich<chargedHadronsIndices.size(); ++ich ) {
2783 unsigned index = chargedHadronsIndices[ich];
2785 float fraction = chargedHadron.
energy()/chargedHadronsTotalEnergy;
2788 chargedHadron.
setHcalEnergy( fraction * totalHcal, fraction * totalHcalEnergyCalibrated );
2791 chargedHadron.
setHcalEnergy( fraction * (totalHcal-totalHO), fraction * totalHcalEnergyCalibrated * (1.-totalHO/totalHcal) );
2792 chargedHadron.
setHoEnergy( fraction * totalHO, fraction * totalHO * totalHcalEnergyCalibrated / totalHcal );
2795 chargedHadron.
setEcalEnergy( fraction * totalEcal, fraction * totalEcalEnergyCalibrated );
2799 for ( IS is = ecalSatellites.begin(); is != ecalSatellites.end(); ++is ) {
2802 unsigned iEcal = is->second.first;
2803 if ( !active[iEcal] )
continue;
2808 PFClusterRef eclusterref = elements[iEcal].clusterRef();
2809 assert(!eclusterref.
isNull() );
2812 active[iEcal] =
false;
2815 std::multimap<double, unsigned> assTracks;
2816 block.associatedElements( iEcal, linkData,
2823 (*pfCandidates_)[tmpi].setEcalEnergy( eclusterref->energy(),
sqrt(is->second.second.Mag2()) );
2824 (*pfCandidates_)[tmpi].setHcalEnergy( 0., 0. );
2825 (*pfCandidates_)[tmpi].setHoEnergy( 0., 0. );
2826 (*pfCandidates_)[tmpi].setPs1Energy( associatedPSs[iEcal].
first );
2827 (*pfCandidates_)[tmpi].setPs2Energy( associatedPSs[iEcal].
second );
2828 (*pfCandidates_)[tmpi].addElementInBlock( blockref, iEcal );
2829 (*pfCandidates_)[tmpi].addElementInBlock( blockref, sortedTracks.begin()->second) ;
2843 <<
"---- loop remaining hcal ------- "<<endl;
2849 for(
unsigned ihcluster=0; ihcluster<hcalIs.size(); ihcluster++) {
2850 unsigned iHcal = hcalIs[ihcluster];
2853 std::vector<unsigned> ecalRefs;
2854 std::vector<unsigned> hoRefs;
2857 cout<<endl<<elements[iHcal]<<
" ";
2860 if( !active[iHcal] ) {
2862 cout<<
"not active"<<endl;
2867 std::multimap<double, unsigned> ecalElems;
2868 block.associatedElements( iHcal, linkData,
2874 float totalEcal = 0.;
2877 for(IE ie = ecalElems.begin(); ie != ecalElems.end(); ++ie ) {
2879 unsigned iEcal = ie->second;
2880 double dist = ie->first;
2885 if( !active[iEcal] )
continue;
2906 std::multimap<double, unsigned> hcalElems;
2907 block.associatedElements( iEcal, linkData,
2912 bool isClosest =
true;
2913 for(IE ih = hcalElems.begin(); ih != hcalElems.end(); ++ih ) {
2915 unsigned jHcal = ih->second;
2916 double distH = ih->first;
2918 if ( !active[jHcal] )
continue;
2920 if ( distH < dist ) {
2927 if (!isClosest)
continue;
2931 cout<<
"\telement "<<elements[iEcal]<<
" linked with dist "<< dist<<endl;
2932 cout<<
"Added to HCAL cluster to form a neutral hadron"<<endl;
2936 assert( !eclusterRef.
isNull() );
2939 vector<double> ps1Ene(1,static_cast<double>(0.));
2941 vector<double> ps2Ene(1,static_cast<double>(0.));
2943 bool crackCorrection =
false;
2944 double ecalEnergy =
calibration_->energyEm(*eclusterRef,ps1Ene,ps2Ene,crackCorrection);
2948 totalEcal += ecalEnergy;
2949 if ( ecalEnergy > ecalMax ) {
2950 ecalMax = ecalEnergy;
2951 eClusterRef = eclusterRef;
2954 ecalRefs.push_back(iEcal);
2955 active[iEcal] =
false;
2961 double totalHO = 0.;
2965 std::multimap<double, unsigned> hoElems;
2966 block.associatedElements( iHcal, linkData,
2976 for(IE ie = hoElems.begin(); ie != hoElems.end(); ++ie ) {
2978 unsigned iHO = ie->second;
2979 double dist = ie->first;
2981 assert( type == PFBlockElement::HO );
2984 if( !active[iHO] )
continue;
2990 std::multimap<double, unsigned> hcalElems;
2991 block.associatedElements( iHO, linkData,
2996 bool isClosest =
true;
2997 for(IE ih = hcalElems.begin(); ih != hcalElems.end(); ++ih ) {
2999 unsigned jHcal = ih->second;
3000 double distH = ih->first;
3002 if ( !active[jHcal] )
continue;
3004 if ( distH < dist ) {
3011 if (!isClosest)
continue;
3014 cout<<
"\telement "<<elements[iHO]<<
" linked with dist "<< dist<<endl;
3015 cout<<
"Added to HCAL cluster to form a neutral hadron"<<endl;
3019 assert( !hoclusterRef.
isNull() );
3021 double hoEnergy = hoclusterRef->energy();
3023 totalHO += hoEnergy;
3024 if ( hoEnergy > hoMax ) {
3026 hoClusterRef = hoclusterRef;
3030 hoRefs.push_back(iHO);
3031 active[iHO] =
false;
3037 = elements[iHcal].clusterRef();
3038 assert( !hclusterRef.
isNull() );
3041 double totalHcal = hclusterRef->energy();
3043 if (
useHO_ ) totalHcal += totalHO;
3051 double calibEcal = totalEcal > 0. ? totalEcal : 0.;
3052 double calibHcal =
std::max(0.,totalHcal);
3056 calibEcal = totalEcal;
3059 hclusterRef->positionREP().Eta(),
3060 hclusterRef->positionREP().Phi());
3073 calibEcal+calibHcal );
3076 (*pfCandidates_)[tmpi].setEcalEnergy( totalEcal, calibEcal );
3078 (*pfCandidates_)[tmpi].setHcalEnergy( totalHcal, calibHcal );
3079 (*pfCandidates_)[tmpi].setHoEnergy(0.,0.);
3081 (*pfCandidates_)[tmpi].setHcalEnergy( totalHcal-totalHO, calibHcal*(1.-totalHO/totalHcal));
3082 (*pfCandidates_)[tmpi].setHoEnergy(totalHO,totalHO*calibHcal/totalHcal);
3084 (*pfCandidates_)[tmpi].setPs1Energy( 0. );
3085 (*pfCandidates_)[tmpi].setPs2Energy( 0. );
3086 (*pfCandidates_)[tmpi].addElementInBlock( blockref, iHcal );
3087 for (
unsigned iec=0; iec<ecalRefs.size(); ++iec)
3088 (*
pfCandidates_)[tmpi].addElementInBlock( blockref, ecalRefs[iec] );
3089 for (
unsigned iho=0; iho<hoRefs.size(); ++iho)
3090 (*
pfCandidates_)[tmpi].addElementInBlock( blockref, hoRefs[iho] );
3099 if(
debug_)
cout<<endl<<
"---- loop ecal------- "<<endl;
3104 for(
unsigned i=0;
i<ecalIs.size();
i++) {
3105 unsigned iEcal = ecalIs[
i];
3108 cout<<endl<<elements[iEcal]<<
" ";
3110 if( ! active[iEcal] ) {
3112 cout<<
"not active"<<endl;
3119 PFClusterRef clusterref = elements[iEcal].clusterRef();
3120 assert(!clusterref.
isNull() );
3122 active[iEcal] =
false;
3125 vector<double> ps1Ene(1,static_cast<double>(0.));
3127 vector<double> ps2Ene(1,static_cast<double>(0.));
3129 bool crackCorrection =
false;
3130 float ecalEnergy =
calibration_->energyEm(*clusterref,ps1Ene,ps2Ene,crackCorrection);
3132 double particleEnergy = ecalEnergy;
3137 (*pfCandidates_)[tmpi].setEcalEnergy( clusterref->energy(),ecalEnergy );
3138 (*pfCandidates_)[tmpi].setHcalEnergy( 0., 0. );
3139 (*pfCandidates_)[tmpi].setHoEnergy( 0., 0. );
3140 (*pfCandidates_)[tmpi].setPs1Energy( 0. );
3141 (*pfCandidates_)[tmpi].setPs2Energy( 0. );
3142 (*pfCandidates_)[tmpi].addElementInBlock( blockref, iEcal );
3161 double px = track.
px();
3162 double py = track.
py();
3163 double pz = track.
pz();
3164 double energy =
sqrt(track.
p()*track.
p() + 0.13957*0.13957);
3176 pfCandidates_->back().setVertexSource( PFCandidate::kTrkVertex );
3189 if ((!isMuon) && isFromDisp) {
3190 double Dpt = trackRef->ptError();
3191 double dptRel = Dpt/trackRef->pt()*100;
3197 cout <<
"Not refitted px = " << px <<
" py = " << py <<
" pz = " << pz <<
" energy = " << energy << endl;
3200 reco::Track trackRefit = vRef->refittedTrack(trackRef);
3205 sqrt(trackRefit.
p()*trackRefit.
p() + 0.13957*0.13957));
3207 cout <<
"Refitted px = " << px <<
" py = " << py <<
" pz = " << pz <<
" energy = " << energy << endl;
3225 double particleEnergy,
3238 if ( useDirection ) {
3239 switch( cluster.
layer() ) {
3242 factor =
std::sqrt(cluster.
position().Perp2()/(particleX*particleX+particleY*particleY));
3248 factor = cluster.
position().Z()/particleZ;
3263 cluster.
position().Y()-vertexPos.Y(),
3264 cluster.
position().Z()-vertexPos.Z());
3266 particleY*factor-vertexPos.Y(),
3267 particleZ*factor-vertexPos.Z() );
3272 clusterPos = useDirection ? particleDirection.Unit() : clusterPos.Unit();
3273 clusterPos *= particleEnergy;
3279 ROOT::Math::LorentzVector<ROOT::Math::PxPyPzM4D<double> >
3280 momentum( clusterPos.X(), clusterPos.Y(), clusterPos.Z(), mass);
3290 switch( cluster.
layer() ) {
3293 particleType = PFCandidate::gamma;
3297 particleType = PFCandidate::h0;
3300 particleType = PFCandidate::h_HF;
3303 particleType = PFCandidate::egamma_HF;
3339 if ( clusterEnergyHCAL < 1. ) clusterEnergyHCAL = 1.;
3341 double resol = fabs(eta) < 1.48 ?
3342 sqrt (1.02*1.02/clusterEnergyHCAL + 0.065*0.065)
3344 sqrt (1.20*1.20/clusterEnergyHCAL + 0.028*0.028);
3352 double nS = fabs(eta) < 1.48 ?
3362 if(!out )
return out;
3364 out<<
"====== Particle Flow Algorithm ======= ";
3371 out<<
"reconstructed particles: "<<endl;
3373 const std::auto_ptr< reco::PFCandidateCollection >&
3376 if(!candidates.get() ) {
3377 out<<
"candidates already transfered"<<endl;
3406 std::vector<bool>& active,
3407 std::vector<double>& psEne) {
3415 std::multimap<double, unsigned> sortedPS;
3416 typedef std::multimap<double, unsigned>::iterator IE;
3418 sortedPS, psElementType,
3422 double totalPS = 0.;
3423 for ( IE ips=sortedPS.begin(); ips!=sortedPS.end(); ++ips ) {
3426 unsigned iPS = ips->second;
3430 if (!active[iPS])
continue;
3433 std::multimap<double, unsigned> sortedECAL;
3438 unsigned jEcal = sortedECAL.begin()->second;
3439 if ( jEcal != iEcal )
continue;
3443 assert( pstype == psElementType );
3444 PFClusterRef psclusterref = elements[iPS].clusterRef();
3445 assert(!psclusterref.
isNull() );
3446 totalPS += psclusterref->energy();
3447 psEne[0] += psclusterref->energy();
3448 active[iPS] =
false;
3463 bool bPrimary = (order.find(
"primary") != string::npos);
3464 bool bSecondary = (order.find(
"secondary") != string::npos);
3465 bool bAll = (order.find(
"all") != string::npos);
3470 if (bPrimary && isToDisp)
return true;
3471 if (bSecondary && isFromDisp )
return true;
3472 if (bAll && ( isToDisp || isFromDisp ) )
return true;
3501 std::vector<unsigned int> pfCandidatesToBeRemoved;
3508 double met2 = metX*metX+metY*metY;
3510 double significance =
std::sqrt(met2/sumet);
3511 double significanceCor = significance;
3514 double metXCor = metX;
3515 double metYCor = metY;
3516 double sumetCor = sumet;
3517 double met2Cor = met2;
3519 double deltaPhiPt = 100.;
3521 unsigned iCor = 1E9;
3526 double metReduc = -1.;
3540 for(
unsigned j=0;
j<pfCandidatesToBeRemoved.size(); ++
j) {
3541 if (
i == pfCandidatesToBeRemoved[
j] ) skip =
true;
3544 if ( skip )
continue;
3547 deltaPhi = std::acos((metX*pfc.
px()+metY*pfc.
py())/(pfc.
pt()*
std::sqrt(met2)));
3548 deltaPhiPt = deltaPhi*pfc.
pt();
3552 double metXInt = metX - pfc.
px();
3553 double metYInt = metY - pfc.
py();
3554 double sumetInt = sumet - pfc.
pt();
3555 double met2Int = metXInt*metXInt+metYInt*metYInt;
3556 if ( met2Int < met2Cor ) {
3559 metReduc = (met2-met2Int)/met2Int;
3561 sumetCor = sumetInt;
3562 significanceCor =
std::sqrt(met2Cor/sumetCor);
3569 pfCandidatesToBeRemoved.push_back(iCor);
3583 std::cout <<
"Significance reduction = " << significance <<
" -> "
3584 << significanceCor <<
" = " << significanceCor - significance
3586 for(
unsigned j=0;
j<pfCandidatesToBeRemoved.size(); ++
j) {
3587 std::cout <<
"Removed : " << (*pfCandidates_)[pfCandidatesToBeRemoved[
j]] << std::endl;
3589 (*pfCandidates_)[pfCandidatesToBeRemoved[
j]].rescaleMomentum(1E-6);
3603 if ( !cleanedHits.size() )
return;
3609 std::vector<unsigned int> hitsToBeAdded;
3616 double met2 = metX*metX+metY*metY;
3617 double met2_Original = met2;
3621 double metXCor = metX;
3622 double metYCor = metY;
3623 double sumetCor = sumet;
3624 double met2Cor = met2;
3626 unsigned iCor = 1E9;
3631 double metReduc = -1.;
3633 for(
unsigned i=0;
i<cleanedHits.size(); ++
i) {
3642 for(
unsigned j=0;
j<hitsToBeAdded.size(); ++
j) {
3643 if (
i == hitsToBeAdded[
j] ) skip =
true;
3646 if ( skip )
continue;
3649 double metXInt = metX + px;
3650 double metYInt = metY + py;
3651 double sumetInt = sumet +
pt;
3652 double met2Int = metXInt*metXInt+metYInt*metYInt;
3655 if ( met2Int < met2Cor ) {
3658 metReduc = (met2-met2Int)/met2Int;
3660 sumetCor = sumetInt;
3669 hitsToBeAdded.push_back(iCor);
3683 std::cout << hitsToBeAdded.size() <<
" hits were re-added " << std::endl;
3687 std::cout <<
"Added after cleaning check : " << std::endl;
3689 for(
unsigned j=0;
j<hitsToBeAdded.size(); ++
j) {
3709 for(
unsigned ic=0;ic<
size;++ic) {
3718 (*pfCandidates_)[ic].setPFElectronExtraRef(theRef);
3730 (*pfCandidates_)[ic].set_mva_e_pi(it->mvaVariable(PFCandidateElectronExtra::MVA_MVA));
3732 (*pfCandidates_)[ic].setPFElectronExtraRef(theRef);
3733 (*pfCandidates_)[ic].setGsfTrackRef(it->gsfTrackRef());
3741 for(
unsigned ic=0;ic<
size;++ic) {
3749 (*pfElectronCandidates_)[ic].setPFElectronExtraRef(theRef);
3760 for(
unsigned ic=0;ic<
size;++ic) {
3765 for(
unsigned pcextra=0;pcextra<sizePhExtra;++pcextra) {
3768 (*pfCandidates_)[ic].setPFPhotonExtraRef(theRef);
PFLayer::Layer layer() const
cluster layer, see PFLayer.h in this directory
const double Z[kNumberCalorimeter]
double p() const
momentum vector magnitude
virtual double energy() const GCC11_FINAL
energy
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
const reco::TrackRef & trackRef() const
std::vector< double > muonHCAL_
Variables for muons and fakes.
virtual void setCharge(Charge q) GCC11_FINAL
set electric charge
algo_(conf.existsAs< bool >("Correct")?conf.getParameter< bool >("Correct"):true, conf.getParameter< double >("e9e25Cut"), conf.getParameter< double >("intercept2DCut"), conf.existsAs< bool >("intercept2DSlope")?conf.getParameter< double >("intercept2DSlope"):defaultSlope2D_, conf.getParameter< std::vector< double > >("e1e9Cut"), conf.getParameter< std::vector< double > >("eCOREe9Cut"), conf.getParameter< std::vector< double > >("eSeLCut"), hfvars_)
ParticleType
particle types
void setPFMuonAndFakeParameters(const edm::ParameterSet &pset)
void addMissingMuons(edm::Handle< reco::MuonCollection >, reco::PFCandidateCollection *cands)
double sumEtEcalIsoForEgammaSC_endcap_
std::auto_ptr< reco::PFCandidateCollection > pfPhotonCandidates_
the unfiltered photon collection
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.
edm::Ref< PFCandidatePhotonExtraCollection > PFCandidatePhotonExtraRef
persistent reference to a PFCandidatePhotonExtra
double coneEcalIsoForEgammaSC_
static bool isMuon(const reco::PFBlockElement &elt)
const std::vector< reco::PFCandidate > & getAllElectronCandidates()
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)
double y() const
y coordinate
bool useProtectionsForJetMET_
double coneTrackIsoForEgammaSC_
void setParameters(const edm::ParameterSet &)
double nSigmaHCAL_
number of sigma to judge energy excess in HCAL
std::map< unsigned int, Link > LinkData
bool isElectronSafeForJetMET(const reco::GsfElectron &, const reco::PFCandidate &, const reco::Vertex &, bool lockTracks)
virtual void processBlock(const reco::PFBlockRef &blockref, std::list< reco::PFBlockRef > &hcalBlockRefs, std::list< reco::PFBlockRef > &ecalBlockRefs)
void setMuonHandle(const edm::Handle< reco::MuonCollection > &)
math::Error< dimension >::type Error
covariance error matrix (3x3)
std::vector< Vertex > VertexCollection
collection of Vertex objects
const edm::OwnVector< reco::PFBlockElement > & elements() const
std::vector< PFRecHit > PFRecHitCollection
collection of PFRecHit objects
const edm::ValueMap< reco::PhotonRef > * valueMapGedPhotons_
RefToBase< value_type > refAt(size_type i) const
void checkCleaning(const reco::PFRecHitCollection &cleanedHF)
Check HF Cleaning.
edm::Ref< PFCandidateElectronExtraCollection > PFCandidateElectronExtraRef
persistent reference to a PFCandidateElectronExtra
virtual void setVertex(const math::XYZPoint &p)
set vertex
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)
std::ostream & operator<<(std::ostream &out, const ALILine &li)
PFCandidateCollection::const_iterator PFCandidateConstIterator
iterator
double sumEtEcalIsoForEgammaSC_barrel_
std::auto_ptr< reco::PFCandidateCollection > pfCleanedCandidates_
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)
void setPFVertexParameters(bool useVertex, const reco::VertexCollection *primaryVertices)
void setEGElectronCollection(const reco::GsfElectronCollection &egelectrons)
std::vector< GsfElectron > GsfElectronCollection
collection of GsfElectron objects
virtual double py() const GCC11_FINAL
y coordinate of momentum vector
bool rejectTracks_Step45_
const math::XYZPointF & positionAtECALEntrance() const
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_
void set_mva_e_pi(float mva)
PFLayer::Layer layer() const
rechit layer
bool useEGammaSupercluster_
U second(std::pair< T, U > const &p)
XYZTLorentzVectorD XYZTLorentzVector
Lorentz vector with cylindrical internal representation using pseudorapidity.
bool isNonnull() const
Checks for non-null.
bool isElectron(const reco::GsfElectron &)
virtual float phi() const GCC11_FINAL
momentum azimuthal angle
bool usePFNuclearInteractions_
bool isNull() const
Checks for null.
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 setParameters(double nSigmaECAL, double nSigmaHCAL, const boost::shared_ptr< PFEnergyCalibration > &calibration, const boost::shared_ptr< PFEnergyCalibrationHF > &thepfEnergyCalibrationHF)
const T & max(const T &a, const T &b)
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 &)
bool check(const DataFrame &df, bool capcheck, bool dvercheck)
const std::vector< reco::PFCandidateElectronExtra > & getElectronExtra()
void setPFPhotonRegWeights(const GBRForest *LCorrForestEB, const GBRForest *LCorrForestEE, const GBRForest *GCorrForestBarrel, const GBRForest *GCorrForestEndcapHr9, const GBRForest *GCorrForestEndcapLr9, const GBRForest *PFEcalResolution)
virtual double px() const GCC11_FINAL
x coordinate of momentum vector
Abs< T >::type abs(const T &t)
double z() const
y 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
std::vector< LinkConnSpec >::const_iterator IT
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_
reco::PFBlockRef createBlockRef(const reco::PFBlockCollection &blocks, unsigned bi)
reco::PFCandidatePhotonExtraCollection pfPhotonExtra_
the extra photon collection
double pz() const
z coordinate of momentum vector
virtual float eta() const GCC11_FINAL
momentum pseudorapidity
void setEcalEnergy(float eeRaw, float eeCorr)
set corrected Ecal energy
float mva_e_pi() const
mva for electron-pion discrimination
const std::vector< reco::PFCandidate > & getElectronCandidates()
const math::XYZPoint & position() const
rechit cell centre x, y, z
std::vector< reco::PFCandidate > PFCandidateCollection
collection of PFCandidates
double x() const
x coordinate
virtual bool trackType(TrackType trType) const
std::list< reco::PFBlockRef >::iterator IBR
unsigned reconstructTrack(const reco::PFBlockElement &elt, bool allowLoose=false)
std::vector< double > muonHO_
XYZVectorD XYZVector
spatial vector with cartesian internal representation
void setGBRForest(const GBRForest *LCorrForest, const GBRForest *GCorrForest, const GBRForest *ResForest)
virtual int charge() const GCC11_FINAL
electric charge
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)
virtual bool trackType(TrackType trType) const
boost::shared_ptr< PFSCEnergyCalibration > thePFSCEnergyCalibration_
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.
double energy() const
rechit energy
boost::shared_ptr< PFEnergyCalibrationHF > thepfEnergyCalibrationHF_
virtual void setP4(const LorentzVector &p4) GCC11_FINAL
set 4-momentum
reco::PFCandidateEGammaExtraRef egammaExtraRef() const
return a reference to the EGamma extra
std::auto_ptr< reco::PFCandidateCollection > pfCandidates_
const PFDisplacedTrackerVertexRef & displacedVertexRef(TrackType trType) const
PFMuonAlgo * getPFMuonAlgo()
bool useEGammaFilters_
Variables for NEW EGAMMA selection.
void setPhotonExtraRef(const edm::OrphanHandle< reco::PFCandidatePhotonExtraCollection > &pf_extrah)
bool applyCrackCorrectionsElectrons_
int charge() const
track electric charge
double sumPtTrackIsoForEgammaSC_endcap_
void setPhotonPrimaryVtx(const reco::Vertex &primary)
volatile std::atomic< bool > shutdown_flag false
const reco::MuonRef & muonRef() const
virtual ParticleType particleId() const
std::auto_ptr< reco::PFCandidateCollection > pfElectronCandidates_
the unfiltered electron collection
double time() const
timing for cleaned hits
double neutralHadronEnergyResolution(double clusterEnergy, double clusterEta) const
todo: use PFClusterTools for this
void postClean(reco::PFCandidateCollection *)
virtual float pt() const GCC11_FINAL
transverse momentum
reco::PFCandidateElectronExtraCollection pfElectronExtra_
the unfiltered electron collection
const ElementsInBlocks & elementsInBlocks() const
bool isPhotonValidCandidate(const reco::PFBlockRef &blockRef, std::vector< bool > &active, std::auto_ptr< reco::PFCandidateCollection > &pfPhotonCandidates, std::vector< reco::PFCandidatePhotonExtra > &pfPhotonExtraCandidates, std::vector< reco::PFCandidate > &tempElectronCandidates)
void setInputsForCleaning(const reco::VertexCollection *)
bool isPhotonSafeForJetMET(const reco::Photon &, const reco::PFCandidate &)
tuple size
Write out results.
double sumPtTrackIsoForEgammaSC_barrel_
const std::auto_ptr< reco::PFCandidateCollection > & pfCandidates() const
void setHcalEnergy(float ehRaw, float ehCorr)
set corrected Hcal energy
double py() const
y coordinate of momentum vector
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, double ph_MinEt, double ph_combIso, double ph_HoE, double ph_sietaieta_eb, double ph_sietaieta_ee, const edm::ParameterSet &ph_protectionsForJetMET)
const edm::ValueMap< reco::GsfElectronRef > * valueMapGedElectrons_
void setElectronExtraRef(const edm::OrphanHandle< reco::PFCandidateElectronExtraCollection > &extrah)
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